// 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) // NOTE(maxtaco) 2016-08-22 // // We used to do this: // // if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { // return errors.SignatureError("hash tag doesn't match") // } // // But don't do anything in this case. Some GPGs generate bad // 2-byte hash prefixes, but GPG also doesn't seem to care on // import. See BrentMaxwell's key. I think it's safe to disable // this check! 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 case PubKeyAlgoEdDSA: if !pk.edk.Verify(hashBytes, sig.EdDSASigR, sig.EdDSASigS) { return errors.SignatureError("EdDSA verification failure") } return nil default: return errors.SignatureError("Unsupported public key algorithm used in signature") } panic("unreachable") }
func main() { var privateKey dsa.PrivateKey params := &privateKey.Parameters // L2048N224 is length of L and N if err := dsa.GenerateParameters(params, rand.Reader, dsa.L2048N224); err != nil { fmt.Printf("Err: %s", err) return } if err := dsa.GenerateKey(&privateKey, rand.Reader); err != nil { fmt.Printf("Err: %s", err) return } hashed := []byte("This is test hashed message") // It returns the signature as a pair of integers. r, s, err := dsa.Sign(rand.Reader, &privateKey, hashed) if err != nil { fmt.Printf("Err: %s", err) return } // Check signnature can be verified publicKey := &privateKey.PublicKey if dsa.Verify(publicKey, hashed, r, s) { fmt.Printf("Verified\n") } }
// verify the message text against signature using the public key // in PubtktAuth. Expects the signature to be base64 encoded. // Returns true if the signature is valid, false otherwise func (pa *PubtktAuth) verifySig(text, signature string) bool { sig, err := base64.StdEncoding.DecodeString(signature) if err != nil { log.Println("problem decoding sig", err) return false } h := sha1.New() h.Write([]byte(text)) digest := h.Sum(nil) // This is inspired by the crypto/x509 standard library switch pub := pa.publicKey.(type) { case *rsa.PublicKey: return nil == rsa.VerifyPKCS1v15(pub, crypto.SHA1, digest, sig) case *dsa.PublicKey: dsaSig := new(dsaSignature) if _, err := asn1.Unmarshal(sig, dsaSig); err != nil { // log.Println("problem decoding dsa", err) return false } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { // log.Println("509: DSA signature contained zero or negative values") return false } return dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) } return false }
// 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") }
// VerifySignature verifies that the passed in signature over data was created by the given PublicKey. func VerifySignature(pubKey crypto.PublicKey, data []byte, sig DigitallySigned) error { hash, hashType, err := generateHash(sig.Algorithm.Hash, data) if err != nil { return err } switch sig.Algorithm.Signature { case RSA: rsaKey, ok := pubKey.(*rsa.PublicKey) if !ok { return fmt.Errorf("cannot verify RSA signature with %T key", pubKey) } if err := rsa.VerifyPKCS1v15(rsaKey, hashType, hash, sig.Signature); err != nil { return fmt.Errorf("failed to verify rsa signature: %v", err) } case DSA: dsaKey, ok := pubKey.(*dsa.PublicKey) if !ok { return fmt.Errorf("cannot verify DSA signature with %T key", pubKey) } var dsaSig dsaSig rest, err := asn1.Unmarshal(sig.Signature, &dsaSig) if err != nil { return fmt.Errorf("failed to unmarshal DSA signature: %v", err) } if len(rest) != 0 { log.Printf("Garbage following signature %v", rest) } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("DSA signature contained zero or negative values") } if !dsa.Verify(dsaKey, hash, dsaSig.R, dsaSig.S) { return errors.New("failed to verify DSA signature") } case ECDSA: ecdsaKey, ok := pubKey.(*ecdsa.PublicKey) if !ok { return fmt.Errorf("cannot verify ECDSA signature with %T key", pubKey) } var ecdsaSig dsaSig rest, err := asn1.Unmarshal(sig.Signature, &ecdsaSig) if err != nil { return fmt.Errorf("failed to unmarshal ECDSA signature: %v", err) } if len(rest) != 0 { log.Printf("Garbage following signature %v", rest) } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("ECDSA signature contained zero or negative values") } if !ecdsa.Verify(ecdsaKey, hash, ecdsaSig.R, ecdsaSig.S) { return errors.New("failed to verify ECDSA signature") } default: return fmt.Errorf("unsupported Algorithm.Signature in signature: %v", sig.Algorithm.Hash) } return nil }
// Verify will verify a signature of a hashed data using dsa Verify. func (pub *PublicKey) Verify(hashed, sig []byte) (nextPoint []byte, sigOk bool) { if len(sig) < 2*20 { return nil, false } r := new(big.Int).SetBytes(sig[:20]) s := new(big.Int).SetBytes(sig[20:40]) ok := dsa.Verify(&pub.PublicKey, hashed, r, s) return sig[20*2:], ok }
func (pk *PublicKey) Verify(hashed, sig []byte) ([]byte, bool) { if len(sig) != 2*dsaSubgroupBytes { return nil, false } r := new(big.Int).SetBytes(sig[:dsaSubgroupBytes]) s := new(big.Int).SetBytes(sig[dsaSubgroupBytes:]) ok := dsa.Verify(&pk.PublicKey, hashed, r, s) return sig[dsaSubgroupBytes*2:], ok }
func (dk *dsaPublicKey) Verify(msg []byte, signature []byte) (bool, error) { h := sha1.New() h.Write(msg) var rs dsaSignature _, err := asn1.Unmarshal(signature, &rs) if err != nil { return false, err } return dsa.Verify(&dk.key, h.Sum(nil), rs.R, rs.S), nil }
func checkSignature(c *x509.Certificate, algo x509.SignatureAlgorithm, signed, signature []byte) (err error) { var hashType crypto.Hash switch algo { case x509.SHA1WithRSA, x509.DSAWithSHA1, x509.ECDSAWithSHA1: hashType = crypto.SHA1 case x509.SHA256WithRSA, x509.DSAWithSHA256, x509.ECDSAWithSHA256: hashType = crypto.SHA256 case x509.SHA384WithRSA, x509.ECDSAWithSHA384: hashType = crypto.SHA384 case x509.SHA512WithRSA, x509.ECDSAWithSHA512: hashType = crypto.SHA512 default: return x509.ErrUnsupportedAlgorithm } if !hashType.Available() { return x509.ErrUnsupportedAlgorithm } h := hashType.New() h.Write(signed) digest := h.Sum(nil) switch pub := c.PublicKey.(type) { case *rsa.PublicKey: // the digest is already hashed, so we force a 0 here return rsa.VerifyPKCS1v15(pub, 0, digest, signature) case *dsa.PublicKey: dsaSig := new(dsaSignature) if _, err := asn1.Unmarshal(signature, dsaSig); err != nil { return err } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("x509: DSA signature contained zero or negative values") } if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { return errors.New("x509: DSA verification failure") } return case *ecdsa.PublicKey: ecdsaSig := new(ecdsaSignature) if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil { return err } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("x509: ECDSA signature contained zero or negative values") } if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { return errors.New("x509: ECDSA verification failure") } return } return x509.ErrUnsupportedAlgorithm }
func SignatureVerify(hash []byte, priv *dsa.PrivateKey, r []byte, s []byte) bool { ri := big.Int{} si := big.Int{} rb, err := base64.StdEncoding.DecodeString(string(r)) if err != nil { return false } sb, err := base64.StdEncoding.DecodeString(string(s)) if err != nil { return false } return dsa.Verify(&priv.PublicKey, hash, ri.SetBytes(rb), si.SetBytes(sb)) }
// 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 case PubKeyAlgoEdDSA: if !pk.edk.Verify(hashBytes, sig.EdDSASigR, sig.EdDSASigS) { return errors.SignatureError("EdDSA verification failure") } return nil default: return errors.SignatureError("Unsupported public key algorithm used in signature") } panic("unreachable") }
// verify hash of data with a dsa public key func (v *DSAVerifier) VerifyHash(h, sig []byte) (err error) { if len(sig) == 40 { r := new(big.Int).SetBytes(sig[:20]) s := new(big.Int).SetBytes(sig[20:]) if dsa.Verify(v.k, h, r, s) { // valid signature } else { // invalid signature err = ErrInvalidSignature } } else { err = ErrBadSignatureSize } return }
func Verify() { r := big.NewInt(0) r.SetString(*rc, 10) s := big.NewInt(0) s.SetString(*sc, 10) hash := HashMessage() key := Key() if dsa.Verify(&key.PublicKey, hash, r, s) { log.Println("message is valid!") } else { log.Println("message is invalid :(") log.Println("did you use the -r and -s flags to pass the r and s values?") } }
// NewDSAVerifier returns a Verifier that uses the DSA algorithm to verify updates. func NewDSAVerifier() Verifier { return verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error { key, ok := publicKey.(*dsa.PublicKey) if !ok { return errors.New("not a valid DSA public key") } var rs rsDER if _, err := asn1.Unmarshal(signature, &rs); err != nil { return err } if !dsa.Verify(key, checksum, rs.R, rs.S) { return errors.New("failed to verify ecsda signature") } return nil }) }
func (k *dsaPublicKey) Verify(data []byte, sigBlob []byte) bool { h := crypto.SHA1.New() h.Write(data) digest := h.Sum(nil) // Per RFC 4253, section 6.6, // The value for 'dss_signature_blob' is encoded as a string containing // r, followed by s (which are 160-bit integers, without lengths or // padding, unsigned, and in network byte order). // For DSS purposes, sig.Blob should be exactly 40 bytes in length. if len(sigBlob) != 40 { return false } r := new(big.Int).SetBytes(sigBlob[:20]) s := new(big.Int).SetBytes(sigBlob[20:]) return dsa.Verify((*dsa.PublicKey)(k), digest, r, s) }
// CheckSignature verifies that signature is a valid signature over signed from // c's public key. func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err os.Error) { var hashType crypto.Hash switch algo { case SHA1WithRSA, DSAWithSHA1: hashType = crypto.SHA1 case SHA256WithRSA, DSAWithSHA256: hashType = crypto.SHA256 case SHA384WithRSA: hashType = crypto.SHA384 case SHA512WithRSA: hashType = crypto.SHA512 default: return UnsupportedAlgorithmError{} } h := hashType.New() if h == nil { return UnsupportedAlgorithmError{} } h.Write(signed) digest := h.Sum() switch pub := c.PublicKey.(type) { case *rsa.PublicKey: return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) case *dsa.PublicKey: dsaSig := new(dsaSignature) if _, err := asn1.Unmarshal(signature, dsaSig); err != nil { return err } if !rawValueIsInteger(&dsaSig.R) || !rawValueIsInteger(&dsaSig.S) { return asn1.StructuralError{"tags don't match"} } r := new(big.Int).SetBytes(dsaSig.R.Bytes) s := new(big.Int).SetBytes(dsaSig.S.Bytes) if !dsa.Verify(pub, digest, r, s) { return os.ErrorString("DSA verification failure") } return } return UnsupportedAlgorithmError{} }
// 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") }
// CheckSignature verifies that signature is a valid signature over signed from // c's public key. func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) { var hashType crypto.Hash switch algo { case SHA1WithRSA, DSAWithSHA1: hashType = crypto.SHA1 case SHA256WithRSA, DSAWithSHA256: hashType = crypto.SHA256 case SHA384WithRSA: hashType = crypto.SHA384 case SHA512WithRSA: hashType = crypto.SHA512 default: return ErrUnsupportedAlgorithm } h := hashType.New() if h == nil { return ErrUnsupportedAlgorithm } h.Write(signed) digest := h.Sum(nil) switch pub := c.PublicKey.(type) { case *rsa.PublicKey: return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) case *dsa.PublicKey: dsaSig := new(dsaSignature) if _, err := asn1.Unmarshal(signature, dsaSig); err != nil { return err } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("DSA signature contained zero or negative values") } if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { return errors.New("DSA verification failure") } return } return ErrUnsupportedAlgorithm }
func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error { if sig.Format != k.Type() { return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type()) } h := crypto.SHA1.New() h.Write(data) digest := h.Sum(nil) // Per RFC 4253, section 6.6, // The value for 'dss_signature_blob' is encoded as a string containing // r, followed by s (which are 160-bit integers, without lengths or // padding, unsigned, and in network byte order). // For DSS purposes, sig.Blob should be exactly 40 bytes in length. if len(sig.Blob) != 40 { return errors.New("ssh: DSA signature parse error") } r := new(big.Int).SetBytes(sig.Blob[:20]) s := new(big.Int).SetBytes(sig.Blob[20:]) if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) { return nil } return errors.New("ssh: signature did not verify") }
// Verify validates the message buf using the key k. // It's assumed that buf is a valid message from which rr was unpacked. func (rr *SIG) Verify(k *KEY, buf []byte) error { if k == nil { return ErrKey } if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { return ErrKey } var hash crypto.Hash switch rr.Algorithm { case DSA, RSASHA1: hash = crypto.SHA1 case RSASHA256, ECDSAP256SHA256: hash = crypto.SHA256 case ECDSAP384SHA384: hash = crypto.SHA384 case RSASHA512: hash = crypto.SHA512 default: return ErrAlg } hasher := hash.New() buflen := len(buf) qdc, _ := unpackUint16(buf, 4) anc, _ := unpackUint16(buf, 6) auc, _ := unpackUint16(buf, 8) adc, offset := unpackUint16(buf, 10) var err error for i := uint16(0); i < qdc && offset < buflen; i++ { _, offset, err = UnpackDomainName(buf, offset) if err != nil { return err } // Skip past Type and Class offset += 2 + 2 } for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ { _, offset, err = UnpackDomainName(buf, offset) if err != nil { return err } // Skip past Type, Class and TTL offset += 2 + 2 + 4 if offset+1 >= buflen { continue } var rdlen uint16 rdlen, offset = unpackUint16(buf, offset) offset += int(rdlen) } if offset >= buflen { return &Error{err: "overflowing unpacking signed message"} } // offset should be just prior to SIG bodyend := offset // owner name SHOULD be root _, offset, err = UnpackDomainName(buf, offset) if err != nil { return err } // Skip Type, Class, TTL, RDLen offset += 2 + 2 + 4 + 2 sigstart := offset // Skip Type Covered, Algorithm, Labels, Original TTL offset += 2 + 1 + 1 + 4 if offset+4+4 >= buflen { return &Error{err: "overflow unpacking signed message"} } expire := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3]) offset += 4 incept := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3]) offset += 4 now := uint32(time.Now().Unix()) if now < incept || now > expire { return ErrTime } // Skip key tag offset += 2 var signername string signername, offset, err = UnpackDomainName(buf, offset) if err != nil { return err } // If key has come from the DNS name compression might // have mangled the case of the name if strings.ToLower(signername) != strings.ToLower(k.Header().Name) { return &Error{err: "signer name doesn't match key name"} } sigend := offset hasher.Write(buf[sigstart:sigend]) hasher.Write(buf[:10]) hasher.Write([]byte{ byte((adc - 1) << 8), byte(adc - 1), }) hasher.Write(buf[12:bodyend]) hashed := hasher.Sum(nil) sig := buf[sigend:] switch k.Algorithm { case DSA: pk := k.publicKeyDSA() sig = sig[1:] r := big.NewInt(0) r.SetBytes(sig[:len(sig)/2]) s := big.NewInt(0) s.SetBytes(sig[len(sig)/2:]) if pk != nil { if dsa.Verify(pk, hashed, r, s) { return nil } return ErrSig } case RSASHA1, RSASHA256, RSASHA512: pk := k.publicKeyRSA() if pk != nil { return rsa.VerifyPKCS1v15(pk, hash, hashed, sig) } case ECDSAP256SHA256, ECDSAP384SHA384: pk := k.publicKeyECDSA() r := big.NewInt(0) r.SetBytes(sig[:len(sig)/2]) s := big.NewInt(0) s.SetBytes(sig[len(sig)/2:]) if pk != nil { if ecdsa.Verify(pk, hashed, r, s) { return nil } return ErrSig } } return ErrKeyAlg }
func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error { if len(sig) < 2 { return errServerKeyExchange } var tls12HashId uint8 if ka.version >= VersionTLS12 { // handle SignatureAndHashAlgorithm var sigAndHash []uint8 sigAndHash, sig = sig[:2], sig[2:] tls12HashId = sigAndHash[0] ka.sh.hash = tls12HashId ka.sh.signature = sigAndHash[1] if sigAndHash[1] != ka.sigType { return errServerKeyExchange } if len(sig) < 2 { return errServerKeyExchange } if !isSupportedSignatureAndHash(signatureAndHash{ka.sigType, tls12HashId}, config.signatureAndHashesForClient()) { return errors.New("tls: unsupported hash function for ServerKeyExchange") } } sigLen := int(sig[0])<<8 | int(sig[1]) if sigLen+2 != len(sig) { return errServerKeyExchange } sig = sig[2:] ka.raw = sig digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, params) if err != nil { return err } switch ka.sigType { case signatureECDSA: pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey) if !ok { return errors.New("ECDHE ECDSA requires a ECDSA server public key") } ecdsaSig := new(ecdsaSignature) if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { return err } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("ECDSA signature contained zero or negative values") } if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { return errors.New("ECDSA verification failure") } case signatureRSA: pubKey, ok := cert.PublicKey.(*rsa.PublicKey) if !ok { return errors.New("ECDHE RSA requires a RSA server public key") } if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { return err } case signatureDSA: pubKey, ok := cert.PublicKey.(*dsa.PublicKey) if !ok { return errors.New("DSS ciphers require a DSA server public key") } dsaSig := new(dsaSignature) if _, err := asn1.Unmarshal(sig, dsaSig); err != nil { return err } if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("DSA signature contained zero or negative values") } if !dsa.Verify(pubKey, digest, dsaSig.R, dsaSig.S) { return errors.New("DSA verification failure") } default: return errors.New("unknown ECDHE signature algorithm") } ka.valid = true return nil }