diff --git a/dnssec.go b/dnssec.go index ec1d4e7e..bd1aa6d3 100644 --- a/dnssec.go +++ b/dnssec.go @@ -28,8 +28,8 @@ const ( AlgRSASHA256 = 8 AlgRSASHA512 = 10 AlgECCGOST = 12 - // AlgECDSAP256SHA256 = 13 - // AlgECDSAP384SHA384 = 14 + AlgECDSAP256SHA256 = 13 + AlgECDSAP384SHA384 = 14 ) // DNSSEC hashing codes. @@ -405,6 +405,16 @@ func (k *RR_DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool { return true } +// Set the public key for Elliptic Curves +func (k *RR_DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool { + if _X == nil || _Y == nil { + return false + } + buf := curveToBuf(_X, _Y) + k.PublicKey = unpackBase64(buf) + return true +} + // Set the public key (the values E and N) for RSA // RFC 3110: Section 2. RSA Public KEY Resource Records func exponentToBuf(_E int) []byte { @@ -423,6 +433,14 @@ func exponentToBuf(_E int) []byte { return buf } +// Set the public key for X and Y for Curve +// Experimental +func curveToBuf(_X, _Y *big.Int) []byte { + buf := _X.Bytes() + buf = append(buf, _Y.Bytes()...) + return buf +} + // return a saw signature data func rawSignatureData(rrset RRset, s *RR_RRSIG) (buf []byte) { for _, r := range rrset { @@ -470,4 +488,6 @@ var alg_str = map[uint8]string{ AlgRSASHA256: "RSASHA256", AlgRSASHA512: "RSASHA512", AlgECCGOST: "ECC-GOST", + AlgECDSAP256SHA256: "ECDSAP256SHA256", + AlgECDSAP384SHA384: "ECDSAP384SHA384", } diff --git a/dnssec_test.go b/dnssec_test.go index 0b6c89e6..c1fcfff5 100644 --- a/dnssec_test.go +++ b/dnssec_test.go @@ -1,6 +1,7 @@ package dns import ( + "fmt" "testing" "strings" ) @@ -100,7 +101,7 @@ func TestSignVerify(t *testing.T) { sig := new(RR_RRSIG) sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} sig.TypeCovered = soa.Hdr.Rrtype - sig.Labels = labelCount(soa.Hdr.Name) + sig.Labels = LabelCount(soa.Hdr.Name) sig.OrigTtl = soa.Hdr.Ttl sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" @@ -119,7 +120,7 @@ func TestSignVerify(t *testing.T) { } } -func TestKeyGen(t *testing.T) { +func TestKeyGenRSA(t *testing.T) { key := new(RR_DNSKEY) key.Hdr.Name = "miek.nl." key.Hdr.Rrtype = TypeDNSKEY @@ -128,9 +129,22 @@ func TestKeyGen(t *testing.T) { key.Flags = 256 key.Protocol = 3 key.Algorithm = AlgRSASHA256 - key.Generate(512) + key.Generate(1024) + fmt.Printf("%v\n", key) } +func TestKeyGenCurve(t *testing.T) { + key := new(RR_DNSKEY) + key.Hdr.Name = "miek.nl." + key.Hdr.Rrtype = TypeDNSKEY + key.Hdr.Class = ClassINET + key.Hdr.Ttl = 3600 + key.Flags = 256 + key.Protocol = 3 + key.Algorithm = AlgECDSAP256SHA256 + key.Generate(0) + fmt.Printf("%v\n", key) +} /* func TestDnskey(t *testing.T) { @@ -199,7 +213,7 @@ func TestTag(t *testing.T) { } } -func TestKeyGenRSA(t *testing.T) { +func TestKeyRSA(t *testing.T) { return // Tijdelijk uit TODO(mg) key := new(RR_DNSKEY) diff --git a/keygen.go b/keygen.go index c7d38a59..0c322c17 100644 --- a/keygen.go +++ b/keygen.go @@ -8,6 +8,8 @@ import ( "bufio" "strconv" "crypto/rsa" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rand" ) @@ -29,8 +31,6 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) { if bits < 1024 || bits > 4096 { return nil, ErrKeySize } - default: - return nil, ErrAlg } switch r.Algorithm { @@ -39,10 +39,24 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) { if err != nil { return nil, err } - keybuf := exponentToBuf(priv.PublicKey.E) - keybuf = append(keybuf, priv.PublicKey.N.Bytes()...) - r.PublicKey = unpackBase64(keybuf) + r.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N) return priv, nil + case AlgECDSAP256SHA256, AlgECDSAP384SHA384: + var c *elliptic.Curve + switch r.Algorithm { + case AlgECDSAP256SHA256: + c = elliptic.P256() + case AlgECDSAP384SHA384: + c = elliptic.P384() + } + priv, err := ecdsa.GenerateKey(c, rand.Reader) + if err != nil { + return nil, err + } + r.setPublicKeyCurve(priv.PublicKey.X, priv.PublicKey.Y) + return priv, nil + default: + return nil, ErrAlg } return nil, nil // Dummy return }