mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-03 20:17:36 +03:00
Support for Ed25519 certificates was added in CL 175478, this wires them up into the TLS stack according to RFC 8422 (TLS 1.2) and RFC 8446 (TLS 1.3). RFC 8422 also specifies support for TLS 1.0 and 1.1, and I initially implemented that, but even OpenSSL doesn't take the complexity, so I just dropped it. It would have required keeping a buffer of the handshake transcript in order to do the direct Ed25519 signatures. We effectively need to support TLS 1.2 because it shares ClientHello signature algorithms with TLS 1.3. While at it, reordered the advertised signature algorithms in the rough order we would want to use them, also based on what curves have fast constant-time implementations. Client and client auth tests changed because of the change in advertised signature algorithms in ClientHello and CertificateRequest. Fixes #25355 Change-Id: I9fdd839afde4fd6b13fcbc5cc7017fd8c35085ee Reviewed-on: https://go-review.googlesource.com/c/go/+/177698 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
472 lines
16 KiB
Go
472 lines
16 KiB
Go
// Copyright 2010 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package tls
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/des"
|
|
"crypto/hmac"
|
|
"crypto/rc4"
|
|
"crypto/sha1"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"golang.org/x/crypto/chacha20poly1305"
|
|
"hash"
|
|
)
|
|
|
|
// a keyAgreement implements the client and server side of a TLS key agreement
|
|
// protocol by generating and processing key exchange messages.
|
|
type keyAgreement interface {
|
|
// On the server side, the first two methods are called in order.
|
|
|
|
// In the case that the key agreement protocol doesn't use a
|
|
// ServerKeyExchange message, generateServerKeyExchange can return nil,
|
|
// nil.
|
|
generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
|
|
processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
|
|
|
|
// On the client side, the next two methods are called in order.
|
|
|
|
// This method may not be called if the server doesn't send a
|
|
// ServerKeyExchange message.
|
|
processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
|
|
generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
|
|
}
|
|
|
|
const (
|
|
// suiteECDH indicates that the cipher suite involves elliptic curve
|
|
// Diffie-Hellman. This means that it should only be selected when the
|
|
// client indicates that it supports ECC with a curve and point format
|
|
// that we're happy with.
|
|
suiteECDHE = 1 << iota
|
|
// suiteECSign indicates that the cipher suite involves an ECDSA or
|
|
// EdDSA signature and therefore may only be selected when the server's
|
|
// certificate is ECDSA or EdDSA. If this is not set then the cipher suite
|
|
// is RSA based.
|
|
suiteECSign
|
|
// suiteTLS12 indicates that the cipher suite should only be advertised
|
|
// and accepted when using TLS 1.2.
|
|
suiteTLS12
|
|
// suiteSHA384 indicates that the cipher suite uses SHA384 as the
|
|
// handshake hash.
|
|
suiteSHA384
|
|
// suiteDefaultOff indicates that this cipher suite is not included by
|
|
// default.
|
|
suiteDefaultOff
|
|
)
|
|
|
|
// A cipherSuite is a specific combination of key agreement, cipher and MAC function.
|
|
type cipherSuite struct {
|
|
id uint16
|
|
// the lengths, in bytes, of the key material needed for each component.
|
|
keyLen int
|
|
macLen int
|
|
ivLen int
|
|
ka func(version uint16) keyAgreement
|
|
// flags is a bitmask of the suite* values, above.
|
|
flags int
|
|
cipher func(key, iv []byte, isRead bool) interface{}
|
|
mac func(version uint16, macKey []byte) macFunction
|
|
aead func(key, fixedNonce []byte) aead
|
|
}
|
|
|
|
var cipherSuites = []*cipherSuite{
|
|
// Ciphersuite order is chosen so that ECDHE comes before plain RSA and
|
|
// AEADs are the top preference.
|
|
{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
|
|
{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
|
|
{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
|
|
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
|
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
|
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
|
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
|
|
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
|
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
|
|
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
|
|
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
|
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
|
|
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
|
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
|
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
|
|
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
|
|
|
|
// RC4-based cipher suites are disabled by default.
|
|
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil},
|
|
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil},
|
|
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteDefaultOff, cipherRC4, macSHA1, nil},
|
|
}
|
|
|
|
// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash
|
|
// algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
|
|
type cipherSuiteTLS13 struct {
|
|
id uint16
|
|
keyLen int
|
|
aead func(key, fixedNonce []byte) aead
|
|
hash crypto.Hash
|
|
}
|
|
|
|
var cipherSuitesTLS13 = []*cipherSuiteTLS13{
|
|
{TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
|
|
{TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
|
|
{TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
|
|
}
|
|
|
|
func cipherRC4(key, iv []byte, isRead bool) interface{} {
|
|
cipher, _ := rc4.NewCipher(key)
|
|
return cipher
|
|
}
|
|
|
|
func cipher3DES(key, iv []byte, isRead bool) interface{} {
|
|
block, _ := des.NewTripleDESCipher(key)
|
|
if isRead {
|
|
return cipher.NewCBCDecrypter(block, iv)
|
|
}
|
|
return cipher.NewCBCEncrypter(block, iv)
|
|
}
|
|
|
|
func cipherAES(key, iv []byte, isRead bool) interface{} {
|
|
block, _ := aes.NewCipher(key)
|
|
if isRead {
|
|
return cipher.NewCBCDecrypter(block, iv)
|
|
}
|
|
return cipher.NewCBCEncrypter(block, iv)
|
|
}
|
|
|
|
// macSHA1 returns a macFunction for the given protocol version.
|
|
func macSHA1(version uint16, key []byte) macFunction {
|
|
if version == VersionSSL30 {
|
|
mac := ssl30MAC{
|
|
h: sha1.New(),
|
|
key: make([]byte, len(key)),
|
|
}
|
|
copy(mac.key, key)
|
|
return mac
|
|
}
|
|
return tls10MAC{h: hmac.New(newConstantTimeHash(sha1.New), key)}
|
|
}
|
|
|
|
// macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2
|
|
// so the given version is ignored.
|
|
func macSHA256(version uint16, key []byte) macFunction {
|
|
return tls10MAC{h: hmac.New(sha256.New, key)}
|
|
}
|
|
|
|
type macFunction interface {
|
|
// Size returns the length of the MAC.
|
|
Size() int
|
|
// MAC appends the MAC of (seq, header, data) to out. The extra data is fed
|
|
// into the MAC after obtaining the result to normalize timing. The result
|
|
// is only valid until the next invocation of MAC as the buffer is reused.
|
|
MAC(seq, header, data, extra []byte) []byte
|
|
}
|
|
|
|
type aead interface {
|
|
cipher.AEAD
|
|
|
|
// explicitNonceLen returns the number of bytes of explicit nonce
|
|
// included in each record. This is eight for older AEADs and
|
|
// zero for modern ones.
|
|
explicitNonceLen() int
|
|
}
|
|
|
|
const (
|
|
aeadNonceLength = 12
|
|
noncePrefixLength = 4
|
|
)
|
|
|
|
// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
|
|
// each call.
|
|
type prefixNonceAEAD struct {
|
|
// nonce contains the fixed part of the nonce in the first four bytes.
|
|
nonce [aeadNonceLength]byte
|
|
aead cipher.AEAD
|
|
}
|
|
|
|
func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength }
|
|
func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() }
|
|
func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }
|
|
|
|
func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
|
|
copy(f.nonce[4:], nonce)
|
|
return f.aead.Seal(out, f.nonce[:], plaintext, additionalData)
|
|
}
|
|
|
|
func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
copy(f.nonce[4:], nonce)
|
|
return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
|
|
}
|
|
|
|
// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
|
|
// before each call.
|
|
type xorNonceAEAD struct {
|
|
nonceMask [aeadNonceLength]byte
|
|
aead cipher.AEAD
|
|
}
|
|
|
|
func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number
|
|
func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
|
|
func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
|
|
|
|
func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
|
|
for i, b := range nonce {
|
|
f.nonceMask[4+i] ^= b
|
|
}
|
|
result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)
|
|
for i, b := range nonce {
|
|
f.nonceMask[4+i] ^= b
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
|
|
for i, b := range nonce {
|
|
f.nonceMask[4+i] ^= b
|
|
}
|
|
result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)
|
|
for i, b := range nonce {
|
|
f.nonceMask[4+i] ^= b
|
|
}
|
|
|
|
return result, err
|
|
}
|
|
|
|
func aeadAESGCM(key, noncePrefix []byte) aead {
|
|
if len(noncePrefix) != noncePrefixLength {
|
|
panic("tls: internal error: wrong nonce length")
|
|
}
|
|
aes, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
aead, err := cipher.NewGCM(aes)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ret := &prefixNonceAEAD{aead: aead}
|
|
copy(ret.nonce[:], noncePrefix)
|
|
return ret
|
|
}
|
|
|
|
func aeadAESGCMTLS13(key, nonceMask []byte) aead {
|
|
if len(nonceMask) != aeadNonceLength {
|
|
panic("tls: internal error: wrong nonce length")
|
|
}
|
|
aes, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
aead, err := cipher.NewGCM(aes)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ret := &xorNonceAEAD{aead: aead}
|
|
copy(ret.nonceMask[:], nonceMask)
|
|
return ret
|
|
}
|
|
|
|
func aeadChaCha20Poly1305(key, nonceMask []byte) aead {
|
|
if len(nonceMask) != aeadNonceLength {
|
|
panic("tls: internal error: wrong nonce length")
|
|
}
|
|
aead, err := chacha20poly1305.New(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ret := &xorNonceAEAD{aead: aead}
|
|
copy(ret.nonceMask[:], nonceMask)
|
|
return ret
|
|
}
|
|
|
|
// ssl30MAC implements the SSLv3 MAC function, as defined in
|
|
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
|
|
type ssl30MAC struct {
|
|
h hash.Hash
|
|
key []byte
|
|
buf []byte
|
|
}
|
|
|
|
func (s ssl30MAC) Size() int {
|
|
return s.h.Size()
|
|
}
|
|
|
|
var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
|
|
|
|
var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
|
|
|
|
// MAC does not offer constant timing guarantees for SSL v3.0, since it's deemed
|
|
// useless considering the similar, protocol-level POODLE vulnerability.
|
|
func (s ssl30MAC) MAC(seq, header, data, extra []byte) []byte {
|
|
padLength := 48
|
|
if s.h.Size() == 20 {
|
|
padLength = 40
|
|
}
|
|
|
|
s.h.Reset()
|
|
s.h.Write(s.key)
|
|
s.h.Write(ssl30Pad1[:padLength])
|
|
s.h.Write(seq)
|
|
s.h.Write(header[:1])
|
|
s.h.Write(header[3:5])
|
|
s.h.Write(data)
|
|
s.buf = s.h.Sum(s.buf[:0])
|
|
|
|
s.h.Reset()
|
|
s.h.Write(s.key)
|
|
s.h.Write(ssl30Pad2[:padLength])
|
|
s.h.Write(s.buf)
|
|
return s.h.Sum(s.buf[:0])
|
|
}
|
|
|
|
type constantTimeHash interface {
|
|
hash.Hash
|
|
ConstantTimeSum(b []byte) []byte
|
|
}
|
|
|
|
// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
|
|
// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
|
|
type cthWrapper struct {
|
|
h constantTimeHash
|
|
}
|
|
|
|
func (c *cthWrapper) Size() int { return c.h.Size() }
|
|
func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() }
|
|
func (c *cthWrapper) Reset() { c.h.Reset() }
|
|
func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
|
|
func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) }
|
|
|
|
func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
|
|
return func() hash.Hash {
|
|
return &cthWrapper{h().(constantTimeHash)}
|
|
}
|
|
}
|
|
|
|
// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
|
|
type tls10MAC struct {
|
|
h hash.Hash
|
|
buf []byte
|
|
}
|
|
|
|
func (s tls10MAC) Size() int {
|
|
return s.h.Size()
|
|
}
|
|
|
|
// MAC is guaranteed to take constant time, as long as
|
|
// len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into
|
|
// the MAC, but is only provided to make the timing profile constant.
|
|
func (s tls10MAC) MAC(seq, header, data, extra []byte) []byte {
|
|
s.h.Reset()
|
|
s.h.Write(seq)
|
|
s.h.Write(header)
|
|
s.h.Write(data)
|
|
res := s.h.Sum(s.buf[:0])
|
|
if extra != nil {
|
|
s.h.Write(extra)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func rsaKA(version uint16) keyAgreement {
|
|
return rsaKeyAgreement{}
|
|
}
|
|
|
|
func ecdheECDSAKA(version uint16) keyAgreement {
|
|
return &ecdheKeyAgreement{
|
|
isRSA: false,
|
|
version: version,
|
|
}
|
|
}
|
|
|
|
func ecdheRSAKA(version uint16) keyAgreement {
|
|
return &ecdheKeyAgreement{
|
|
isRSA: true,
|
|
version: version,
|
|
}
|
|
}
|
|
|
|
// mutualCipherSuite returns a cipherSuite given a list of supported
|
|
// ciphersuites and the id requested by the peer.
|
|
func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
|
|
for _, id := range have {
|
|
if id == want {
|
|
return cipherSuiteByID(id)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func cipherSuiteByID(id uint16) *cipherSuite {
|
|
for _, cipherSuite := range cipherSuites {
|
|
if cipherSuite.id == id {
|
|
return cipherSuite
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 {
|
|
for _, id := range have {
|
|
if id == want {
|
|
return cipherSuiteTLS13ByID(id)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 {
|
|
for _, cipherSuite := range cipherSuitesTLS13 {
|
|
if cipherSuite.id == id {
|
|
return cipherSuite
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// A list of cipher suite IDs that are, or have been, implemented by this
|
|
// package.
|
|
//
|
|
// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
|
const (
|
|
// TLS 1.0 - 1.2 cipher suites.
|
|
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
|
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
|
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
|
TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
|
|
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
|
|
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
|
|
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
|
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
|
|
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
|
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
|
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
|
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
|
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
|
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
|
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
|
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
|
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
|
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca8
|
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca9
|
|
|
|
// TLS 1.3 cipher suites.
|
|
TLS_AES_128_GCM_SHA256 uint16 = 0x1301
|
|
TLS_AES_256_GCM_SHA384 uint16 = 0x1302
|
|
TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
|
|
|
|
// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
|
|
// that the client is doing version fallback. See RFC 7507.
|
|
TLS_FALLBACK_SCSV uint16 = 0x5600
|
|
)
|