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