Search code examples
encryptiongnupg

Why gpg --encrypt fails with sub key packet with key flags 0x0C that never expires?


When I analyze the output of that gpg --list-packets output I see that the sub key packet never expires, and its key flags is 0C which is for "Encryption". (see output at the bottom.)

The public key packet is already expired but its key flags is 03 which stands for "Key Certification" | "Sign Data", and therefore is not needed for encryption.

Yet when I run gpg --always-trust -r user@user.com --encrypt abc I get this error:

gpg: user@user.com: skipped: unusable public key
gpg: abc: encryption failed: unusable public key

Why is this so? Why the "never expire" encryption key is not usable in this case? Is the fact that public key expired, regardless of what the key flags is, all sub keys automatically invalid?

Here is the output of gpg --list-packets user.public.key:

gpg: WARNING: using insecure memory!
gpg: please see http://www.gnupg.org/faq.html for more information
:public key packet:
        version 4, algo 1, created 1471460125, expires 0
        pkey[0]: [2048 bits]
        pkey[1]: [17 bits]
:user ID packet: "userid <user@user.com>"
:signature packet: algo 1, keyid A5038DC251BC03DC
        version 4, created 1471460130, md5len 0, sigclass 0x13
        digest algo 2, begin of digest c4 fa
        hashed subpkt 2 len 4 (sig created 2016-08-17)
        hashed subpkt 9 len 4 (key expires after 2y0d0h0m)
        hashed subpkt 27 len 1 (key flags: 03)
        hashed subpkt 11 len 7 (pref-sym-algos: 2 3 4 7 8 9 10)
        hashed subpkt 22 len 4 (pref-zip-algos: 2 1 0 3)
        hashed subpkt 25 len 1 (primary user ID)
        subpkt 16 len 8 (issuer key ID A5038DC251BC03DC)
        data: [2046 bits]
:public sub key packet:
        version 4, algo 1, created 1471460125, expires 0
        pkey[0]: [2048 bits]
        pkey[1]: [17 bits]
:signature packet: algo 1, keyid A5038DC251BC03DC
        version 4, created 1471460131, md5len 0, sigclass 0x18
        digest algo 2, begin of digest 7f 63
        hashed subpkt 2 len 4 (sig created 2016-08-17)
        hashed subpkt 27 len 1 (key flags: 0C)
        subpkt 16 len 8 (issuer key ID A5038DC251BC03DC)
        data: [2042 bits]

Solution

  • After further analysis this is what I came up to:

    Instead of using gpg --list-packets I use gpg --with-colon, and I take the first pub key from the output. I have noticed that if the pub key is not expired then it always allows encryption. If pub is expired then it does not matter what sub is - the key is expired and gpg refuses to encrypt.

    Example of the never expired public key with expired subkeys (using gpg --with-colon user.public.key)

    pub:-:3072:1:BFDEF66008072C77:2016-08-21:::-:userid <user@user.com>:
    sub:-:3072:1:1AF28CF198A6BEA3:2016-08-21:2018-08-21::: [expires: 2018-08-21]
    sub:-:3072:1:DA2B5429D88156C7:2016-08-21:2016-08-26::: [expires: 2016-08-26]
    

    This one will allow encryption.

    See details how to process this output here:

    https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS

    Example of