boulder/cmd/ceremony/rsa_test.go

154 lines
5.8 KiB
Go

package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"errors"
"math/big"
"testing"
"github.com/letsencrypt/boulder/pkcs11helpers"
"github.com/letsencrypt/boulder/test"
"github.com/miekg/pkcs11"
)
func TestRSAPub(t *testing.T) {
s, ctx := pkcs11helpers.NewSessionWithMock()
// test we fail to construct key with non-matching exp
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
return []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{1, 0, 1}),
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, []byte{255}),
}, nil
}
_, err := rsaPub(s, 0, 0, 255)
test.AssertError(t, err, "rsaPub didn't fail with non-matching exp")
// test we fail to construct key with non-matching modulus
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
return []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{1, 0, 1}),
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, []byte{255}),
}, nil
}
_, err = rsaPub(s, 0, 16, 65537)
test.AssertError(t, err, "rsaPub didn't fail with non-matching modulus size")
// test we don't fail with the correct attributes
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
return []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, []byte{1, 0, 1}),
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, []byte{255}),
}, nil
}
_, err = rsaPub(s, 0, 8, 65537)
test.AssertNotError(t, err, "rsaPub failed with valid attributes")
}
func TestRSAVerify(t *testing.T) {
s, ctx := pkcs11helpers.NewSessionWithMock()
// test GenerateRandom failing
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return nil, errors.New("yup")
}
err := rsaVerify(s, 0, nil)
test.AssertError(t, err, "rsaVerify didn't fail on GenerateRandom error")
// test SignInit failing
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return []byte{1, 2, 3}, nil
}
ctx.SignInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
return errors.New("yup")
}
err = rsaVerify(s, 0, nil)
test.AssertError(t, err, "rsaVerify didn't fail on SignInit error")
// test Sign failing
ctx.SignInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
return nil
}
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return []byte{1, 2, 3, 4}, nil
}
ctx.SignFunc = func(pkcs11.SessionHandle, []byte) ([]byte, error) {
return nil, errors.New("yup")
}
err = rsaVerify(s, 0, nil)
test.AssertError(t, err, "rsaVerify didn't fail on Sign error")
// test signature verification failing
ctx.SignFunc = func(pkcs11.SessionHandle, []byte) ([]byte, error) {
return []byte{1, 2, 3}, nil
}
tk, err := rsa.GenerateKey(rand.Reader, 1024)
test.AssertNotError(t, err, "rsa.GenerateKey failed")
err = rsaVerify(s, 0, &tk.PublicKey)
test.AssertError(t, err, "rsaVerify didn't fail on signature verification error")
// test we don't fail with valid signature
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
return rsa.SignPKCS1v15(rand.Reader, tk, crypto.SHA256, msg[19:])
}
err = rsaVerify(s, 0, &tk.PublicKey)
test.AssertNotError(t, err, "rsaVerify failed with a valid signature")
}
func TestRSAGenerate(t *testing.T) {
s, ctx := pkcs11helpers.NewSessionWithMock()
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return []byte{1, 2, 3}, nil
}
priv, err := rsa.GenerateKey(rand.Reader, 1024)
test.AssertNotError(t, err, "Failed to generate a RSA test key")
// Test rsaGenerate fails when GenerateKeyPair fails
ctx.GenerateKeyPairFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) {
return 0, 0, errors.New("bad")
}
_, _, err = rsaGenerate(s, "", 1024, 65537)
test.AssertError(t, err, "rsaGenerate didn't fail on GenerateKeyPair error")
// Test rsaGenerate fails when rsaPub fails
ctx.GenerateKeyPairFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, []*pkcs11.Attribute, []*pkcs11.Attribute) (pkcs11.ObjectHandle, pkcs11.ObjectHandle, error) {
return 0, 0, nil
}
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
return nil, errors.New("bad")
}
_, _, err = rsaGenerate(s, "", 1024, 65537)
test.AssertError(t, err, "rsaGenerate didn't fail on rsaPub error")
// Test rsaGenerate fails when rsaVerify fails
ctx.GetAttributeValueFunc = func(pkcs11.SessionHandle, pkcs11.ObjectHandle, []*pkcs11.Attribute) ([]*pkcs11.Attribute, error) {
return []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(priv.E)).Bytes()),
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, priv.N.Bytes()),
}, nil
}
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return nil, errors.New("yup")
}
_, _, err = rsaGenerate(s, "", 1024, 65537)
test.AssertError(t, err, "rsaGenerate didn't fail on rsaVerify error")
// Test rsaGenerate doesn't fail when everything works
ctx.SignInitFunc = func(pkcs11.SessionHandle, []*pkcs11.Mechanism, pkcs11.ObjectHandle) error {
return nil
}
ctx.GenerateRandomFunc = func(pkcs11.SessionHandle, int) ([]byte, error) {
return []byte{1, 2, 3}, nil
}
ctx.SignFunc = func(_ pkcs11.SessionHandle, msg []byte) ([]byte, error) {
// Chop of the hash identifier and feed back into rsa.SignPKCS1v15
return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, msg[19:])
}
_, _, err = rsaGenerate(s, "", 1024, 65537)
test.AssertNotError(t, err, "rsaGenerate didn't succeed when everything worked as expected")
}