mirror of
https://github.com/refraction-networking/utls.git
synced 2025-03-31 10:37:36 +03:00
This CL adds a (very opinionated) client-side ECH implementation. In particular, if a user configures a ECHConfigList, by setting the Config.EncryptedClientHelloConfigList, but we determine that none of the configs are appropriate, we will not fallback to plaintext SNI, and will instead return an error. It is then up to the user to decide if they wish to fallback to plaintext themselves (by removing the config list). Additionally if Config.EncryptedClientHelloConfigList is provided, we will not offer TLS support lower than 1.3, since negotiating any other version, while offering ECH, is a hard error anyway. Similarly, if a user wishes to fallback to plaintext SNI by using 1.2, they may do so by removing the config list. With regard to PSK GREASE, we match the boringssl behavior, which does not include PSK identities/binders in the outer hello when doing ECH. If the server rejects ECH, we will return a ECHRejectionError error, which, if provided by the server, will contain a ECHConfigList in the RetryConfigList field containing configs that should be used if the user wishes to retry. It is up to the user to replace their existing Config.EncryptedClientHelloConfigList with the retry config list. Fixes #63369 Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest Change-Id: I9bc373c044064221a647a388ac61624efd6bbdbf Reviewed-on: https://go-review.googlesource.com/c/go/+/578575 Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Auto-Submit: Roland Shoemaker <roland@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
111 lines
4.3 KiB
Go
111 lines
4.3 KiB
Go
// Copyright 2009 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 "strconv"
|
|
|
|
// An AlertError is a TLS alert.
|
|
//
|
|
// When using a QUIC transport, QUICConn methods will return an error
|
|
// which wraps AlertError rather than sending a TLS alert.
|
|
type AlertError uint8
|
|
|
|
func (e AlertError) Error() string {
|
|
return alert(e).String()
|
|
}
|
|
|
|
type alert uint8
|
|
|
|
const (
|
|
// alert level
|
|
alertLevelWarning = 1
|
|
alertLevelError = 2
|
|
)
|
|
|
|
const (
|
|
alertCloseNotify alert = 0
|
|
alertUnexpectedMessage alert = 10
|
|
alertBadRecordMAC alert = 20
|
|
alertDecryptionFailed alert = 21
|
|
alertRecordOverflow alert = 22
|
|
alertDecompressionFailure alert = 30
|
|
alertHandshakeFailure alert = 40
|
|
alertBadCertificate alert = 42
|
|
alertUnsupportedCertificate alert = 43
|
|
alertCertificateRevoked alert = 44
|
|
alertCertificateExpired alert = 45
|
|
alertCertificateUnknown alert = 46
|
|
alertIllegalParameter alert = 47
|
|
alertUnknownCA alert = 48
|
|
alertAccessDenied alert = 49
|
|
alertDecodeError alert = 50
|
|
alertDecryptError alert = 51
|
|
alertExportRestriction alert = 60
|
|
alertProtocolVersion alert = 70
|
|
alertInsufficientSecurity alert = 71
|
|
alertInternalError alert = 80
|
|
alertInappropriateFallback alert = 86
|
|
alertUserCanceled alert = 90
|
|
alertNoRenegotiation alert = 100
|
|
alertMissingExtension alert = 109
|
|
alertUnsupportedExtension alert = 110
|
|
alertCertificateUnobtainable alert = 111
|
|
alertUnrecognizedName alert = 112
|
|
alertBadCertificateStatusResponse alert = 113
|
|
alertBadCertificateHashValue alert = 114
|
|
alertUnknownPSKIdentity alert = 115
|
|
alertCertificateRequired alert = 116
|
|
alertNoApplicationProtocol alert = 120
|
|
alertECHRequired alert = 121
|
|
)
|
|
|
|
var alertText = map[alert]string{
|
|
alertCloseNotify: "close notify",
|
|
alertUnexpectedMessage: "unexpected message",
|
|
alertBadRecordMAC: "bad record MAC",
|
|
alertDecryptionFailed: "decryption failed",
|
|
alertRecordOverflow: "record overflow",
|
|
alertDecompressionFailure: "decompression failure",
|
|
alertHandshakeFailure: "handshake failure",
|
|
alertBadCertificate: "bad certificate",
|
|
alertUnsupportedCertificate: "unsupported certificate",
|
|
alertCertificateRevoked: "revoked certificate",
|
|
alertCertificateExpired: "expired certificate",
|
|
alertCertificateUnknown: "unknown certificate",
|
|
alertIllegalParameter: "illegal parameter",
|
|
alertUnknownCA: "unknown certificate authority",
|
|
alertAccessDenied: "access denied",
|
|
alertDecodeError: "error decoding message",
|
|
alertDecryptError: "error decrypting message",
|
|
alertExportRestriction: "export restriction",
|
|
alertProtocolVersion: "protocol version not supported",
|
|
alertInsufficientSecurity: "insufficient security level",
|
|
alertInternalError: "internal error",
|
|
alertInappropriateFallback: "inappropriate fallback",
|
|
alertUserCanceled: "user canceled",
|
|
alertNoRenegotiation: "no renegotiation",
|
|
alertMissingExtension: "missing extension",
|
|
alertUnsupportedExtension: "unsupported extension",
|
|
alertCertificateUnobtainable: "certificate unobtainable",
|
|
alertUnrecognizedName: "unrecognized name",
|
|
alertBadCertificateStatusResponse: "bad certificate status response",
|
|
alertBadCertificateHashValue: "bad certificate hash value",
|
|
alertUnknownPSKIdentity: "unknown PSK identity",
|
|
alertCertificateRequired: "certificate required",
|
|
alertNoApplicationProtocol: "no application protocol",
|
|
alertECHRequired: "encrypted client hello required",
|
|
}
|
|
|
|
func (e alert) String() string {
|
|
s, ok := alertText[e]
|
|
if ok {
|
|
return "tls: " + s
|
|
}
|
|
return "tls: alert(" + strconv.Itoa(int(e)) + ")"
|
|
}
|
|
|
|
func (e alert) Error() string {
|
|
return e.String()
|
|
}
|