|
|
@@ -2,22 +2,37 @@ package info.knacki.pass.io;
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
|
+import org.bouncycastle.bcpg.ArmoredOutputStream;
|
|
|
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
import org.bouncycastle.openpgp.PGPCompressedData;
|
|
|
+import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
|
|
|
+import org.bouncycastle.openpgp.PGPEncryptedData;
|
|
|
+import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
|
|
|
import org.bouncycastle.openpgp.PGPEncryptedDataList;
|
|
|
import org.bouncycastle.openpgp.PGPException;
|
|
|
import org.bouncycastle.openpgp.PGPLiteralData;
|
|
|
+import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
|
|
|
import org.bouncycastle.openpgp.PGPObjectFactory;
|
|
|
-import org.bouncycastle.openpgp.PGPOnePassSignature;
|
|
|
-import org.bouncycastle.openpgp.PGPOnePassSignatureList;
|
|
|
+import org.bouncycastle.openpgp.PGPPBEEncryptedData;
|
|
|
import org.bouncycastle.openpgp.PGPPrivateKey;
|
|
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
|
|
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
|
|
|
-import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
|
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
|
|
+import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
|
|
import org.bouncycastle.openpgp.PGPSignature;
|
|
|
-import org.bouncycastle.openpgp.PGPSignatureList;
|
|
|
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
|
|
|
+import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
|
|
|
import org.bouncycastle.openpgp.PGPUtil;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
|
|
+import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
|
|
+import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
|
|
+import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
|
|
+import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
|
|
import org.bouncycastle.util.io.Streams;
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
@@ -27,10 +42,12 @@ import java.io.FileNotFoundException;
|
|
|
import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
+import java.io.OutputStream;
|
|
|
import java.nio.charset.Charset;
|
|
|
-import java.security.NoSuchProviderException;
|
|
|
-import java.security.SignatureException;
|
|
|
+import java.security.Security;
|
|
|
+import java.util.Date;
|
|
|
import java.util.Iterator;
|
|
|
+import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
import info.knacki.pass.git.GitInterface;
|
|
|
@@ -49,23 +66,23 @@ class GPGFileInterface implements IFileInterface {
|
|
|
fPasswordGetter = passwordGetter;
|
|
|
}
|
|
|
|
|
|
- private boolean TryPassword(PGPSecretKey pgpSecKey, String pass, GitInterface.OnResponseListener<PGPPrivateKey> onResponse) {
|
|
|
+ private boolean TryPassword(PGPSecretKey pgpSecKey, String pass, GitInterface.OnResponseListener<PGPPrivateKeyAndPass> onResponse) {
|
|
|
try {
|
|
|
- PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(pass.toCharArray(), "BC");
|
|
|
- onResponse.onResponse(pgpPrivKey);
|
|
|
- return true;
|
|
|
- }
|
|
|
- catch (NoSuchProviderException e) {
|
|
|
- onResponse.onError(e.getMessage(), e);
|
|
|
+ PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(pass.toCharArray()));
|
|
|
+ PGPPrivateKeyAndPass res = new PGPPrivateKeyAndPass();
|
|
|
+ res.key = pgpPrivKey;
|
|
|
+ res.pass = pass;
|
|
|
+ onResponse.onResponse(res);
|
|
|
return true;
|
|
|
}
|
|
|
catch (PGPException e) {
|
|
|
// Wrong password
|
|
|
+ log.log(Level.INFO, e.getMessage() +" (wrong password ?)", e);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- protected boolean FindSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, final GitInterface.OnResponseListener<PGPPrivateKey> onResponse) throws PGPException {
|
|
|
+ protected boolean FindSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, final GitInterface.OnResponseListener<PGPPrivateKeyAndPass> onResponse) throws PGPException {
|
|
|
final PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);
|
|
|
|
|
|
if (pgpSecKey != null) {
|
|
|
@@ -93,88 +110,82 @@ class GPGFileInterface implements IFileInterface {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ private InputStream getFirstLiteralDataInputStream(InputStream in, PGPPrivateKeyAndPass pKey) throws IOException, PGPException {
|
|
|
+ PGPObjectFactory pof = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
|
|
|
+ Object po;
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ po = pof.nextObject();
|
|
|
+
|
|
|
+ if (po == null) {
|
|
|
+ break;
|
|
|
+ } else if (po instanceof PGPCompressedData) {
|
|
|
+ InputStream ret = getFirstLiteralDataInputStream(((PGPCompressedData) po).getDataStream(), pKey);
|
|
|
+
|
|
|
+ if (ret != null) return ret;
|
|
|
+ } else if (po instanceof PGPLiteralData) {
|
|
|
+ return ((PGPLiteralData) po).getDataStream();
|
|
|
+ } else if (po instanceof PGPEncryptedDataList) {
|
|
|
+ for (Iterator<PGPEncryptedData> it = ((PGPEncryptedDataList) po).getEncryptedDataObjects(); it.hasNext();) {
|
|
|
+ PGPEncryptedData ped = it.next();
|
|
|
+
|
|
|
+ if (ped instanceof PGPPublicKeyEncryptedData) {
|
|
|
+ PGPPublicKeyEncryptedData pked = (PGPPublicKeyEncryptedData) ped;
|
|
|
+
|
|
|
+ InputStream ret = getFirstLiteralDataInputStream(pked.getDataStream(new BcPublicKeyDataDecryptorFactory(pKey.key)), pKey);
|
|
|
+
|
|
|
+ if (ret != null) return ret;
|
|
|
+ // TODO: To verify integrity,
|
|
|
+ // we need to keep the
|
|
|
+ // pked reference.
|
|
|
+ } else if (ped instanceof PGPPBEEncryptedData) {
|
|
|
+ PGPPBEEncryptedData pped = (PGPPBEEncryptedData) ped;
|
|
|
+
|
|
|
+ InputStream ret = getFirstLiteralDataInputStream(pped.getDataStream(new BcPBEDataDecryptorFactory(pKey.pass.toCharArray(), new BcPGPDigestCalculatorProvider())), pKey);
|
|
|
+
|
|
|
+ if (ret != null) return ret;
|
|
|
+ } else {
|
|
|
+ throw new IOException("Unknown encryption packet");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private class PGPPrivateKeyAndPass {
|
|
|
+ public PGPPrivateKey key;
|
|
|
+ public String pass;
|
|
|
+ }
|
|
|
+
|
|
|
public void DecryptFile(final GitInterface.OnResponseListener<byte[]> resp) throws IOException, PGPException {
|
|
|
- PGPObjectFactory pgpF = new PGPObjectFactory(PGPUtil.getDecoderStream(new FileInputStream(fFile)));
|
|
|
+ PGPObjectFactory pgpF = new PGPObjectFactory(PGPUtil.getDecoderStream(new FileInputStream(fFile)), new JcaKeyFingerprintCalculator());
|
|
|
Object o = pgpF.nextObject();
|
|
|
- PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(new FileInputStream(fKeyFile)));
|
|
|
- Iterator<?> it = ((o instanceof PGPEncryptedDataList) ? (PGPEncryptedDataList) o : (PGPEncryptedDataList) pgpF.nextObject()).getEncryptedDataObjects();
|
|
|
+ final Iterator<?> it = ((o instanceof PGPEncryptedDataList) ? (PGPEncryptedDataList) o : (PGPEncryptedDataList) pgpF.nextObject()).getEncryptedDataObjects();
|
|
|
|
|
|
while (it.hasNext()) {
|
|
|
final PGPPublicKeyEncryptedData pbe = (PGPPublicKeyEncryptedData) it.next();
|
|
|
|
|
|
- if (FindSecretKey(pgpSec, pbe.getKeyID(), new GitInterface.OnResponseListener<PGPPrivateKey>() {
|
|
|
+ if (FindSecretKey(
|
|
|
+ new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(new FileInputStream(fKeyFile)), new JcaKeyFingerprintCalculator()),
|
|
|
+ pbe.getKeyID(),
|
|
|
+ new GitInterface.OnResponseListener<PGPPrivateKeyAndPass>() {
|
|
|
@Override
|
|
|
- public void onResponse(PGPPrivateKey sKey) {
|
|
|
+ public void onResponse(PGPPrivateKeyAndPass sKey) {
|
|
|
byte[] output;
|
|
|
try {
|
|
|
- InputStream clear = pbe.getDataStream(sKey, "BC");
|
|
|
- PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
|
|
- Object message = null;
|
|
|
- PGPOnePassSignatureList onePassSignatureList = null;
|
|
|
- PGPSignatureList signatureList = null;
|
|
|
- PGPCompressedData compressedData = null;
|
|
|
- message = plainFact.nextObject();
|
|
|
- ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();
|
|
|
-
|
|
|
- while (message != null) {
|
|
|
- log.info(message.toString());
|
|
|
- if (message instanceof PGPCompressedData) {
|
|
|
- compressedData = (PGPCompressedData) message;
|
|
|
- plainFact = new PGPObjectFactory(compressedData.getDataStream());
|
|
|
- message = plainFact.nextObject();
|
|
|
- }
|
|
|
-
|
|
|
- if (message instanceof PGPLiteralData) {
|
|
|
- Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput);
|
|
|
- } else if (message instanceof PGPOnePassSignatureList) {
|
|
|
- onePassSignatureList = (PGPOnePassSignatureList) message;
|
|
|
- } else if (message instanceof PGPSignatureList) {
|
|
|
- signatureList = (PGPSignatureList) message;
|
|
|
- } else {
|
|
|
- throw new PGPException("message unknown message type.");
|
|
|
- }
|
|
|
- message = plainFact.nextObject();
|
|
|
+ BcPublicKeyDataDecryptorFactory publicKeyDataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(sKey.key);
|
|
|
+ InputStream ss = getFirstLiteralDataInputStream(pbe.getDataStream(publicKeyDataDecryptorFactory), sKey);
|
|
|
+ if (null == ss) {
|
|
|
+ resp.onError("No literal GPG data found", null);
|
|
|
+ return;
|
|
|
}
|
|
|
+ ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();
|
|
|
+ Streams.pipeAll(ss, actualOutput);
|
|
|
actualOutput.close();
|
|
|
- PGPPublicKey publicKey = null;
|
|
|
output = actualOutput.toByteArray();
|
|
|
- if (onePassSignatureList == null || signatureList == null) {
|
|
|
- log.warning("Poor PGP. Signatures not found.");
|
|
|
- resp.onResponse(output);
|
|
|
- return;
|
|
|
- } else {
|
|
|
-
|
|
|
- for (int i = 0; i < onePassSignatureList.size(); i++) {
|
|
|
- PGPOnePassSignature ops = onePassSignatureList.get(0);
|
|
|
- log.info("verifier : " + ops.getKeyID());
|
|
|
- PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(new FileInputStream(fKeyFile)));
|
|
|
- publicKey = pgpRing.getPublicKey(ops.getKeyID());
|
|
|
- if (publicKey != null) {
|
|
|
- // FIXME ops.init(publicKey, "BC");
|
|
|
- ops.update(output);
|
|
|
- PGPSignature signature = signatureList.get(i);
|
|
|
- if (ops.verify(signature)) {
|
|
|
- Iterator<?> userIds = publicKey.getUserIDs();
|
|
|
- while (userIds.hasNext()) {
|
|
|
- String userId = (String) userIds.next();
|
|
|
- log.info("Signed by " + userId);
|
|
|
- }
|
|
|
- log.info("Signature verified");
|
|
|
- } else {
|
|
|
- throw new SignatureException("Signature verification failed");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (pbe.isIntegrityProtected() && !pbe.verify()) {
|
|
|
- throw new PGPException("Data is integrity protected but integrity is lost.");
|
|
|
- } else if (publicKey == null) {
|
|
|
- throw new SignatureException("Signature not found");
|
|
|
- }
|
|
|
}
|
|
|
- catch (Throwable e) {
|
|
|
+ catch (PGPException | IOException e) {
|
|
|
resp.onError(e.getMessage(), e);
|
|
|
return;
|
|
|
}
|
|
|
@@ -183,18 +194,179 @@ class GPGFileInterface implements IFileInterface {
|
|
|
|
|
|
@Override
|
|
|
public void onError(String msg, Throwable e) {
|
|
|
-
|
|
|
+ resp.onError(msg, e);
|
|
|
}
|
|
|
}))
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void CryptFile(FileOutputStream file, byte[] data) {
|
|
|
+ private void FindPassword(final PGPSecretKey pgpSecKey, final GitInterface.OnResponseListener<PGPPrivateKeyAndPass> resp) {
|
|
|
+ if (!TryPassword(pgpSecKey, "", resp)) {
|
|
|
+ GitInterface.OnResponseListener<String> onResp = new GitInterface.OnResponseListener<String>() {
|
|
|
+ @Override
|
|
|
+ public void onResponse(String result) {
|
|
|
+ if (result == null) {
|
|
|
+ resp.onError("Invalid password", null);
|
|
|
+ } else if (!TryPassword(pgpSecKey, result, resp)) {
|
|
|
+ fPasswordGetter.WrongPassword();
|
|
|
+ fPasswordGetter.GetPassword(this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(String msg, Throwable e) {
|
|
|
+ resp.onError(msg, e);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ fPasswordGetter.GetPassword(onResp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PGPSecretKey findSecretKey(InputStream in) throws IOException, PGPException {
|
|
|
+ in = PGPUtil.getDecoderStream(in);
|
|
|
+ PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in, new JcaKeyFingerprintCalculator());
|
|
|
+ PGPSecretKey key = null;
|
|
|
+ Iterator rIt = pgpSec.getKeyRings();
|
|
|
+
|
|
|
+ while (key == null && rIt.hasNext()) {
|
|
|
+ PGPSecretKeyRing kRing = (PGPSecretKeyRing) rIt.next();
|
|
|
+ Iterator kIt = kRing.getSecretKeys();
|
|
|
+
|
|
|
+ while (key == null && kIt.hasNext()) {
|
|
|
+ PGPSecretKey k = (PGPSecretKey) kIt.next();
|
|
|
+
|
|
|
+ if (k.isSigningKey()) {
|
|
|
+ key = k;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (key == null) {
|
|
|
+ throw new IllegalArgumentException("Can't find signing key in key ring.");
|
|
|
+ }
|
|
|
+ return key;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PGPPublicKey findPublicKey(InputStream in) throws IOException, PGPException {
|
|
|
+ return findSecretKey(in).getPublicKey();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CryptFile(final OutputStream fileOutStream, final byte[] data, final GitInterface.OnResponseListener<Void> resp) {
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
+ final PGPEncryptedDataGenerator pedg = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_256));
|
|
|
+ final ArmoredOutputStream armoredOutput = new ArmoredOutputStream(fileOutStream);
|
|
|
+ final PGPSecretKey secretKey;
|
|
|
+
|
|
|
+ try {
|
|
|
+ secretKey = findSecretKey(new FileInputStream(fKeyFile));
|
|
|
+ }
|
|
|
+ catch (Throwable e) {
|
|
|
+ resp.onError(e.getMessage(), e);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ FindPassword(secretKey, new GitInterface.OnResponseListener<PGPPrivateKeyAndPass>() {
|
|
|
+ @Override
|
|
|
+ public void onResponse(PGPPrivateKeyAndPass privateKey) {
|
|
|
+ try {
|
|
|
+ PGPSignatureGenerator sg = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1));
|
|
|
+ pedg.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(secretKey.getPublicKey()));
|
|
|
+ OutputStream encryptdOutStream = pedg.open(armoredOutput, new byte[1 << 16]);
|
|
|
+ PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( PGPCompressedData.UNCOMPRESSED);
|
|
|
+ OutputStream compressedOutStream = comData.open(encryptdOutStream);
|
|
|
+
|
|
|
+ sg.init(PGPSignature.BINARY_DOCUMENT, privateKey.key);
|
|
|
+ Iterator it = secretKey.getPublicKey().getUserIDs();
|
|
|
+ if (it.hasNext()) {
|
|
|
+ PGPSignatureSubpacketGenerator ssg = new PGPSignatureSubpacketGenerator();
|
|
|
+ ssg.setSignerUserID(false, (String) it.next());
|
|
|
+ sg.setHashedSubpackets(ssg.generate());
|
|
|
+ }
|
|
|
+ sg.generateOnePassVersion(false).encode(compressedOutStream);
|
|
|
+
|
|
|
+ PGPLiteralDataGenerator lg = new PGPLiteralDataGenerator();
|
|
|
+ OutputStream literalDataOutStream = lg.open(compressedOutStream, PGPLiteralData.BINARY, PGPLiteralDataGenerator.CONSOLE, new Date(), data);
|
|
|
+
|
|
|
+ literalDataOutStream.write(data);
|
|
|
+ //sg.update(data);
|
|
|
+ sg.generate().encode(compressedOutStream);
|
|
|
+ literalDataOutStream.close();
|
|
|
+ lg.close();
|
|
|
+ compressedOutStream.close();
|
|
|
+ comData.close();
|
|
|
+ pedg.close();
|
|
|
+ armoredOutput.close();
|
|
|
+ resp.onResponse(null);
|
|
|
+ }
|
|
|
+ catch (Throwable e) {
|
|
|
+ resp.onError(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(String msg, Throwable e) {
|
|
|
+ resp.onError(msg, e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ This one do write, but ???9 instead of 12359*
|
|
|
+ private void CryptFile(OutputStream fileOutStream, final byte[] data, final GitInterface.OnResponseListener<Void> resp) {
|
|
|
+ if (null == Security.getProvider(BouncyCastleProvider.PROVIDER_NAME)) {
|
|
|
+ Security.addProvider(new BouncyCastleProvider());
|
|
|
+ }
|
|
|
+
|
|
|
+ final PGPEncryptedDataGenerator pedg = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TWOFISH));
|
|
|
+ ArmoredOutputStream aos = new ArmoredOutputStream(fileOutStream);
|
|
|
+
|
|
|
+ try {
|
|
|
+ pedg.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(findPublicKey(new FileInputStream(fKeyFile))));
|
|
|
+ PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.UNCOMPRESSED);
|
|
|
+ OutputStream compressedOutStream = comData.open(pedg.open(aos, new byte[1 << 16]));
|
|
|
+
|
|
|
+ PGPLiteralDataGenerator lg = new PGPLiteralDataGenerator();
|
|
|
+ OutputStream literalDataOutStream = lg.open(compressedOutStream, PGPLiteralData.TEXT, "-", new Date(), data);
|
|
|
+ literalDataOutStream.write(data);
|
|
|
+ literalDataOutStream.close();
|
|
|
+ lg.close();
|
|
|
+
|
|
|
+ compressedOutStream.close();
|
|
|
+ comData.close();
|
|
|
+ literalDataOutStream.close();
|
|
|
+ pedg.close();
|
|
|
+ aos.close();
|
|
|
+ fileOutStream.close();
|
|
|
+ resp.onResponse(null);
|
|
|
+ }
|
|
|
+ catch (Throwable e) {
|
|
|
+ resp.onError(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ private void CryptFile(final OutputStream fileOutStream, final byte[] data, final GitInterface.OnResponseListener<Void> resp) {
|
|
|
+ try {
|
|
|
+ PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
|
|
|
+ OutputStream pOut = lData.open(fileOutStream, PGPLiteralDataGenerator.TEXT, "-", new Date(), data);
|
|
|
+ pOut.write(data, 0, data.length);
|
|
|
+ lData.close();
|
|
|
+ fileOutStream.close();
|
|
|
+ resp.onResponse(null);
|
|
|
+ }
|
|
|
+ catch (IOException e) {
|
|
|
+ resp.onError(e.getMessage(), e);
|
|
|
+ }
|
|
|
}
|
|
|
+ */
|
|
|
|
|
|
@Override
|
|
|
public void ReadFile(final GitInterface.OnResponseListener<String> resp) {
|
|
|
+ if (fFile.length() == 0) {
|
|
|
+ resp.onResponse("");
|
|
|
+ return;
|
|
|
+ }
|
|
|
try {
|
|
|
if (fKeyFile == null)
|
|
|
throw new FileNotFoundException("GPG key not set");
|
|
|
@@ -215,9 +387,14 @@ class GPGFileInterface implements IFileInterface {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void WriteFile(String content) throws IOException {
|
|
|
- if (fKeyFile == null)
|
|
|
- throw new FileNotFoundException("GPG key not set");
|
|
|
- CryptFile(new FileOutputStream(fFile), content.getBytes());
|
|
|
+ public void WriteFile(String content, GitInterface.OnResponseListener<Void> resp) {
|
|
|
+ try {
|
|
|
+ if (fKeyFile == null)
|
|
|
+ throw new FileNotFoundException("GPG key not set");
|
|
|
+ CryptFile(new FileOutputStream(fFile), content.getBytes(), resp);
|
|
|
+ }
|
|
|
+ catch (Throwable e) {
|
|
|
+ resp.onError(e.getMessage(), e);
|
|
|
+ }
|
|
|
}
|
|
|
}
|