func (vr *VerifyRequest) VerifySignature() bool { armorData := reArmor(vr.CamliSig) block, _ := armor.Decode(bytes.NewBufferString(armorData)) if block == nil { return vr.fail("can't parse camliSig armor") } var p packet.Packet var err os.Error p, err = packet.Read(block.Body) if err != nil { return vr.fail("error reading PGP packet from camliSig: " + err.String()) } sig, ok := p.(*packet.Signature) if !ok { return vr.fail("PGP packet isn't a signature packet") } if sig.Hash != crypto.SHA1 && sig.Hash != crypto.SHA256 { return vr.fail("I can only verify SHA1 or SHA256 signatures") } if sig.SigType != packet.SigTypeBinary { return vr.fail("I can only verify binary signatures") } hash := sig.Hash.New() hash.Write(vr.bp) // payload bytes err = vr.PublicKeyPacket.VerifySignature(hash, sig) if err != nil { return vr.fail(fmt.Sprintf("bad signature: %s", err)) } vr.SignerKeyId = vr.PublicKeyPacket.KeyIdString() return true }
// CheckDetachedSignature takes a signed file and a detached signature and // returns the signer if the signature is valid. If the signer isn't know, // UnknownIssuerError is returned. func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err os.Error) { p, err := packet.Read(signature) if err != nil { return } sig, ok := p.(*packet.Signature) if !ok { return nil, error.StructuralError("non signature packet found") } if sig.IssuerKeyId == nil { return nil, error.StructuralError("signature doesn't have an issuer") } keys := keyring.KeysById(*sig.IssuerKeyId) if len(keys) == 0 { return nil, error.UnknownIssuerError } h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType) if err != nil { return } _, err = io.Copy(wrappedHash, signed) if err != nil && err != os.EOF { return } for _, key := range keys { if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign { continue } err = key.PublicKey.VerifySignature(h, sig) if err == nil { return key.Entity, nil } } if err != nil { return } return nil, error.UnknownIssuerError }
func openArmoredPublicKeyFile(reader io.ReadCloser) (*packet.PublicKey, os.Error) { defer reader.Close() var lr = io.LimitReader(reader, publicKeyMaxSize) block, _ := armor.Decode(lr) if block == nil { return nil, os.NewError("Couldn't find PGP block in public key file") } if block.Type != "PGP PUBLIC KEY BLOCK" { return nil, os.NewError("Invalid public key blob.") } p, err := packet.Read(block.Body) if err != nil { return nil, os.NewError(fmt.Sprintf("Invalid public key blob: %v", err)) } pk, ok := p.(*packet.PublicKey) if !ok { return nil, os.NewError(fmt.Sprintf("Invalid public key blob; not a public key packet")) } return pk, nil }