user1484793
user1484793

Reputation: 367

OpenPGP encryption key - isValidForEncrypting()?

I was looking at some code of MyPGP to check whether an OpenPGP key is valid for encryption or not. RFC 4880 helped me understanding the code a bit. But given that I do not have a very good understanding of signature types, I am not able to clearly understand the following code piece:

 private static boolean hasKeyFlags(PGPPublicKey key, int keyUsage) {
    if (key.isMasterKey()) {
        for (int certificationType : MASTER_KEY_CERTIFICATION_TYPES) {
            Iterator eIt = key.getSignaturesOfType(certificationType);
            while (eIt.hasNext()) {
                PGPSignature signature = (PGPSignature) eIt.next();
                if (!isMatchingUsage(signature, keyUsage))
                    return false;
            }
        }
    } else {
        Iterator eIt = key.getSignaturesOfType(PGPSignature.SUBKEY_BINDING);
        while (eIt.hasNext()) {
            PGPSignature signature = (PGPSignature) eIt.next();
            if (!isMatchingUsage(signature, keyUsage))
                return false;
        }
    }
    return true;
   }

where

 private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[]{
        PGPSignature.POSITIVE_CERTIFICATION,
        PGPSignature.CASUAL_CERTIFICATION,
        PGPSignature.NO_CERTIFICATION,
        PGPSignature.DEFAULT_CERTIFICATION
};

I not sure why are we looking for particular signature types for master keys and why looking into SUBKEY_BINDINGs otherwise.

Upvotes: 1

Views: 127

Answers (1)

Jens Erat
Jens Erat

Reputation: 38722

Key Usage Flags and Self Signatures

Primary ("master") and subkeys have their usage flags defined in self-signatures, which can be of different signature types (from RFC 4880, 5.2.3.3. Notes on Self-Signatures:

There are three types of self-signatures, the certification signatures (types 0x10-0x13), the direct-key signature (type 0x1F), and the subkey binding signature (type 0x18).

The Code

For primary keys, types 0x10-0x13 are used (this is the loop over MASTER_KEY_CERTIFICATION_TYPES in the first branch of the function). For subkeys, the usage flag is always stored in the subkey binding signature of type 0x18. which is checked in the second branch.

As there can be multiple self-signatures, the author loops over all of them. I didn't completely read the code, but I'm unsure whether he conforms to RFC 4880, I think he should use the newest non-revoked self signature; it might be that he uses the first matching one (no matter whether it is superseded or even revoked).

Looking at a Key

You can verify where the key usage flag is stored using a command like

gpg --export-options export-minimal --export 0xdeadbeef | gpg --list-packets

Look for lines starting with hashed subpkt 27, these indicate key usage flag settings. The sigclass is listed a little bit above. gpg --list-packets output is hardly readable and contains lots of numeric references to look up in RFC 4880, but it seems you're somewhat familiar with the RFC anyway already.

Upvotes: 1

Related Questions