aboutsummaryrefslogtreecommitdiff
path: root/plugin/dnssec/dnskey.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/dnssec/dnskey.go')
-rw-r--r--plugin/dnssec/dnskey.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/plugin/dnssec/dnskey.go b/plugin/dnssec/dnskey.go
new file mode 100644
index 000000000..ce787ab54
--- /dev/null
+++ b/plugin/dnssec/dnskey.go
@@ -0,0 +1,72 @@
+package dnssec
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/rsa"
+ "errors"
+ "os"
+ "time"
+
+ "github.com/coredns/coredns/request"
+
+ "github.com/miekg/dns"
+)
+
+// DNSKEY holds a DNSSEC public and private key used for on-the-fly signing.
+type DNSKEY struct {
+ K *dns.DNSKEY
+ s crypto.Signer
+ keytag uint16
+}
+
+// ParseKeyFile read a DNSSEC keyfile as generated by dnssec-keygen or other
+// utilities. It adds ".key" for the public key and ".private" for the private key.
+func ParseKeyFile(pubFile, privFile string) (*DNSKEY, error) {
+ f, e := os.Open(pubFile)
+ if e != nil {
+ return nil, e
+ }
+ k, e := dns.ReadRR(f, pubFile)
+ if e != nil {
+ return nil, e
+ }
+
+ f, e = os.Open(privFile)
+ if e != nil {
+ return nil, e
+ }
+ p, e := k.(*dns.DNSKEY).ReadPrivateKey(f, privFile)
+ if e != nil {
+ return nil, e
+ }
+
+ if v, ok := p.(*rsa.PrivateKey); ok {
+ return &DNSKEY{k.(*dns.DNSKEY), v, k.(*dns.DNSKEY).KeyTag()}, nil
+ }
+ if v, ok := p.(*ecdsa.PrivateKey); ok {
+ return &DNSKEY{k.(*dns.DNSKEY), v, k.(*dns.DNSKEY).KeyTag()}, nil
+ }
+ return &DNSKEY{k.(*dns.DNSKEY), nil, 0}, errors.New("no known? private key found")
+}
+
+// getDNSKEY returns the correct DNSKEY to the client. Signatures are added when do is true.
+func (d Dnssec) getDNSKEY(state request.Request, zone string, do bool) *dns.Msg {
+ keys := make([]dns.RR, len(d.keys))
+ for i, k := range d.keys {
+ keys[i] = dns.Copy(k.K)
+ keys[i].Header().Name = zone
+ }
+ m := new(dns.Msg)
+ m.SetReply(state.Req)
+ m.Answer = keys
+ if !do {
+ return m
+ }
+
+ incep, expir := incepExpir(time.Now().UTC())
+ if sigs, err := d.sign(keys, zone, 3600, incep, expir); err == nil {
+ m.Answer = append(m.Answer, sigs...)
+ }
+ return m
+}