ThalesGroup / crypto11

Implement crypto.Signer and crypto.Decrypter for HSM-protected keys via PKCS#11
MIT License
209 stars 81 forks source link

Keys without id values not found #82

Open salrashid123 opened 3 years ago

salrashid123 commented 3 years ago

FindKeyPair only looks for keys that has an id value here https://github.com/ThalesIgnite/crypto11/blob/master/keys.go#L122

In my case, the tpm-backed key has a label but not an id

# pkcs11-tool --module /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1 --list-slots
Available slots:
Slot 0 (0x1): token1                          GOOG
  token label        : token1
  token manufacturer : GOOG
  token model        : vTPM
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 1.42
  firmware version   : 22.17
  serial num         : 0000000000000000
  pin min/max        : 0/128
Slot 1 (0x2):                                 GOOG
  token state:   uninitialized

# pkcs11-tool --module /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1 --list-objects
Using slot 0 with a present token (0x1)
Public Key Object; RSA 2048 bits
  label:      keylabel1
  Usage:      encrypt, verify
  Access:     local

which still works with openssl with used with modules

/usr/lib/x86_64-linux-gnu/engines-1.1/libpkcs11.so
/usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1
export PKCS11_PUBLIC_KEY="pkcs11:model=vTPM;manufacturer=GOOG;serial=0000000000000000;token=token1;type=public;object=keylabel1?pin-value=mynewpin"
export PKCS11_PRIVATE_KEY="pkcs11:model=vTPM;manufacturer=GOOG;serial=0000000000000000;token=token1;type=private;object=keylabel1?pin-value=mynewpin"

$openssl rsa -engine pkcs11  -inform engine -in "$PKCS11_PUBLIC_KEY" -pubout
engine "pkcs11" set.
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAny6DoDA8cuf44wWsfwKM
PxBcsmW0igzyqf5DmiD9fADrUOXO4suEfdTMMP1mT3laXd0yGfyzd98zKEIhPGwf
vJa2EaeuHrq51AdcT/AjQKXp4O2epZ4+/m0OfruBPieGwQDdx446KuLPDcR4ubs3
U71AtMWwYhBznqm2b5toEH2x6XKFBkFija+ddnKMpLhiMucj+DWnb09MKD6g19SL
an1A6op006HZWesW2uMSp5uoasRH2QNSrLyF+Nxv4rIIAXLUKxLitniQ+v2lbvtW
xMw2HMGsVynyqNWBBgqrmxtoTlQrIz8BAE1KzSKwTGVkmzNKQ7yAeOyG7e0tVlH2
dwIDAQAB
-----END PUBLIC KEY-----

$ echo "sig data" > "data.txt"
$ openssl rsa -engine pkcs11  -inform engine -in "$PKCS11_PUBLIC_KEY" -pubout -out pub.pem
engine "pkcs11" set.
writing RSA key

$ openssl pkeyutl -engine pkcs11 -keyform engine -inkey $PKCS11_PRIVATE_KEY -sign -in data.txt -out data.sig
engine "pkcs11" set.

$ openssl pkeyutl -pubin -inkey pub.pem -verify -in data.txt -sigfile data.sig
Signature Verified Successfully

i do not know if specs requires it or not but the fix used was to check for either

var errNoCkaIdOrLabel = errors.New("private key has no CKA_ID or CKA_LABEL")

    // Ensure the private key actually has a non-empty CKA_ID to match on
    if (id == nil || len(id) == 0) && (label == nil || len(label) == 0) {
        return nil, nil, errNoCkaIdOrLabel
    }
dwmw2 commented 1 year ago

If there's no id= or object= in the URI used to specify the object, why do we even care if it has one? If I have a token with only one key in it, I should be able to use just pkcs11:manufacturer=mytoken;type=private as the key, surely?

I may update http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#rfc.section.8 to make that explicit.