aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-09-02 17:16:04 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-09-02 17:16:04 +0200
commite2d51b86f5c1d1c23b744e5c32539a739bfa4c8c (patch)
tree9e7273912ec06e144b00bfbb03de48d81e38b592 /OpenKeychain/src
parentb08aa132e06abe6052d8e19b4bf7c4cfa4e2e95d (diff)
downloadopen-keychain-e2d51b86f5c1d1c23b744e5c32539a739bfa4c8c.tar.gz
open-keychain-e2d51b86f5c1d1c23b744e5c32539a739bfa4c8c.tar.bz2
open-keychain-e2d51b86f5c1d1c23b744e5c32539a739bfa4c8c.zip
If no key flags subpacket is present allow all key flags, fixes mailvelope keys
Diffstat (limited to 'OpenKeychain/src')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedPublicKey.java71
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() {