[DNSSEC] Make int to bytes conversions fixed length in ECDSA
ECDSA public keys consist of a single value, called "Q" in FIPS 186-3. In DNSSEC keys, Q is a simple bit string that represents the uncompressed form of a curve point, "x | y". The ECDSA signature is the combination of two non-negative integers, called "r" and "s" in FIPS 186-3. The two integers, each of which is formatted as a simple octet string, are combined into a single longer octet string for DNSSEC as the concatenation "r | s". (Conversion of the integers to bit strings is described in Section C.2 of FIPS 186-3.) For P-256, each integer MUST be encoded as 32 octets; for P-384, each integer MUST be encoded as 48 octets.
This commit is contained in:
parent
0f1b1184ae
commit
ed475ae9fa
24
dnssec.go
24
dnssec.go
|
@ -255,6 +255,7 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
|||
var sighash []byte
|
||||
var h hash.Hash
|
||||
var ch crypto.Hash // Only need for RSA
|
||||
var intlen int
|
||||
switch rr.Algorithm {
|
||||
case DSA, DSANSEC3SHA1:
|
||||
// Implicit in the ParameterSizes
|
||||
|
@ -264,8 +265,10 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
|||
case RSASHA256, ECDSAP256SHA256:
|
||||
h = sha256.New()
|
||||
ch = crypto.SHA256
|
||||
intlen = 32
|
||||
case ECDSAP384SHA384:
|
||||
h = sha512.New384()
|
||||
intlen = 48
|
||||
case RSASHA512:
|
||||
h = sha512.New()
|
||||
ch = crypto.SHA512
|
||||
|
@ -299,8 +302,8 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signature := r1.Bytes()
|
||||
signature = append(signature, s1.Bytes()...)
|
||||
signature := intToBytes(r1, intlen)
|
||||
signature = append(signature, intToBytes(s1, intlen)...)
|
||||
rr.Signature = toBase64(signature)
|
||||
default:
|
||||
// Not given the correct key
|
||||
|
@ -582,9 +585,14 @@ func (k *DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool {
|
|||
if _X == nil || _Y == nil {
|
||||
return false
|
||||
}
|
||||
buf := curveToBuf(_X, _Y)
|
||||
// Check the length of the buffer, either 64 or 92 bytes
|
||||
k.PublicKey = toBase64(buf)
|
||||
var intlen int
|
||||
switch k.Algorithm {
|
||||
case ECDSAP256SHA256:
|
||||
intlen = 32
|
||||
case ECDSAP384SHA384:
|
||||
intlen = 48
|
||||
}
|
||||
k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -618,9 +626,9 @@ func exponentToBuf(_E int) []byte {
|
|||
|
||||
// Set the public key for X and Y for Curve. The two
|
||||
// values are just concatenated.
|
||||
func curveToBuf(_X, _Y *big.Int) []byte {
|
||||
buf := _X.Bytes()
|
||||
buf = append(buf, _Y.Bytes()...)
|
||||
func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
|
||||
buf := intToBytes(_X, intlen)
|
||||
buf = append(buf, intToBytes(_Y, intlen)...)
|
||||
return buf
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,14 @@ func (r *DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
|||
"Coefficient: " + coefficient + "\n"
|
||||
case *ecdsa.PrivateKey:
|
||||
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||
private := toBase64(t.D.Bytes())
|
||||
var intlen int
|
||||
switch r.Algorithm {
|
||||
case ECDSAP256SHA256:
|
||||
intlen = 32
|
||||
case ECDSAP384SHA384:
|
||||
intlen = 48
|
||||
}
|
||||
private := toBase64(intToBytes(t.D, intlen))
|
||||
s = _FORMAT +
|
||||
"Algorithm: " + algorithm + "\n" +
|
||||
"PrivateKey: " + private + "\n"
|
||||
|
|
11
msg.go
11
msg.go
|
@ -12,6 +12,7 @@ import (
|
|||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"net"
|
||||
"reflect"
|
||||
|
@ -1305,6 +1306,16 @@ func UnpackStruct(any interface{}, msg []byte, off int) (int, error) {
|
|||
}
|
||||
|
||||
// Helper function for packing and unpacking
|
||||
func intToBytes(i *big.Int, length int) []byte {
|
||||
buf := i.Bytes()
|
||||
if len(buf) < length {
|
||||
b := make([]byte, length)
|
||||
copy(b[length-len(buf):], buf)
|
||||
return b
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func unpackUint16(msg []byte, off int) (uint16, int) {
|
||||
return uint16(msg[off])<<8 | uint16(msg[off+1]), off + 2
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue