...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package crypto11
23
24 import (
25 "C"
26 "encoding/asn1"
27 "math/big"
28 "unsafe"
29
30 "github.com/miekg/pkcs11"
31 "github.com/pkg/errors"
32 )
33
34 func ulongToBytes(n uint) []byte {
35 return C.GoBytes(unsafe.Pointer(&n), C.sizeof_ulong)
36 }
37
38 func bytesToUlong(bs []byte) (n uint) {
39 sliceSize := len(bs)
40 if sliceSize == 0 {
41 return 0
42 }
43
44 value := *(*uint)(unsafe.Pointer(&bs[0]))
45 if sliceSize > C.sizeof_ulong {
46 return value
47 }
48
49
50
51 var mask uint
52 for i := 0; i < sliceSize; i++ {
53 mask |= 0xff << uint(i * 8)
54 }
55 return value & mask
56 }
57
58 func concat(slices ...[]byte) []byte {
59 n := 0
60 for _, slice := range slices {
61 n += len(slice)
62 }
63 r := make([]byte, n)
64 n = 0
65 for _, slice := range slices {
66 n += copy(r[n:], slice)
67 }
68 return r
69 }
70
71
72 type dsaSignature struct {
73 R, S *big.Int
74 }
75
76
77 func (sig *dsaSignature) unmarshalBytes(sigBytes []byte) error {
78 if len(sigBytes) == 0 || len(sigBytes)%2 != 0 {
79 return errors.New("DSA signature length is invalid from token")
80 }
81 n := len(sigBytes) / 2
82 sig.R, sig.S = new(big.Int), new(big.Int)
83 sig.R.SetBytes(sigBytes[:n])
84 sig.S.SetBytes(sigBytes[n:])
85 return nil
86 }
87
88
89 func (sig *dsaSignature) unmarshalDER(sigDER []byte) error {
90 if rest, err := asn1.Unmarshal(sigDER, sig); err != nil {
91 return errors.WithMessage(err, "DSA signature contains invalid ASN.1 data")
92 } else if len(rest) > 0 {
93 return errors.New("unexpected data found after DSA signature")
94 }
95 return nil
96 }
97
98
99 func (sig *dsaSignature) marshalDER() ([]byte, error) {
100 return asn1.Marshal(*sig)
101 }
102
103
104 func (c *Context) dsaGeneric(key pkcs11.ObjectHandle, mechanism uint, digest []byte) ([]byte, error) {
105 var err error
106 var sigBytes []byte
107 var sig dsaSignature
108 mech := []*pkcs11.Mechanism{pkcs11.NewMechanism(mechanism, nil)}
109 err = c.withSession(func(session *pkcs11Session) error {
110 if err = c.ctx.SignInit(session.handle, mech, key); err != nil {
111 return err
112 }
113 sigBytes, err = c.ctx.Sign(session.handle, digest)
114 return err
115 })
116 if err != nil {
117 return nil, err
118 }
119 err = sig.unmarshalBytes(sigBytes)
120 if err != nil {
121 return nil, err
122 }
123
124 return sig.marshalDER()
125 }
126
View as plain text