aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/thialfihar/android/apg/Apg.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/thialfihar/android/apg/Apg.java')
-rw-r--r--src/org/thialfihar/android/apg/Apg.java197
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) {