1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package p11token
18
19 import (
20 "crypto/sha1"
21 "crypto/x509"
22 "errors"
23 "fmt"
24
25 "github.com/miekg/pkcs11"
26 "github.com/sassoftware/relic/signers/sigerrors"
27 )
28
29 var newCertAttrs = []*pkcs11.Attribute{
30 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
31 pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
32 pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, false),
33 pkcs11.NewAttribute(pkcs11.CKA_CERTIFICATE_TYPE, pkcs11.CKC_X_509),
34 }
35
36 func (tk *Token) ImportCertificate(cert *x509.Certificate, labelBase string) error {
37 fingerprint := sha1.Sum(cert.Raw)
38 if labelBase == "" {
39 return errors.New("label is required")
40 }
41
42 label := fmt.Sprintf("%s_chain_%x", labelBase, fingerprint[:8])
43 tk.mutex.Lock()
44 defer tk.mutex.Unlock()
45 if err := tk.certExists(label); err != nil {
46 return err
47 }
48 keyID := makeKeyID()
49 if keyID == nil {
50 return errors.New("failed to make key ID")
51 }
52 attrs := []*pkcs11.Attribute{
53 pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
54 pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
55 pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, cert.RawSubject),
56 pkcs11.NewAttribute(pkcs11.CKA_ISSUER, cert.RawIssuer),
57 pkcs11.NewAttribute(pkcs11.CKA_VALUE, cert.Raw),
58 }
59 attrs = append(attrs, newCertAttrs...)
60 _, err := tk.ctx.CreateObject(tk.sh, attrs)
61 return err
62 }
63
64 func (tk *Token) certExists(label string) error {
65 attrs := []*pkcs11.Attribute{
66 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
67 pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
68 }
69 objects, err := tk.findObject(attrs)
70 if err != nil {
71 return err
72 } else if len(objects) != 0 {
73 return sigerrors.ErrExist
74 } else {
75 return nil
76 }
77 }
78
79 func (key *Key) ImportCertificate(cert *x509.Certificate) error {
80 keyID, handle, err := key.findCertificate()
81 if err != nil {
82 return err
83 } else if handle != 0 {
84 return sigerrors.ErrExist
85 }
86 label := key.getLabel()
87 if label == "" {
88 return errors.New("label is required")
89 }
90 attrs := []*pkcs11.Attribute{
91 pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
92 pkcs11.NewAttribute(pkcs11.CKA_LABEL, label),
93 pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, cert.RawSubject),
94 pkcs11.NewAttribute(pkcs11.CKA_ISSUER, cert.RawIssuer),
95 pkcs11.NewAttribute(pkcs11.CKA_VALUE, cert.Raw),
96 }
97 attrs = append(attrs, newCertAttrs...)
98 key.token.mutex.Lock()
99 defer key.token.mutex.Unlock()
100 _, err = key.token.ctx.CreateObject(key.token.sh, attrs)
101 return err
102 }
103
104 func (key *Key) findCertificate() (keyID []byte, handle pkcs11.ObjectHandle, err error) {
105 keyID = key.GetID()
106 if len(keyID) == 0 {
107 return nil, 0, errors.New("no keyID")
108 }
109 key.token.mutex.Lock()
110 defer key.token.mutex.Unlock()
111 attrs := []*pkcs11.Attribute{
112 pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
113 pkcs11.NewAttribute(pkcs11.CKA_ID, keyID),
114 }
115 objects, err := key.token.findObject(attrs)
116 if err != nil {
117 return nil, 0, err
118 }
119 if len(objects) == 0 {
120 return keyID, 0, nil
121 }
122 return keyID, objects[0], nil
123 }
124
View as plain text