diff options
Diffstat (limited to 'OpenKeychain/src')
5 files changed, 34 insertions, 27 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index 00f73a5b0..69244ca14 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -313,6 +313,11 @@ public class PgpKeyOperation { for (String userId : saveParcel.mAddUserIds) { log.add(LogLevel.INFO, LogType.MSG_MF_UID_ADD, indent); + if (userId.equals("")) { + log.add(LogLevel.ERROR, LogType.MSG_MF_UID_ERROR_EMPTY, indent+1); + return null; + } + // this operation supersedes all previous binding and revocation certificates, // so remove those to retain assertions from canonicalization for later operations @SuppressWarnings("unchecked") diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index 6020fc084..91b06324a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -14,6 +14,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureList; import org.spongycastle.openpgp.PGPUtil; +import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; @@ -24,6 +25,7 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -193,7 +195,7 @@ public class UncachedKeyRing { * - Remove all certificates flagged as "local" * - Remove all certificates which are superseded by a newer one on the same target, * including revocations with later re-certifications. - * - Remove all certificates of unknown type: + * - Remove all certificates in other positions if not of known type: * - key revocation signatures on the master key * - subkey binding signatures for subkeys * - certifications and certification revocations for user ids @@ -658,7 +660,7 @@ public class UncachedKeyRing { return left.length - right.length; } // compare byte-by-byte - for (int i = 0; i < left.length && i < right.length; i++) { + for (int i = 0; i < left.length; i++) { if (left[i] != right[i]) { return (left[i] & 0xff) - (right[i] & 0xff); } @@ -686,7 +688,14 @@ public class UncachedKeyRing { final PGPPublicKey resultKey = result.getPublicKey(key.getKeyID()); if (resultKey == null) { log.add(LogLevel.DEBUG, LogType.MSG_MG_NEW_SUBKEY, indent); - result = replacePublicKey(result, key); + // special case: if both rings are secret, copy over the secret key + if (isSecret() && other.isSecret()) { + PGPSecretKey sKey = ((PGPSecretKeyRing) candidate).getSecretKey(key.getKeyID()); + result = PGPSecretKeyRing.insertSecretKey((PGPSecretKeyRing) result, sKey); + } else { + // otherwise, just insert the public key + result = replacePublicKey(result, key); + } continue; } @@ -694,17 +703,7 @@ public class UncachedKeyRing { PGPPublicKey modified = resultKey; // Iterate certifications - for (PGPSignature cert : new IterableIterator<PGPSignature>(key.getSignatures())) { - int type = cert.getSignatureType(); - // Disregard certifications on user ids, we will deal with those later - if (type == PGPSignature.NO_CERTIFICATION - || type == PGPSignature.DEFAULT_CERTIFICATION - || type == PGPSignature.CASUAL_CERTIFICATION - || type == PGPSignature.POSITIVE_CERTIFICATION - || type == PGPSignature.CERTIFICATION_REVOCATION) { - continue; - } - + for (PGPSignature cert : new IterableIterator<PGPSignature>(key.getKeySignatures())) { // Don't merge foreign stuff into secret keys if (cert.getKeyID() != masterKeyId && isSecret()) { continue; @@ -768,19 +767,20 @@ public class UncachedKeyRing { } - public UncachedKeyRing extractPublicKeyRing() { + public UncachedKeyRing extractPublicKeyRing() throws IOException { if(!isSecret()) { throw new RuntimeException("Tried to extract public keyring from non-secret keyring. " + "This is a programming error and should never happen!"); } - ArrayList<PGPPublicKey> keys = new ArrayList(); Iterator<PGPPublicKey> it = mRing.getPublicKeys(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(2048); while (it.hasNext()) { - keys.add(it.next()); + stream.write(it.next().getEncoded()); } - return new UncachedKeyRing(new PGPPublicKeyRing(keys)); + return new UncachedKeyRing( + new PGPPublicKeyRing(stream.toByteArray(), new JcaKeyFingerprintCalculator())); } /** This method replaces a public key in a keyring. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKeyRing.java index 57d84072a..bb1f7d778 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedPublicKeyRing.java @@ -1,14 +1,11 @@ package org.sufficientlysecure.keychain.pgp; import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.openpgp.PGPKeyRing; import org.spongycastle.openpgp.PGPObjectFactory; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.util.IterableIterator; -import org.sufficientlysecure.keychain.util.Log; import java.io.IOException; import java.util.Iterator; @@ -25,17 +22,20 @@ public class WrappedPublicKeyRing extends WrappedKeyRing { PGPPublicKeyRing getRing() { if(mRing == null) { + // get first object in block PGPObjectFactory factory = new PGPObjectFactory(mPubKey); - PGPKeyRing keyRing = null; try { - if ((keyRing = (PGPKeyRing) factory.nextObject()) == null) { - Log.e(Constants.TAG, "No keys given!"); + Object obj = factory.nextObject(); + if (! (obj instanceof PGPPublicKeyRing)) { + throw new RuntimeException("Error constructing WrappedPublicKeyRing, should never happen!"); + } + mRing = (PGPPublicKeyRing) obj; + if (factory.nextObject() != null) { + throw new RuntimeException("Encountered trailing data after keyring, should never happen!"); } } catch (IOException e) { - Log.e(Constants.TAG, "Error while converting to PGPKeyRing!", e); + throw new RuntimeException("IO Error constructing WrappedPublicKeyRing, should never happen!"); } - - mRing = (PGPPublicKeyRing) keyRing; } return mRing; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java index 89d534df6..e55ec5568 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java @@ -279,6 +279,7 @@ public class OperationResultParcel implements Parcelable { MSG_MF_UID_ADD (R.string.msg_mf_uid_add), MSG_MF_UID_PRIMARY (R.string.msg_mf_uid_primary), MSG_MF_UID_REVOKE (R.string.msg_mf_uid_revoke), + MSG_MF_UID_ERROR_EMPTY (R.string.msg_mf_uid_error_empty), MSG_MF_UNLOCK_ERROR (R.string.msg_mf_unlock_error), MSG_MF_UNLOCK (R.string.msg_mf_unlock), ; diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 55ecf3ae0..d1a20813b 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -674,6 +674,7 @@ <string name="msg_mf_uid_add">Adding user id %s</string> <string name="msg_mf_uid_primary">Changing primary uid to %s</string> <string name="msg_mf_uid_revoke">Revoking user id %s</string> + <string name="msg_mf_uid_error_empty">User ID must not be empty!</string> <string name="msg_mf_unlock_error">Error unlocking keyring!</string> <string name="msg_mf_unlock">Unlocking keyring</string> |