git.prognetwork.ru/x0r/utls@v1.3.3/u_handshake_client.go (about) 1 // Copyright 2022 uTLS 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 5 package tls 6 7 import ( 8 "bytes" 9 "compress/zlib" 10 "errors" 11 "fmt" 12 "io" 13 14 "github.com/andybalholm/brotli" 15 "github.com/klauspost/compress/zstd" 16 ) 17 18 // This function is called by (*clientHandshakeStateTLS13).readServerCertificate() 19 // to retrieve the certificate out of a message read by (*Conn).readHandshake() 20 func (hs *clientHandshakeStateTLS13) utlsReadServerCertificate(msg any) (processedMsg any, err error) { 21 for _, ext := range hs.uconn.Extensions { 22 switch ext.(type) { 23 case *UtlsCompressCertExtension: 24 // Included Compressed Certificate extension 25 if len(hs.uconn.certCompressionAlgs) > 0 { 26 compressedCertMsg, ok := msg.(*utlsCompressedCertificateMsg) 27 if ok { 28 if err = transcriptMsg(compressedCertMsg, hs.transcript); err != nil { 29 return nil, err 30 } 31 msg, err = hs.decompressCert(*compressedCertMsg) 32 if err != nil { 33 return nil, fmt.Errorf("tls: failed to decompress certificate message: %w", err) 34 } else { 35 return msg, nil 36 } 37 } 38 } 39 default: 40 continue 41 } 42 } 43 return nil, nil 44 } 45 46 // called by (*clientHandshakeStateTLS13).utlsReadServerCertificate() when UtlsCompressCertExtension is used 47 func (hs *clientHandshakeStateTLS13) decompressCert(m utlsCompressedCertificateMsg) (*certificateMsgTLS13, error) { 48 var ( 49 decompressed io.Reader 50 compressed = bytes.NewReader(m.compressedCertificateMessage) 51 c = hs.c 52 ) 53 54 // Check to see if the peer responded with an algorithm we advertised. 55 supportedAlg := false 56 for _, alg := range hs.uconn.certCompressionAlgs { 57 if m.algorithm == uint16(alg) { 58 supportedAlg = true 59 } 60 } 61 if !supportedAlg { 62 c.sendAlert(alertBadCertificate) 63 return nil, fmt.Errorf("unadvertised algorithm (%d)", m.algorithm) 64 } 65 66 switch CertCompressionAlgo(m.algorithm) { 67 case CertCompressionBrotli: 68 decompressed = brotli.NewReader(compressed) 69 70 case CertCompressionZlib: 71 rc, err := zlib.NewReader(compressed) 72 if err != nil { 73 c.sendAlert(alertBadCertificate) 74 return nil, fmt.Errorf("failed to open zlib reader: %w", err) 75 } 76 defer rc.Close() 77 decompressed = rc 78 79 case CertCompressionZstd: 80 rc, err := zstd.NewReader(compressed) 81 if err != nil { 82 c.sendAlert(alertBadCertificate) 83 return nil, fmt.Errorf("failed to open zstd reader: %w", err) 84 } 85 defer rc.Close() 86 decompressed = rc 87 88 default: 89 c.sendAlert(alertBadCertificate) 90 return nil, fmt.Errorf("unsupported algorithm (%d)", m.algorithm) 91 } 92 93 rawMsg := make([]byte, m.uncompressedLength+4) // +4 for message type and uint24 length field 94 rawMsg[0] = typeCertificate 95 rawMsg[1] = uint8(m.uncompressedLength >> 16) 96 rawMsg[2] = uint8(m.uncompressedLength >> 8) 97 rawMsg[3] = uint8(m.uncompressedLength) 98 99 n, err := decompressed.Read(rawMsg[4:]) 100 if err != nil { 101 c.sendAlert(alertBadCertificate) 102 return nil, err 103 } 104 if n < len(rawMsg)-4 { 105 // If, after decompression, the specified length does not match the actual length, the party 106 // receiving the invalid message MUST abort the connection with the "bad_certificate" alert. 107 // https://datatracker.ietf.org/doc/html/rfc8879#section-4 108 c.sendAlert(alertBadCertificate) 109 return nil, fmt.Errorf("decompressed len (%d) does not match specified len (%d)", n, m.uncompressedLength) 110 } 111 certMsg := new(certificateMsgTLS13) 112 if !certMsg.unmarshal(rawMsg) { 113 return nil, c.sendAlert(alertUnexpectedMessage) 114 } 115 return certMsg, nil 116 } 117 118 // to be called in (*clientHandshakeStateTLS13).handshake(), 119 // after hs.readServerFinished() and before hs.sendClientCertificate() 120 func (hs *clientHandshakeStateTLS13) serverFinishedReceived() error { 121 if err := hs.sendClientEncryptedExtensions(); err != nil { 122 return err 123 } 124 return nil 125 } 126 127 func (hs *clientHandshakeStateTLS13) sendClientEncryptedExtensions() error { 128 c := hs.c 129 clientEncryptedExtensions := new(utlsClientEncryptedExtensionsMsg) 130 if c.utls.hasApplicationSettings { 131 clientEncryptedExtensions.hasApplicationSettings = true 132 clientEncryptedExtensions.applicationSettings = c.utls.localApplicationSettings 133 if _, err := c.writeHandshakeRecord(clientEncryptedExtensions, hs.transcript); err != nil { 134 return err 135 } 136 } 137 138 return nil 139 } 140 141 func (hs *clientHandshakeStateTLS13) utlsReadServerParameters(encryptedExtensions *encryptedExtensionsMsg) error { 142 hs.c.utls.hasApplicationSettings = encryptedExtensions.utls.hasApplicationSettings 143 hs.c.utls.peerApplicationSettings = encryptedExtensions.utls.applicationSettings 144 145 if hs.c.utls.hasApplicationSettings { 146 if hs.uconn.vers < VersionTLS13 { 147 return errors.New("tls: server sent application settings at invalid version") 148 } 149 if len(hs.uconn.clientProtocol) == 0 { 150 return errors.New("tls: server sent application settings without ALPN") 151 } 152 153 // Check if the ALPN selected by the server exists in the client's list. 154 if alps, ok := hs.uconn.config.ApplicationSettings[hs.serverHello.alpnProtocol]; ok { 155 hs.c.utls.localApplicationSettings = alps 156 } else { 157 // return errors.New("tls: server selected ALPN doesn't match a client ALPS") 158 return nil // ignore if client doesn't have ALPS in use. 159 // TODO: is this a issue or not? 160 } 161 } 162 163 return nil 164 }