func (ser *seMDCReader) Close() error { if ser.error { return errors.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 == io.EOF { break } if err != nil { return errors.SignatureError("error during reading") } } if ser.trailer[0]!=mdcPacketTagByte || ser.trailer[1]!=sha1.Size { return errors.SignatureError("MDC packet not found") } ser.h.Write(ser.trailer[:2]) final := ser.h.Sum(nil) if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 { return errors.SignatureError("hash mismatch") } return nil }
// VerifySignatureV3 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 *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) { if !pk.CanSign() { return errors.InvalidArgumentError("public key cannot generate signatures") } suffix := make([]byte, 5) suffix[0] = byte(sig.SigType) binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix())) signed.Write(suffix) hashBytes := signed.Sum(nil) if hashBytes[0]!=sig.HashTag[0] || hashBytes[1]!=sig.HashTag[1] { return errors.SignatureError("hash tag doesn't match") } if pk.PubKeyAlgo != sig.PubKeyAlgo { return errors.InvalidArgumentError("public key and signature use different algorithms") } switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { return errors.SignatureError("RSA verification failure") } return default: // V3 public keys only support RSA. panic("shouldn't happen") } panic("unreachable") }
// 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 error) { if !pk.CanSign() { return errors.InvalidArgumentError("public key cannot generate signatures") } signed.Write(sig.HashSuffix) hashBytes := signed.Sum(nil) if hashBytes[0]!=sig.HashTag[0] || hashBytes[1]!=sig.HashTag[1] { return errors.SignatureError("hash tag doesn't match") } if pk.PubKeyAlgo != sig.PubKeyAlgo { return errors.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.bytes) if err != nil { return errors.SignatureError("RSA verification failure") } return nil case PubKeyAlgoDSA: dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey) // Need to truncate hashBytes to match FIPS 186-3 section 4.6. subgroupSize := (dsaPublicKey.Q.BitLen() + 7)/8 if len(hashBytes) > subgroupSize { hashBytes = hashBytes[:subgroupSize] } if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { return errors.SignatureError("DSA verification failure") } return nil case PubKeyAlgoECDSA: ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey) if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) { return errors.SignatureError("ECDSA verification failure") } return nil default: return errors.SignatureError("Unsupported public key algorithm used in signature") } panic("unreachable") }
// VerifySignatureV3 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) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) { if !pk.CanSign() { return errors.InvalidArgumentError("public key cannot generate signatures") } suffix := make([]byte, 5) suffix[0] = byte(sig.SigType) binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix())) signed.Write(suffix) hashBytes := signed.Sum(nil) if hashBytes[0]!=sig.HashTag[0] || hashBytes[1]!=sig.HashTag[1] { return errors.SignatureError("hash tag doesn't match") } if pk.PubKeyAlgo != sig.PubKeyAlgo { return errors.InvalidArgumentError("public key and signature use different algorithms") } switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: rsaPublicKey := pk.PublicKey.(*rsa.PublicKey) if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { return errors.SignatureError("RSA verification failure") } return case PubKeyAlgoDSA: dsaPublicKey := pk.PublicKey.(*dsa.PublicKey) // Need to truncate hashBytes to match FIPS 186-3 section 4.6. subgroupSize := (dsaPublicKey.Q.BitLen() + 7)/8 if len(hashBytes) > subgroupSize { hashBytes = hashBytes[:subgroupSize] } if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { return errors.SignatureError("DSA verification failure") } return nil default: panic("shouldn't happen") } panic("unreachable") }