github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/tls/key_agreement.go (about) 1 // Copyright 2010 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/ecdh" 10 "crypto/md5" 11 "crypto/rsa" 12 "crypto/sha1" 13 "crypto/x509" 14 "errors" 15 "fmt" 16 "io" 17 ) 18 19 // a keyAgreement implements the client and server side of a TLS key agreement 20 // protocol by generating and processing key exchange messages. 21 type keyAgreement interface { 22 // On the server side, the first two methods are called in order. 23 24 // In the case that the key agreement protocol doesn't use a 25 // ServerKeyExchange message, generateServerKeyExchange can return nil, 26 // nil. 27 generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) 28 processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) 29 30 // On the client side, the next two methods are called in order. 31 32 // This method may not be called if the server doesn't send a 33 // ServerKeyExchange message. 34 processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error 35 generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) 36 } 37 38 var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") 39 var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") 40 41 // rsaKeyAgreement implements the standard TLS key agreement where the client 42 // encrypts the pre-master secret to the server's public key. 43 type rsaKeyAgreement struct{} 44 45 func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 46 return nil, nil 47 } 48 49 func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 50 if len(ckx.ciphertext) < 2 { 51 return nil, errClientKeyExchange 52 } 53 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) 54 if ciphertextLen != len(ckx.ciphertext)-2 { 55 return nil, errClientKeyExchange 56 } 57 ciphertext := ckx.ciphertext[2:] 58 59 priv, ok := cert.PrivateKey.(crypto.Decrypter) 60 if !ok { 61 return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") 62 } 63 // Perform constant time RSA PKCS #1 v1.5 decryption 64 preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) 65 if err != nil { 66 return nil, err 67 } 68 // We don't check the version number in the premaster secret. For one, 69 // by checking it, we would leak information about the validity of the 70 // encrypted pre-master secret. Secondly, it provides only a small 71 // benefit against a downgrade attack and some implementations send the 72 // wrong version anyway. See the discussion at the end of section 73 // 7.4.7.1 of RFC 4346. 74 return preMasterSecret, nil 75 } 76 77 func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { 78 return errors.New("tls: unexpected ServerKeyExchange") 79 } 80 81 func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 82 preMasterSecret := make([]byte, 48) 83 preMasterSecret[0] = byte(clientHello.vers >> 8) 84 preMasterSecret[1] = byte(clientHello.vers) 85 _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) 86 if err != nil { 87 return nil, nil, err 88 } 89 90 rsaKey, ok := cert.PublicKey.(*rsa.PublicKey) 91 if !ok { 92 return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite") 93 } 94 encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret) 95 if err != nil { 96 return nil, nil, err 97 } 98 ckx := new(clientKeyExchangeMsg) 99 ckx.ciphertext = make([]byte, len(encrypted)+2) 100 ckx.ciphertext[0] = byte(len(encrypted) >> 8) 101 ckx.ciphertext[1] = byte(len(encrypted)) 102 copy(ckx.ciphertext[2:], encrypted) 103 return preMasterSecret, ckx, nil 104 } 105 106 // sha1Hash calculates a SHA1 hash over the given byte slices. 107 func sha1Hash(slices [][]byte) []byte { 108 hsha1 := sha1.New() 109 for _, slice := range slices { 110 hsha1.Write(slice) 111 } 112 return hsha1.Sum(nil) 113 } 114 115 // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the 116 // concatenation of an MD5 and SHA1 hash. 117 func md5SHA1Hash(slices [][]byte) []byte { 118 md5sha1 := make([]byte, md5.Size+sha1.Size) 119 hmd5 := md5.New() 120 for _, slice := range slices { 121 hmd5.Write(slice) 122 } 123 copy(md5sha1, hmd5.Sum(nil)) 124 copy(md5sha1[md5.Size:], sha1Hash(slices)) 125 return md5sha1 126 } 127 128 // hashForServerKeyExchange hashes the given slices and returns their digest 129 // using the given hash function (for >= TLS 1.2) or using a default based on 130 // the sigType (for earlier TLS versions). For Ed25519 signatures, which don't 131 // do pre-hashing, it returns the concatenation of the slices. 132 func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte { 133 if sigType == signatureEd25519 { 134 var signed []byte 135 for _, slice := range slices { 136 signed = append(signed, slice...) 137 } 138 return signed 139 } 140 if version >= VersionTLS12 { 141 h := hashFunc.New() 142 for _, slice := range slices { 143 h.Write(slice) 144 } 145 digest := h.Sum(nil) 146 return digest 147 } 148 if sigType == signatureECDSA { 149 return sha1Hash(slices) 150 } 151 return md5SHA1Hash(slices) 152 } 153 154 // ecdheKeyAgreement implements a TLS key agreement where the server 155 // generates an ephemeral EC public/private key pair and signs it. The 156 // pre-master secret is then calculated using ECDH. The signature may 157 // be ECDSA, Ed25519 or RSA. 158 type ecdheKeyAgreement struct { 159 version uint16 160 isRSA bool 161 key *ecdh.PrivateKey 162 163 // ckx and preMasterSecret are generated in processServerKeyExchange 164 // and returned in generateClientKeyExchange. 165 ckx *clientKeyExchangeMsg 166 preMasterSecret []byte 167 } 168 169 func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 170 var curveID CurveID 171 for _, c := range clientHello.supportedCurves { 172 if config.supportsCurve(c) { 173 curveID = c 174 break 175 } 176 } 177 178 if curveID == 0 { 179 return nil, errors.New("tls: no supported elliptic curves offered") 180 } 181 if _, ok := curveForCurveID(curveID); !ok { 182 return nil, errors.New("tls: CurvePreferences includes unsupported curve") 183 } 184 185 key, err := generateECDHEKey(config.rand(), curveID) 186 if err != nil { 187 return nil, err 188 } 189 ka.key = key 190 191 // See RFC 4492, Section 5.4. 192 ecdhePublic := key.PublicKey().Bytes() 193 serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) 194 serverECDHEParams[0] = 3 // named curve 195 serverECDHEParams[1] = byte(curveID >> 8) 196 serverECDHEParams[2] = byte(curveID) 197 serverECDHEParams[3] = byte(len(ecdhePublic)) 198 copy(serverECDHEParams[4:], ecdhePublic) 199 200 priv, ok := cert.PrivateKey.(crypto.Signer) 201 if !ok { 202 return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) 203 } 204 205 var signatureAlgorithm SignatureScheme 206 var sigType uint8 207 var sigHash crypto.Hash 208 if ka.version >= VersionTLS12 { 209 signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) 210 if err != nil { 211 return nil, err 212 } 213 sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) 214 if err != nil { 215 return nil, err 216 } 217 } else { 218 sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) 219 if err != nil { 220 return nil, err 221 } 222 } 223 if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { 224 return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") 225 } 226 227 signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams) 228 229 signOpts := crypto.SignerOpts(sigHash) 230 if sigType == signatureRSAPSS { 231 signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} 232 } 233 sig, err := priv.Sign(config.rand(), signed, signOpts) 234 if err != nil { 235 return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) 236 } 237 238 skx := new(serverKeyExchangeMsg) 239 sigAndHashLen := 0 240 if ka.version >= VersionTLS12 { 241 sigAndHashLen = 2 242 } 243 skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig)) 244 copy(skx.key, serverECDHEParams) 245 k := skx.key[len(serverECDHEParams):] 246 if ka.version >= VersionTLS12 { 247 k[0] = byte(signatureAlgorithm >> 8) 248 k[1] = byte(signatureAlgorithm) 249 k = k[2:] 250 } 251 k[0] = byte(len(sig) >> 8) 252 k[1] = byte(len(sig)) 253 copy(k[2:], sig) 254 255 return skx, nil 256 } 257 258 func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 259 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { 260 return nil, errClientKeyExchange 261 } 262 263 peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:]) 264 if err != nil { 265 return nil, errClientKeyExchange 266 } 267 preMasterSecret, err := ka.key.ECDH(peerKey) 268 if err != nil { 269 return nil, errClientKeyExchange 270 } 271 272 return preMasterSecret, nil 273 } 274 275 func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { 276 if len(skx.key) < 4 { 277 return errServerKeyExchange 278 } 279 if skx.key[0] != 3 { // named curve 280 return errors.New("tls: server selected unsupported curve") 281 } 282 curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) 283 284 publicLen := int(skx.key[3]) 285 if publicLen+4 > len(skx.key) { 286 return errServerKeyExchange 287 } 288 serverECDHEParams := skx.key[:4+publicLen] 289 publicKey := serverECDHEParams[4:] 290 291 sig := skx.key[4+publicLen:] 292 if len(sig) < 2 { 293 return errServerKeyExchange 294 } 295 296 if _, ok := curveForCurveID(curveID); !ok { 297 return errors.New("tls: server selected unsupported curve") 298 } 299 300 key, err := generateECDHEKey(config.rand(), curveID) 301 if err != nil { 302 return err 303 } 304 ka.key = key 305 306 peerKey, err := key.Curve().NewPublicKey(publicKey) 307 if err != nil { 308 return errServerKeyExchange 309 } 310 ka.preMasterSecret, err = key.ECDH(peerKey) 311 if err != nil { 312 return errServerKeyExchange 313 } 314 315 ourPublicKey := key.PublicKey().Bytes() 316 ka.ckx = new(clientKeyExchangeMsg) 317 ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey)) 318 ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) 319 copy(ka.ckx.ciphertext[1:], ourPublicKey) 320 321 var sigType uint8 322 var sigHash crypto.Hash 323 if ka.version >= VersionTLS12 { 324 signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) 325 sig = sig[2:] 326 if len(sig) < 2 { 327 return errServerKeyExchange 328 } 329 330 if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) { 331 return errors.New("tls: certificate used with invalid signature algorithm") 332 } 333 sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) 334 if err != nil { 335 return err 336 } 337 } else { 338 sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey) 339 if err != nil { 340 return err 341 } 342 } 343 if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { 344 return errServerKeyExchange 345 } 346 347 sigLen := int(sig[0])<<8 | int(sig[1]) 348 if sigLen+2 != len(sig) { 349 return errServerKeyExchange 350 } 351 sig = sig[2:] 352 353 signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams) 354 if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil { 355 return errors.New("tls: invalid signature by the server certificate: " + err.Error()) 356 } 357 return nil 358 } 359 360 func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 361 if ka.ckx == nil { 362 return nil, nil, errors.New("tls: missing ServerKeyExchange message") 363 } 364 365 return ka.preMasterSecret, ka.ckx, nil 366 }