only respect most recent signature for key flags

This commit is contained in:
Vincent Breitmoser 2015-01-19 18:31:27 +01:00
parent e71bd3d9dd
commit a65edcdb2f
2 changed files with 42 additions and 12 deletions

View File

@ -53,7 +53,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canSign() { public boolean canSign() {
// if key flags subpacket is available, honor it! // if key flags subpacket is available, honor it!
if (getKeyUsage() != null) { if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0; return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0;
} }
@ -66,7 +66,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canCertify() { public boolean canCertify() {
// if key flags subpacket is available, honor it! // if key flags subpacket is available, honor it!
if (getKeyUsage() != null) { if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0; return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0;
} }
@ -79,7 +79,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canEncrypt() { public boolean canEncrypt() {
// if key flags subpacket is available, honor it! // if key flags subpacket is available, honor it!
if (getKeyUsage() != null) { if (getKeyUsage() != 0) {
return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0; return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0;
} }
@ -93,7 +93,7 @@ public class CanonicalizedPublicKey extends UncachedPublicKey {
public boolean canAuthenticate() { public boolean canAuthenticate() {
// if key flags subpacket is available, honor it! // if key flags subpacket is available, honor it!
if (getKeyUsage() != null) { if (getKeyUsage() != 0) {
return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0; return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0;
} }

View File

@ -305,26 +305,56 @@ public class UncachedPublicKey {
* *
* Note that this method has package visiblity because it is used in test * Note that this method has package visiblity because it is used in test
* cases. Certificates of UncachedPublicKey instances can NOT be assumed to * cases. Certificates of UncachedPublicKey instances can NOT be assumed to
* be verified, so the result of this method should not be used in other * be verified or even by the correct key, so the result of this method
* places! * should never be used in other places!
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Integer getKeyUsage() { Integer getKeyUsage() {
if (mCacheUsage == null) { if (mCacheUsage == null) {
PGPSignature mostRecentSig = null;
for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignatures())) { for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignatures())) {
if (mPublicKey.isMasterKey() && sig.getKeyID() != mPublicKey.getKeyID()) { if (mPublicKey.isMasterKey() && sig.getKeyID() != mPublicKey.getKeyID()) {
continue; continue;
} }
PGPSignatureSubpacketVector hashed = sig.getHashedSubPackets(); switch (sig.getSignatureType()) {
if (hashed != null && hashed.getSubpacket(SignatureSubpacketTags.KEY_FLAGS) != null) { case PGPSignature.DEFAULT_CERTIFICATION:
// init if at least one key flag subpacket has been found case PGPSignature.POSITIVE_CERTIFICATION:
if (mCacheUsage == null) { case PGPSignature.CASUAL_CERTIFICATION:
case PGPSignature.NO_CERTIFICATION:
case PGPSignature.SUBKEY_BINDING:
break;
// if this is not one of the above types, don't care
default:
continue;
}
// If we have no sig yet, take the first we can get
if (mostRecentSig == null) {
mostRecentSig = sig;
continue;
}
// If the new sig is less recent, skip it
if (mostRecentSig.getCreationTime().after(sig.getCreationTime())) {
continue;
}
// Otherwise, note it down as the new "most recent" one
mostRecentSig = sig;
}
// Initialize to 0 as cached but empty value, if there is no sig (can't happen
// for canonicalized keyring), or there is no KEY_FLAGS packet in the sig
mCacheUsage = 0; mCacheUsage = 0;
} if (mostRecentSig != null) {
mCacheUsage |= hashed.getKeyFlags(); // If a mostRecentSig has been found, (cache and) return its flags
PGPSignatureSubpacketVector hashed = mostRecentSig.getHashedSubPackets();
if (hashed != null && hashed.getSubpacket(SignatureSubpacketTags.KEY_FLAGS) != null) {
mCacheUsage = hashed.getKeyFlags();
} }
} }
} }
return mCacheUsage; return mCacheUsage;
} }