Love interfaces

Using interfaces to make key.Generate and Sign much more generic
This commit is contained in:
Miek Gieben 2011-01-14 18:25:36 +01:00
parent 0c95585952
commit ab4a5b5477
7 changed files with 73 additions and 50 deletions

View File

@ -21,7 +21,7 @@ include $(GOROOT)/src/Make.pkg
all: package
gomake -C resolver package
gomake -C responder package
# gomake -C strconv package
gomake -C strconv package
dnstest:
gotest

View File

@ -15,10 +15,8 @@ func TestKeyGen(t *testing.T) {
key.Flags = 256
key.Protocol = 3
key.Algorithm = AlgRSASHA256
key.GenerateRSA(512)
fmt.Printf("%v\n", key)
key.Generate(512)
fmt.Printf("Generated key: %v\n", key)
}

View File

@ -153,7 +153,7 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
// the rest is copied from the RRset. Return true when all ok.
// The Signature data is filled by this method
// There is no check if rrset is a proper (RFC 2181) RRSet
func (s *RR_RRSIG) Sign(k *rsa.PrivateKey, rrset RRset) bool {
func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) bool {
if k == nil {
return false
}
@ -252,13 +252,21 @@ func (s *RR_RRSIG) Sign(k *rsa.PrivateKey, rrset RRset) bool {
// Need privakey representation in godns TODO(mg) see keygen.go
io.WriteString(h, string(signdata))
sighash := h.Sum()
signature, err = rsa.SignPKCS1v15(rand.Reader, k, ch, sighash)
if err != nil {
// Get the key from the interface
switch p := k.(type) {
case *rsa.PrivateKey:
signature, err = rsa.SignPKCS1v15(rand.Reader, p, ch, sighash)
if err != nil {
return false
}
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(signature)))
base64.StdEncoding.Encode(b64, signature)
s.Signature = string(b64)
default:
// Not given the correct key
return false
}
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(signature)))
base64.StdEncoding.Encode(b64, signature)
s.Signature = string(b64)
case AlgDH:
case AlgDSA:
case AlgECC:

View File

@ -1,54 +1,62 @@
package dns
import (
"os"
"crypto/rsa"
"crypto/rand"
"encoding/base64"
"os"
"crypto/rsa"
"crypto/rand"
"encoding/base64"
)
// Empty interface so all crypty private key
// can be grouped together
type PrivateKey interface{}
// io.Reader
// PrivateKeyToString
// PrivateKeyFromString
// PrivateKeyToDNSKEY
// Generate a RSA key of the given bit size.
// Generate a Key of the given bit size.
// The public part is directly put inside the DNSKEY record.
// The Algorithm in the key must be set
func (r *RR_DNSKEY) GenerateRSA(bits int) (*rsa.PrivateKey, os.Error) {
// The Algorithm in the key must be set as this will define
// what kind of DNSKEY will be generated
func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
switch r.Algorithm {
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256:
if bits < 512 || bits > 4096 {
return nil, &Error{Error: "Size not in range [512..4096]"}
}
case AlgRSASHA512:
if bits < 1024 || bits > 4096 {
return nil, &Error{Error: "Size not in range [1024..4096]"}
}
default:
return nil, &Error{Error: "Algorithm not recognized"}
}
switch r.Algorithm {
case AlgRSAMD5: fallthrough
case AlgRSASHA1: fallthrough
case AlgRSASHA256:
if bits < 512 || bits > 4096 {
return nil, &Error{Error: "Size not in range [512..4096]"}
}
case AlgRSASHA512:
if bits < 1024 || bits > 4096 {
return nil, &Error{Error: "Size not in range [1024..4096]"}
}
default:
return nil, &Error{Error: "Algorithm does not match RSA*"}
}
priv, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, err
}
keybuf := make([]byte, 1)
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256, AlgRSASHA512:
priv, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, err
}
keybuf := make([]byte, 1)
if priv.PublicKey.E < 256 {
keybuf[0] = uint8(priv.PublicKey.E)
} else {
keybuf[0] = 0
// keybuf[1]+[2] have the length
// keybuf[3:..3+lenght] have exponent
// not implemented
return nil, &Error{Error: "Exponent too large"}
}
keybuf = append(keybuf, priv.PublicKey.N.Bytes()...)
if priv.PublicKey.E < 256 {
keybuf[0] = uint8(priv.PublicKey.E)
} else {
keybuf[0] = 0
// keybuf[1]+[2] have the length
// keybuf[3:..3+lenght] have exponent
// not implemented
return nil, &Error{Error: "Exponent too large"}
}
keybuf = append(keybuf, priv.PublicKey.N.Bytes()...)
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(keybuf)))
base64.StdEncoding.Encode(b64, keybuf)
r.PubKey = string(b64)
return priv, nil
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(keybuf)))
base64.StdEncoding.Encode(b64, keybuf)
r.PubKey = string(b64)
return priv, nil
}
return nil, nil // Dummy return
}

Binary file not shown.

Binary file not shown.

View File

@ -3,6 +3,7 @@ package strconv
import (
"unicode"
conv "strconv"
"dns"
)
const (
@ -71,3 +72,11 @@ func SecondsToString(val uint32) (str string) {
}
return
}
// Read a string and convert it to the correct
// Resource Record.
func SetString(s string) dns.RR {
k := new(dns.RR_DNSKEY)
return k
}