mirror of
https://github.com/XTLS/REALITY.git
synced 2026-10-02 11:58:09 +03:00
Sync upstream Go 1.27+; Add "[REALITY] SECTION" comments (#30)
https://github.com/XTLS/REALITY/pull/30#issuecomment-5579024460 https://github.com/XTLS/REALITY/pull/30#issuecomment-5594872257 https://github.com/XTLS/REALITY/pull/38#issuecomment-5752892932
This commit is contained in:
+63
-18
@@ -9,10 +9,10 @@ import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/mldsa"
|
||||
"crypto/rsa"
|
||||
"crypto/subtle"
|
||||
"crypto/x509"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
@@ -189,7 +189,7 @@ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, *echServer
|
||||
} else if len(clientVersions) == 0 {
|
||||
clientVersions = supportedVersionsFromMax(clientHello.vers)
|
||||
}
|
||||
c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
|
||||
c.vers, ok = c.config.mutualVersion(roleServer, c.quic != nil, clientVersions)
|
||||
if !ok {
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
return nil, nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
|
||||
@@ -236,7 +236,7 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||
hs.hello.random = make([]byte, 32)
|
||||
serverRandom := hs.hello.random
|
||||
// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
|
||||
maxVers := c.config.maxSupportedVersion(roleServer)
|
||||
maxVers := c.config.maxSupportedVersion(roleServer, c.quic != nil)
|
||||
if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
|
||||
if c.vers == VersionTLS12 {
|
||||
copy(serverRandom[24:], downgradeCanaryTLS12)
|
||||
@@ -280,6 +280,7 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if hs.clientHello.scts {
|
||||
hs.hello.scts = hs.cert.SignedCertificateTimestamps
|
||||
}
|
||||
@@ -307,6 +308,11 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||
hs.ecSignOk = true
|
||||
case *rsa.PublicKey:
|
||||
hs.rsaSignOk = true
|
||||
case *mldsa.PublicKey:
|
||||
// ML-DSA can only be used with TLS 1.3.
|
||||
c.sendAlert(alertInternalError)
|
||||
return fmt.Errorf("tls: ML-DSA certificates require TLS 1.3, but client negotiated %s",
|
||||
VersionName(c.vers))
|
||||
default:
|
||||
c.sendAlert(alertInternalError)
|
||||
return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
|
||||
@@ -354,7 +360,7 @@ func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, erro
|
||||
if http11fallback {
|
||||
return "", nil
|
||||
}
|
||||
return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
|
||||
return "", fmt.Errorf("tls: client requested unsupported application protocols (%q)", clientProtos)
|
||||
}
|
||||
|
||||
// supportsECDHE returns whether ECDHE key exchanges can be used with this
|
||||
@@ -406,7 +412,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
|
||||
for _, id := range hs.clientHello.cipherSuites {
|
||||
if id == TLS_FALLBACK_SCSV {
|
||||
// The client is doing a fallback connection. See RFC 7507.
|
||||
if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
|
||||
if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer, c.quic != nil) {
|
||||
c.sendAlert(alertInappropriateFallback)
|
||||
return errors.New("tls: client using inappropriate protocol fallback")
|
||||
}
|
||||
@@ -511,8 +517,13 @@ func (hs *serverHandshakeState) checkForResumption() error {
|
||||
if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
|
||||
return nil
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.ClientCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
|
||||
len(sessionState.verifiedChains) == 0 {
|
||||
!anyValidVerifiedChain(sessionState.verifiedChains, opts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -582,6 +593,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
hs.hello.ocspStapling = true
|
||||
}
|
||||
|
||||
if hs.clientHello.serverName != "" {
|
||||
hs.hello.serverNameAck = true
|
||||
}
|
||||
|
||||
hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
|
||||
hs.hello.cipherSuite = hs.suite.id
|
||||
|
||||
@@ -600,6 +615,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
|
||||
certMsg := new(certificateMsg)
|
||||
certMsg.certificates = hs.cert.Certificate
|
||||
// Set localCertificate here, rather than at certificate selection time, so
|
||||
// that it is only populated when a certificate is actually presented to the
|
||||
// peer, and not on resumed connections.
|
||||
c.localCertificate = hs.cert.Certificate
|
||||
if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -619,8 +638,9 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
return err
|
||||
}
|
||||
if skx != nil {
|
||||
if len(skx.key) >= 3 && skx.key[0] == 3 /* named curve */ {
|
||||
c.curveID = CurveID(binary.BigEndian.Uint16(skx.key[1:]))
|
||||
if keyAgreement, ok := keyAgreement.(*ecdheKeyAgreement); ok {
|
||||
c.curveID = keyAgreement.curveID
|
||||
c.peerSigAlg = keyAgreement.signatureAlgorithm
|
||||
}
|
||||
if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil {
|
||||
return err
|
||||
@@ -637,7 +657,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
}
|
||||
if c.vers >= VersionTLS12 {
|
||||
certReq.hasSignatureAlgorithm = true
|
||||
certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms(c.vers)
|
||||
certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms(c.vers, c.vers)
|
||||
}
|
||||
|
||||
// An empty list of certificateAuthorities signals to
|
||||
@@ -759,19 +779,28 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
if err != nil {
|
||||
return c.sendAlert(alertInternalError)
|
||||
}
|
||||
if hs.finishedHash.buffer == nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return errors.New("tls: internal error: did not keep handshake transcript for TLS 1.2")
|
||||
}
|
||||
if err := verifyHandshakeSignature(sigType, pub, sigHash, hs.finishedHash.buffer, certVerify.signature); err != nil {
|
||||
c.sendAlert(alertDecryptError)
|
||||
return errors.New("tls: invalid signature by the client certificate: " + err.Error())
|
||||
}
|
||||
} else {
|
||||
sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
|
||||
if err != nil {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return err
|
||||
}
|
||||
signed := hs.finishedHash.hashForClientCertificate(sigType)
|
||||
if err := verifyLegacyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
|
||||
c.sendAlert(alertDecryptError)
|
||||
return errors.New("tls: invalid signature by the client certificate: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
|
||||
if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
|
||||
c.sendAlert(alertDecryptError)
|
||||
return errors.New("tls: invalid signature by the client certificate: " + err.Error())
|
||||
}
|
||||
c.peerSigAlg = certVerify.signatureAlgorithm
|
||||
|
||||
if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil {
|
||||
return err
|
||||
@@ -943,10 +972,9 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
|
||||
|
||||
chains, err := certs[0].Verify(opts)
|
||||
if err != nil {
|
||||
var errCertificateInvalid x509.CertificateInvalidError
|
||||
if errors.As(err, &x509.UnknownAuthorityError{}) {
|
||||
if _, ok := errors.AsType[x509.UnknownAuthorityError](err); ok {
|
||||
c.sendAlert(alertUnknownCA)
|
||||
} else if errors.As(err, &errCertificateInvalid) && errCertificateInvalid.Reason == x509.Expired {
|
||||
} else if errCertificateInvalid, ok := errors.AsType[x509.CertificateInvalidError](err); ok && errCertificateInvalid.Reason == x509.Expired {
|
||||
c.sendAlert(alertCertificateExpired)
|
||||
} else {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
@@ -966,8 +994,19 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
|
||||
c.scts = certificate.SignedCertificateTimestamps
|
||||
|
||||
if len(certs) > 0 {
|
||||
if fips140tls.Required() && !isCertificateAllowedFIPS(certs[0]) {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
err := errors.New("client's certificate is not allowed in FIPS 140-3 mode")
|
||||
return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
|
||||
}
|
||||
|
||||
switch certs[0].PublicKey.(type) {
|
||||
case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
|
||||
case *mldsa.PublicKey:
|
||||
if c.vers < VersionTLS13 {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: client certificate uses ML-DSA, which requires TLS 1.3")
|
||||
}
|
||||
default:
|
||||
c.sendAlert(alertUnsupportedCertificate)
|
||||
return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
|
||||
@@ -990,6 +1029,10 @@ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg)
|
||||
supportedVersions = supportedVersionsFromMax(clientHello.vers)
|
||||
}
|
||||
|
||||
conn := c.conn
|
||||
if c.quic != nil {
|
||||
conn = c.quic.clientHelloInfoConn
|
||||
}
|
||||
return &ClientHelloInfo{
|
||||
CipherSuites: clientHello.cipherSuites,
|
||||
ServerName: clientHello.serverName,
|
||||
@@ -999,8 +1042,10 @@ func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg)
|
||||
SupportedProtos: clientHello.alpnProtocols,
|
||||
SupportedVersions: supportedVersions,
|
||||
Extensions: clientHello.extensions,
|
||||
Conn: c.conn,
|
||||
Conn: conn,
|
||||
HelloRetryRequest: c.didHRR,
|
||||
config: c.config,
|
||||
isQUIC: c.quic != nil,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user