diff options
Diffstat (limited to 'OpenKeychain/src')
| -rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java | 71 | 
1 files changed, 47 insertions, 24 deletions
| 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<PGPSignature>(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() { | 
