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