Page MenuHome GnuPG

Able to certify public keys without a certify key present when using smartcard.
Closed, ResolvedPublic

Description

When using a GnuPG smartcard in 2.2.4+ with an offline master [C]ertify key, it is possible to sign the keys of others with only a [S]igning subkey present.

Once a key has been erroneously signed and pushed to keyservers in this way, gpg won't allow it to be signed again correctly with the master key, claiming it is already signed.

Was able to reproduce on 2.2.4 on Arch Linux and 2.2.5 on OSX Sierra with a Yubikey 4 and RSA4096 subkeys and Yubikey Neo with RSA2048 subkeys. Also reproduced with pcscd and with gpg built-in scdaemon.

Example:

[lrvick@kephel ~]$ gpg --version
gpg (GnuPG) 2.2.4
libgcrypt 1.8.2
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/lrvick/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
[lrvick@kephel ~]$ gpg --card-status

Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006057635220000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 05763522
Name of cardholder: Lance Vick
Language prefs ...: en
Sex ..............: male
URL of public key : https://lrvick.net/0x36C8AAA9.asc
Login data .......: lrvick
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 390
Signature key ....: 6755 3FBD A46B B71A BD2E  0B0B 8E47 A1EC 35A1 551D
      created ....: 2016-02-15 00:49:42
Encryption key....: 54BA 9099 5CCB D6D6 B0E6  8D27 CDAB 3CCD A649 FFDA
      created ....: 2009-05-09 02:05:34
Authentication key: 4654 2022 DCA1 27AD 42D8  B9FE 6C1F 8F1D 4D08 A9A6
      created ....: 2015-02-01 08:16:59
General key info..: sub  rsa4096/8E47A1EC35A1551D 2016-02-15 Lance R. Vick (Personal) <lance@lrvick.net>
sec#  rsa4096/E90A401336C8AAA9  created: 2009-05-09  expires: 2018-07-03
ssb#  rsa2048/8D5B2F41F66444E5  created: 2015-03-19  expires: 2018-05-29
ssb#  rsa2048/530106BDD94A0B8A  created: 2015-03-19  expires: 2018-05-29
ssb#  rsa2048/D362694AF189271D  created: 2015-03-19  expires: 2018-05-29
ssb>  rsa4096/CDAB3CCDA649FFDA  created: 2009-05-09  expires: 2018-07-03
                                card-no: 0006 05763522
ssb>  rsa4096/6C1F8F1D4D08A9A6  created: 2015-02-01  expires: 2018-07-03
                                card-no: 0006 05763522
ssb>  rsa4096/8E47A1EC35A1551D  created: 2016-02-15  expires: 2018-07-03
                                card-no: 0006 05763522
[lrvick@kephel ~]$ gpg --list-secret-keys lance@lrvick.net
sec#  rsa4096 2009-05-09 [SC] [expires: 2018-07-03]
      6B61ECD76088748C70590D55E90A401336C8AAA9
uid           [ultimate] Lance R. Vick (Personal) <lance@lrvick.net>
uid           [ultimate] [jpeg image of size 6119]
uid           [ultimate] Lance R. Vick (Work) <lance@bitgo.com>
ssb#  rsa2048 2015-03-19 [S] [expires: 2018-05-29]
ssb#  rsa2048 2015-03-19 [E] [expires: 2018-05-29]
ssb#  rsa2048 2015-03-19 [A] [expires: 2018-05-29]
ssb>  rsa4096 2009-05-09 [E] [expires: 2018-07-03]
ssb>  rsa4096 2015-02-01 [A] [expires: 2018-07-03]
ssb>  rsa4096 2016-02-15 [S] [expires: 2018-07-03]

[lrvick@kephel ~]$ gpg --list-keys john@doe.com
pub   rsa2048 2018-03-10 [SC] [expires: 2020-03-09]
      691D9AC876EAABBC0AFA5403DF5E676BBF2D7AE8
uid           [ultimate] John Doe <john@doe.com>
sub   rsa2048 2018-03-10 [E] [expires: 2020-03-09]

[lrvick@kephel ~]$ gpg --sign-key 691D9AC876EAABBC0AFA5403DF5E676BBF2D7AE8

sec  rsa2048/DF5E676BBF2D7AE8
     created: 2018-03-10  expires: 2020-03-09  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/02E38722C42DA22F
     created: 2018-03-10  expires: 2020-03-09  usage: E   
[ultimate] (1). John Doe <john@doe.com>


sec  rsa2048/DF5E676BBF2D7AE8
     created: 2018-03-10  expires: 2020-03-09  usage: SC  
     trust: ultimate      validity: ultimate
 Primary key fingerprint: 691D 9AC8 76EA ABBC 0AFA  5403 DF5E 676B BF2D 7AE8

     John Doe <john@doe.com>

This key is due to expire on 2020-03-09.
Are you sure that you want to sign this key with your
key "Lance R. Vick (Personal) <lance@lrvick.net>" (8E47A1EC35A1551D)

Really sign? (y/N) y

[lrvick@kephel ~]$ gpg --list-sigs 691D9AC876EAABBC0AFA5403DF5E676BBF2D7AE8
pub   rsa2048 2018-03-10 [SC] [expires: 2020-03-09]
      691D9AC876EAABBC0AFA5403DF5E676BBF2D7AE8
uid           [ultimate] John Doe <john@doe.com>
sig 3        DF5E676BBF2D7AE8 2018-03-10  John Doe <john@doe.com>
sig          8E47A1EC35A1551D 2018-03-10  Lance R. Vick (Personal) <lance@lrvick.net>
sub   rsa2048 2018-03-10 [E] [expires: 2020-03-09]
sig          DF5E676BBF2D7AE8 2018-03-10  John Doe <john@doe.com>

Details

Version
2.2.5

Event Timeline

lrvick renamed this task from Able to certify keys without a certify key present when using smartcard. to Able to certify public keys without a certify key present when using smartcard..Mar 19 2018, 3:05 AM
lrvick created this task.
lrvick updated the task description. (Show Details)

Reproduced again with a brand new Yubikey 4 Nano on another Arch Linux machine with a newly created test keychain:

[lrvick@qatan ~]$ gpg --list-secret-keys test@user.com
sec#  rsa4096 2018-03-19 [C] [expires: 2019-03-19]
      C1F0C6A9F5F69C17F191D4E02CCD7B5711024FF5
uid           [ unknown] Test User <test@user.com>
ssb>  rsa4096 2018-03-19 [S] [expires: 2019-03-19]
ssb>  rsa4096 2018-03-19 [E] [expires: 2019-03-19]
ssb>  rsa4096 2018-03-19 [A] [expires: 2019-03-19]

[lrvick@qatan ~]$ gpg --card-status

Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006064514430000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06451443
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 2
Signature key ....: 70F3 E108 54FE 1543 77FB  2952 90CD 672F 25BB 6CA4
      created ....: 2018-03-19 03:55:44
Encryption key....: E818 2161 D30C 8CF1 B0C4  B1C8 F893 D52B D380 3E55
      created ....: 2018-03-19 03:55:47
Authentication key: A514 B27D 471B 8478 87AE  910D 995A 0D90 3CC5 D604
      created ....: 2018-03-19 03:55:48
General key info..: sub  rsa4096/90CD672F25BB6CA4 2018-03-19 Test User <test@user.com>
sec#  rsa4096/2CCD7B5711024FF5  created: 2018-03-19  expires: 2019-03-19
ssb>  rsa4096/90CD672F25BB6CA4  created: 2018-03-19  expires: 2019-03-19
                                card-no: 0006 06451443
ssb>  rsa4096/F893D52BD3803E55  created: 2018-03-19  expires: 2019-03-19
                                card-no: 0006 06451443
ssb>  rsa4096/995A0D903CC5D604  created: 2018-03-19  expires: 2019-03-19
                                card-no: 0006 06451443
[lrvick@qatan ~]$ gpg --list-keys jdoe@example.com
pub   rsa2048 2018-03-19 [SC] [expires: 2020-03-18]
      483B197C8D155B6D1D1032D9F08F443160EAE3A0
uid           [ unknown] John Doe <jdoe@example.com>
sub   rsa2048 2018-03-19 [E] [expires: 2020-03-18]

[lrvick@qatan ~]$ gpg --sign-key 483B197C8D155B6D1D1032D9F08F443160EAE3A0

pub  rsa2048/F08F443160EAE3A0
     created: 2018-03-19  expires: 2020-03-18  usage: SC  
     trust: unknown       validity: unknown
sub  rsa2048/B831D9F85950283D
     created: 2018-03-19  expires: 2020-03-18  usage: E   
[ unknown] (1). John Doe <jdoe@example.com>


pub  rsa2048/F08F443160EAE3A0
     created: 2018-03-19  expires: 2020-03-18  usage: SC  
     trust: unknown       validity: unknown
 Primary key fingerprint: 483B 197C 8D15 5B6D 1D10  32D9 F08F 4431 60EA E3A0

     John Doe <jdoe@example.com>

This key is due to expire on 2020-03-18.
Are you sure that you want to sign this key with your
key "Test User <test@user.com>" (90CD672F25BB6CA4)

Really sign? (y/N) y

[lrvick@qatan ~]$ gpg --list-sigs jdoe@example.com
pub   rsa2048 2018-03-19 [SC] [expires: 2020-03-18]
      483B197C8D155B6D1D1032D9F08F443160EAE3A0
uid           [ unknown] John Doe <jdoe@example.com>
sig 3        F08F443160EAE3A0 2018-03-19  John Doe <jdoe@example.com>
sig          90CD672F25BB6CA4 2018-03-19  Test User <test@user.com>
sub   rsa2048 2018-03-19 [E] [expires: 2020-03-18]
sig          F08F443160EAE3A0 2018-03-19  John Doe <jdoe@example.com>

Attached is a full scdaemon guru log of the above operations.

werner added a project: gnupg (gpg20).
gniibe changed the task status from Open to Testing.Apr 3 2018, 1:25 AM

I think that I located the bug and fixed. I wonder why Werner put gpg20 tag.

Shouldn't this also be applied to STABLE-BRANCH-1-4?

The bug is specific to 2.2, which may select available key on card. When such a selection, checking the PK->REQ_USAGE was missed.

If someone claims this is a kind of vulnerability, I think that what we need to fix is signature checking side:


Speaking about this, similar patch would be required to gpg1.4.

Sorry, the patch above is completely wrong, since pk->pubkey_usage is not the right key to check.

I created another patch:
https://dev.gnupg.org/D460

I wish this patch is correct.

werner added a subscriber: werner.

The gpg20 tag was a typo.

I have another patch proposal to check the key usage. However, there is a catch-22. We get the usage flags from the key signatures and thus we can only check them after we checked the key signature.

Forget my former comment. We only need to check subkeys becuase the primary key can always certify.
Here is a new revision of the patch:

The patch has two parts; (1) detecting signature by incapable key and (2) limiting key with relevant capability.
I think that (1) is enough. I wonder with (2), (1) would not occur.

Right with (2) (1) will not occur if the key has been created with GnuPG. However, we have caches in the code path and further rogue software may create creates, interesting keys (tm). Thus I consider it better to explicitly request keys with cert flag set.

fwiw, i agree that if there's any security vulnerability here, it is in the verification side, not the creation side.

So we had two releases with the fist. Can we set this bug to resolved?