2011-01-11 02:10:15 +11:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
2011-01-15 04:25:36 +11:00
|
|
|
"os"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/rand"
|
2011-01-11 02:10:15 +11:00
|
|
|
)
|
|
|
|
|
2011-01-15 20:38:14 +11:00
|
|
|
// Empty interface that is used a wrapper around all possible
|
|
|
|
// private key implementation from the crypto package.
|
2011-01-15 04:25:36 +11:00
|
|
|
type PrivateKey interface{}
|
|
|
|
|
2011-01-11 19:55:01 +11:00
|
|
|
// io.Reader
|
|
|
|
// PrivateKeyToString
|
|
|
|
// PrivateKeyFromString
|
|
|
|
// PrivateKeyToDNSKEY
|
2011-01-11 02:10:15 +11:00
|
|
|
|
2011-01-15 20:38:14 +11:00
|
|
|
// Generate a key of the given bit size.
|
2011-01-11 19:55:01 +11:00
|
|
|
// The public part is directly put inside the DNSKEY record.
|
2011-01-15 04:25:36 +11:00
|
|
|
// The Algorithm in the key must be set as this will define
|
2011-01-15 20:38:14 +11:00
|
|
|
// what kind of DNSKEY will be generated.
|
2011-01-15 04:25:36 +11:00
|
|
|
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"}
|
2011-01-11 02:10:15 +11:00
|
|
|
}
|
|
|
|
|
2011-01-15 04:25:36 +11:00
|
|
|
switch r.Algorithm {
|
|
|
|
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256, AlgRSASHA512:
|
|
|
|
priv, err := rsa.GenerateKey(rand.Reader, bits)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2011-01-15 05:15:25 +11:00
|
|
|
keybuf := make([]byte, 2)
|
2011-01-15 04:25:36 +11:00
|
|
|
|
|
|
|
if priv.PublicKey.E < 256 {
|
2011-01-15 05:15:25 +11:00
|
|
|
keybuf[0] = 1
|
|
|
|
keybuf[1] = uint8(priv.PublicKey.E)
|
2011-01-15 04:25:36 +11:00
|
|
|
} else {
|
|
|
|
keybuf[0] = 0
|
2011-01-15 05:15:25 +11:00
|
|
|
//keybuf[1] = part of length
|
|
|
|
//keybuf[2] = rest of length
|
2011-01-15 04:25:36 +11:00
|
|
|
// 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()...)
|
2011-01-15 20:38:14 +11:00
|
|
|
r.PubKey = unpackBase64(keybuf)
|
2011-01-15 04:25:36 +11:00
|
|
|
return priv, nil
|
|
|
|
}
|
|
|
|
return nil, nil // Dummy return
|
2011-01-11 02:10:15 +11:00
|
|
|
}
|