github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/auth.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "crypto" 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rsa" 12 "encoding/asn1" 13 "errors" 14 "fmt" 15 "hash" 16 "io" 17 ) 18 19 // pickSignatureAlgorithm selects a signature algorithm that is compatible with 20 // the given public key and the list of algorithms from the peer and this side. 21 // The lists of signature algorithms (peerSigAlgs and ourSigAlgs) are ignored 22 // for tlsVersion < VersionTLS12. 23 // 24 // The returned SignatureScheme codepoint is only meaningful for TLS 1.2, 25 // previous TLS versions have a fixed hash function. 26 func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []SignatureScheme, tlsVersion uint16) (sigAlg SignatureScheme, sigType uint8, hashFunc crypto.Hash, err error) { 27 if tlsVersion < VersionTLS12 || len(peerSigAlgs) == 0 { 28 // For TLS 1.1 and before, the signature algorithm could not be 29 // negotiated and the hash is fixed based on the signature type. For TLS 30 // 1.2, if the client didn't send signature_algorithms extension then we 31 // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. 32 switch pubkey.(type) { 33 case *rsa.PublicKey: 34 if tlsVersion < VersionTLS12 { 35 return 0, signaturePKCS1v15, crypto.MD5SHA1, nil 36 } else { 37 return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil 38 } 39 case *ecdsa.PublicKey: 40 return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil 41 default: 42 return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) 43 } 44 } 45 for _, sigAlg := range peerSigAlgs { 46 if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) { 47 continue 48 } 49 hashAlg, err := hashFromSignatureScheme(sigAlg) 50 if err != nil { 51 panic("tls: supported signature algorithm has an unknown hash function") 52 } 53 sigType := signatureFromSignatureScheme(sigAlg) 54 switch pubkey.(type) { 55 case *rsa.PublicKey: 56 if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS { 57 return sigAlg, sigType, hashAlg, nil 58 } 59 case *ecdsa.PublicKey: 60 if sigType == signatureECDSA { 61 return sigAlg, sigType, hashAlg, nil 62 } 63 default: 64 return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) 65 } 66 } 67 return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms") 68 } 69 70 // verifyHandshakeSignature verifies a signature against pre-hashed handshake 71 // contents. 72 func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error { 73 switch sigType { 74 case signatureECDSA: 75 pubKey, ok := pubkey.(*ecdsa.PublicKey) 76 if !ok { 77 return errors.New("tls: ECDSA signing requires a ECDSA public key") 78 } 79 ecdsaSig := new(ecdsaSignature) 80 if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { 81 return err 82 } 83 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { 84 return errors.New("tls: ECDSA signature contained zero or negative values") 85 } 86 if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { 87 return errors.New("tls: ECDSA verification failure") 88 } 89 case signaturePKCS1v15: 90 pubKey, ok := pubkey.(*rsa.PublicKey) 91 if !ok { 92 return errors.New("tls: RSA signing requires a RSA public key") 93 } 94 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { 95 return err 96 } 97 case signatureRSAPSS: 98 pubKey, ok := pubkey.(*rsa.PublicKey) 99 if !ok { 100 return errors.New("tls: RSA signing requires a RSA public key") 101 } 102 signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} 103 if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil { 104 return err 105 } 106 default: 107 return errors.New("tls: unknown signature algorithm") 108 } 109 return nil 110 } 111 112 const ( 113 serverSignatureContext = "TLS 1.3, server CertificateVerify\x00" 114 clientSignatureContext = "TLS 1.3, client CertificateVerify\x00" 115 ) 116 117 var signaturePadding = []byte{ 118 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 119 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 120 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 121 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 122 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 123 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 124 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 125 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 126 } 127 128 // writeSignedMessage writes the content to be signed by certificate keys in TLS 129 // 1.3 to sigHash. See RFC 8446, Section 4.4.3. 130 func writeSignedMessage(sigHash io.Writer, context string, transcript hash.Hash) { 131 sigHash.Write(signaturePadding) 132 io.WriteString(sigHash, context) 133 sigHash.Write(transcript.Sum(nil)) 134 } 135 136 // signatureSchemesForCertificate returns the list of supported SignatureSchemes 137 // for a given certificate, based on the public key and the protocol version. It 138 // does not support the crypto.Decrypter interface, so shouldn't be used on the 139 // server side in TLS 1.2 and earlier. 140 func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { 141 priv, ok := cert.PrivateKey.(crypto.Signer) 142 if !ok { 143 return nil 144 } 145 146 switch pub := priv.Public().(type) { 147 case *ecdsa.PublicKey: 148 if version != VersionTLS13 { 149 // In TLS 1.2 and earlier, ECDSA algorithms are not 150 // constrained to a single curve. 151 return []SignatureScheme{ 152 ECDSAWithP256AndSHA256, 153 ECDSAWithP384AndSHA384, 154 ECDSAWithP521AndSHA512, 155 ECDSAWithSHA1, 156 } 157 } 158 switch pub.Curve { 159 case elliptic.P256(): 160 return []SignatureScheme{ECDSAWithP256AndSHA256} 161 case elliptic.P384(): 162 return []SignatureScheme{ECDSAWithP384AndSHA384} 163 case elliptic.P521(): 164 return []SignatureScheme{ECDSAWithP521AndSHA512} 165 default: 166 return nil 167 } 168 case *rsa.PublicKey: 169 if version != VersionTLS13 { 170 return []SignatureScheme{ 171 PSSWithSHA256, 172 PSSWithSHA384, 173 PSSWithSHA512, 174 PKCS1WithSHA256, 175 PKCS1WithSHA384, 176 PKCS1WithSHA512, 177 PKCS1WithSHA1, 178 } 179 } 180 // RSA keys with RSA-PSS OID are not supported by crypto/x509. 181 return []SignatureScheme{ 182 PSSWithSHA256, 183 PSSWithSHA384, 184 PSSWithSHA512, 185 } 186 default: 187 return nil 188 } 189 } 190 191 // unsupportedCertificateError returns a helpful error for certificates with 192 // an unsupported private key. 193 func unsupportedCertificateError(cert *Certificate) error { 194 switch cert.PrivateKey.(type) { 195 case rsa.PrivateKey, ecdsa.PrivateKey: 196 return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T", 197 cert.PrivateKey, cert.PrivateKey) 198 } 199 200 signer, ok := cert.PrivateKey.(crypto.Signer) 201 if !ok { 202 return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer", 203 cert.PrivateKey) 204 } 205 206 switch pub := signer.Public().(type) { 207 case *ecdsa.PublicKey: 208 switch pub.Curve { 209 case elliptic.P256(): 210 case elliptic.P384(): 211 case elliptic.P521(): 212 default: 213 return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) 214 } 215 case *rsa.PublicKey: 216 default: 217 return fmt.Errorf("tls: unsupported certificate key (%T)", pub) 218 } 219 220 return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) 221 }