Public key fingerprints.

This commit is contained in:
Brad Fitzpatrick 2010-12-07 16:59:24 -08:00
parent 0f16c9b29d
commit bfcc2ae8f5
1 changed files with 35 additions and 11 deletions

View File

@ -1,9 +1,11 @@
package packet
import (
"fmt"
"big"
"crypto/openpgp/error"
"crypto/rsa"
"crypto/sha1"
"io"
"os"
)
@ -80,7 +82,7 @@ func ReadPacket(r io.Reader) (p Packet, err os.Error) {
case 2:
p, err = readSignaturePacket(limitReader)
case 6:
p, err = readPublicKeyPacket(limitReader)
p, err = readPublicKeyPacket(limitReader, uint16(length))
default:
err = error.Unsupported("unknown packet type")
}
@ -195,17 +197,16 @@ func readSignaturePacket(r io.Reader) (sig SignaturePacket, err os.Error) {
}
// We have already checked that the public key algorithm is RSA.
sig.Signature, err = readMPI(r)
sig.Signature, _, err = readMPI(r)
return
}
func readMPI(r io.Reader) (mpi []byte, err os.Error) {
var buf [2]byte
_, err = io.ReadFull(r, buf[0:])
func readMPI(r io.Reader) (mpi []byte, hdr [2]byte, err os.Error) {
_, err = io.ReadFull(r, hdr[0:])
if err != nil {
return
}
numBits := int(buf[0]) << 8 | int(buf[1])
numBits := int(hdr[0]) << 8 | int(hdr[1])
numBytes := (numBits + 7) / 8
mpi = make([]byte, numBytes)
_, err = io.ReadFull(r, mpi)
@ -291,15 +292,24 @@ func parseSignatureSubpacket(sig *SignaturePacket, subpacket []byte, isHashed bo
type PublicKeyPacket struct {
CreationTime uint32
PubKeyAlgo PublicKeyAlgorithm
PublicKey rsa.PublicKey
PubKeyAlgo PublicKeyAlgorithm
PublicKey rsa.PublicKey
Fingerprint []byte
}
func (pk PublicKeyPacket) Type() string {
return "public key"
}
func readPublicKeyPacket(r io.Reader) (pk PublicKeyPacket, err os.Error) {
func (pk PublicKeyPacket) FingerprintString() string {
return fmt.Sprintf("%X", pk.Fingerprint)
}
func (pk PublicKeyPacket) KeyIdString() string {
return fmt.Sprintf("%X", pk.Fingerprint[len(pk.Fingerprint)-4:])
}
func readPublicKeyPacket(r io.Reader, length uint16) (pk PublicKeyPacket, err os.Error) {
// RFC 4880, section 5.5.2
var buf [6]byte
_, err = io.ReadFull(r, buf[0:])
@ -309,6 +319,13 @@ func readPublicKeyPacket(r io.Reader) (pk PublicKeyPacket, err os.Error) {
if buf[0] != 4 {
err = error.Unsupported("public key version")
}
// RFC 4880, section 12.2
fprint := sha1.New()
fprint.Write([]byte{'\x99', uint8(length >> 8),
uint8(length & 0xff)})
fprint.Write(buf[0:6]) // version, timestamp, algorithm
pk.CreationTime = uint32(buf[1]) << 24 |
uint32(buf[2]) << 16 |
uint32(buf[3]) << 8 |
@ -320,14 +337,20 @@ func readPublicKeyPacket(r io.Reader) (pk PublicKeyPacket, err os.Error) {
err = error.Unsupported("public key type")
return
}
nBytes, err := readMPI(r)
nBytes, mpiHdr, err := readMPI(r)
if err != nil {
return
}
eBytes, err := readMPI(r)
fprint.Write(mpiHdr[:])
fprint.Write(nBytes)
eBytes, mpiHdr, err := readMPI(r)
if err != nil {
return
}
fprint.Write(mpiHdr[:])
fprint.Write(eBytes)
if len(eBytes) > 3 {
err = error.Unsupported("large public exponent")
@ -339,5 +362,6 @@ func readPublicKeyPacket(r io.Reader) (pk PublicKeyPacket, err os.Error) {
pk.PublicKey.E |= int(eBytes[i])
}
pk.PublicKey.N = (new(big.Int)).SetBytes(nBytes)
pk.Fingerprint = fprint.Sum()
return
}