If no key flags subpacket is present allow all key flags, fixes mailvelope keys

This commit is contained in:
Dominik Schürmann 2014-09-02 17:16:04 +02:00
parent b08aa132e0
commit e2d51b86f5
2 changed files with 70 additions and 27 deletions

View File

@ -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-----

View File

@ -22,6 +22,7 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.nist.NISTNamedCurves; import org.spongycastle.asn1.nist.NISTNamedCurves;
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves; import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.spongycastle.bcpg.ECPublicBCPGKey; import org.spongycastle.bcpg.ECPublicBCPGKey;
import org.spongycastle.bcpg.SignatureSubpacketTags;
import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignature;
@ -208,21 +209,24 @@ public class UncachedPublicKey {
} }
/** /**
* Get all key usage flags * Get all key usage flags.
* * If at least one key flag subpacket is present return these.
* TODO make this safe * If no subpacket is present it returns null.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public int getKeyUsage() { public Integer getKeyUsage() {
if(mCacheUsage == null) { if (mCacheUsage == null) {
mCacheUsage = 0;
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(); 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(); mCacheUsage |= hashed.getKeyFlags();
} }
} }
@ -230,38 +234,57 @@ public class UncachedPublicKey {
return mCacheUsage; return mCacheUsage;
} }
public boolean canAuthenticate() {
return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0;
}
public boolean canCertify() { 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;
public boolean canEncrypt() {
if (!mPublicKey.isEncryptionKey()) {
return false;
} }
// special cases if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_GENERAL
if (mPublicKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT) { || mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN
|| mPublicKey.getAlgorithm() == PGPPublicKey.ECDSA) {
return true; return true;
} }
if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_ENCRYPT) { return false;
return true;
}
return (getKeyUsage() & (KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE)) != 0;
} }
public boolean canSign() { public boolean canSign() {
// special case // if key flags subpacket is available, honor it!
if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN) { if (getKeyUsage() != null) {
return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0;
}
if (mPublicKey.getAlgorithm() == PGPPublicKey.RSA_GENERAL
|| mPublicKey.getAlgorithm() == PGPPublicKey.RSA_SIGN
|| mPublicKey.getAlgorithm() == PGPPublicKey.ECDSA) {
return true; return true;
} }
return (getKeyUsage() & KeyFlags.SIGN_DATA) != 0; 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 false;
}
public boolean canAuthenticate() {
// if key flags subpacket is available, honor it!
if (getKeyUsage() != null) {
return (getKeyUsage() & KeyFlags.AUTHENTICATION) != 0;
}
return false;
} }
public byte[] getFingerprint() { public byte[] getFingerprint() {