From b58c604e17e3782ee324f93b8b066bcb7ac4be6e Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 15 Apr 2012 20:50:53 +0200 Subject: [PATCH] Add symmetry to the reading of public/private keys Add a NewPrivateKey that works on strings and calls ReadPrivateKey that works on io.Readers. --- dnssec.go | 4 ++-- dnssec_test.go | 4 ++-- kscan.go | 33 ++++++++++++++++++++++++++++----- parse_test.go | 5 +---- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/dnssec.go b/dnssec.go index b95395c0..83851e33 100644 --- a/dnssec.go +++ b/dnssec.go @@ -407,8 +407,8 @@ func (s *RR_RRSIG) sigBuf() []byte { return sigbuf } -// SetPrivatePublicKey sets the public key in the private key. -func (k *RR_DNSKEY) SetPrivatePublicKey(p PrivateKey) bool { +// setPublicKeyInPrivate sets the public key in the private key. +func (k *RR_DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool { switch t := p.(type) { case *rsa.PrivateKey: // Something - but the diff --git a/dnssec_test.go b/dnssec_test.go index de7755ca..bbede0a2 100644 --- a/dnssec_test.go +++ b/dnssec_test.go @@ -166,10 +166,10 @@ func TestSignVerify(t *testing.T) { } func TestDnskey(t *testing.T) { - f, _ := os.Open("t/Kmiek.nl.+010+05240.private") - privkey, _ := ReadPrivateKey(f, "t/Kmiek.nl.+010+05240.private") f, _ = os.Open("t/Kmiek.nl.+010+05240.key") pubkey, _ := ReadRR(f, "t/Kmiek.nl.+010+05240.key") + f, _ := os.Open("t/Kmiek.nl.+010+05240.private") + privkey, _ := pubkey.(*RR_DNSKEU).ReadPrivateKey(f, "t/Kmiek.nl.+010+05240.private") // Okay, we assume this has gone OK if pubkey.(*RR_DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" { t.Log("Pubkey is not what we've read") diff --git a/kscan.go b/kscan.go index 2fb41bc6..ff467c76 100644 --- a/kscan.go +++ b/kscan.go @@ -8,8 +8,16 @@ import ( "strings" ) -// ReadPrivateKey reads a private key from the io.Reader q. -func ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) { +func (k *RR_DNSKEY) NewPrivateKey(s string) (PrivateKey, error) { + if s[len(s)-1] != '\n' { // We need a closing newline + return k.ReadPrivateKey(strings.NewReader(s+"\n"), "") + } + return k.ReadPrivateKey(strings.NewReader(s), "") +} + +// NewPrivateKey reads a private key from the io.Reader q. The public key must be +// known, because some cryptographics algorithms embed the public inside the privatekey. +func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) { m, e := parseKey(q, file) if m == nil { return nil, e @@ -20,6 +28,7 @@ func ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) { if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" { return nil, ErrPrivKey } + // TODO(mg): check if the pubkey matches the private key switch m["algorithm"] { case "1 (RSAMD5)": fallthrough @@ -30,9 +39,23 @@ func ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) { case "10 (RSASHA512)": fallthrough case "7 (RSASHA1NSEC3SHA1)": - return readPrivateKeyRSA(m) - case "13 (ECDSAP256SHA256)", "14 (ECDSAP384SHA384)": - return readPrivateKeyECDSA(m) + p, e := readPrivateKeyRSA(m) + if e != nil { + if !k.setPublicKeyInPrivate(p) { + return nil, ErrPrivKey + } + } + return p, e + case "13 (ECDSAP256SHA256)": + fallthrough + case "14 (ECDSAP384SHA384)": + p, e := readPrivateKeyECDSA(m) + if e != nil { + if !k.setPublicKeyInPrivate(p) { + return nil, ErrPrivKey + } + } + return p, e } return nil, ErrPrivKey } diff --git a/parse_test.go b/parse_test.go index c80d28a7..a7dc7540 100644 --- a/parse_test.go +++ b/parse_test.go @@ -88,13 +88,10 @@ PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR` if err != nil { t.Fatal(err.Error()) } - privkey, err := ReadPrivateKey(strings.NewReader(priv), "") + privkey, err := eckey.(RR_DNSKEY).NewPrivateKey(strings.NewReader(priv), "") if err != nil { t.Fatal(err.Error()) } - // We need to set the pubkey in the private key - eckey.(*RR_DNSKEY).SetPrivatePublicKey(privkey) - ds := eckey.(*RR_DNSKEY).ToDS(SHA384) if ds.KeyTag != 10771 { t.Fatal("Wrong keytag on DS")