1// Copyright 2009 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
5package tls
6
7import (
8	"crypto"
9	"crypto/ecdsa"
10	"crypto/ed25519"
11	"crypto/rsa"
12	"crypto/subtle"
13	"crypto/x509"
14	"errors"
15	"fmt"
16	"io"
17	"sync/atomic"
18)
19
20// serverHandshakeState contains details of a server handshake in progress.
21// It's discarded once the handshake has completed.
22type serverHandshakeState struct {
23	c            *Conn
24	clientHello  *clientHelloMsg
25	hello        *serverHelloMsg
26	suite        *cipherSuite
27	ecdheOk      bool
28	ecSignOk     bool
29	rsaDecryptOk bool
30	rsaSignOk    bool
31	sessionState *sessionState
32	finishedHash finishedHash
33	masterSecret []byte
34	cert         *Certificate
35}
36
37// serverHandshake performs a TLS handshake as a server.
38func (c *Conn) serverHandshake() error {
39	// If this is the first server handshake, we generate a random key to
40	// encrypt the tickets with.
41	c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) })
42
43	clientHello, err := c.readClientHello()
44	if err != nil {
45		return err
46	}
47
48	if c.vers == VersionTLS13 {
49		hs := serverHandshakeStateTLS13{
50			c:           c,
51			clientHello: clientHello,
52		}
53		return hs.handshake()
54	}
55
56	hs := serverHandshakeState{
57		c:           c,
58		clientHello: clientHello,
59	}
60	return hs.handshake()
61}
62
63func (hs *serverHandshakeState) handshake() error {
64	c := hs.c
65
66	if err := hs.processClientHello(); err != nil {
67		return err
68	}
69
70	// For an overview of TLS handshaking, see RFC 5246, Section 7.3.
71	c.buffering = true
72	if hs.checkForResumption() {
73		// The client has included a session ticket and so we do an abbreviated handshake.
74		if err := hs.doResumeHandshake(); err != nil {
75			return err
76		}
77		if err := hs.establishKeys(); err != nil {
78			return err
79		}
80		// ticketSupported is set in a resumption handshake if the
81		// ticket from the client was encrypted with an old session
82		// ticket key and thus a refreshed ticket should be sent.
83		if hs.hello.ticketSupported {
84			if err := hs.sendSessionTicket(); err != nil {
85				return err
86			}
87		}
88		if err := hs.sendFinished(c.serverFinished[:]); err != nil {
89			return err
90		}
91		if _, err := c.flush(); err != nil {
92			return err
93		}
94		c.clientFinishedIsFirst = false
95		if err := hs.readFinished(nil); err != nil {
96			return err
97		}
98		c.didResume = true
99	} else {
100		// The client didn't include a session ticket, or it wasn't
101		// valid so we do a full handshake.
102		if err := hs.pickCipherSuite(); err != nil {
103			return err
104		}
105		if err := hs.doFullHandshake(); err != nil {
106			return err
107		}
108		if err := hs.establishKeys(); err != nil {
109			return err
110		}
111		if err := hs.readFinished(c.clientFinished[:]); err != nil {
112			return err
113		}
114		c.clientFinishedIsFirst = true
115		c.buffering = true
116		if err := hs.sendSessionTicket(); err != nil {
117			return err
118		}
119		if err := hs.sendFinished(nil); err != nil {
120			return err
121		}
122		if _, err := c.flush(); err != nil {
123			return err
124		}
125	}
126
127	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
128	atomic.StoreUint32(&c.handshakeStatus, 1)
129
130	return nil
131}
132
133// readClientHello reads a ClientHello message and selects the protocol version.
134func (c *Conn) readClientHello() (*clientHelloMsg, error) {
135	msg, err := c.readHandshake()
136	if err != nil {
137		return nil, err
138	}
139	clientHello, ok := msg.(*clientHelloMsg)
140	if !ok {
141		c.sendAlert(alertUnexpectedMessage)
142		return nil, unexpectedMessageError(clientHello, msg)
143	}
144
145	if c.config.GetConfigForClient != nil {
146		chi := clientHelloInfo(c, clientHello)
147		if newConfig, err := c.config.GetConfigForClient(chi); err != nil {
148			c.sendAlert(alertInternalError)
149			return nil, err
150		} else if newConfig != nil {
151			newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) })
152			c.config = newConfig
153		}
154	}
155
156	clientVersions := clientHello.supportedVersions
157	if len(clientHello.supportedVersions) == 0 {
158		clientVersions = supportedVersionsFromMax(clientHello.vers)
159	}
160	c.vers, ok = c.config.mutualVersion(clientVersions)
161	if !ok {
162		c.sendAlert(alertProtocolVersion)
163		return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
164	}
165	c.haveVers = true
166	c.in.version = c.vers
167	c.out.version = c.vers
168
169	return clientHello, nil
170}
171
172func (hs *serverHandshakeState) processClientHello() error {
173	c := hs.c
174
175	hs.hello = new(serverHelloMsg)
176	hs.hello.vers = c.vers
177
178	foundCompression := false
179	// We only support null compression, so check that the client offered it.
180	for _, compression := range hs.clientHello.compressionMethods {
181		if compression == compressionNone {
182			foundCompression = true
183			break
184		}
185	}
186
187	if !foundCompression {
188		c.sendAlert(alertHandshakeFailure)
189		return errors.New("tls: client does not support uncompressed connections")
190	}
191
192	hs.hello.random = make([]byte, 32)
193	serverRandom := hs.hello.random
194	// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
195	maxVers := c.config.maxSupportedVersion()
196	if maxVers >= VersionTLS12 && c.vers < maxVers {
197		if c.vers == VersionTLS12 {
198			copy(serverRandom[24:], downgradeCanaryTLS12)
199		} else {
200			copy(serverRandom[24:], downgradeCanaryTLS11)
201		}
202		serverRandom = serverRandom[:24]
203	}
204	_, err := io.ReadFull(c.config.rand(), serverRandom)
205	if err != nil {
206		c.sendAlert(alertInternalError)
207		return err
208	}
209
210	if len(hs.clientHello.secureRenegotiation) != 0 {
211		c.sendAlert(alertHandshakeFailure)
212		return errors.New("tls: initial handshake had non-empty renegotiation extension")
213	}
214
215	hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
216	hs.hello.compressionMethod = compressionNone
217	if len(hs.clientHello.serverName) > 0 {
218		c.serverName = hs.clientHello.serverName
219	}
220
221	if len(hs.clientHello.alpnProtocols) > 0 {
222		if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
223			hs.hello.alpnProtocol = selectedProto
224			c.clientProtocol = selectedProto
225		}
226	}
227
228	hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello))
229	if err != nil {
230		if err == errNoCertificates {
231			c.sendAlert(alertUnrecognizedName)
232		} else {
233			c.sendAlert(alertInternalError)
234		}
235		return err
236	}
237	if hs.clientHello.scts {
238		hs.hello.scts = hs.cert.SignedCertificateTimestamps
239	}
240
241	hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
242
243	if hs.ecdheOk {
244		// Although omitting the ec_point_formats extension is permitted, some
245		// old OpenSSL version will refuse to handshake if not present.
246		//
247		// Per RFC 4492, section 5.1.2, implementations MUST support the
248		// uncompressed point format. See golang.org/issue/31943.
249		hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
250	}
251
252	if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
253		switch priv.Public().(type) {
254		case *ecdsa.PublicKey:
255			hs.ecSignOk = true
256		case ed25519.PublicKey:
257			hs.ecSignOk = true
258		case *rsa.PublicKey:
259			hs.rsaSignOk = true
260		default:
261			c.sendAlert(alertInternalError)
262			return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
263		}
264	}
265	if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
266		switch priv.Public().(type) {
267		case *rsa.PublicKey:
268			hs.rsaDecryptOk = true
269		default:
270			c.sendAlert(alertInternalError)
271			return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
272		}
273	}
274
275	return nil
276}
277
278// supportsECDHE returns whether ECDHE key exchanges can be used with this
279// pre-TLS 1.3 client.
280func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
281	supportsCurve := false
282	for _, curve := range supportedCurves {
283		if c.supportsCurve(curve) {
284			supportsCurve = true
285			break
286		}
287	}
288
289	supportsPointFormat := false
290	for _, pointFormat := range supportedPoints {
291		if pointFormat == pointFormatUncompressed {
292			supportsPointFormat = true
293			break
294		}
295	}
296
297	return supportsCurve && supportsPointFormat
298}
299
300func (hs *serverHandshakeState) pickCipherSuite() error {
301	c := hs.c
302
303	var preferenceList, supportedList []uint16
304	if c.config.PreferServerCipherSuites {
305		preferenceList = c.config.cipherSuites()
306		supportedList = hs.clientHello.cipherSuites
307	} else {
308		preferenceList = hs.clientHello.cipherSuites
309		supportedList = c.config.cipherSuites()
310	}
311
312	hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk)
313	if hs.suite == nil {
314		c.sendAlert(alertHandshakeFailure)
315		return errors.New("tls: no cipher suite supported by both client and server")
316	}
317
318	for _, id := range hs.clientHello.cipherSuites {
319		if id == TLS_FALLBACK_SCSV {
320			// The client is doing a fallback connection. See RFC 7507.
321			if hs.clientHello.vers < c.config.maxSupportedVersion() {
322				c.sendAlert(alertInappropriateFallback)
323				return errors.New("tls: client using inappropriate protocol fallback")
324			}
325			break
326		}
327	}
328
329	return nil
330}
331
332func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
333	if c.flags&suiteECDHE != 0 {
334		if !hs.ecdheOk {
335			return false
336		}
337		if c.flags&suiteECSign != 0 {
338			if !hs.ecSignOk {
339				return false
340			}
341		} else if !hs.rsaSignOk {
342			return false
343		}
344	} else if !hs.rsaDecryptOk {
345		return false
346	}
347	if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
348		return false
349	}
350	return true
351}
352
353// checkForResumption reports whether we should perform resumption on this connection.
354func (hs *serverHandshakeState) checkForResumption() bool {
355	c := hs.c
356
357	if c.config.SessionTicketsDisabled {
358		return false
359	}
360
361	plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
362	if plaintext == nil {
363		return false
364	}
365	hs.sessionState = &sessionState{usedOldKey: usedOldKey}
366	ok := hs.sessionState.unmarshal(plaintext)
367	if !ok {
368		return false
369	}
370
371	// Never resume a session for a different TLS version.
372	if c.vers != hs.sessionState.vers {
373		return false
374	}
375
376	cipherSuiteOk := false
377	// Check that the client is still offering the ciphersuite in the session.
378	for _, id := range hs.clientHello.cipherSuites {
379		if id == hs.sessionState.cipherSuite {
380			cipherSuiteOk = true
381			break
382		}
383	}
384	if !cipherSuiteOk {
385		return false
386	}
387
388	// Check that we also support the ciphersuite from the session.
389	hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
390		c.config.cipherSuites(), hs.cipherSuiteOk)
391	if hs.suite == nil {
392		return false
393	}
394
395	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
396	needClientCerts := requiresClientCert(c.config.ClientAuth)
397	if needClientCerts && !sessionHasClientCerts {
398		return false
399	}
400	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
401		return false
402	}
403
404	return true
405}
406
407func (hs *serverHandshakeState) doResumeHandshake() error {
408	c := hs.c
409
410	hs.hello.cipherSuite = hs.suite.id
411	// We echo the client's session ID in the ServerHello to let it know
412	// that we're doing a resumption.
413	hs.hello.sessionId = hs.clientHello.sessionId
414	hs.hello.ticketSupported = hs.sessionState.usedOldKey
415	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
416	hs.finishedHash.discardHandshakeBuffer()
417	hs.finishedHash.Write(hs.clientHello.marshal())
418	hs.finishedHash.Write(hs.hello.marshal())
419	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
420		return err
421	}
422
423	if err := c.processCertsFromClient(Certificate{
424		Certificate: hs.sessionState.certificates,
425	}); err != nil {
426		return err
427	}
428
429	hs.masterSecret = hs.sessionState.masterSecret
430
431	return nil
432}
433
434func (hs *serverHandshakeState) doFullHandshake() error {
435	c := hs.c
436
437	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
438		hs.hello.ocspStapling = true
439	}
440
441	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
442	hs.hello.cipherSuite = hs.suite.id
443
444	hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
445	if c.config.ClientAuth == NoClientCert {
446		// No need to keep a full record of the handshake if client
447		// certificates won't be used.
448		hs.finishedHash.discardHandshakeBuffer()
449	}
450	hs.finishedHash.Write(hs.clientHello.marshal())
451	hs.finishedHash.Write(hs.hello.marshal())
452	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
453		return err
454	}
455
456	certMsg := new(certificateMsg)
457	certMsg.certificates = hs.cert.Certificate
458	hs.finishedHash.Write(certMsg.marshal())
459	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
460		return err
461	}
462
463	if hs.hello.ocspStapling {
464		certStatus := new(certificateStatusMsg)
465		certStatus.response = hs.cert.OCSPStaple
466		hs.finishedHash.Write(certStatus.marshal())
467		if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
468			return err
469		}
470	}
471
472	keyAgreement := hs.suite.ka(c.vers)
473	skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
474	if err != nil {
475		c.sendAlert(alertHandshakeFailure)
476		return err
477	}
478	if skx != nil {
479		hs.finishedHash.Write(skx.marshal())
480		if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
481			return err
482		}
483	}
484
485	var certReq *certificateRequestMsg
486	if c.config.ClientAuth >= RequestClientCert {
487		// Request a client certificate
488		certReq = new(certificateRequestMsg)
489		certReq.certificateTypes = []byte{
490			byte(certTypeRSASign),
491			byte(certTypeECDSASign),
492		}
493		if c.vers >= VersionTLS12 {
494			certReq.hasSignatureAlgorithm = true
495			certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
496		}
497
498		// An empty list of certificateAuthorities signals to
499		// the client that it may send any certificate in response
500		// to our request. When we know the CAs we trust, then
501		// we can send them down, so that the client can choose
502		// an appropriate certificate to give to us.
503		if c.config.ClientCAs != nil {
504			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
505		}
506		hs.finishedHash.Write(certReq.marshal())
507		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
508			return err
509		}
510	}
511
512	helloDone := new(serverHelloDoneMsg)
513	hs.finishedHash.Write(helloDone.marshal())
514	if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
515		return err
516	}
517
518	if _, err := c.flush(); err != nil {
519		return err
520	}
521
522	var pub crypto.PublicKey // public key for client auth, if any
523
524	msg, err := c.readHandshake()
525	if err != nil {
526		return err
527	}
528
529	// If we requested a client certificate, then the client must send a
530	// certificate message, even if it's empty.
531	if c.config.ClientAuth >= RequestClientCert {
532		certMsg, ok := msg.(*certificateMsg)
533		if !ok {
534			c.sendAlert(alertUnexpectedMessage)
535			return unexpectedMessageError(certMsg, msg)
536		}
537		hs.finishedHash.Write(certMsg.marshal())
538
539		if err := c.processCertsFromClient(Certificate{
540			Certificate: certMsg.certificates,
541		}); err != nil {
542			return err
543		}
544		if len(certMsg.certificates) != 0 {
545			pub = c.peerCertificates[0].PublicKey
546		}
547
548		msg, err = c.readHandshake()
549		if err != nil {
550			return err
551		}
552	}
553
554	// Get client key exchange
555	ckx, ok := msg.(*clientKeyExchangeMsg)
556	if !ok {
557		c.sendAlert(alertUnexpectedMessage)
558		return unexpectedMessageError(ckx, msg)
559	}
560	hs.finishedHash.Write(ckx.marshal())
561
562	preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
563	if err != nil {
564		c.sendAlert(alertHandshakeFailure)
565		return err
566	}
567	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
568	if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
569		c.sendAlert(alertInternalError)
570		return err
571	}
572
573	// If we received a client cert in response to our certificate request message,
574	// the client will send us a certificateVerifyMsg immediately after the
575	// clientKeyExchangeMsg. This message is a digest of all preceding
576	// handshake-layer messages that is signed using the private key corresponding
577	// to the client's certificate. This allows us to verify that the client is in
578	// possession of the private key of the certificate.
579	if len(c.peerCertificates) > 0 {
580		msg, err = c.readHandshake()
581		if err != nil {
582			return err
583		}
584		certVerify, ok := msg.(*certificateVerifyMsg)
585		if !ok {
586			c.sendAlert(alertUnexpectedMessage)
587			return unexpectedMessageError(certVerify, msg)
588		}
589
590		var sigType uint8
591		var sigHash crypto.Hash
592		if c.vers >= VersionTLS12 {
593			if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
594				c.sendAlert(alertIllegalParameter)
595				return errors.New("tls: client certificate used with invalid signature algorithm")
596			}
597			sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
598			if err != nil {
599				return c.sendAlert(alertInternalError)
600			}
601		} else {
602			sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
603			if err != nil {
604				c.sendAlert(alertIllegalParameter)
605				return err
606			}
607		}
608
609		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
610		if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
611			c.sendAlert(alertDecryptError)
612			return errors.New("tls: invalid signature by the client certificate: " + err.Error())
613		}
614
615		hs.finishedHash.Write(certVerify.marshal())
616	}
617
618	hs.finishedHash.discardHandshakeBuffer()
619
620	return nil
621}
622
623func (hs *serverHandshakeState) establishKeys() error {
624	c := hs.c
625
626	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
627		keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
628
629	var clientCipher, serverCipher interface{}
630	var clientHash, serverHash macFunction
631
632	if hs.suite.aead == nil {
633		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
634		clientHash = hs.suite.mac(c.vers, clientMAC)
635		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
636		serverHash = hs.suite.mac(c.vers, serverMAC)
637	} else {
638		clientCipher = hs.suite.aead(clientKey, clientIV)
639		serverCipher = hs.suite.aead(serverKey, serverIV)
640	}
641
642	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
643	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
644
645	return nil
646}
647
648func (hs *serverHandshakeState) readFinished(out []byte) error {
649	c := hs.c
650
651	if err := c.readChangeCipherSpec(); err != nil {
652		return err
653	}
654
655	msg, err := c.readHandshake()
656	if err != nil {
657		return err
658	}
659	clientFinished, ok := msg.(*finishedMsg)
660	if !ok {
661		c.sendAlert(alertUnexpectedMessage)
662		return unexpectedMessageError(clientFinished, msg)
663	}
664
665	verify := hs.finishedHash.clientSum(hs.masterSecret)
666	if len(verify) != len(clientFinished.verifyData) ||
667		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
668		c.sendAlert(alertHandshakeFailure)
669		return errors.New("tls: client's Finished message is incorrect")
670	}
671
672	hs.finishedHash.Write(clientFinished.marshal())
673	copy(out, verify)
674	return nil
675}
676
677func (hs *serverHandshakeState) sendSessionTicket() error {
678	if !hs.hello.ticketSupported {
679		return nil
680	}
681
682	c := hs.c
683	m := new(newSessionTicketMsg)
684
685	var certsFromClient [][]byte
686	for _, cert := range c.peerCertificates {
687		certsFromClient = append(certsFromClient, cert.Raw)
688	}
689	state := sessionState{
690		vers:         c.vers,
691		cipherSuite:  hs.suite.id,
692		masterSecret: hs.masterSecret,
693		certificates: certsFromClient,
694	}
695	var err error
696	m.ticket, err = c.encryptTicket(state.marshal())
697	if err != nil {
698		return err
699	}
700
701	hs.finishedHash.Write(m.marshal())
702	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
703		return err
704	}
705
706	return nil
707}
708
709func (hs *serverHandshakeState) sendFinished(out []byte) error {
710	c := hs.c
711
712	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
713		return err
714	}
715
716	finished := new(finishedMsg)
717	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
718	hs.finishedHash.Write(finished.marshal())
719	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
720		return err
721	}
722
723	c.cipherSuite = hs.suite.id
724	copy(out, finished.verifyData)
725
726	return nil
727}
728
729// processCertsFromClient takes a chain of client certificates either from a
730// Certificates message or from a sessionState and verifies them. It returns
731// the public key of the leaf certificate.
732func (c *Conn) processCertsFromClient(certificate Certificate) error {
733	certificates := certificate.Certificate
734	certs := make([]*x509.Certificate, len(certificates))
735	var err error
736	for i, asn1Data := range certificates {
737		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
738			c.sendAlert(alertBadCertificate)
739			return errors.New("tls: failed to parse client certificate: " + err.Error())
740		}
741	}
742
743	if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
744		c.sendAlert(alertBadCertificate)
745		return errors.New("tls: client didn't provide a certificate")
746	}
747
748	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
749		opts := x509.VerifyOptions{
750			Roots:         c.config.ClientCAs,
751			CurrentTime:   c.config.time(),
752			Intermediates: x509.NewCertPool(),
753			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
754		}
755
756		for _, cert := range certs[1:] {
757			opts.Intermediates.AddCert(cert)
758		}
759
760		chains, err := certs[0].Verify(opts)
761		if err != nil {
762			c.sendAlert(alertBadCertificate)
763			return errors.New("tls: failed to verify client certificate: " + err.Error())
764		}
765
766		c.verifiedChains = chains
767	}
768
769	if c.config.VerifyPeerCertificate != nil {
770		if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
771			c.sendAlert(alertBadCertificate)
772			return err
773		}
774	}
775
776	if len(certs) == 0 {
777		return nil
778	}
779
780	switch certs[0].PublicKey.(type) {
781	case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
782	default:
783		c.sendAlert(alertUnsupportedCertificate)
784		return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
785	}
786
787	c.peerCertificates = certs
788	c.ocspResponse = certificate.OCSPStaple
789	c.scts = certificate.SignedCertificateTimestamps
790	return nil
791}
792
793func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
794	supportedVersions := clientHello.supportedVersions
795	if len(clientHello.supportedVersions) == 0 {
796		supportedVersions = supportedVersionsFromMax(clientHello.vers)
797	}
798
799	return &ClientHelloInfo{
800		CipherSuites:      clientHello.cipherSuites,
801		ServerName:        clientHello.serverName,
802		SupportedCurves:   clientHello.supportedCurves,
803		SupportedPoints:   clientHello.supportedPoints,
804		SignatureSchemes:  clientHello.supportedSignatureAlgorithms,
805		SupportedProtos:   clientHello.alpnProtocols,
806		SupportedVersions: supportedVersions,
807		Conn:              c.conn,
808		config:            c.config,
809	}
810}
811