1
0
mirror of https://github.com/golang/go synced 2024-11-19 18:44:41 -07:00

crypto/openpgp: change PublicKey.Serialize to include the header.

Signature.Serialize already does this and they should be consistent.

R=bradfitz
CC=golang-dev
https://golang.org/cl/4521064
This commit is contained in:
Adam Langley 2011-05-14 19:13:12 -04:00
parent 816f4bb1d8
commit 4eb67563f6
4 changed files with 71 additions and 12 deletions

View File

@ -386,6 +386,14 @@ func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err os.Error) {
return
}
// mpiLength returns the length of the given *big.Int when serialised as an
// MPI.
func mpiLength(n *big.Int) (mpiLengthInBytes int) {
mpiLengthInBytes = 2 /* MPI length */
mpiLengthInBytes += (n.BitLen() + 7) / 8
return
}
// writeMPI serializes a big integer to w.
func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err os.Error) {
_, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)})

View File

@ -57,7 +57,7 @@ func (pk *PublicKey) parse(r io.Reader) (err os.Error) {
// RFC 4880, section 12.2
fingerPrint := sha1.New()
pk.SerializeSignaturePrefix(fingerPrint)
pk.Serialize(fingerPrint)
pk.serializeWithoutHeaders(fingerPrint)
copy(pk.Fingerprint[:], fingerPrint.Sum())
pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
@ -143,9 +143,30 @@ func (pk *PublicKey) SerializeSignaturePrefix(h hash.Hash) {
return
}
// Serialize marshals the PublicKey to w in the form of an OpenPGP public key
// packet, not including the packet header.
func (pk *PublicKey) Serialize(w io.Writer) (err os.Error) {
length := 6 // 6 byte header
switch pk.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
length += 2 + len(pk.n.bytes)
length += 2 + len(pk.e.bytes)
case PubKeyAlgoDSA:
length += 2 + len(pk.p.bytes)
length += 2 + len(pk.q.bytes)
length += 2 + len(pk.g.bytes)
length += 2 + len(pk.y.bytes)
}
err = serializeHeader(w, packetTypePublicKey, length)
if err != nil {
return
}
return pk.serializeWithoutHeaders(w)
}
// serializeWithoutHeaders marshals the PublicKey to w in the form of an
// OpenPGP public key packet, not including the packet header.
func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err os.Error) {
var buf [6]byte
buf[0] = 4
buf[1] = byte(pk.CreationTime >> 24)
@ -221,9 +242,9 @@ func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err
// RFC 4880, section 5.2.4
pk.SerializeSignaturePrefix(h)
pk.Serialize(h)
pk.serializeWithoutHeaders(h)
signed.SerializeSignaturePrefix(h)
signed.Serialize(h)
signed.serializeWithoutHeaders(h)
return pk.VerifySignature(h, sig)
}
@ -238,7 +259,7 @@ func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err os.Er
// RFC 4880, section 5.2.4
pk.SerializeSignaturePrefix(h)
pk.Serialize(h)
pk.serializeWithoutHeaders(h)
var buf [5]byte
buf[0] = 0xb4

View File

@ -28,12 +28,12 @@ func TestPublicKeyRead(t *testing.T) {
packet, err := Read(readerFromHex(test.hexData))
if err != nil {
t.Errorf("#%d: Read error: %s", i, err)
return
continue
}
pk, ok := packet.(*PublicKey)
if !ok {
t.Errorf("#%d: failed to parse, got: %#v", i, packet)
return
continue
}
if pk.PubKeyAlgo != test.pubKeyAlgo {
t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo)
@ -57,6 +57,38 @@ func TestPublicKeyRead(t *testing.T) {
}
}
func TestPublicKeySerialize(t *testing.T) {
for i, test := range pubKeyTests {
packet, err := Read(readerFromHex(test.hexData))
if err != nil {
t.Errorf("#%d: Read error: %s", i, err)
continue
}
pk, ok := packet.(*PublicKey)
if !ok {
t.Errorf("#%d: failed to parse, got: %#v", i, packet)
continue
}
serializeBuf := bytes.NewBuffer(nil)
err = pk.Serialize(serializeBuf)
if err != nil {
t.Errorf("#%d: failed to serialize: %s", err)
continue
}
packet, err = Read(serializeBuf)
if err != nil {
t.Errorf("#%d: Read error (from serialized data): %s", i, err)
continue
}
pk, ok = packet.(*PublicKey)
if !ok {
t.Errorf("#%d: failed to parse serialized data, got: %#v", i, packet)
continue
}
}
}
const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb"
const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001"

View File

@ -455,10 +455,8 @@ func (sig *Signature) Serialize(w io.Writer) (err os.Error) {
case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
sigLength = len(sig.RSASignature)
case PubKeyAlgoDSA:
sigLength = 2 /* MPI length */
sigLength += (sig.DSASigR.BitLen() + 7) / 8
sigLength += 2 /* MPI length */
sigLength += (sig.DSASigS.BitLen() + 7) / 8
sigLength = mpiLength(sig.DSASigR)
sigLength += mpiLength(sig.DSASigS)
default:
panic("impossible")
}