@@ -6,14 +6,14 @@ import (
66 "crypto/dsa"
77 "crypto/ecdsa"
88 "crypto/elliptic"
9- "crypto/md5"
9+ _ "crypto/md5"
10+ "crypto/rand"
1011 "crypto/rsa"
11- "crypto/sha1"
12- "crypto/sha256"
13- "crypto/sha512"
12+ _ "crypto/sha1"
13+ _ "crypto/sha256"
14+ _ "crypto/sha512"
15+ "encoding/asn1"
1416 "encoding/hex"
15- "hash"
16- "io"
1717 "math/big"
1818 "sort"
1919 "strings"
@@ -42,6 +42,38 @@ const (
4242 PRIVATEOID uint8 = 254
4343)
4444
45+ // Map for algorithm names.
46+ var AlgorithmToString = map [uint8 ]string {
47+ RSAMD5 : "RSAMD5" ,
48+ DH : "DH" ,
49+ DSA : "DSA" ,
50+ RSASHA1 : "RSASHA1" ,
51+ DSANSEC3SHA1 : "DSA-NSEC3-SHA1" ,
52+ RSASHA1NSEC3SHA1 : "RSASHA1-NSEC3-SHA1" ,
53+ RSASHA256 : "RSASHA256" ,
54+ RSASHA512 : "RSASHA512" ,
55+ ECCGOST : "ECC-GOST" ,
56+ ECDSAP256SHA256 : "ECDSAP256SHA256" ,
57+ ECDSAP384SHA384 : "ECDSAP384SHA384" ,
58+ INDIRECT : "INDIRECT" ,
59+ PRIVATEDNS : "PRIVATEDNS" ,
60+ PRIVATEOID : "PRIVATEOID" ,
61+ }
62+
63+ // Map of algorithm strings.
64+ var StringToAlgorithm = reverseInt8 (AlgorithmToString )
65+
66+ // Map of algorithm crypto hashes.
67+ var AlgorithmToHash = map [uint8 ]crypto.Hash {
68+ RSAMD5 : crypto .MD5 , // Deprecated in RFC 6725
69+ RSASHA1 : crypto .SHA1 ,
70+ RSASHA1NSEC3SHA1 : crypto .SHA1 ,
71+ RSASHA256 : crypto .SHA256 ,
72+ ECDSAP256SHA256 : crypto .SHA256 ,
73+ ECDSAP384SHA384 : crypto .SHA384 ,
74+ RSASHA512 : crypto .SHA512 ,
75+ }
76+
4577// DNSSEC hashing algorithm codes.
4678const (
4779 _ uint8 = iota
@@ -52,6 +84,18 @@ const (
5284 SHA512 // Experimental
5385)
5486
87+ // Map for hash names.
88+ var HashToString = map [uint8 ]string {
89+ SHA1 : "SHA1" ,
90+ SHA256 : "SHA256" ,
91+ GOST94 : "GOST94" ,
92+ SHA384 : "SHA384" ,
93+ SHA512 : "SHA512" ,
94+ }
95+
96+ // Map of hash strings.
97+ var StringToHash = reverseInt8 (HashToString )
98+
5599// DNSKEY flag values.
56100const (
57101 SEP = 1
@@ -168,24 +212,23 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
168212 // digest buffer
169213 digest := append (owner , wire ... ) // another copy
170214
215+ var hash crypto.Hash
171216 switch h {
172217 case SHA1 :
173- s := sha1 .New ()
174- io .WriteString (s , string (digest ))
175- ds .Digest = hex .EncodeToString (s .Sum (nil ))
218+ hash = crypto .SHA1
176219 case SHA256 :
177- s := sha256 .New ()
178- io .WriteString (s , string (digest ))
179- ds .Digest = hex .EncodeToString (s .Sum (nil ))
220+ hash = crypto .SHA256
180221 case SHA384 :
181- s := sha512 .New384 ()
182- io .WriteString (s , string (digest ))
183- ds .Digest = hex .EncodeToString (s .Sum (nil ))
184- case GOST94 :
185- /* I have no clue */
222+ hash = crypto .SHA384
223+ case SHA512 :
224+ hash = crypto .SHA512
186225 default :
187226 return nil
188227 }
228+
229+ s := hash .New ()
230+ s .Write (digest )
231+ ds .Digest = hex .EncodeToString (s .Sum (nil ))
189232 return ds
190233}
191234
@@ -212,7 +255,7 @@ func (d *DS) ToCDS() *CDS {
212255// There is no check if RRSet is a proper (RFC 2181) RRSet.
213256// If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset
214257// is used as the OrigTTL.
215- func (rr * RRSIG ) Sign (k PrivateKey , rrset []RR ) error {
258+ func (rr * RRSIG ) Sign (k crypto. Signer , rrset []RR ) error {
216259 if k == nil {
217260 return ErrPrivKey
218261 }
@@ -258,39 +301,66 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
258301 }
259302 signdata = append (signdata , wire ... )
260303
261- var h hash.Hash
262- switch rr .Algorithm {
263- case DSA , DSANSEC3SHA1 :
264- // TODO: this seems bugged, will panic
265- case RSASHA1 , RSASHA1NSEC3SHA1 :
266- h = sha1 .New ()
267- case RSASHA256 , ECDSAP256SHA256 :
268- h = sha256 .New ()
269- case ECDSAP384SHA384 :
270- h = sha512 .New384 ()
271- case RSASHA512 :
272- h = sha512 .New ()
273- case RSAMD5 :
274- fallthrough // Deprecated in RFC 6725
275- default :
304+ hash , ok := AlgorithmToHash [rr .Algorithm ]
305+ if ! ok {
276306 return ErrAlg
277307 }
278308
279- _ , err = h .Write (signdata )
280- if err != nil {
281- return err
282- }
283- sighash := h .Sum (nil )
309+ h := hash .New ()
310+ h .Write (signdata )
284311
285- signature , err := k . Sign ( sighash , rr .Algorithm )
312+ signature , err := sign ( k , h . Sum ( nil ), hash , rr .Algorithm )
286313 if err != nil {
287314 return err
288315 }
316+
289317 rr .Signature = toBase64 (signature )
290318
291319 return nil
292320}
293321
322+ func sign (k crypto.Signer , hashed []byte , hash crypto.Hash , alg uint8 ) ([]byte , error ) {
323+ signature , err := k .Sign (rand .Reader , hashed , hash )
324+ if err != nil {
325+ return nil , err
326+ }
327+
328+ switch alg {
329+ case RSASHA1 , RSASHA1NSEC3SHA1 , RSASHA256 , RSASHA512 :
330+ return signature , nil
331+
332+ case ECDSAP256SHA256 , ECDSAP384SHA384 :
333+ ecdsaSignature := & struct {
334+ R , S * big.Int
335+ }{}
336+ if _ , err := asn1 .Unmarshal (signature , ecdsaSignature ); err != nil {
337+ return nil , err
338+ }
339+
340+ var intlen int
341+ switch alg {
342+ case ECDSAP256SHA256 :
343+ intlen = 32
344+ case ECDSAP384SHA384 :
345+ intlen = 48
346+ }
347+
348+ signature := intToBytes (ecdsaSignature .R , intlen )
349+ signature = append (signature , intToBytes (ecdsaSignature .S , intlen )... )
350+ return signature , nil
351+
352+ // There is no defined interface for what a DSA backed crypto.Signer returns
353+ case DSA , DSANSEC3SHA1 :
354+ // t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
355+ // signature := []byte{byte(t)}
356+ // signature = append(signature, intToBytes(r1, 20)...)
357+ // signature = append(signature, intToBytes(s1, 20)...)
358+ // rr.Signature = signature
359+ }
360+
361+ return nil , ErrAlg
362+ }
363+
294364// Verify validates an RRSet with the signature and key. This is only the
295365// cryptographic test, the signature validity period must be checked separately.
296366// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
@@ -355,59 +425,43 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
355425 // remove the domain name and assume its our
356426 }
357427
428+ hash , ok := AlgorithmToHash [rr .Algorithm ]
429+ if ! ok {
430+ return ErrAlg
431+ }
432+
358433 switch rr .Algorithm {
359434 case RSASHA1 , RSASHA1NSEC3SHA1 , RSASHA256 , RSASHA512 , RSAMD5 :
360435 // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
361436 pubkey := k .publicKeyRSA () // Get the key
362437 if pubkey == nil {
363438 return ErrKey
364439 }
365- // Setup the hash as defined for this alg.
366- var h hash.Hash
367- var ch crypto.Hash
368- switch rr .Algorithm {
369- case RSAMD5 :
370- h = md5 .New ()
371- ch = crypto .MD5
372- case RSASHA1 , RSASHA1NSEC3SHA1 :
373- h = sha1 .New ()
374- ch = crypto .SHA1
375- case RSASHA256 :
376- h = sha256 .New ()
377- ch = crypto .SHA256
378- case RSASHA512 :
379- h = sha512 .New ()
380- ch = crypto .SHA512
381- }
382- io .WriteString (h , string (signeddata ))
383- sighash := h .Sum (nil )
384- return rsa .VerifyPKCS1v15 (pubkey , ch , sighash , sigbuf )
440+
441+ h := hash .New ()
442+ h .Write (signeddata )
443+ return rsa .VerifyPKCS1v15 (pubkey , hash , h .Sum (nil ), sigbuf )
444+
385445 case ECDSAP256SHA256 , ECDSAP384SHA384 :
386446 pubkey := k .publicKeyECDSA ()
387447 if pubkey == nil {
388448 return ErrKey
389449 }
390- var h hash.Hash
391- switch rr .Algorithm {
392- case ECDSAP256SHA256 :
393- h = sha256 .New ()
394- case ECDSAP384SHA384 :
395- h = sha512 .New384 ()
396- }
397- io .WriteString (h , string (signeddata ))
398- sighash := h .Sum (nil )
450+
399451 // Split sigbuf into the r and s coordinates
400- r := big .NewInt (0 )
401- r .SetBytes (sigbuf [:len (sigbuf )/ 2 ])
402- s := big .NewInt (0 )
403- s .SetBytes (sigbuf [len (sigbuf )/ 2 :])
404- if ecdsa .Verify (pubkey , sighash , r , s ) {
452+ r := new (big.Int ).SetBytes (sigbuf [:len (sigbuf )/ 2 ])
453+ s := new (big.Int ).SetBytes (sigbuf [len (sigbuf )/ 2 :])
454+
455+ h := hash .New ()
456+ h .Write (signeddata )
457+ if ecdsa .Verify (pubkey , h .Sum (nil ), r , s ) {
405458 return nil
406459 }
407460 return ErrSig
461+
462+ default :
463+ return ErrAlg
408464 }
409- // Unknown alg
410- return ErrAlg
411465}
412466
413467// ValidityPeriod uses RFC1982 serial arithmetic to calculate
@@ -603,36 +657,3 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
603657 }
604658 return buf , nil
605659}
606-
607- // Map for algorithm names.
608- var AlgorithmToString = map [uint8 ]string {
609- RSAMD5 : "RSAMD5" ,
610- DH : "DH" ,
611- DSA : "DSA" ,
612- RSASHA1 : "RSASHA1" ,
613- DSANSEC3SHA1 : "DSA-NSEC3-SHA1" ,
614- RSASHA1NSEC3SHA1 : "RSASHA1-NSEC3-SHA1" ,
615- RSASHA256 : "RSASHA256" ,
616- RSASHA512 : "RSASHA512" ,
617- ECCGOST : "ECC-GOST" ,
618- ECDSAP256SHA256 : "ECDSAP256SHA256" ,
619- ECDSAP384SHA384 : "ECDSAP384SHA384" ,
620- INDIRECT : "INDIRECT" ,
621- PRIVATEDNS : "PRIVATEDNS" ,
622- PRIVATEOID : "PRIVATEOID" ,
623- }
624-
625- // Map of algorithm strings.
626- var StringToAlgorithm = reverseInt8 (AlgorithmToString )
627-
628- // Map for hash names.
629- var HashToString = map [uint8 ]string {
630- SHA1 : "SHA1" ,
631- SHA256 : "SHA256" ,
632- GOST94 : "GOST94" ,
633- SHA384 : "SHA384" ,
634- SHA512 : "SHA512" ,
635- }
636-
637- // Map of hash strings.
638- var StringToHash = reverseInt8 (HashToString )
0 commit comments