Helper functions for base64 encoding/decoding

This commit is contained in:
Miek Gieben 2011-01-15 10:38:14 +01:00
parent 3e11fafac5
commit 54f158c23d
3 changed files with 40 additions and 31 deletions

View File

@ -8,7 +8,6 @@ import (
"crypto/rsa"
"crypto/rand"
"encoding/hex"
"encoding/base64"
"hash"
"time"
"io"
@ -260,9 +259,7 @@ func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) bool {
if err != nil {
return false
}
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(signature)))
base64.StdEncoding.Encode(b64, signature)
s.Signature = string(b64)
s.Signature = unpackBase64(signature)
default:
// Not given the correct key
return false
@ -410,20 +407,19 @@ func (s *RR_RRSIG) PeriodOK() bool {
// Return the signatures base64 encodedig sigdata as a byte slice.
func (s *RR_RRSIG) sigBuf() []byte {
sigbuf := make([]byte, 1024) // TODO(mg) length!
sigbuflen := base64.StdEncoding.DecodedLen(len(s.Signature))
sigbuflen, _ = base64.StdEncoding.Decode(sigbuf[0:sigbuflen], []byte(s.Signature))
sigbuf = sigbuf[:sigbuflen]
sigbuf, err := packBase64([]byte(s.Signature))
if err != nil {
return nil
}
return sigbuf
}
// Extract the RSA public key from the Key record
func (k *RR_DNSKEY) pubKeyRSA() *rsa.PublicKey {
// Buffer holding the key data
keybuf := make([]byte, 1024)
keybuflen := base64.StdEncoding.DecodedLen(len(k.PubKey))
keybuflen, _ = base64.StdEncoding.Decode(keybuf[0:keybuflen], []byte(k.PubKey))
keybuf = keybuf[:keybuflen]
keybuf, err := packBase64([]byte(k.PubKey))
if err != nil {
return nil
}
// RFC 2537/3110, section 2. RSA Public KEY Resource Records
// Length is in the 0th byte, unless its zero, then it

View File

@ -4,11 +4,10 @@ import (
"os"
"crypto/rsa"
"crypto/rand"
"encoding/base64"
)
// Empty interface so all crypty private key
// can be grouped together
// Empty interface that is used a wrapper around all possible
// private key implementation from the crypto package.
type PrivateKey interface{}
// io.Reader
@ -16,10 +15,10 @@ type PrivateKey interface{}
// PrivateKeyFromString
// PrivateKeyToDNSKEY
// Generate a Key of the given bit size.
// Generate a key of the given bit size.
// The public part is directly put inside the DNSKEY record.
// The Algorithm in the key must be set as this will define
// what kind of DNSKEY will be generated
// what kind of DNSKEY will be generated.
func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
switch r.Algorithm {
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256:
@ -56,10 +55,7 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
return nil, &Error{Error: "Exponent too large"}
}
keybuf = append(keybuf, priv.PublicKey.N.Bytes()...)
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(keybuf)))
base64.StdEncoding.Encode(b64, keybuf)
r.PubKey = string(b64)
r.PubKey = unpackBase64(keybuf)
return priv, nil
}
return nil, nil // Dummy return

35
msg.go
View File

@ -286,10 +286,10 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o
msg[off] = byte(fv.Elem(j).(*reflect.UintValue).Get())
off++
}
case "NSEC": // NSEC/NSEC3
case "NSEC": // NSEC/NSEC3
for j := 0; j < val.Field(i).(*reflect.SliceValue).Len(); j++ {
var _ = byte(fv.Elem(j).(*reflect.UintValue).Get())
}
var _ = byte(fv.Elem(j).(*reflect.UintValue).Get())
}
// handle type bit maps
}
case *reflect.StructValue:
@ -342,7 +342,7 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o
default:
return len(msg), false
case "base64":
// TODO(mg) use the Len as return from the conversion (not used right now)
// TODO(mg) use the Len as return from the conversion (not used right now)
b64len := base64.StdEncoding.DecodedLen(len(s))
_, err := base64.StdEncoding.Decode(msg[off:off+b64len], []byte(s))
if err != nil {
@ -559,10 +559,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
default:
consumed = 0 // TODO
}
// TODO(mg) check return value of encoding
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(msg[off:off+rdlength-consumed])))
base64.StdEncoding.Encode(b64, msg[off:off+rdlength-consumed])
s = string(b64)
s = unpackBase64(msg[off : off+rdlength-consumed])
off += rdlength - consumed
case "domain-name":
s, off, ok = unpackDomainName(msg, off)
@ -600,6 +597,24 @@ func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
return off, ok
}
func unpackBase64(b []byte) string {
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(b)))
base64.StdEncoding.Encode(b64, b)
return string(b64)
}
// Helper function for packing, mostly used in dnssec.go
func packBase64(s []byte) ([]byte, os.Error) {
b64len := base64.StdEncoding.DecodedLen(len(s))
buf := make([]byte, b64len)
n, err := base64.StdEncoding.Decode(buf, []byte(s))
if err != nil {
return nil, err
}
buf = buf[:n]
return buf, nil
}
// Resource record packer.
func packRR(rr RR, msg []byte, off int) (off2 int, ok bool) {
if rr == nil {
@ -696,6 +711,7 @@ func (h *MsgHdr) String() string {
return s
}
// Pack a msg: convert it to wire format.
func (dns *Msg) Pack() (msg []byte, ok bool) {
var dh Header
@ -764,6 +780,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
return msg[:off], true
}
// Unpack a binary message to a Msg structure.
func (dns *Msg) Unpack(msg []byte) bool {
// Header.
var dh Header
@ -808,7 +825,7 @@ func (dns *Msg) Unpack(msg []byte) bool {
return true
}
// Convert a complete message to a string, use dig-like output.
// Convert a complete message to a string using dig-like output.
func (dns *Msg) String() string {
if dns == nil {
return "<nil> MsgHdr"