1 package main
2
3 import (
4 "crypto/rsa"
5 "errors"
6 "log"
7 "math/big"
8
9 "github.com/letsencrypt/boulder/pkcs11helpers"
10 "github.com/miekg/pkcs11"
11 )
12
13 const (
14 rsaExp = 65537
15 )
16
17
18
19
20
21 func rsaArgs(label string, modulusLen, exponent uint, keyID []byte) generateArgs {
22
23 expSlice := big.NewInt(int64(exponent)).Bytes()
24 log.Printf("\tEncoded public exponent (%d) as: %0X\n", exponent, expSlice)
25 return generateArgs{
26 mechanism: []*pkcs11.Mechanism{
27 pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_KEY_PAIR_GEN, nil),
28 },
29 publicAttrs: []*pkcs11.Attribute{
30 pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
31 pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
32 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
33
34 pkcs11.NewAttribute(pkcs11.CKA_VERIFY, true),
35
36 pkcs11.NewAttribute(pkcs11.CKA_MODULUS_BITS, modulusLen),
37
38 pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, expSlice),
39 },
40 privateAttrs: []*pkcs11.Attribute{
41 pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
42 pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
43 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
44
45 pkcs11.NewAttribute(pkcs11.CKA_SENSITIVE, true),
46
47 pkcs11.NewAttribute(pkcs11.CKA_EXTRACTABLE, false),
48
49 pkcs11.NewAttribute(pkcs11.CKA_SIGN, true),
50 },
51 }
52 }
53
54
55
56
57
58 func rsaPub(session *pkcs11helpers.Session, object pkcs11.ObjectHandle, modulusLen, exponent uint) (*rsa.PublicKey, error) {
59 pubKey, err := session.GetRSAPublicKey(object)
60 if err != nil {
61 return nil, err
62 }
63 if pubKey.E != int(exponent) {
64 return nil, errors.New("returned CKA_PUBLIC_EXPONENT doesn't match expected exponent")
65 }
66 if pubKey.N.BitLen() != int(modulusLen) {
67 return nil, errors.New("returned CKA_MODULUS isn't of the expected bit length")
68 }
69 log.Printf("\tPublic exponent: %d\n", pubKey.E)
70 log.Printf("\tModulus: (%d bits) %X\n", pubKey.N.BitLen(), pubKey.N.Bytes())
71 return pubKey, nil
72 }
73
74
75
76
77
78 func rsaGenerate(session *pkcs11helpers.Session, label string, modulusLen uint) (*rsa.PublicKey, []byte, error) {
79 keyID := make([]byte, 4)
80 _, err := newRandReader(session).Read(keyID)
81 if err != nil {
82 return nil, nil, err
83 }
84 log.Printf("Generating RSA key with %d bit modulus and public exponent %d and ID %x\n", modulusLen, rsaExp, keyID)
85 args := rsaArgs(label, modulusLen, rsaExp, keyID)
86 pub, _, err := session.GenerateKeyPair(args.mechanism, args.publicAttrs, args.privateAttrs)
87 if err != nil {
88 return nil, nil, err
89 }
90 log.Println("Key generated")
91 log.Println("Extracting public key")
92 pk, err := rsaPub(session, pub, modulusLen, rsaExp)
93 if err != nil {
94 return nil, nil, err
95 }
96 log.Println("Extracted public key")
97 return pk, keyID, nil
98 }
99
View as plain text