+tls13 extensions; +Chrome 70, Firefox 63 parrots

Adds support for following TLS 1.3 extensions:
 - PSKKeyExchangeModes
 - SupportedVersions
 - KeyShare
and uses them to implement newest Chrome and Firefox parrots.

Tests for default Golang uTLS were regenerated because
they previously used TLS-1.2 as max version.
This commit is contained in:
Sergey Frolov 2018-12-07 18:30:34 -07:00 committed by sergeyfrolov
parent 04ef89985b
commit b84d7d5f05
36 changed files with 3149 additions and 335 deletions

View file

@ -9,6 +9,7 @@ import (
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"io"
"math/big"
"sort"
@ -68,6 +69,78 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
},
GetSessionID: sha256.Sum256,
}, nil
case HelloChrome_70:
return ClientHelloSpec{
TLSVersMin: VersionTLS10,
TLSVersMax: VersionTLS13,
CipherSuites: []uint16{
GREASE_PLACEHOLDER,
TLS_AES_128_GCM_SHA256,
TLS_AES_256_GCM_SHA384,
TLS_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
},
CompressionMethods: []byte{
compressionNone,
},
Extensions: []TLSExtension{
&UtlsGREASEExtension{},
&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
&SNIExtension{},
&UtlsExtendedMasterSecretExtension{},
&SessionTicketExtension{},
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
ECDSAWithP256AndSHA256,
PSSWithSHA256,
PKCS1WithSHA256,
ECDSAWithP384AndSHA384,
PSSWithSHA384,
PKCS1WithSHA384,
PSSWithSHA512,
PKCS1WithSHA512,
PKCS1WithSHA1,
}},
&StatusRequestExtension{},
&SCTExtension{},
&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
&FakeChannelIDExtension{},
&SupportedPointsExtension{SupportedPoints: []byte{
pointFormatUncompressed,
}},
&KeyShareExtension{[]KeyShare{
{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
{Group: X25519},
}},
&PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}},
&SupportedVersionsExtension{[]uint16{
GREASE_PLACEHOLDER,
VersionTLS13,
VersionTLS12,
VersionTLS11,
VersionTLS10}},
&SupportedCurvesExtension{[]CurveID{
CurveID(GREASE_PLACEHOLDER),
X25519,
CurveP256,
CurveP384,
}},
&GenericExtension{id: fakeCertCompressionAlgs, data: []byte{02, 00, 02}},
&UtlsGREASEExtension{},
&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
},
}, nil
case HelloFirefox_55, HelloFirefox_56:
return ClientHelloSpec{
TLSVersMax: VersionTLS12,
@ -116,6 +189,77 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
},
GetSessionID: nil,
}, nil
case HelloFirefox_63:
return ClientHelloSpec{
TLSVersMin: VersionTLS10,
TLSVersMax: VersionTLS13,
CipherSuites: []uint16{
TLS_AES_128_GCM_SHA256,
TLS_CHACHA20_POLY1305_SHA256,
TLS_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
},
CompressionMethods: []byte{
compressionNone,
},
Extensions: []TLSExtension{
&SNIExtension{},
&UtlsExtendedMasterSecretExtension{},
&RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient},
&SupportedCurvesExtension{[]CurveID{
X25519,
CurveP256,
CurveP384,
CurveP521,
CurveID(FakeFFDHE2048),
CurveID(FakeFFDHE3072),
}},
&SupportedPointsExtension{SupportedPoints: []byte{
pointFormatUncompressed,
}},
&SessionTicketExtension{},
&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
&StatusRequestExtension{},
&KeyShareExtension{[]KeyShare{
{Group: X25519},
{Group: CurveP256},
}},
&SupportedVersionsExtension{[]uint16{
VersionTLS13,
VersionTLS12,
VersionTLS11,
VersionTLS10}},
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
ECDSAWithP256AndSHA256,
ECDSAWithP384AndSHA384,
ECDSAWithP521AndSHA512,
PSSWithSHA256,
PSSWithSHA384,
PSSWithSHA512,
PKCS1WithSHA256,
PKCS1WithSHA384,
PKCS1WithSHA512,
ECDSAWithSHA1,
PKCS1WithSHA1,
}},
&PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}},
&GenericExtension{id: fakeRecordSizeLimit, data: []byte{0x40, 0x01}},
&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
}}, nil
case HelloIOS_11_1:
return ClientHelloSpec{
TLSVersMax: VersionTLS12,
@ -278,6 +422,7 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
uconn.Extensions = make([]TLSExtension, len(p.Extensions))
copy(uconn.Extensions, p.Extensions)
// reGrease, and point things to each other
for _, e := range uconn.Extensions {
switch ext := e.(type) {
case *SNIExtension:
@ -306,6 +451,36 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
ext.Curves[i] = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group))
}
}
case *KeyShareExtension:
preferredCurveIsSet := false
for i := range ext.KeyShares {
curveID := ext.KeyShares[i].Group
if curveID == GREASE_PLACEHOLDER {
ext.KeyShares[i].Group = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group))
continue
}
if len(ext.KeyShares[i].Data) > 1 {
continue
}
ecdheParams, err := generateECDHEParameters(uconn.config.rand(), curveID)
if err != nil {
return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+
"To mimic it, fill the Data(key) field manually.", curveID)
}
ext.KeyShares[i].Data = ecdheParams.PublicKey()
if !preferredCurveIsSet {
// only do this once for the first non-grease curve
uconn.HandshakeState.State13.EcdheParams = ecdheParams
preferredCurveIsSet = true
}
}
case *SupportedVersionsExtension:
for i := range ext.Versions {
if ext.Versions[i] == GREASE_PLACEHOLDER {
ext.Versions[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_version)
}
}
}
}
return nil