Fix the reading of private key files
This commit is contained in:
parent
b244ea1a3e
commit
512d1dae46
85
keygen.go
85
keygen.go
|
@ -5,7 +5,6 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"io"
|
||||
"math/big"
|
||||
"strconv"
|
||||
)
|
||||
|
@ -71,7 +70,7 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, error) {
|
|||
// Convert a PrivateKey to a string. This
|
||||
// string has the same format as the private-key-file of BIND9 (Private-key-format: v1.3).
|
||||
// It needs some info from the key (hashing, keytag), so its a method of the RR_DNSKEY.
|
||||
func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
||||
func (r *RR_DNSKEY) PrivateKeyToString(p PrivateKey) (s string) {
|
||||
switch t := p.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + alg_str[r.Algorithm] + ")"
|
||||
|
@ -110,85 +109,3 @@ func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReadPrivateKey reads a private key from the io.Reader q.
|
||||
func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, error) {
|
||||
/*
|
||||
p := NewParser(q)
|
||||
kv, _ := p.PrivateKey()
|
||||
if kv == nil {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
if _, ok := kv["private-key-format"]; !ok {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
if kv["private-key-format"] != "v1.2" && kv["private-key-format"] != "v1.3" {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
switch kv["algorithm"] {
|
||||
case "RSAMD5", "RSASHA1", "RSASHA256", "RSASHA512":
|
||||
return k.readPrivateKeyRSA(kv)
|
||||
case "ECDSAP256SHA256", "ECDSAP384SHA384":
|
||||
return k.readPrivateKeyECDSA(kv)
|
||||
}
|
||||
return nil, ErrPrivKey
|
||||
*/
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Read a private key (file) string and create a public key. Return the private key.
|
||||
func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, error) {
|
||||
p := new(rsa.PrivateKey)
|
||||
p.Primes = []*big.Int{nil, nil}
|
||||
for k, v := range kv {
|
||||
switch k {
|
||||
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
|
||||
v1, err := packBase64([]byte(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch k {
|
||||
case "modulus":
|
||||
p.PublicKey.N = big.NewInt(0)
|
||||
p.PublicKey.N.SetBytes(v1)
|
||||
case "publicexponent":
|
||||
i := big.NewInt(0)
|
||||
i.SetBytes(v1)
|
||||
p.PublicKey.E = int(i.Int64()) // int64 should be large enough
|
||||
case "privateexponent":
|
||||
p.D = big.NewInt(0)
|
||||
p.D.SetBytes(v1)
|
||||
case "prime1":
|
||||
p.Primes[0] = big.NewInt(0)
|
||||
p.Primes[0].SetBytes(v1)
|
||||
case "prime2":
|
||||
p.Primes[1] = big.NewInt(0)
|
||||
p.Primes[1].SetBytes(v1)
|
||||
}
|
||||
case "exponent1", "exponent2", "coefficient":
|
||||
// not used in Go (yet)
|
||||
case "created", "publish", "activate":
|
||||
// not used in Go (yet)
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, error) {
|
||||
p := new(ecdsa.PrivateKey)
|
||||
p.D = big.NewInt(0)
|
||||
// Need to check if we have everything
|
||||
for k, v := range kv {
|
||||
switch k {
|
||||
case "privatekey:":
|
||||
v1, err := packBase64([]byte(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.D.SetBytes(v1)
|
||||
case "created:", "publish:", "activate:":
|
||||
/* not used in Go (yet) */
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
|
105
kscan.go
105
kscan.go
|
@ -1,12 +1,96 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"io"
|
||||
"math/big"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR on the
|
||||
// channel cr. The channel cr is closed by ParseZone when the end of r is reached.
|
||||
// ReadPrivateKey reads a private key from the io.Reader q.
|
||||
func ReadPrivateKey(q io.Reader) (PrivateKey, error) {
|
||||
m, e := ParseKey(q)
|
||||
if m == nil {
|
||||
return nil, e
|
||||
}
|
||||
if _, ok := m["private-key-format"]; !ok {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
switch m["algorithm"] {
|
||||
case "1 (RSAMD5)", "5 (RSASHA1)", "8 (RSASHA256)", "10 (RSASHA512)":
|
||||
fallthrough
|
||||
case "7 (RSASHA1NSEC3SHA1)":
|
||||
return readPrivateKeyRSA(m)
|
||||
case "13 (ECDSAP256SHA256)", "14 (ECDSAP384SHA384)":
|
||||
return readPrivateKeyECDSA(m)
|
||||
}
|
||||
return nil, ErrPrivKey
|
||||
}
|
||||
|
||||
// Read a private key (file) string and create a public key. Return the private key.
|
||||
func readPrivateKeyRSA(m map[string]string) (PrivateKey, error) {
|
||||
p := new(rsa.PrivateKey)
|
||||
p.Primes = []*big.Int{nil, nil}
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
|
||||
v1, err := packBase64([]byte(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch k {
|
||||
case "modulus":
|
||||
p.PublicKey.N = big.NewInt(0)
|
||||
p.PublicKey.N.SetBytes(v1)
|
||||
case "publicexponent":
|
||||
i := big.NewInt(0)
|
||||
i.SetBytes(v1)
|
||||
p.PublicKey.E = int(i.Int64()) // int64 should be large enough
|
||||
case "privateexponent":
|
||||
p.D = big.NewInt(0)
|
||||
p.D.SetBytes(v1)
|
||||
case "prime1":
|
||||
p.Primes[0] = big.NewInt(0)
|
||||
p.Primes[0].SetBytes(v1)
|
||||
case "prime2":
|
||||
p.Primes[1] = big.NewInt(0)
|
||||
p.Primes[1].SetBytes(v1)
|
||||
}
|
||||
case "exponent1", "exponent2", "coefficient":
|
||||
// not used in Go (yet)
|
||||
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)
|
||||
// Need to check if we have everything
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "privatekey:":
|
||||
v1, err := packBase64([]byte(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.D.SetBytes(v1)
|
||||
case "created:", "publish:", "activate:":
|
||||
/* not used in Go (yet) */
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ParseKey reads a private key from r. It returns a map[string]string,
|
||||
// with the key-value pairs, or an error when the file is not correct.
|
||||
func ParseKey(r io.Reader) (map[string]string, error) {
|
||||
var s scanner.Scanner
|
||||
m := make(map[string]string)
|
||||
|
@ -23,11 +107,12 @@ func ParseKey(r io.Reader) (map[string]string, error) {
|
|||
case _KEY:
|
||||
k = l.token
|
||||
case _VALUE:
|
||||
if k == "" {
|
||||
return nil, &ParseError{"No key seen", l}
|
||||
}
|
||||
m[k] = l.token
|
||||
k = ""
|
||||
if k == "" {
|
||||
return nil, &ParseError{"No key seen", l}
|
||||
}
|
||||
//println("Setting", strings.ToLower(k), "to", l.token, "b")
|
||||
m[strings.ToLower(k)] = l.token
|
||||
k = ""
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
@ -49,10 +134,14 @@ func klexer(s scanner.Scanner, c chan Lex) {
|
|||
if commt {
|
||||
break
|
||||
}
|
||||
l.token = str
|
||||
if key {
|
||||
l.value = _KEY
|
||||
c <- l
|
||||
// Next token is a space, eat it
|
||||
s.Scan()
|
||||
key = false
|
||||
str = ""
|
||||
} else {
|
||||
l.value = _VALUE
|
||||
}
|
||||
|
@ -63,6 +152,8 @@ func klexer(s scanner.Scanner, c chan Lex) {
|
|||
// Reset a comment
|
||||
commt = false
|
||||
}
|
||||
l.value = _VALUE
|
||||
l.token = str
|
||||
c <- l
|
||||
str = ""
|
||||
commt = false
|
||||
|
|
|
@ -25,9 +25,9 @@ Created: 20110302104537
|
|||
Publish: 20110302104537
|
||||
Activate: 20110302104537`
|
||||
|
||||
xk, _ := NewRR(pub) // TODO err
|
||||
xk, _ := NewRR(pub)
|
||||
k := xk.(*RR_DNSKEY)
|
||||
p, err := k.ReadPrivateKey(strings.NewReader(priv))
|
||||
p, err := ReadPrivateKey(strings.NewReader(priv))
|
||||
if err != nil {
|
||||
t.Logf("%v\n", err)
|
||||
t.Fail()
|
||||
|
|
Loading…
Reference in New Issue