1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package tls
16
17 import (
18 "crypto"
19 "crypto/dsa"
20 "crypto/ecdsa"
21 _ "crypto/md5"
22 "crypto/rand"
23 "crypto/rsa"
24 _ "crypto/sha1"
25 _ "crypto/sha256"
26 _ "crypto/sha512"
27 "errors"
28 "fmt"
29 "log"
30 "math/big"
31
32 "github.com/google/certificate-transparency-go/asn1"
33 )
34
35 type dsaSig struct {
36 R, S *big.Int
37 }
38
39 func generateHash(algo HashAlgorithm, data []byte) ([]byte, crypto.Hash, error) {
40 var hashType crypto.Hash
41 switch algo {
42 case MD5:
43 hashType = crypto.MD5
44 case SHA1:
45 hashType = crypto.SHA1
46 case SHA224:
47 hashType = crypto.SHA224
48 case SHA256:
49 hashType = crypto.SHA256
50 case SHA384:
51 hashType = crypto.SHA384
52 case SHA512:
53 hashType = crypto.SHA512
54 default:
55 return nil, hashType, fmt.Errorf("unsupported Algorithm.Hash in signature: %v", algo)
56 }
57
58 hasher := hashType.New()
59 if _, err := hasher.Write(data); err != nil {
60 return nil, hashType, fmt.Errorf("failed to write to hasher: %v", err)
61 }
62 return hasher.Sum([]byte{}), hashType, nil
63 }
64
65
66 func VerifySignature(pubKey crypto.PublicKey, data []byte, sig DigitallySigned) error {
67 hash, hashType, err := generateHash(sig.Algorithm.Hash, data)
68 if err != nil {
69 return err
70 }
71
72 switch sig.Algorithm.Signature {
73 case RSA:
74 rsaKey, ok := pubKey.(*rsa.PublicKey)
75 if !ok {
76 return fmt.Errorf("cannot verify RSA signature with %T key", pubKey)
77 }
78 if err := rsa.VerifyPKCS1v15(rsaKey, hashType, hash, sig.Signature); err != nil {
79 return fmt.Errorf("failed to verify rsa signature: %v", err)
80 }
81 case DSA:
82 dsaKey, ok := pubKey.(*dsa.PublicKey)
83 if !ok {
84 return fmt.Errorf("cannot verify DSA signature with %T key", pubKey)
85 }
86 var dsaSig dsaSig
87 rest, err := asn1.Unmarshal(sig.Signature, &dsaSig)
88 if err != nil {
89 return fmt.Errorf("failed to unmarshal DSA signature: %v", err)
90 }
91 if len(rest) != 0 {
92 log.Printf("Garbage following signature %q", rest)
93 }
94 if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
95 return errors.New("DSA signature contained zero or negative values")
96 }
97 if !dsa.Verify(dsaKey, hash, dsaSig.R, dsaSig.S) {
98 return errors.New("failed to verify DSA signature")
99 }
100 case ECDSA:
101 ecdsaKey, ok := pubKey.(*ecdsa.PublicKey)
102 if !ok {
103 return fmt.Errorf("cannot verify ECDSA signature with %T key", pubKey)
104 }
105 var ecdsaSig dsaSig
106 rest, err := asn1.Unmarshal(sig.Signature, &ecdsaSig)
107 if err != nil {
108 return fmt.Errorf("failed to unmarshal ECDSA signature: %v", err)
109 }
110 if len(rest) != 0 {
111 log.Printf("Garbage following signature %q", rest)
112 }
113 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
114 return errors.New("ECDSA signature contained zero or negative values")
115 }
116
117 if !ecdsa.Verify(ecdsaKey, hash, ecdsaSig.R, ecdsaSig.S) {
118 return errors.New("failed to verify ECDSA signature")
119 }
120 default:
121 return fmt.Errorf("unsupported Algorithm.Signature in signature: %v", sig.Algorithm.Hash)
122 }
123 return nil
124 }
125
126
127 func CreateSignature(privKey crypto.PrivateKey, hashAlgo HashAlgorithm, data []byte) (DigitallySigned, error) {
128 var sig DigitallySigned
129 sig.Algorithm.Hash = hashAlgo
130 hash, hashType, err := generateHash(sig.Algorithm.Hash, data)
131 if err != nil {
132 return sig, err
133 }
134
135 switch privKey := privKey.(type) {
136 case rsa.PrivateKey:
137 sig.Algorithm.Signature = RSA
138 sig.Signature, err = rsa.SignPKCS1v15(rand.Reader, &privKey, hashType, hash)
139 return sig, err
140 case ecdsa.PrivateKey:
141 sig.Algorithm.Signature = ECDSA
142 var ecdsaSig dsaSig
143 ecdsaSig.R, ecdsaSig.S, err = ecdsa.Sign(rand.Reader, &privKey, hash)
144 if err != nil {
145 return sig, err
146 }
147 sig.Signature, err = asn1.Marshal(ecdsaSig)
148 return sig, err
149 default:
150 return sig, fmt.Errorf("unsupported private key type %T", privKey)
151 }
152 }
153
View as plain text