diff options
Diffstat (limited to 'src/org/thialfihar/android/apg/Apg.java')
-rw-r--r-- | src/org/thialfihar/android/apg/Apg.java | 197 |
1 files changed, 126 insertions, 71 deletions
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index 52f142fb9..4d898ab5e 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -119,6 +119,8 @@ public class Apg { public static final String LOOK_UP_KEY_ID = "org.thialfihar.android.apg.intent.LOOK_UP_KEY_ID"; public static final String LOOK_UP_KEY_ID_AND_RETURN = "org.thialfihar.android.apg.intent.LOOK_UP_KEY_ID_AND_RETURN"; public static final String GENERATE_SIGNATURE = "org.thialfihar.android.apg.intent.GENERATE_SIGNATURE"; + public static final String EXPORT_KEY_TO_SERVER = "org.thialfihar.android.apg.intent.EXPORT_KEY_TO_SERVER"; + public static final String IMPORT_FROM_QR_CODE = "org.thialfihar.android.apg.intent.IMPORT_FROM_QR_CODE"; } public static final String EXTRA_TEXT = "text"; @@ -147,6 +149,7 @@ public class Apg { public static final String EXTRA_ASCII_ARMOUR = "asciiArmour"; public static final String EXTRA_BINARY = "binary"; public static final String EXTRA_KEY_SERVERS = "keyServers"; + public static final String EXTRA_EXPECTED_FINGERPRINT = "org.thialfihar.android.apg.EXPECTED_FINGERPRINT"; public static final String AUTHORITY = DataProvider.AUTHORITY; @@ -598,6 +601,75 @@ public class Apg { if( progress != null ) progress.setProgress(R.string.progress_done, 100, 100); } + + public static PGPKeyRing decodeKeyRing(InputStream is) throws IOException { + InputStream in = PGPUtil.getDecoderStream(is); + PGPObjectFactory objectFactory = new PGPObjectFactory(in); + Object obj = objectFactory.nextObject(); + + if (obj instanceof PGPKeyRing) { + return (PGPKeyRing) obj; + } + + return null; + } + + public static int storeKeyRingInCache(PGPKeyRing keyring) { + int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*) + try { + if (keyring instanceof PGPSecretKeyRing) { + PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring; + boolean save = true; + try { + PGPPrivateKey testKey = secretKeyRing.getSecretKey().extractPrivateKey(new char[] {}, new BouncyCastleProvider()); + if (testKey == null) { + // this is bad, something is very wrong... likely a --export-secret-subkeys export + save = false; + status = Id.return_value.bad; + } + } catch (PGPException e) { + // all good if this fails, we likely didn't use the right password + } + + if (save) { + status = mDatabase.saveKeyRing(secretKeyRing); + } + } else if (keyring instanceof PGPPublicKeyRing) { + PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring; + status = mDatabase.saveKeyRing(publicKeyRing); + } + } catch (IOException e) { + status = Id.return_value.error; + } catch (Database.GeneralException e) { + status = Id.return_value.error; + } + + return status; + } + + public static boolean uploadKeyRingToServer(HkpKeyServer server, PGPPublicKeyRing keyring) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ArmoredOutputStream aos = new ArmoredOutputStream(bos); + try { + aos.write(keyring.getEncoded()); + aos.close(); + + String armouredKey = bos.toString("UTF-8"); + server.add(armouredKey); + + return true; + } catch (IOException e) { + return false; + } catch(AddKeyException e) { + // TODO: tell the user? + return false; + } finally { + try { + bos.close(); + } catch (IOException e) { + } + } + } public static Bundle importKeyRings(Activity context, int type, InputData data, @@ -626,65 +698,36 @@ public class Apg { int oldKeys = 0; int badKeys = 0; try { - while (true) { - InputStream in = PGPUtil.getDecoderStream(bufferedInput); - PGPObjectFactory objectFactory = new PGPObjectFactory(in); - Object obj = objectFactory.nextObject(); - // if the first is already a null object, then we can stop trying - if (obj == null) { - break; + PGPKeyRing keyring = decodeKeyRing(bufferedInput); + while (keyring != null) { + int status = Integer.MIN_VALUE; // out of bounds value + + // if this key is what we expect it to be, save it + if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing) || + (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) { + status = storeKeyRingInCache(keyring); } - while (obj != null) { - PGPPublicKeyRing publicKeyRing; - PGPSecretKeyRing secretKeyRing; - // a return value that doesn't match any Id.return_value.* values, in case - // saveKeyRing is never called - int retValue = 2107; - - try { - if (type == Id.type.secret_key && obj instanceof PGPSecretKeyRing) { - secretKeyRing = (PGPSecretKeyRing) obj; - boolean save = true; - try { - PGPPrivateKey testKey = secretKeyRing.getSecretKey() - .extractPrivateKey(new char[] {}, new BouncyCastleProvider()); - if (testKey == null) { - // this is bad, something is very wrong... likely a - // --export-secret-subkeys export - retValue = Id.return_value.bad; - save = false; - } - } catch (PGPException e) { - // all good if this fails, we likely didn't use the right password - } - if (save) { - retValue = mDatabase.saveKeyRing(secretKeyRing); - } - } else if (type == Id.type.public_key && obj instanceof PGPPublicKeyRing) { - publicKeyRing = (PGPPublicKeyRing) obj; - retValue = mDatabase.saveKeyRing(publicKeyRing); - } - } catch (IOException e) { - retValue = Id.return_value.error; - } catch (Database.GeneralException e) { - retValue = Id.return_value.error; - } - if (retValue == Id.return_value.error) { - throw new GeneralException(context.getString(R.string.error_savingKeys)); - } + if (status == Id.return_value.error) { + throw new GeneralException(context.getString(R.string.error_savingKeys)); + } - if (retValue == Id.return_value.updated) { - ++oldKeys; - } else if (retValue == Id.return_value.ok) { - ++newKeys; - } else if (retValue == Id.return_value.bad) { - ++badKeys; - } - if( progress != null ) - progress.setProgress((int)(100 * progressIn.position() / data.getSize()), 100); - obj = objectFactory.nextObject(); + // update the counts to display to the user at the end + if (status == Id.return_value.updated) { + ++oldKeys; + } else if (status == Id.return_value.ok) { + ++newKeys; + } else if (status == Id.return_value.bad) { + ++badKeys; + } + + if (progress != null) { + progress.setProgress((int)(100 * progressIn.position() / data.getSize()), 100); } + //TODO: needed? + //obj = objectFactory.nextObject(); + + keyring = decodeKeyRing(bufferedInput); } } catch (EOFException e) { // nothing to do, we are done @@ -755,6 +798,7 @@ public class Apg { return key.getPublicKey().getCreationTime(); } + @SuppressWarnings("unchecked") public static PGPPublicKey getMasterKey(PGPPublicKeyRing keyRing) { if (keyRing == null) { return null; @@ -768,6 +812,7 @@ public class Apg { return null; } + @SuppressWarnings("unchecked") public static PGPSecretKey getMasterKey(PGPSecretKeyRing keyRing) { if (keyRing == null) { return null; @@ -781,6 +826,7 @@ public class Apg { return null; } + @SuppressWarnings("unchecked") public static Vector<PGPPublicKey> getEncryptKeys(PGPPublicKeyRing keyRing) { Vector<PGPPublicKey> encryptKeys = new Vector<PGPPublicKey>(); @@ -793,6 +839,7 @@ public class Apg { return encryptKeys; } + @SuppressWarnings("unchecked") public static Vector<PGPSecretKey> getSigningKeys(PGPSecretKeyRing keyRing) { Vector<PGPSecretKey> signingKeys = new Vector<PGPSecretKey>(); @@ -900,6 +947,7 @@ public class Apg { return signingKeys.get(0); } + @SuppressWarnings("unchecked") public static String getMainUserId(PGPPublicKey key) { for (String userId : new IterableIterator<String>(key.getUserIDs())) { return userId; @@ -907,6 +955,7 @@ public class Apg { return null; } + @SuppressWarnings("unchecked") public static String getMainUserId(PGPSecretKey key) { for (String userId : new IterableIterator<String>(key.getUserIDs())) { return userId; @@ -930,6 +979,7 @@ public class Apg { return userId; } + @SuppressWarnings("unchecked") public static boolean isEncryptionKey(PGPPublicKey key) { if (!key.isEncryptionKey()) { return false; @@ -974,6 +1024,7 @@ public class Apg { return isEncryptionKey(key.getPublicKey()); } + @SuppressWarnings("unchecked") public static boolean isSigningKey(PGPPublicKey key) { if (key.getVersion() <= 3) { return true; @@ -1046,18 +1097,8 @@ public class Apg { return algorithmStr + ", " + keySize + "bit"; } - public static String getFingerPrint(long keyId) { - PGPPublicKey key = Apg.getPublicKey(keyId); - if (key == null) { - PGPSecretKey secretKey = Apg.getSecretKey(keyId); - if (secretKey == null) { - return ""; - } - key = secretKey.getPublicKey(); - } - + public static String convertToHex(byte[] fp) { String fingerPrint = ""; - byte fp[] = key.getFingerprint(); for (int i = 0; i < fp.length; ++i) { if (i != 0 && i % 10 == 0) { fingerPrint += " "; @@ -1072,6 +1113,20 @@ public class Apg { } return fingerPrint; + + } + + public static String getFingerPrint(long keyId) { + PGPPublicKey key = Apg.getPublicKey(keyId); + if (key == null) { + PGPSecretKey secretKey = Apg.getSecretKey(keyId); + if (secretKey == null) { + return ""; + } + key = secretKey.getPublicKey(); + } + + return convertToHex(key.getFingerprint()); } public static String getSmallFingerPrint(long keyId) { @@ -1097,8 +1152,8 @@ public class Apg { mDatabase.deleteKeyRing(keyRingId); } - public static Object getKeyRing(int keyRingId) { - return mDatabase.getKeyRing(keyRingId); + public static PGPKeyRing getKeyRing(int keyRingId) { + return (PGPKeyRing) mDatabase.getKeyRing(keyRingId); } public static PGPSecretKeyRing getSecretKeyRing(long keyId) { @@ -1117,7 +1172,7 @@ public class Apg { } return null; } - + public static PGPPublicKeyRing getPublicKeyRing(long keyId) { byte[] data = mDatabase.getKeyRingDataFromKeyId(Id.database.type_public, keyId); if (data == null) { @@ -1145,8 +1200,8 @@ public class Apg { if (keyRing == null) { return null; } - return keyRing.getPublicKey(keyId); - + + return keyRing.getPublicKey(keyId); } public static Vector<Integer> getKeyRingIds(int type) { |