From e2d51b86f5c1d1c23b744e5c32539a739bfa4c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 2 Sep 2014 17:16:04 +0200 Subject: If no key flags subpacket is present allow all key flags, fixes mailvelope keys --- .../test-keys/mailvelope_07_no_key_flags.asc | 20 ++++++ .../keychain/pgp/UncachedPublicKey.java | 71 ++++++++++++++-------- 2 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 OpenKeychain-Test/src/test/resources/test-keys/mailvelope_07_no_key_flags.asc diff --git a/OpenKeychain-Test/src/test/resources/test-keys/mailvelope_07_no_key_flags.asc b/OpenKeychain-Test/src/test/resources/test-keys/mailvelope_07_no_key_flags.asc new file mode 100644 index 000000000..30e6b85e1 --- /dev/null +++ b/OpenKeychain-Test/src/test/resources/test-keys/mailvelope_07_no_key_flags.asc @@ -0,0 +1,20 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: Mailvelope v0.7.0 +Comment: Email security by Mailvelope - http://www.mailvelope.com + +xsBNBFL9xMwBCACAa8z36B4Z4Yvpo7s4Y8jQsHNrJygyd8mh9+Bd3Sg+zt0Z +UjfNS3SfwXocBTGOXrFlS0bRKd2CRXeXdTO0HqjCEKhGKHX73UhAcpBUoTV7 +6cgpYtKZL4tkIYWn47UPoASujjpwHxbDGaas/kmsTFPrlh8x5VOdEEVFkqPC +wP1tnX1WALO58BWbs4R1vqrqBrOrGclm9cF2mErWP9QBLR/nH+soaVPK3Hrj +/fX4S43xIxuhKmdZsljrfK7jsUkcF187QkK7xpyS5XSyoosPYIF/d06sVNlZ +XlFFlJXuyndwnRA/VJHowa4hqFFQf1PjxV3g7IVqZfbtOX+SpcLCW507ABEB +AAHNKlRlc3QgTWFpbCA8bWFpbHZlbG9wZUBzb21ld2hlcmUtZ21haWwuY29t +PsLAXAQQAQgAEAUCUv3EzwkQ3CnDbfC4HTYAAIMAB/9AolqHiQun6rxyKgF5 +u9hgufo6FziYAtCQelRnUtONsGGUz6mvPsVliNsfbg0BAqwzeExXGBtsIoOv +YAQ3a9zkK3lZSzO7lJIrg4UJyvqZAB6Vp5kJLJnWO1sfe4Pg8Xr8heawp2Hk +na3MPma+ISb2jiioq8wGZHfSMdTYWPYSHf6645yKvfIZGSaG8TOtFYsASSHh +ECfo6mQ+N/akF9pNI1S54RiZinssDn/vy2ZUUPpJGpaHDJ7zf6dATobaV+dV +uqroe00SyJbYPzwKhEo7NgTEGdvICGnCXVoqDkS4j+lK07e5ztxE3OAIy5Un +fC5CQLlbzR9jHSpe2FD6S9H+ +=hu6f +-----END PGP PUBLIC KEY BLOCK----- diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java index 5afbd81ea..2224d7391 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java @@ -22,6 +22,7 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier; import org.spongycastle.asn1.nist.NISTNamedCurves; import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.spongycastle.bcpg.ECPublicBCPGKey; +import org.spongycastle.bcpg.SignatureSubpacketTags; import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPSignature; @@ -208,21 +209,24 @@ public class UncachedPublicKey { } /** - * Get all key usage flags - * - * TODO make this safe + * Get all key usage flags. + * If at least one key flag subpacket is present return these. + * If no subpacket is present it returns null. */ @SuppressWarnings("unchecked") - public int getKeyUsage() { - if(mCacheUsage == null) { - mCacheUsage = 0; + public Integer getKeyUsage() { + if (mCacheUsage == null) { for (PGPSignature sig : new IterableIterator(mPublicKey.getSignatures())) { if (mPublicKey.isMasterKey() && sig.getKeyID() != mPublicKey.getKeyID()) { continue; } PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); - if (hashed != null) { + if (hashed != null && hashed.getSubpacket(SignatureSubpacketTags.KEY_FLAGS) != null) { + // init if at least one key flag subpacket has been found + if (mCacheUsage == null) { + mCacheUsage = 0; + } mCacheUsage |= hashed.getKeyFlags(); } } @@ -230,38 +234,57 @@ public class UncachedPublicKey { return mCacheUsage; } - public boolean canAuthenticate() { - return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0; - } - public boolean canCertify() { - return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0; + // if key flags subpacket is available, honor it! + if (getKeyUsage() != null) { + return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0; + } + + if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_GENERAL + || mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN + || mPublicKey.getAlgorithm() == PGPPublicKey.ECDSA) { + return true; + } + + return false; } - public boolean canEncrypt() { - if (!mPublicKey.isEncryptionKey()) { - return false; + public boolean canSign() { + // if key flags subpacket is available, honor it! + if (getKeyUsage() != null) { + return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0; } - // special cases - if (mPublicKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT) { + if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_GENERAL + || mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN + || mPublicKey.getAlgorithm() == PGPPublicKey.ECDSA) { return true; } - if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT) { + return false; + } + + public boolean canEncrypt() { + // if key flags subpacket is available, honor it! + if (getKeyUsage() != null) { + return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0; + } + + // RSA_GENERAL, RSA_ENCRYPT, ELGAMAL_ENCRYPT, ELGAMAL_GENERAL, ECDH + if (mPublicKey.isEncryptionKey()) { return true; } - return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0; + return false; } - public boolean canSign() { - // special case - if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN) { - return true; + public boolean canAuthenticate() { + // if key flags subpacket is available, honor it! + if (getKeyUsage() != null) { + return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0; } - return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0; + return false; } public byte[] getFingerprint() { -- cgit v1.2.3