1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package p11token
18
19 import (
20 "crypto"
21 "crypto/rsa"
22 "errors"
23 "math/big"
24
25 "github.com/miekg/pkcs11"
26 "github.com/sassoftware/relic/lib/x509tools"
27 )
28
29
30 func (key *Key) toRsaKey() (crypto.PublicKey, error) {
31 modulus := key.token.getAttribute(key.pub, pkcs11.CKA_MODULUS)
32 exponent := key.token.getAttribute(key.pub, pkcs11.CKA_PUBLIC_EXPONENT)
33 if len(modulus) == 0 || len(exponent) == 0 {
34 return nil, errors.New("Unable to retrieve RSA public key")
35 }
36 n := new(big.Int).SetBytes([]byte(modulus))
37 e := int(attrToInt(exponent))
38 return &rsa.PublicKey{N: n, E: e}, nil
39 }
40
41 func (key *Key) newPssMech(opts *rsa.PSSOptions) (*pkcs11.Mechanism, error) {
42 var hashAlg, mgfType uint
43 switch opts.Hash {
44 case crypto.SHA1:
45 hashAlg = pkcs11.CKM_SHA_1
46 mgfType = pkcs11.CKG_MGF1_SHA1
47 case crypto.SHA224:
48 hashAlg = pkcs11.CKM_SHA224
49 mgfType = pkcs11.CKG_MGF1_SHA224
50 case crypto.SHA256:
51 hashAlg = pkcs11.CKM_SHA256
52 mgfType = pkcs11.CKG_MGF1_SHA256
53 case crypto.SHA384:
54 hashAlg = pkcs11.CKM_SHA384
55 mgfType = pkcs11.CKG_MGF1_SHA384
56 case crypto.SHA512:
57 hashAlg = pkcs11.CKM_SHA512
58 mgfType = pkcs11.CKG_MGF1_SHA512
59 default:
60 return nil, errors.New("unsupported hash type for PSS")
61 }
62 saltLength := opts.SaltLength
63 switch saltLength {
64 case rsa.PSSSaltLengthAuto:
65 pub := key.pubParsed.(*rsa.PublicKey)
66 saltLength = (pub.N.BitLen()+7)/8 - 2 - opts.Hash.Size()
67 case rsa.PSSSaltLengthEqualsHash:
68 saltLength = opts.Hash.Size()
69 }
70 args := make([]byte, ulongSize*3)
71 putUlong(args, hashAlg)
72 putUlong(args[ulongSize:], mgfType)
73 putUlong(args[ulongSize*2:], uint(saltLength))
74 return pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_PSS, args), nil
75 }
76
77
78 func (key *Key) signRSA(digest []byte, opts crypto.SignerOpts) ([]byte, error) {
79 var mech *pkcs11.Mechanism
80 if opts == nil || opts.HashFunc() == 0 {
81 return nil, errors.New("Signer options are required")
82 } else if pss, ok := opts.(*rsa.PSSOptions); ok {
83 var err error
84 mech, err = key.newPssMech(pss)
85 if err != nil {
86 return nil, err
87 }
88 } else {
89 var ok bool
90 digest, ok = x509tools.MarshalDigest(opts.HashFunc(), digest)
91 if !ok {
92 return nil, errors.New("unsupported hash function")
93 }
94 mech = pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)
95 }
96 err := key.token.ctx.SignInit(key.token.sh, []*pkcs11.Mechanism{mech}, key.priv)
97 if err != nil {
98 return nil, err
99 }
100 return key.token.ctx.Sign(key.token.sh, digest)
101 }
102
103
104 func rsaImportAttrs(priv *rsa.PrivateKey) (pubAttrs, privAttrs []*pkcs11.Attribute, err error) {
105 if len(priv.Primes) != 2 || priv.Precomputed.Dp == nil || priv.Precomputed.Dq == nil || priv.Precomputed.Qinv == nil {
106
107
108 return nil, nil, errors.New("unsupported RSA key")
109 }
110 pubAttrs = []*pkcs11.Attribute{
111 pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(priv.E)).Bytes()),
112 pkcs11.NewAttribute(pkcs11.CKA_MODULUS, priv.N.Bytes()),
113 }
114 privAttrs = []*pkcs11.Attribute{
115 pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, big.NewInt(int64(priv.E)).Bytes()),
116 pkcs11.NewAttribute(pkcs11.CKA_MODULUS, priv.N.Bytes()),
117 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE_EXPONENT, priv.D.Bytes()),
118 pkcs11.NewAttribute(pkcs11.CKA_PRIME_1, priv.Primes[0].Bytes()),
119 pkcs11.NewAttribute(pkcs11.CKA_PRIME_2, priv.Primes[1].Bytes()),
120 pkcs11.NewAttribute(pkcs11.CKA_EXPONENT_1, priv.Precomputed.Dp.Bytes()),
121 pkcs11.NewAttribute(pkcs11.CKA_EXPONENT_2, priv.Precomputed.Dq.Bytes()),
122 pkcs11.NewAttribute(pkcs11.CKA_COEFFICIENT, priv.Precomputed.Qinv.Bytes()),
123 }
124 return
125 }
126
127
128 func rsaGenerateAttrs(bits uint) ([]*pkcs11.Attribute, *pkcs11.Mechanism, error) {
129 if bits < 1024 || bits > 4096 {
130 return nil, nil, errors.New("unsupported number of bits")
131 }
132 pubExponent := []byte{1, 0, 1}
133 attrs := []*pkcs11.Attribute{
134 pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, bits),
135 pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, pubExponent),
136 }
137 mech := pkcs11.NewMechanism(pkcs11.CKM_RSA_X9_31_KEY_PAIR_GEN, nil)
138 return attrs, mech, nil
139 }
140
View as plain text