use of net.i2p.util.SecureFileOutputStream in project i2p.i2p by i2p.
the class ConfigClientsHandler method installPluginFromFile.
/**
* @since 0.9.19
*/
private void installPluginFromFile() {
InputStream in = _requestWrapper.getInputStream("pluginFile");
// go to some trouble to verify it's an su3 or xpi2p file before
// passing it along, so we can display a good error message
byte[] su3Magic = DataHelper.getASCII(SU3File.MAGIC);
byte[] zipMagic = new byte[] { 0x50, 0x4b, 0x03, 0x04 };
byte[] magic = new byte[TrustedUpdate.HEADER_BYTES + zipMagic.length];
File tmp = null;
OutputStream out = null;
try {
// non-null but zero bytes if no file entered, don't know why
if (in == null || in.available() <= 0) {
addFormError(_t("You must enter a file"));
return;
}
DataHelper.read(in, magic);
boolean isSU3 = DataHelper.eq(magic, 0, su3Magic, 0, su3Magic.length);
if (!isSU3) {
if (!DataHelper.eq(magic, TrustedUpdate.HEADER_BYTES, zipMagic, 0, zipMagic.length)) {
String name = _requestWrapper.getFilename("pluginFile");
if (name == null)
name = "File";
throw new IOException(name + " is not an xpi2p or su3 plugin");
}
}
tmp = new File(_context.getTempDir(), "plugin-" + _context.random().nextInt() + (isSU3 ? ".su3" : ".xpi2p"));
out = new BufferedOutputStream(new SecureFileOutputStream(tmp));
out.write(magic);
DataHelper.copy(in, out);
out.close();
String url = tmp.toURI().toString();
// threaded... TODO inline to get better result to UI?
installPlugin(null, url);
// above sleeps 1000, give it some more time?
// or check for complete?
ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
if (mgr == null)
return;
for (int i = 0; i < 20; i++) {
if (!mgr.isUpdateInProgress(PLUGIN)) {
tmp.delete();
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
String status = mgr.getStatus();
if (status != null && status.length() > 0)
addFormNoticeNoEscape(status);
} catch (IOException ioe) {
addFormError(_t("Install from file failed") + " - " + ioe.getMessage());
} finally {
// it's really a ByteArrayInputStream but we'll play along...
if (in != null)
try {
in.close();
} catch (IOException ioe) {
}
if (out != null)
try {
out.close();
} catch (IOException ioe) {
}
}
}
use of net.i2p.util.SecureFileOutputStream in project i2p.i2p by i2p.
the class KeyStoreUtil method importPrivateKey.
/**
* Import the private key and certificate chain to a keystore.
* Keystore will be created if it does not exist.
* Private key MUST be first in the stream.
* Closes the stream. Throws on all errors.
*
* @param ks path to the keystore
* @param ksPW the keystore password, may be null
* @param alias the name of the key. If null, will be taken from the Subject CN
* of the first certificate in the chain.
* @param keyPW the key password, must be at least 6 characters
* @return the alias as specified or extracted
* @since 0.9.25
*/
public static String importPrivateKey(File ks, String ksPW, String alias, String keyPW, InputStream in) throws GeneralSecurityException, IOException {
OutputStream fos = null;
try {
KeyStore keyStore = createKeyStore(ks, ksPW);
PrivateKey pk = CertUtil.loadPrivateKey(in);
List<X509Certificate> certs = CertUtil.loadCerts(in);
if (alias == null) {
alias = CertUtil.getSubjectValue(certs.get(0), "CN");
if (alias == null)
throw new GeneralSecurityException("no alias specified and no Subject CN in cert");
if (alias.endsWith(".family.i2p.net") && alias.length() > ".family.i2p.net".length())
alias = alias.substring(0, ".family.i2p.net".length());
}
keyStore.setKeyEntry(alias, pk, keyPW.toCharArray(), certs.toArray(new Certificate[certs.size()]));
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
fos = new SecureFileOutputStream(ks);
keyStore.store(fos, pwchars);
return alias;
} finally {
if (fos != null)
try {
fos.close();
} catch (IOException ioe) {
}
try {
in.close();
} catch (IOException ioe) {
}
}
}
use of net.i2p.util.SecureFileOutputStream in project i2p.i2p by i2p.
the class SU3File method verifyAndMigrate.
/**
* One-pass verify and extract the content.
* Recommend extracting to a temp location as the sig is not checked until
* after extraction. This will delete the file if the sig does not verify.
* Throws IOE on all format errors.
*
* @param migrateTo the output file, probably in zip format. Null for verify only.
* @return true if signature is good
*/
public boolean verifyAndMigrate(File migrateTo) throws IOException {
InputStream in = null;
FileOutputStream out = null;
boolean rv = false;
try {
in = new BufferedInputStream(new FileInputStream(_file));
// read 10 bytes to get the sig type
in.mark(10);
// following is a dup of that in verifyHeader()
byte[] magic = new byte[MAGIC_BYTES.length];
DataHelper.read(in, magic);
if (!DataHelper.eq(magic, MAGIC_BYTES))
throw new IOException("Not an su3 file");
skip(in, 1);
int foo = in.read();
if (foo != FILE_VERSION)
throw new IOException("bad file version");
skip(in, 1);
int sigTypeCode = in.read();
_sigType = SigType.getByCode(sigTypeCode);
if (_sigType == null)
throw new IOException("unknown sig type: " + sigTypeCode);
// end duplicate code
// rewind
in.reset();
MessageDigest md = _sigType.getDigestInstance();
DigestInputStream din = new DigestInputStream(in, md);
in = din;
if (!_headerVerified)
verifyHeader(in);
else
skip(in, getContentOffset());
if (_verifySignature) {
if (_signerPubkey == null)
throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
}
if (// else verify only
migrateTo != null)
out = new SecureFileOutputStream(migrateTo);
byte[] buf = new byte[16 * 1024];
long tot = 0;
while (tot < _contentLength) {
int read = in.read(buf, 0, (int) Math.min(buf.length, _contentLength - tot));
if (read < 0)
throw new EOFException();
if (// else verify only
migrateTo != null)
out.write(buf, 0, read);
tot += read;
}
if (_verifySignature) {
byte[] sha = md.digest();
din.on(false);
Signature signature = new Signature(_sigType);
signature.readBytes(in);
int avail = in.available();
if (avail > 0)
throw new IOException(avail + " bytes data after sig");
SimpleDataStructure hash = _sigType.getHashInstance();
hash.setData(sha);
// System.out.println("hash\n" + HexDump.dump(sha));
// System.out.println("sig\n" + HexDump.dump(signature.getData()));
rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
} else {
rv = true;
}
} catch (DataFormatException dfe) {
IOException ioe = new IOException("foo");
ioe.initCause(dfe);
throw ioe;
} finally {
if (in != null)
try {
in.close();
} catch (IOException ioe) {
}
if (out != null) {
// so do a POSIX flush and sync to ensure it will be there.
try {
out.flush();
out.getFD().sync();
} catch (IOException ioe) {
}
try {
out.close();
} catch (IOException ioe) {
}
}
if (migrateTo != null && !rv)
migrateTo.delete();
}
return rv;
}
use of net.i2p.util.SecureFileOutputStream in project i2p.i2p by i2p.
the class CertUtil method saveCRL.
/**
* Write a CRL to a file in base64 format.
*
* @return success
* @since 0.9.25
*/
public static boolean saveCRL(X509CRL crl, File file) {
OutputStream os = null;
try {
os = new SecureFileOutputStream(file);
exportCRL(crl, os);
return true;
} catch (CRLException ce) {
error("Error writing X509 CRL " + file.getAbsolutePath(), ce);
return false;
} catch (IOException ioe) {
error("Error writing X509 CRL " + file.getAbsolutePath(), ioe);
return false;
} finally {
try {
if (os != null)
os.close();
} catch (IOException foo) {
}
}
}
use of net.i2p.util.SecureFileOutputStream in project i2p.i2p by i2p.
the class SingleFileNamingService method put.
/**
* @param hostname case-sensitive; caller should convert to lower case
* @param options if non-null, any prefixed with '=' will be appended
* in subscription format
*/
@Override
public boolean put(String hostname, Destination d, Properties options) {
// try easy way first, most adds are not replaces
if (putIfAbsent(hostname, d, options))
return true;
if (!getWriteLock())
return false;
BufferedReader in = null;
BufferedWriter out = null;
try {
if (_isClosed)
return false;
File tmp = SecureFile.createTempFile("temp-", ".tmp", _file.getAbsoluteFile().getParentFile());
out = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8"));
if (_file.exists()) {
in = new BufferedReader(new InputStreamReader(new FileInputStream(_file), "UTF-8"), 16 * 1024);
String line = null;
String search = hostname + '=';
while ((line = in.readLine()) != null) {
if (line.startsWith(search))
continue;
out.write(line);
out.newLine();
}
in.close();
}
out.write(hostname);
out.write('=');
out.write(d.toBase64());
// subscription options
if (options != null)
writeOptions(options, out);
out.newLine();
out.close();
boolean success = FileUtil.rename(tmp, _file);
if (success) {
for (NamingServiceListener nsl : _listeners) {
nsl.entryChanged(this, hostname, d, options);
}
}
return success;
} catch (IOException ioe) {
_log.error("Error adding " + hostname, ioe);
return false;
} finally {
if (in != null)
try {
in.close();
} catch (IOException e) {
}
if (out != null)
try {
out.close();
} catch (IOException e) {
}
releaseWriteLock();
}
}
Aggregations