1

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.

Jens Erat
  • 37,523
  • 16
  • 80
  • 96
user1484793
  • 359
  • 3
  • 16

1 Answers1

1

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.

Community
  • 1
  • 1
Jens Erat
  • 37,523
  • 16
  • 80
  • 96
  • Thank you very much. That indeed helped me. BTW the author of the code is checking if the key is revoked before even calling this function. So, looks like she/he has taken care of revoked self signature. – user1484793 Feb 21 '15 at 05:05
  • 1
    0x133 in "For primary keys, types 0x10-0x133" should be 0x13. I could not edit it since it needs minimum 6 chars change and I did not want to change other content. – user1484793 Feb 21 '15 at 05:26
  • Indeed, I fixed that. – Jens Erat Feb 21 '15 at 09:56