-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Closed
Labels
Milestone
Description
When a GPG secring contains a smartcard stub, the openpgp package fails to read the keyring correctly and does not return an error. A call to openpgp.ReadKeyRing() will returns the entities that precedes the stub, excluding the entity located right before the stub.
For example, if a secring contains 3 entities and the smartcard stub is in position 3, then openpgp.ReadKeyRing() will only return the first entity. The second entity and the stub are ignored. No error is returned.
Steps to reproduce:
1. Create a keyring with two regular 1024 bits RSA keys
$ mkdir /tmp/testgolangopenpgp$ gpg --batch --no-default-keyring --keyring /tmp/testgolangopenpgp/pubring.gpg --secret-keyring /tmp/testgolangopenpgp/secring.gpg --gen-key << EOF
> Key-Type: 1
> Key-Length: 1024
> Subkey-Type: 1
> Subkey-Length: 1024
> Name-Real: test key 1
> Name-Email: testkey1@example.net
> Expire-Date: 12m
> EOF
gpg: keyring `/tmp/testgolangopenpgp/secring.gpg' created
gpg: keyring `/tmp/testgolangopenpgp/pubring.gpg' created
..+++++
...+++++
.....+++++
..+++++
gpg: key 4BACAA9F marked as ultimately trusted$ gpg --batch --no-default-keyring --keyring /tmp/testgolangopenpgp/pubring.gpg --secret-keyring /tmp/testgolangopenpgp/secring.gpg --gen-key << EOF
> Key-Type: 1
> Key-Length: 1024
> Subkey-Type: 1
> Subkey-Length: 1024
> Name-Real: test key 2
> Name-Email: testkey2@example.net
> Expire-Date: 12m
> EOF
.+++++
.+++++
+++++
+++++
gpg: key 56CE5F62 marked as ultimately trusted2. Import a smartcard stub from a yubikey into the keyring
$ gpg --no-default-keyring --keyring /tmp/testgolangopenpgp/pubring.gpg --secret-keyring /tmp/testgolangopenpgp/secring.gpg --allow-secret-key-import --import yubikeystub yubikeytest1_stub.asc
gpg: key 4FB5544F: already in secret keyring
gpg: key 59BEDBFC: already in secret keyring
gpg: Total number processed: 2
gpg: secret keys read: 2
gpg: secret keys unchanged: 2
/tmp/testgolangopenpgp/secring.gpg
----------------------------------
sec 1024R/4BACAA9F 2014-12-14 [expires: 2015-12-09]
uid test key 1 <testkey1@example.net>
ssb 1024R/AEC9CD3A 2014-12-14
sec 1024R/56CE5F62 2014-12-14 [expires: 2015-12-09]
uid test key 2 <testkey2@example.net>
ssb 1024R/A1E03C73 2014-12-14
sec> 2048R/59BEDBFC 2014-12-14 [expires: 2015-12-09]
Card serial no. = 0000 00000001
uid Yubikey Smartcard test1 <yubikeytest1@example.net>
ssb> 2048R/9B633300 2014-12-14
ssb> 2048R/A8DE1BB7 2014-12-143. Attempt to read the entities in the keyring. Only the first entity is returned.
$ go run readkeyring.go
found 1 entities in keyring
reading entity with fingerprint 2FA49C2800342153CA439C90ADC366D34BACAA9Fsource code:
package main
import (
"code.google.com/p/go.crypto/openpgp"
"encoding/hex"
"fmt"
"os"
"strings"
)
func main() {
secringFile, err := os.Open("/tmp/testgolangopenpgp/secring.gpg")
if err != nil {
panic(err)
}
defer secringFile.Close()
keyring, err := openpgp.ReadKeyRing(secringFile)
if err != nil {
err = fmt.Errorf("Keyring access failed: '%v'", err)
panic(err)
}
fmt.Printf("found %d entities in keyring\n", len(keyring))
for _, entity := range keyring {
fingerprint := strings.ToUpper(hex.EncodeToString(entity.PrimaryKey.Fingerprint[:]))
fmt.Println("reading entity with fingerprint", fingerprint)
}
}dominikschulz