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 "errors"
22 "io"
23
24 "github.com/miekg/pkcs11"
25 "github.com/sassoftware/relic/config"
26 "github.com/sassoftware/relic/signers/sigerrors"
27 "github.com/sassoftware/relic/token"
28 )
29
30 type Key struct {
31 PgpCertificate string
32 X509Certificate string
33 token *Token
34 keyConf *config.KeyConfig
35 keyType uint
36 pub pkcs11.ObjectHandle
37 priv pkcs11.ObjectHandle
38 pubParsed crypto.PublicKey
39 }
40
41 func (token *Token) GetKey(keyName string) (token.Key, error) {
42 token.mutex.Lock()
43 defer token.mutex.Unlock()
44 keyConf, err := token.config.GetKey(keyName)
45 if err != nil {
46 return nil, err
47 }
48 return token.getKey(keyConf, keyName)
49 }
50
51 func (token *Token) getKey(keyConf *config.KeyConfig, keyName string) (*Key, error) {
52 var err error
53 key := &Key{
54 token: token,
55 keyConf: keyConf,
56 PgpCertificate: keyConf.PgpCertificate,
57 X509Certificate: keyConf.X509Certificate,
58 }
59 key.priv, err = token.findKey(keyConf, pkcs11.CKO_PRIVATE_KEY)
60 if err != nil {
61 return nil, err
62 }
63 key.pub, err = token.findKey(keyConf, pkcs11.CKO_PUBLIC_KEY)
64 if err != nil {
65 return nil, err
66 }
67 keyTypeBlob := token.getAttribute(key.priv, pkcs11.CKA_KEY_TYPE)
68 if len(keyTypeBlob) == 0 {
69 return nil, errors.New("Missing CKA_KEY_TYPE on private key")
70 }
71 key.keyType = attrToInt(keyTypeBlob)
72 switch key.keyType {
73 case CKK_RSA:
74 key.pubParsed, err = key.toRsaKey()
75 case CKK_ECDSA:
76 key.pubParsed, err = key.toEcdsaKey()
77 default:
78 return nil, errors.New("Unsupported key type")
79 }
80 if err != nil {
81 return nil, err
82 }
83 return key, nil
84 }
85
86 func (token *Token) findKey(keyConf *config.KeyConfig, class uint) (pkcs11.ObjectHandle, error) {
87 attrs := []*pkcs11.Attribute{
88 pkcs11.NewAttribute(pkcs11.CKA_CLASS, class),
89 }
90 if keyConf.Label != "" {
91 attrs = append(attrs, pkcs11.NewAttribute(pkcs11.CKA_LABEL, keyConf.Label))
92 }
93 if keyConf.ID != "" {
94 keyID, err := parseKeyID(keyConf.ID)
95 if err != nil {
96 return 0, err
97 }
98 attrs = append(attrs, pkcs11.NewAttribute(pkcs11.CKA_ID, keyID))
99 }
100 objects, err := token.findObject(attrs)
101 if err != nil {
102 return 0, err
103 } else if len(objects) > 1 {
104 return 0, errors.New("Multiple token objects with the specified attributes")
105 } else if len(objects) == 0 {
106 return 0, sigerrors.KeyNotFoundError{}
107 }
108 return objects[0], nil
109 }
110
111 func (key *Key) Config() *config.KeyConfig {
112 return key.keyConf
113 }
114
115 func (key *Key) Public() crypto.PublicKey {
116 return key.pubParsed
117 }
118
119 func (key *Key) getLabel() string {
120 key.token.mutex.Lock()
121 defer key.token.mutex.Unlock()
122 return string(key.token.getAttribute(key.priv, pkcs11.CKA_LABEL))
123 }
124
125 func (key *Key) GetID() []byte {
126 key.token.mutex.Lock()
127 defer key.token.mutex.Unlock()
128 return key.token.getAttribute(key.priv, pkcs11.CKA_ID)
129 }
130
131 func (key *Key) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
132 key.token.mutex.Lock()
133 defer key.token.mutex.Unlock()
134 switch key.keyType {
135 case CKK_RSA:
136 return key.signRSA(digest, opts)
137 case CKK_ECDSA:
138 return key.signECDSA(digest)
139 default:
140 return nil, errors.New("Unsupported key type")
141 }
142 }
143
View as plain text