1/2 support for DSA

This commit is contained in:
Miek Gieben 2012-04-17 11:39:58 +02:00
parent 70efdaabea
commit 4536259037
3 changed files with 73 additions and 4 deletions

View File

@ -6,7 +6,7 @@ need to be fixed.
* Speed, we can always go faster. A simple reflect server now hits 35/45K qps
* go test; only works correct on my machine
* Add handy zone data structure (r/b tree)? Or not...
* dnssec: DSA (also the keytag)
* privatekey.Precompute() when signing?
## Examples to add

View File

@ -16,6 +16,7 @@ package dns
import (
"bytes"
"crypto"
"crypto/dsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/md5"
@ -432,8 +433,18 @@ func (s *RR_RRSIG) sigBuf() []byte {
// setPublicKeyInPrivate sets the public key in the private key.
func (k *RR_DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool {
switch t := p.(type) {
case *dsa.PrivateKey:
x := k.publicKeyDSA()
if x == nil {
return false
}
t.PublicKey = *x
case *rsa.PrivateKey:
// Something - but the
x := k.publicKeyRSA()
if x == nil {
return false
}
t.PublicKey = *x
case *ecdsa.PrivateKey:
x := k.publicKeyCurve()
if x == nil {
@ -510,6 +521,28 @@ func (k *RR_DNSKEY) publicKeyCurve() *ecdsa.PublicKey {
return pubkey
}
func (k *RR_DNSKEY) publicKeyDSA() *dsa.PublicKey {
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
if len(keybuf) < 22 { // TODO: check
return nil
}
t := int(keybuf[0])
size := 64 + t*8
pubkey := new(dsa.PublicKey)
pubkey.Parameters.Q = big.NewInt(0)
pubkey.Parameters.Q.SetBytes(keybuf[1:21]) // +/- 1 ?
pubkey.Parameters.P = big.NewInt(0)
pubkey.Parameters.P.SetBytes(keybuf[22:22+size])
pubkey.Parameters.G = big.NewInt(0)
pubkey.Parameters.G.SetBytes(keybuf[22+size+1:22+size*2])
pubkey.Y = big.NewInt(0)
pubkey.Y.SetBytes(keybuf[22+size*2+1:22+size*3])
return pubkey
}
// Set the public key (the value E and N)
func (k *RR_DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
if _E == 0 || _N == nil {
@ -532,6 +565,14 @@ func (k *RR_DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool {
return true
}
// Set the public key for DSA
func (k RR_DNSKEY) setPublicKeyDSA(_P, _Q, _G, _Y *big.Int) bool {
if _P == nil || _Q == nil || _G == nil || _Y == nil {
return false
}
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 {

View File

@ -3,6 +3,7 @@ package dns
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/dsa"
"io"
"math/big"
"strings"
@ -30,15 +31,24 @@ func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error)
}
// TODO(mg): check if the pubkey matches the private key
switch m["algorithm"] {
case "3 (DSA)":
p, e := readPrivateKeyDSA(m)
if e != nil {
return nil, e
}
if !k.setPublicKeyInPrivate(p) {
return nil, ErrPrivKey
}
return p, e
case "1 (RSAMD5)":
fallthrough
case "5 (RSASHA1)":
fallthrough
case "7 (RSASHA1NSEC3SHA1)":
fallthrough
case "8 (RSASHA256)":
fallthrough
case "10 (RSASHA512)":
fallthrough
case "7 (RSASHA1NSEC3SHA1)":
p, e := readPrivateKeyRSA(m)
if e != nil {
return nil, e
@ -107,6 +117,24 @@ func readPrivateKeyRSA(m map[string]string) (PrivateKey, error) {
return p, nil
}
func readPrivateKeyDSA(m map[string]string) (PrivateKey, error) {
p := new(dsa.PrivateKey)
p.X = big.NewInt(0)
for k, v := range m {
switch k {
case "private_value(x):":
v1, err := packBase64([]byte(v))
if err != nil {
return nil, err
}
p.X.SetBytes(v1)
case "created:", "publish:", "activate:":
/* not used in Go (yet) */
}
}
return p, nil
}
func readPrivateKeyECDSA(m map[string]string) (PrivateKey, error) {
p := new(ecdsa.PrivateKey)
p.D = big.NewInt(0)