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

View File

@ -4,11 +4,10 @@ import (
"os" "os"
"crypto/rsa" "crypto/rsa"
"crypto/rand" "crypto/rand"
"encoding/base64"
) )
// Empty interface so all crypty private key // Empty interface that is used a wrapper around all possible
// can be grouped together // private key implementation from the crypto package.
type PrivateKey interface{} type PrivateKey interface{}
// io.Reader // io.Reader
@ -16,10 +15,10 @@ type PrivateKey interface{}
// PrivateKeyFromString // PrivateKeyFromString
// PrivateKeyToDNSKEY // 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 public part is directly put inside the DNSKEY record.
// The Algorithm in the key must be set as this will define // 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) { func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
switch r.Algorithm { switch r.Algorithm {
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256: 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"} return nil, &Error{Error: "Exponent too large"}
} }
keybuf = append(keybuf, priv.PublicKey.N.Bytes()...) keybuf = append(keybuf, priv.PublicKey.N.Bytes()...)
r.PubKey = unpackBase64(keybuf)
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(keybuf)))
base64.StdEncoding.Encode(b64, keybuf)
r.PubKey = string(b64)
return priv, nil return priv, nil
} }
return nil, nil // Dummy return 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()) msg[off] = byte(fv.Elem(j).(*reflect.UintValue).Get())
off++ off++
} }
case "NSEC": // NSEC/NSEC3 case "NSEC": // NSEC/NSEC3
for j := 0; j < val.Field(i).(*reflect.SliceValue).Len(); j++ { 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 // handle type bit maps
} }
case *reflect.StructValue: case *reflect.StructValue:
@ -342,7 +342,7 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o
default: default:
return len(msg), false return len(msg), false
case "base64": 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)) b64len := base64.StdEncoding.DecodedLen(len(s))
_, err := base64.StdEncoding.Decode(msg[off:off+b64len], []byte(s)) _, err := base64.StdEncoding.Decode(msg[off:off+b64len], []byte(s))
if err != nil { if err != nil {
@ -559,10 +559,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
default: default:
consumed = 0 // TODO consumed = 0 // TODO
} }
// TODO(mg) check return value of encoding s = unpackBase64(msg[off : off+rdlength-consumed])
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(msg[off:off+rdlength-consumed])))
base64.StdEncoding.Encode(b64, msg[off:off+rdlength-consumed])
s = string(b64)
off += rdlength - consumed off += rdlength - consumed
case "domain-name": case "domain-name":
s, off, ok = unpackDomainName(msg, off) 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 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. // Resource record packer.
func packRR(rr RR, msg []byte, off int) (off2 int, ok bool) { func packRR(rr RR, msg []byte, off int) (off2 int, ok bool) {
if rr == nil { if rr == nil {
@ -696,6 +711,7 @@ func (h *MsgHdr) String() string {
return s return s
} }
// Pack a msg: convert it to wire format.
func (dns *Msg) Pack() (msg []byte, ok bool) { func (dns *Msg) Pack() (msg []byte, ok bool) {
var dh Header var dh Header
@ -764,6 +780,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
return msg[:off], true return msg[:off], true
} }
// Unpack a binary message to a Msg structure.
func (dns *Msg) Unpack(msg []byte) bool { func (dns *Msg) Unpack(msg []byte) bool {
// Header. // Header.
var dh Header var dh Header
@ -808,7 +825,7 @@ func (dns *Msg) Unpack(msg []byte) bool {
return true 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 { func (dns *Msg) String() string {
if dns == nil { if dns == nil {
return "<nil> MsgHdr" return "<nil> MsgHdr"