From 706e60474d15f833ad5ead519518775812978bac Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 28 Sep 2014 14:25:54 +0200 Subject: be more mindful of algorithm and usage flag interaction Fixes #895 --- .../keychain/pgp/UncachedKeyRing.java | 40 ++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java') 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 0e9377890..b4842b0a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -619,8 +619,7 @@ public class UncachedKeyRing { boolean needsPrimaryBinding = false; // If the algorithm is even suitable for signing - if (key.getAlgorithm() != PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT - && key.getAlgorithm() != PublicKeyAlgorithmTags.RSA_ENCRYPT) { + if (isSigningAlgo(key.getAlgorithm())) { // If this certificate says it allows signing for the key if (zert.getHashedSubPackets() != null && @@ -722,6 +721,24 @@ public class UncachedKeyRing { continue; } + // If we have flags, check if the algorithm supports all of them + if (selfCert.getHashedSubPackets() == null + && selfCert.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.KEY_FLAGS)) { + int flags = ((KeyFlags) selfCert.getHashedSubPackets().getSubpacket(SignatureSubpacketTags.KEY_FLAGS)).getFlags(); + int algo = key.getAlgorithm(); + // If this is a signing key, but not a signing algorithm, warn the user + if (!isSigningAlgo(algo) && (flags & PGPKeyFlags.CAN_SIGN) == PGPKeyFlags.CAN_SIGN) { + log.add(LogType.MSG_KC_SUB_ALGO_BAD_SIGN, indent); + } + // If this is an encryption key, but not an encryption algorithm, warn the user + if (!isEncryptionAlgo(algo) && ( + (flags & PGPKeyFlags.CAN_ENCRYPT_COMMS) == PGPKeyFlags.CAN_ENCRYPT_COMMS + || (flags & PGPKeyFlags.CAN_ENCRYPT_STORAGE) == PGPKeyFlags.CAN_ENCRYPT_STORAGE + )) { + log.add(LogType.MSG_KC_SUB_ALGO_BAD_ENCRYPT, indent); + } + } + // re-add certification modified = PGPPublicKey.addCertification(modified, selfCert); // add revocation, if any @@ -953,4 +970,23 @@ public class UncachedKeyRing { } } + + /** Returns true if the algorithm is of a type which is suitable for signing. */ + static boolean isSigningAlgo(int algorithm) { + return algorithm == PGPPublicKey.RSA_GENERAL + || algorithm == PGPPublicKey.RSA_SIGN + || algorithm == PGPPublicKey.DSA + || algorithm == PGPPublicKey.ELGAMAL_GENERAL + || algorithm == PGPPublicKey.ECDSA; + } + + /** Returns true if the algorithm is of a type which is suitable for encryption. */ + static boolean isEncryptionAlgo(int algorithm) { + return algorithm == PGPPublicKey.RSA_GENERAL + || algorithm == PGPPublicKey.RSA_ENCRYPT + || algorithm == PGPPublicKey.ELGAMAL_ENCRYPT + || algorithm == PGPPublicKey.ELGAMAL_GENERAL + || algorithm == PGPPublicKey.ECDH; + } + } -- cgit v1.2.3