2021-01-27 04:15:57 +00:00
|
|
|
// +build cgo
|
|
|
|
|
|
|
|
package pkcs11
|
2021-01-28 04:17:14 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto"
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/ed25519"
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
2021-01-28 04:35:42 +00:00
|
|
|
"math/big"
|
2021-01-28 04:17:14 +00:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/smallstep/certificates/kms/apiv1"
|
2021-01-28 04:35:42 +00:00
|
|
|
"golang.org/x/crypto/cryptobyte"
|
|
|
|
"golang.org/x/crypto/cryptobyte/asn1"
|
2021-01-28 04:17:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestNew(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
ctx context.Context
|
|
|
|
opts apiv1.Options
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
want *PKCS11
|
|
|
|
wantErr bool
|
|
|
|
}{}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
got, err := New(tt.args.ctx, tt.args.opts)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
|
|
t.Errorf("New() = %v, want %v", got, tt.want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPKCS11_GetPublicKey(t *testing.T) {
|
|
|
|
setupSoftHSM2, setupYubiHSM2 := setupFuncs(t)
|
|
|
|
type args struct {
|
|
|
|
req *apiv1.GetPublicKeyRequest
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
setup func(t *testing.T) *PKCS11
|
|
|
|
args args
|
|
|
|
want crypto.PublicKey
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
// SoftHSM2
|
|
|
|
{"softhsm RSA", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"softhsm RSA by id", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7371",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"softhsm RSA by label", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:object=rsa-key",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"softhsm ECDSA", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7373;object=ecdsa-p256-key",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
{"softhsm ECDSA by id", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7373",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
{"softhsm ECDSA by label", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:object=ecdsa-p256-key",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
// YubiHSM2
|
|
|
|
{"yubiHSM2 RSA", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"yubiHSM2 RSA by id", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7371",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"yubiHSM2 RSA by label", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:object=rsa-key",
|
|
|
|
}}, &rsa.PublicKey{}, false},
|
|
|
|
{"yubiHSM2 ECDSA", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7373;object=ecdsa-p256-key",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
{"yubiHSM2 ECDSA by id", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=7373",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
{"yubiHSM2 ECDSA by label", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:object=ecdsa-p256-key",
|
|
|
|
}}, &ecdsa.PublicKey{}, false},
|
|
|
|
// Errors
|
|
|
|
{"fail name", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail uri", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "https:id=9999;object=https",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail softhsm missing", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=rsa-key",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail yubiHSM2 missing", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=ecdsa-p256-key",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail softhsm FindKeyPair", setupSoftHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail yubiHSM2 FindKeyPair", setupYubiHSM2, args{&apiv1.GetPublicKeyRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
}}, nil, true},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
k := tt.setup(t)
|
|
|
|
got, err := k.GetPublicKey(tt.args.req)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("PKCS11.GetPublicKey() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
|
|
|
|
t.Errorf("PKCS11.GetPublicKey() = %T, want %T", got, tt.want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPKCS11_CreateKey(t *testing.T) {
|
|
|
|
setupSoftHSM2, setupYubiHSM2 := setupFuncs(t)
|
|
|
|
type args struct {
|
|
|
|
req *apiv1.CreateKeyRequest
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
setup func(t *testing.T) *PKCS11
|
|
|
|
args args
|
|
|
|
want *apiv1.CreateKeyResponse
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
// SoftHSM2
|
|
|
|
{"softhsm Default", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA256WithRSA", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA384WithRSA", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA384WithRSA,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA512WithRSA", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA512WithRSA,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA256WithRSAPSS", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSAPSS,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA384WithRSAPSS", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA384WithRSAPSS,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA SHA512WithRSAPSS", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA512WithRSAPSS,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA 2048", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
Bits: 2048,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm RSA 4096", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
Bits: 4096,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm ECDSA P256", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA256,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm ECDSA P384", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA384,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"softhsm ECDSA P521", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA512,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
// YubiHSM2
|
|
|
|
{"yubihsm RSA", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm RSA 2048", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
Bits: 2048,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm RSA 4096", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSA,
|
|
|
|
Bits: 4096,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &rsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm Default", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=ecdsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm ECDSA P256", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA256,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm ECDSA P384", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA384,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
{"yubihsm ECDSA P521", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.ECDSAWithSHA512,
|
|
|
|
}}, &apiv1.CreateKeyResponse{
|
|
|
|
Name: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
PublicKey: &ecdsa.PublicKey{},
|
|
|
|
CreateSignerRequest: apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7771;object=rsa-create-key",
|
|
|
|
},
|
|
|
|
}, false},
|
|
|
|
// Errors
|
|
|
|
{"fail name", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail bits", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=rsa-create-key",
|
|
|
|
Bits: -1,
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSAPSS,
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail ed25519", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.PureEd25519,
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail unknown", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=rsa-create-key",
|
|
|
|
SignatureAlgorithm: apiv1.SignatureAlgorithm(100),
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail uri", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:id=xxxx;object=https",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSAPSS,
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail softhsm FindKeyPair", setupSoftHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSAPSS,
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail yubihsm FindKeyPair", setupYubiHSM2, args{&apiv1.CreateKeyRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
SignatureAlgorithm: apiv1.SHA256WithRSAPSS,
|
|
|
|
}}, nil, true},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
k := tt.setup(t)
|
|
|
|
got, err := k.CreateKey(tt.args.req)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("PKCS11.CreateKey() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if got != nil {
|
|
|
|
got.PublicKey = tt.want.PublicKey
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
|
|
t.Errorf("PKCS11.CreateKey() = %v, want %v", got, tt.want)
|
|
|
|
}
|
|
|
|
if got != nil {
|
|
|
|
if err := k.DeleteKey(got.Name); err != nil {
|
|
|
|
t.Errorf("PKCS11.DeleteKey() error = %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPKCS11_CreateSigner(t *testing.T) {
|
|
|
|
data := []byte("buggy-coheir-RUBRIC-rabbet-liberal-eaglet-khartoum-stagger")
|
|
|
|
setupSoftHSM2, setupYubiHSM2 := setupFuncs(t)
|
|
|
|
|
|
|
|
type args struct {
|
|
|
|
req *apiv1.CreateSignerRequest
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
setup func(t *testing.T) *PKCS11
|
|
|
|
args args
|
|
|
|
algorithm apiv1.SignatureAlgorithm
|
|
|
|
signerOpts crypto.SignerOpts
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
// SoftHSM2
|
|
|
|
{"softhsm RSA", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, apiv1.SHA256WithRSA, crypto.SHA256, false},
|
|
|
|
{"softhsm RSA PSS", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, apiv1.SHA256WithRSA, crypto.SHA256, false},
|
|
|
|
{"softhsm ECDSA P256", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7373;object=ecdsa-p256-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA256, crypto.SHA256, false},
|
|
|
|
{"softhsm ECDSA P384", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7374;object=ecdsa-p384-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA384, crypto.SHA384, false},
|
|
|
|
{"softhsm ECDSA P521", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7375;object=ecdsa-p521-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA512, crypto.SHA512, false},
|
|
|
|
// YubiHSM2
|
|
|
|
{"yubihsm RSA", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, apiv1.SHA256WithRSA, crypto.SHA256, false},
|
|
|
|
{"yubihsm RSA PSS", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7371;object=rsa-key",
|
|
|
|
}}, apiv1.SHA256WithRSA, crypto.SHA256, false},
|
|
|
|
{"yubihsm ECDSA P256", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7373;object=ecdsa-p256-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA256, crypto.SHA256, false},
|
|
|
|
{"yubihsm ECDSA P384", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7374;object=ecdsa-p384-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA384, crypto.SHA384, false},
|
|
|
|
{"yubihsm ECDSA P521", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:id=7375;object=ecdsa-p521-key",
|
|
|
|
}}, apiv1.ECDSAWithSHA512, crypto.SHA512, false},
|
|
|
|
// Errors
|
|
|
|
{"fail SigningKey", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "",
|
|
|
|
}}, 0, nil, true},
|
|
|
|
{"fail uri", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "https:id=7375;object=ecdsa-p521-key",
|
|
|
|
}}, 0, nil, true},
|
|
|
|
{"fail softhsm FindKeyPair", setupSoftHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:foo=bar",
|
|
|
|
}}, 0, nil, true},
|
|
|
|
{"fail yubihsm FindKeyPair", setupYubiHSM2, args{&apiv1.CreateSignerRequest{
|
|
|
|
SigningKey: "pkcs11:foo=bar",
|
|
|
|
}}, 0, nil, true},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
k := tt.setup(t)
|
|
|
|
got, err := k.CreateSigner(tt.args.req)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("PKCS11.CreateSigner() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if got != nil {
|
|
|
|
hash := tt.signerOpts.HashFunc()
|
|
|
|
h := hash.New()
|
|
|
|
h.Write(data)
|
|
|
|
digest := h.Sum(nil)
|
|
|
|
sig, err := got.Sign(rand.Reader, digest, tt.signerOpts)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("cyrpto.Signer.Sign() error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch tt.algorithm {
|
|
|
|
case apiv1.SHA256WithRSA, apiv1.SHA384WithRSA, apiv1.SHA512WithRSA:
|
|
|
|
pub := got.Public().(*rsa.PublicKey)
|
|
|
|
if err := rsa.VerifyPKCS1v15(pub, hash, digest, sig); err != nil {
|
|
|
|
t.Errorf("rsa.VerifyPKCS1v15() error = %v", err)
|
|
|
|
}
|
|
|
|
case apiv1.UnspecifiedSignAlgorithm, apiv1.SHA256WithRSAPSS, apiv1.SHA384WithRSAPSS, apiv1.SHA512WithRSAPSS:
|
|
|
|
pub := got.Public().(*rsa.PublicKey)
|
|
|
|
if err := rsa.VerifyPSS(pub, hash, digest, sig, tt.signerOpts.(*rsa.PSSOptions)); err != nil {
|
|
|
|
t.Errorf("rsa.VerifyPSS() error = %v", err)
|
|
|
|
}
|
|
|
|
case apiv1.ECDSAWithSHA256, apiv1.ECDSAWithSHA384, apiv1.ECDSAWithSHA512:
|
|
|
|
pub := got.Public().(*ecdsa.PublicKey)
|
2021-01-28 04:35:42 +00:00
|
|
|
if !VerifyASN1(pub, digest, sig) {
|
2021-01-28 04:17:14 +00:00
|
|
|
t.Error("ecdsa.VerifyASN1() failed")
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
t.Errorf("signature algorithm %s is not supported", tt.algorithm)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPKCS11_LoadCertificate(t *testing.T) {
|
|
|
|
setupSoftHSM2, setupYubiHSM2 := setupFuncs(t)
|
|
|
|
|
|
|
|
getCertFn := func(i, j int) func() *x509.Certificate {
|
|
|
|
return func() *x509.Certificate {
|
|
|
|
return testCerts[i].Certificates[j]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type args struct {
|
|
|
|
req *apiv1.LoadCertificateRequest
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
setup func(t *testing.T) *PKCS11
|
|
|
|
args args
|
|
|
|
wantFn func() *x509.Certificate
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{"softhsm", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7370;object=root",
|
|
|
|
}}, getCertFn(0, 0), false},
|
|
|
|
{"softhsm by id", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7370",
|
|
|
|
}}, getCertFn(0, 0), false},
|
|
|
|
{"softhsm by label", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:object=root",
|
|
|
|
}}, getCertFn(0, 0), false},
|
|
|
|
{"yubihsm", setupYubiHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7370;object=root",
|
|
|
|
}}, getCertFn(0, 1), false},
|
|
|
|
{"yubihsm by id", setupYubiHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7370",
|
|
|
|
}}, getCertFn(0, 1), false},
|
|
|
|
{"yubihsm by label", setupYubiHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:object=root",
|
|
|
|
}}, getCertFn(0, 1), false},
|
|
|
|
{"fail softhsm missing", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=root",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail yubihsm missing", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=9999;object=root",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail name", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail uri", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:id=xxxx;object=root",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail softhsm FindCertificate", setupSoftHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
}}, nil, true},
|
|
|
|
{"fail yubihsm FindCertificate", setupYubiHSM2, args{&apiv1.LoadCertificateRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
}}, nil, true},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
k := tt.setup(t)
|
|
|
|
got, err := k.LoadCertificate(tt.args.req)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("PKCS11.LoadCertificate() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var want *x509.Certificate
|
|
|
|
if tt.wantFn != nil {
|
|
|
|
want = tt.wantFn()
|
|
|
|
got.Raw, got.RawIssuer, got.RawSubject, got.RawTBSCertificate, got.RawSubjectPublicKeyInfo = nil, nil, nil, nil, nil
|
|
|
|
want.Raw, want.RawIssuer, want.RawSubject, want.RawTBSCertificate, want.RawSubjectPublicKeyInfo = nil, nil, nil, nil, nil
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
|
|
t.Errorf("PKCS11.LoadCertificate() = %v, want %v", got, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPKCS11_StoreCertificate(t *testing.T) {
|
|
|
|
setupSoftHSM2, setupYubiHSM2 := setupFuncs(t)
|
|
|
|
|
|
|
|
pub, priv, err := ed25519.GenerateKey(rand.Reader)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("ed25519.GenerateKey() error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cert, err := generateCertificate(pub, priv)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("x509.CreateCertificate() error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
type args struct {
|
|
|
|
req *apiv1.StoreCertificateRequest
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
setup func(t *testing.T) *PKCS11
|
|
|
|
args args
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{"softhsm", setupSoftHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=root",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, false},
|
|
|
|
{"yubihsm", setupYubiHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=root",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, false},
|
|
|
|
{"fail name", setupSoftHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, true},
|
|
|
|
{"fail certificate", setupSoftHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "pkcs11:id=7771;object=root",
|
|
|
|
Certificate: nil,
|
|
|
|
}}, true},
|
|
|
|
{"fail uri", setupSoftHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "http:id=7771;object=root",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, true},
|
|
|
|
{"fail softhsm ImportCertificateWithLabel", setupSoftHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, true},
|
|
|
|
{"fail yubihsm ImportCertificateWithLabel", setupYubiHSM2, args{&apiv1.StoreCertificateRequest{
|
|
|
|
Name: "pkcs11:foo=bar",
|
|
|
|
Certificate: cert,
|
|
|
|
}}, true},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
k := tt.setup(t)
|
|
|
|
if err := k.StoreCertificate(tt.args.req); (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("PKCS11.StoreCertificate() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
}
|
|
|
|
if !tt.wantErr {
|
|
|
|
got, err := k.LoadCertificate(&apiv1.LoadCertificateRequest{
|
|
|
|
Name: tt.args.req.Name,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("PKCS11.LoadCertificate() error = %v", err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, cert) {
|
|
|
|
t.Errorf("PKCS11.LoadCertificate() = %v, want %v", got, cert)
|
|
|
|
}
|
|
|
|
if err := k.DeleteCertificate(tt.args.req.Name); err != nil {
|
|
|
|
t.Errorf("PKCS11.DeleteCertificate() error = %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-01-28 04:35:42 +00:00
|
|
|
|
|
|
|
// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
|
|
|
|
// public key, pub. Its return value records whether the signature is valid.
|
|
|
|
func VerifyASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool {
|
|
|
|
var (
|
|
|
|
r, s = &big.Int{}, &big.Int{}
|
|
|
|
inner cryptobyte.String
|
|
|
|
)
|
|
|
|
input := cryptobyte.String(sig)
|
|
|
|
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
|
|
|
|
input.Empty() ||
|
|
|
|
inner.ReadASN1Integer(r) ||
|
|
|
|
inner.ReadASN1Integer(s) ||
|
|
|
|
inner.Empty() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return ecdsa.Verify(pub, hash, r, s)
|
|
|
|
}
|