func (ser *seMDCReader) Close() os.Error { if ser.error { return error.SignatureError("error during reading") } for !ser.eof { // We haven't seen EOF so we need to read to the end var buf [1024]byte _, err := ser.Read(buf[:]) if err == os.EOF { break } if err != nil { return error.SignatureError("error during reading") } } if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size { return error.SignatureError("MDC packet not found") } ser.h.Write(ser.trailer[:2]) final := ser.h.Sum() if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 { return error.SignatureError("hash mismatch") } return nil }
// VerifySignature returns nil iff sig is a valid signature, made by this // public key, of the data hashed into signed. signed is mutated by this call. func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err os.Error) { if !pk.CanSign() { return error.InvalidArgumentError("public key cannot generate signatures") } signed.Write(sig.HashSuffix) hashBytes := signed.Sum() if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { return error.SignatureError("hash tag doesn't match") } if pk.PubKeyAlgo != sig.PubKeyAlgo { return error.InvalidArgumentError("public key and signature use different algorithms") } switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey) err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature) if err != nil { return error.SignatureError("RSA verification failure") } return nil case PubKeyAlgoDSA: dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey) if !dsa.Verify(dsaPublicKey, hashBytes, sig.DSASigR, sig.DSASigS) { return error.SignatureError("DSA verification failure") } return nil default: panic("shouldn't happen") } panic("unreachable") }