diff --git a/kms/yubikey/yubikey.go b/kms/yubikey/yubikey.go index 3349ea63..943cd534 100644 --- a/kms/yubikey/yubikey.go +++ b/kms/yubikey/yubikey.go @@ -106,12 +106,12 @@ func (k *YubiKey) GetPublicKey(req *apiv1.GetPublicKeyRequest) (crypto.PublicKey return nil, err } - cert, err := k.yk.Certificate(slot) + pub, err := k.getPublicKey(slot) if err != nil { - return nil, errors.Wrap(err, "error retrieving certificate") + return nil, err } - return cert.PublicKey, nil + return pub, nil } // CreateKey generates a new key in the YubiKey and returns the public key. @@ -150,12 +150,12 @@ func (k *YubiKey) CreateSigner(req *apiv1.CreateSignerRequest) (crypto.Signer, e return nil, err } - cert, err := k.yk.Certificate(slot) + pub, err := k.getPublicKey(slot) if err != nil { - return nil, errors.Wrap(err, "error retrieving certificate") + return nil, err } - priv, err := k.yk.PrivateKey(slot, cert.PublicKey, piv.KeyAuth{ + priv, err := k.yk.PrivateKey(slot, pub, piv.KeyAuth{ PIN: k.pin, PINPolicy: piv.PINPolicyAlways, }) @@ -175,6 +175,20 @@ func (k *YubiKey) Close() error { return errors.Wrap(k.yk.Close(), "error closing yubikey") } +// getPublicKey returns the public key on a slot. First it attempts to do +// attestation to get a certificate with the public key in it, if this succeeds +// means that the key was generated in the device. If not we'll try to get the +// key from a stored certificate in the same slot. +func (k *YubiKey) getPublicKey(slot piv.Slot) (crypto.PublicKey, error) { + cert, err := k.yk.Attest(slot) + if err != nil { + if cert, err = k.yk.Certificate(slot); err != nil { + return nil, errors.Wrap(err, "error retrieving public key") + } + } + return cert.PublicKey, nil +} + // signatureAlgorithmMapping is a mapping between the step signature algorithm, // and bits for RSA keys, with yubikey ones. var signatureAlgorithmMapping = map[apiv1.SignatureAlgorithm]interface{}{ @@ -228,6 +242,26 @@ var slotMapping = map[string]piv.Slot{ "9c": piv.SlotSignature, "9e": piv.SlotCardAuthentication, "9d": piv.SlotKeyManagement, + "82": {Key: 0x82, Object: 0x5FC10D}, + "83": {Key: 0x83, Object: 0x5FC10E}, + "84": {Key: 0x84, Object: 0x5FC10F}, + "85": {Key: 0x85, Object: 0x5FC110}, + "86": {Key: 0x86, Object: 0x5FC111}, + "87": {Key: 0x87, Object: 0x5FC112}, + "88": {Key: 0x88, Object: 0x5FC113}, + "89": {Key: 0x89, Object: 0x5FC114}, + "8a": {Key: 0x8a, Object: 0x5FC115}, + "8b": {Key: 0x8b, Object: 0x5FC116}, + "8c": {Key: 0x8c, Object: 0x5FC117}, + "8d": {Key: 0x8d, Object: 0x5FC118}, + "8e": {Key: 0x8e, Object: 0x5FC119}, + "8f": {Key: 0x8f, Object: 0x5FC11A}, + "90": {Key: 0x90, Object: 0x5FC11B}, + "91": {Key: 0x91, Object: 0x5FC11C}, + "92": {Key: 0x92, Object: 0x5FC11D}, + "93": {Key: 0x93, Object: 0x5FC11E}, + "94": {Key: 0x94, Object: 0x5FC11F}, + "95": {Key: 0x95, Object: 0x5FC120}, } func getSlot(name string) (piv.Slot, error) {