github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/crypto/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/ecdsa" 10 "crypto/elliptic" 11 "crypto/md5" 12 "crypto/rsa" 13 "crypto/sha1" 14 "encoding/asn1" 15 "errors" 16 "io" 17 "math/big" 18 19 "golang_org/x/crypto/curve25519" 20 21 "crypto/sm2" 22 ) 23 24 var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") 25 var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") 26 27 // rsaKeyAgreement implements the standard TLS key agreement where the client 28 // encrypts the pre-master secret to the server's public key. 29 type rsaKeyAgreement struct{} 30 31 func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 32 return nil, nil 33 } 34 35 func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 36 if len(ckx.ciphertext) < 2 { 37 return nil, errClientKeyExchange 38 } 39 40 ciphertext := ckx.ciphertext 41 if version != VersionSSL30 { 42 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) 43 if ciphertextLen != len(ckx.ciphertext)-2 { 44 return nil, errClientKeyExchange 45 } 46 ciphertext = ckx.ciphertext[2:] 47 } 48 priv, ok := cert.PrivateKey.(crypto.Decrypter) 49 if !ok { 50 return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") 51 } 52 // Perform constant time RSA PKCS#1 v1.5 decryption 53 preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) 54 if err != nil { 55 return nil, err 56 } 57 // We don't check the version number in the premaster secret. For one, 58 // by checking it, we would leak information about the validity of the 59 // encrypted pre-master secret. Secondly, it provides only a small 60 // benefit against a downgrade attack and some implementations send the 61 // wrong version anyway. See the discussion at the end of section 62 // 7.4.7.1 of RFC 4346. 63 return preMasterSecret, nil 64 } 65 66 func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *sm2.Certificate, skx *serverKeyExchangeMsg) error { 67 return errors.New("tls: unexpected ServerKeyExchange") 68 } 69 70 func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *sm2.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 71 preMasterSecret := make([]byte, 48) 72 preMasterSecret[0] = byte(clientHello.vers >> 8) 73 preMasterSecret[1] = byte(clientHello.vers) 74 _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) 75 if err != nil { 76 return nil, nil, err 77 } 78 79 encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) 80 if err != nil { 81 return nil, nil, err 82 } 83 ckx := new(clientKeyExchangeMsg) 84 ckx.ciphertext = make([]byte, len(encrypted)+2) 85 ckx.ciphertext[0] = byte(len(encrypted) >> 8) 86 ckx.ciphertext[1] = byte(len(encrypted)) 87 copy(ckx.ciphertext[2:], encrypted) 88 return preMasterSecret, ckx, nil 89 } 90 91 // sha1Hash calculates a SHA1 hash over the given byte slices. 92 func sha1Hash(slices [][]byte) []byte { 93 hsha1 := sha1.New() 94 for _, slice := range slices { 95 hsha1.Write(slice) 96 } 97 return hsha1.Sum(nil) 98 } 99 100 // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the 101 // concatenation of an MD5 and SHA1 hash. 102 func md5SHA1Hash(slices [][]byte) []byte { 103 md5sha1 := make([]byte, md5.Size+sha1.Size) 104 hmd5 := md5.New() 105 for _, slice := range slices { 106 hmd5.Write(slice) 107 } 108 copy(md5sha1, hmd5.Sum(nil)) 109 copy(md5sha1[md5.Size:], sha1Hash(slices)) 110 return md5sha1 111 } 112 113 // hashForServerKeyExchange hashes the given slices and returns their digest 114 // and the identifier of the hash function used. The sigAndHash argument is 115 // only used for >= TLS 1.2 and precisely identifies the hash function to use. 116 func hashForServerKeyExchange(sigAndHash signatureAndHash, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) { 117 if version >= VersionTLS12 { 118 if !isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) { 119 return nil, crypto.Hash(0), errors.New("tls: unsupported hash function used by peer") 120 } 121 hashFunc, err := lookupTLSHash(sigAndHash.hash) 122 if err != nil { 123 return nil, crypto.Hash(0), err 124 } 125 h := hashFunc.New() 126 for _, slice := range slices { 127 h.Write(slice) 128 } 129 digest := h.Sum(nil) 130 return digest, hashFunc, nil 131 } 132 if sigAndHash.signature == signatureECDSA { 133 return sha1Hash(slices), crypto.SHA1, nil 134 } 135 return md5SHA1Hash(slices), crypto.MD5SHA1, nil 136 } 137 138 // pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a 139 // ServerKeyExchange given the signature type being used and the client's 140 // advertised list of supported signature and hash combinations. 141 func pickTLS12HashForSignature(sigType uint8, clientList []signatureAndHash) (uint8, error) { 142 if len(clientList) == 0 { 143 // If the client didn't specify any signature_algorithms 144 // extension then we can assume that it supports SHA1. See 145 // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 146 return hashSHA1, nil 147 } 148 149 for _, sigAndHash := range clientList { 150 if sigAndHash.signature != sigType { 151 continue 152 } 153 if isSupportedSignatureAndHash(sigAndHash, supportedSignatureAlgorithms) { 154 return sigAndHash.hash, nil 155 } 156 } 157 158 return 0, errors.New("tls: client doesn't support any common hash functions") 159 } 160 161 func curveForCurveID(id CurveID) (elliptic.Curve, bool) { 162 switch id { 163 case CurveP256: 164 return elliptic.P256(), true 165 case CurveP384: 166 return elliptic.P384(), true 167 case CurveP521: 168 return elliptic.P521(), true 169 case CureP256SM2: 170 return sm2.P256Sm2(), true 171 default: 172 return nil, false 173 } 174 175 } 176 177 // ecdheRSAKeyAgreement implements a TLS key agreement where the server 178 // generates a ephemeral EC public/private key pair and signs it. The 179 // pre-master secret is then calculated using ECDH. The signature may 180 // either be ECDSA or RSA. 181 type ecdheKeyAgreement struct { 182 version uint16 183 sigType uint8 184 privateKey []byte 185 curveid CurveID 186 187 // publicKey is used to store the peer's public value when X25519 is 188 // being used. 189 publicKey []byte 190 // x and y are used to store the peer's public value when one of the 191 // NIST curves is being used. 192 x, y *big.Int 193 } 194 195 func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 196 preferredCurves := config.curvePreferences() 197 198 NextCandidate: 199 for _, candidate := range preferredCurves { 200 for _, c := range clientHello.supportedCurves { 201 if candidate == c { 202 ka.curveid = c 203 break NextCandidate 204 } 205 } 206 } 207 208 if ka.curveid == 0 { 209 return nil, errors.New("tls: no supported elliptic curves offered") 210 } 211 212 var ecdhePublic []byte 213 214 if ka.curveid == X25519 { 215 var scalar, public [32]byte 216 if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil { 217 return nil, err 218 } 219 220 curve25519.ScalarBaseMult(&public, &scalar) 221 ka.privateKey = scalar[:] 222 ecdhePublic = public[:] 223 } else { 224 curve, ok := curveForCurveID(ka.curveid) 225 if !ok { 226 return nil, errors.New("tls: preferredCurves includes unsupported curve") 227 } 228 229 var x, y *big.Int 230 var err error 231 ka.privateKey, x, y, err = elliptic.GenerateKey(curve, config.rand()) 232 if err != nil { 233 return nil, err 234 } 235 ecdhePublic = elliptic.Marshal(curve, x, y) 236 } 237 238 // http://tools.ietf.org/html/rfc4492#section-5.4 239 serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) 240 serverECDHParams[0] = 3 // named curve 241 serverECDHParams[1] = byte(ka.curveid >> 8) 242 serverECDHParams[2] = byte(ka.curveid) 243 serverECDHParams[3] = byte(len(ecdhePublic)) 244 copy(serverECDHParams[4:], ecdhePublic) 245 246 sigAndHash := signatureAndHash{signature: ka.sigType} 247 248 if ka.version >= VersionTLS12 { 249 var err error 250 if sigAndHash.hash, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil { 251 return nil, err 252 } 253 } 254 255 digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, hello.random, serverECDHParams) 256 if err != nil { 257 return nil, err 258 } 259 260 priv, ok := cert.PrivateKey.(crypto.Signer) 261 if !ok { 262 return nil, errors.New("tls: certificate private key does not implement crypto.Signer") 263 } 264 var sig []byte 265 switch ka.sigType { 266 case signatureECDSA: 267 _, ok1 := priv.Public().(*sm2.PublicKey) 268 _, ok2 := priv.Public().(*ecdsa.PublicKey) 269 if !ok1 && !ok2 { 270 return nil, errors.New("tls: ECDHE ECDSA requires an ECDSA server key") 271 } 272 case signatureRSA: 273 _, ok := priv.Public().(*rsa.PublicKey) 274 if !ok { 275 return nil, errors.New("tls: ECDHE RSA requires a RSA server key") 276 } 277 default: 278 return nil, errors.New("tls: unknown ECDHE signature algorithm") 279 } 280 sig, err = priv.Sign(config.rand(), digest, hashFunc) 281 if err != nil { 282 return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) 283 } 284 285 skx := new(serverKeyExchangeMsg) 286 sigAndHashLen := 0 287 if ka.version >= VersionTLS12 { 288 sigAndHashLen = 2 289 } 290 skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) 291 copy(skx.key, serverECDHParams) 292 k := skx.key[len(serverECDHParams):] 293 if ka.version >= VersionTLS12 { 294 k[0] = sigAndHash.hash 295 k[1] = sigAndHash.signature 296 k = k[2:] 297 } 298 k[0] = byte(len(sig) >> 8) 299 k[1] = byte(len(sig)) 300 copy(k[2:], sig) 301 302 return skx, nil 303 } 304 305 func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 306 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { 307 return nil, errClientKeyExchange 308 } 309 310 if ka.curveid == X25519 { 311 if len(ckx.ciphertext) != 1+32 { 312 return nil, errClientKeyExchange 313 } 314 315 var theirPublic, sharedKey, scalar [32]byte 316 copy(theirPublic[:], ckx.ciphertext[1:]) 317 copy(scalar[:], ka.privateKey) 318 curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic) 319 return sharedKey[:], nil 320 } 321 322 curve, ok := curveForCurveID(ka.curveid) 323 if !ok { 324 panic("internal error") 325 } 326 x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:]) 327 if x == nil { 328 return nil, errClientKeyExchange 329 } 330 if !curve.IsOnCurve(x, y) { 331 return nil, errClientKeyExchange 332 } 333 x, _ = curve.ScalarMult(x, y, ka.privateKey) 334 preMasterSecret := make([]byte, (curve.Params().BitSize+7)>>3) 335 xBytes := x.Bytes() 336 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) 337 338 return preMasterSecret, nil 339 } 340 341 func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *sm2.Certificate, skx *serverKeyExchangeMsg) error { 342 if len(skx.key) < 4 { 343 return errServerKeyExchange 344 } 345 if skx.key[0] != 3 { // named curve 346 return errors.New("tls: server selected unsupported curve") 347 } 348 ka.curveid = CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) 349 350 publicLen := int(skx.key[3]) 351 if publicLen+4 > len(skx.key) { 352 return errServerKeyExchange 353 } 354 serverECDHParams := skx.key[:4+publicLen] 355 publicKey := serverECDHParams[4:] 356 357 sig := skx.key[4+publicLen:] 358 if len(sig) < 2 { 359 return errServerKeyExchange 360 } 361 362 if ka.curveid == X25519 { 363 if len(publicKey) != 32 { 364 return errors.New("tls: bad X25519 public value") 365 } 366 ka.publicKey = publicKey 367 } else { 368 curve, ok := curveForCurveID(ka.curveid) 369 if !ok { 370 return errors.New("tls: server selected unsupported curve") 371 } 372 373 ka.x, ka.y = elliptic.Unmarshal(curve, publicKey) 374 if ka.x == nil { 375 return errServerKeyExchange 376 } 377 if !curve.IsOnCurve(ka.x, ka.y) { 378 return errServerKeyExchange 379 } 380 } 381 382 sigAndHash := signatureAndHash{signature: ka.sigType} 383 if ka.version >= VersionTLS12 { 384 // handle SignatureAndHashAlgorithm 385 sigAndHash = signatureAndHash{hash: sig[0], signature: sig[1]} 386 if sigAndHash.signature != ka.sigType { 387 return errServerKeyExchange 388 } 389 sig = sig[2:] 390 if len(sig) < 2 { 391 return errServerKeyExchange 392 } 393 } 394 sigLen := int(sig[0])<<8 | int(sig[1]) 395 if sigLen+2 != len(sig) { 396 return errServerKeyExchange 397 } 398 sig = sig[2:] 399 400 digest, hashFunc, err := hashForServerKeyExchange(sigAndHash, ka.version, clientHello.random, serverHello.random, serverECDHParams) 401 if err != nil { 402 return err 403 } 404 switch ka.sigType { 405 case signatureECDSA: 406 pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey) 407 if !ok { 408 return errors.New("tls: ECDHE ECDSA requires a ECDSA server public key") 409 } 410 ecdsaSig := new(ecdsaSignature) 411 if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { 412 return err 413 } 414 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { 415 return errors.New("tls: ECDSA signature contained zero or negative values") 416 } 417 switch pubKey.Curve { 418 case sm2.P256Sm2(): 419 if !sm2.Verify(&sm2.PublicKey{ 420 X: pubKey.X, 421 Y: pubKey.Y, 422 Curve: pubKey.Curve, 423 }, digest, ecdsaSig.R, ecdsaSig.S) { 424 return errors.New("tls: SM2 verification failure") 425 } 426 default: 427 if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { 428 return errors.New("tls: ECDSA verification failure") 429 } 430 } 431 case signatureRSA: 432 pubKey, ok := cert.PublicKey.(*rsa.PublicKey) 433 if !ok { 434 return errors.New("tls: ECDHE RSA requires a RSA server public key") 435 } 436 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { 437 return err 438 } 439 default: 440 return errors.New("tls: unknown ECDHE signature algorithm") 441 } 442 443 return nil 444 } 445 446 func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *sm2.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 447 if ka.curveid == 0 { 448 return nil, nil, errors.New("tls: missing ServerKeyExchange message") 449 } 450 451 var serialized, preMasterSecret []byte 452 453 if ka.curveid == X25519 { 454 var ourPublic, theirPublic, sharedKey, scalar [32]byte 455 456 if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil { 457 return nil, nil, err 458 } 459 460 copy(theirPublic[:], ka.publicKey) 461 curve25519.ScalarBaseMult(&ourPublic, &scalar) 462 curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic) 463 serialized = ourPublic[:] 464 preMasterSecret = sharedKey[:] 465 } else { 466 curve, ok := curveForCurveID(ka.curveid) 467 if !ok { 468 panic("internal error") 469 } 470 priv, mx, my, err := elliptic.GenerateKey(curve, config.rand()) 471 if err != nil { 472 return nil, nil, err 473 } 474 x, _ := curve.ScalarMult(ka.x, ka.y, priv) 475 preMasterSecret = make([]byte, (curve.Params().BitSize+7)>>3) 476 xBytes := x.Bytes() 477 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) 478 479 serialized = elliptic.Marshal(curve, mx, my) 480 } 481 482 ckx := new(clientKeyExchangeMsg) 483 ckx.ciphertext = make([]byte, 1+len(serialized)) 484 ckx.ciphertext[0] = byte(len(serialized)) 485 copy(ckx.ciphertext[1:], serialized) 486 487 return preMasterSecret, ckx, nil 488 }