├── LICENSE ├── LICENSE-Go ├── README.md ├── alert.go ├── auth.go ├── cipher_suites.go ├── common.go ├── common_string.go ├── conn.go ├── generate_cert.go ├── go.mod ├── go.sum ├── handshake_client.go ├── handshake_client_tls13.go ├── handshake_messages.go ├── handshake_server.go ├── handshake_server_tls13.go ├── key_agreement.go ├── key_schedule.go ├── prf.go ├── ticket.go └── tls.go /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2022 RPRX. All rights reserved. 2 | 3 | Mozilla Public License Version 2.0 4 | ================================== 5 | 6 | 1. Definitions 7 | -------------- 8 | 9 | 1.1. "Contributor" 10 | means each individual or legal entity that creates, contributes to 11 | the creation of, or owns Covered Software. 12 | 13 | 1.2. "Contributor Version" 14 | means the combination of the Contributions of others (if any) used 15 | by a Contributor and that particular Contributor's Contribution. 16 | 17 | 1.3. "Contribution" 18 | means Covered Software of a particular Contributor. 19 | 20 | 1.4. "Covered Software" 21 | means Source Code Form to which the initial Contributor has attached 22 | the notice in Exhibit A, the Executable Form of such Source Code 23 | Form, and Modifications of such Source Code Form, in each case 24 | including portions thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | (a) that the initial Contributor has attached the notice described 30 | in Exhibit B to the Covered Software; or 31 | 32 | (b) that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the 34 | terms of a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | means any form of the work other than Source Code Form. 38 | 39 | 1.7. "Larger Work" 40 | means a work that combines Covered Software with other material, in 41 | a separate file or files, that is not Covered Software. 42 | 43 | 1.8. "License" 44 | means this document. 45 | 46 | 1.9. "Licensable" 47 | means having the right to grant, to the maximum extent possible, 48 | whether at the time of the initial grant or subsequently, any and 49 | all of the rights conveyed by this License. 50 | 51 | 1.10. "Modifications" 52 | means any of the following: 53 | 54 | (a) any file in Source Code Form that results from an addition to, 55 | deletion from, or modification of the contents of Covered 56 | Software; or 57 | 58 | (b) any new file in Source Code Form that contains any Covered 59 | Software. 60 | 61 | 1.11. "Patent Claims" of a Contributor 62 | means any patent claim(s), including without limitation, method, 63 | process, and apparatus claims, in any patent Licensable by such 64 | Contributor that would be infringed, but for the grant of the 65 | License, by the making, using, selling, offering for sale, having 66 | made, import, or transfer of either its Contributions or its 67 | Contributor Version. 68 | 69 | 1.12. "Secondary License" 70 | means either the GNU General Public License, Version 2.0, the GNU 71 | Lesser General Public License, Version 2.1, the GNU Affero General 72 | Public License, Version 3.0, or any later versions of those 73 | licenses. 74 | 75 | 1.13. "Source Code Form" 76 | means the form of the work preferred for making modifications. 77 | 78 | 1.14. "You" (or "Your") 79 | means an individual or a legal entity exercising rights under this 80 | License. For legal entities, "You" includes any entity that 81 | controls, is controlled by, or is under common control with You. For 82 | purposes of this definition, "control" means (a) the power, direct 83 | or indirect, to cause the direction or management of such entity, 84 | whether by contract or otherwise, or (b) ownership of more than 85 | fifty percent (50%) of the outstanding shares or beneficial 86 | ownership of such entity. 87 | 88 | 2. License Grants and Conditions 89 | -------------------------------- 90 | 91 | 2.1. Grants 92 | 93 | Each Contributor hereby grants You a world-wide, royalty-free, 94 | non-exclusive license: 95 | 96 | (a) under intellectual property rights (other than patent or trademark) 97 | Licensable by such Contributor to use, reproduce, make available, 98 | modify, display, perform, distribute, and otherwise exploit its 99 | Contributions, either on an unmodified basis, with Modifications, or 100 | as part of a Larger Work; and 101 | 102 | (b) under Patent Claims of such Contributor to make, use, sell, offer 103 | for sale, have made, import, and otherwise transfer either its 104 | Contributions or its Contributor Version. 105 | 106 | 2.2. Effective Date 107 | 108 | The licenses granted in Section 2.1 with respect to any Contribution 109 | become effective for each Contribution on the date the Contributor first 110 | distributes such Contribution. 111 | 112 | 2.3. Limitations on Grant Scope 113 | 114 | The licenses granted in this Section 2 are the only rights granted under 115 | this License. No additional rights or licenses will be implied from the 116 | distribution or licensing of Covered Software under this License. 117 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 118 | Contributor: 119 | 120 | (a) for any code that a Contributor has removed from Covered Software; 121 | or 122 | 123 | (b) for infringements caused by: (i) Your and any other third party's 124 | modifications of Covered Software, or (ii) the combination of its 125 | Contributions with other software (except as part of its Contributor 126 | Version); or 127 | 128 | (c) under Patent Claims infringed by Covered Software in the absence of 129 | its Contributions. 130 | 131 | This License does not grant any rights in the trademarks, service marks, 132 | or logos of any Contributor (except as may be necessary to comply with 133 | the notice requirements in Section 3.4). 134 | 135 | 2.4. Subsequent Licenses 136 | 137 | No Contributor makes additional grants as a result of Your choice to 138 | distribute the Covered Software under a subsequent version of this 139 | License (see Section 10.2) or under the terms of a Secondary License (if 140 | permitted under the terms of Section 3.3). 141 | 142 | 2.5. Representation 143 | 144 | Each Contributor represents that the Contributor believes its 145 | Contributions are its original creation(s) or it has sufficient rights 146 | to grant the rights to its Contributions conveyed by this License. 147 | 148 | 2.6. Fair Use 149 | 150 | This License is not intended to limit any rights You have under 151 | applicable copyright doctrines of fair use, fair dealing, or other 152 | equivalents. 153 | 154 | 2.7. Conditions 155 | 156 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 157 | in Section 2.1. 158 | 159 | 3. Responsibilities 160 | ------------------- 161 | 162 | 3.1. Distribution of Source Form 163 | 164 | All distribution of Covered Software in Source Code Form, including any 165 | Modifications that You create or to which You contribute, must be under 166 | the terms of this License. You must inform recipients that the Source 167 | Code Form of the Covered Software is governed by the terms of this 168 | License, and how they can obtain a copy of this License. You may not 169 | attempt to alter or restrict the recipients' rights in the Source Code 170 | Form. 171 | 172 | 3.2. Distribution of Executable Form 173 | 174 | If You distribute Covered Software in Executable Form then: 175 | 176 | (a) such Covered Software must also be made available in Source Code 177 | Form, as described in Section 3.1, and You must inform recipients of 178 | the Executable Form how they can obtain a copy of such Source Code 179 | Form by reasonable means in a timely manner, at a charge no more 180 | than the cost of distribution to the recipient; and 181 | 182 | (b) You may distribute such Executable Form under the terms of this 183 | License, or sublicense it under different terms, provided that the 184 | license for the Executable Form does not attempt to limit or alter 185 | the recipients' rights in the Source Code Form under this License. 186 | 187 | 3.3. Distribution of a Larger Work 188 | 189 | You may create and distribute a Larger Work under terms of Your choice, 190 | provided that You also comply with the requirements of this License for 191 | the Covered Software. If the Larger Work is a combination of Covered 192 | Software with a work governed by one or more Secondary Licenses, and the 193 | Covered Software is not Incompatible With Secondary Licenses, this 194 | License permits You to additionally distribute such Covered Software 195 | under the terms of such Secondary License(s), so that the recipient of 196 | the Larger Work may, at their option, further distribute the Covered 197 | Software under the terms of either this License or such Secondary 198 | License(s). 199 | 200 | 3.4. Notices 201 | 202 | You may not remove or alter the substance of any license notices 203 | (including copyright notices, patent notices, disclaimers of warranty, 204 | or limitations of liability) contained within the Source Code Form of 205 | the Covered Software, except that You may alter any license notices to 206 | the extent required to remedy known factual inaccuracies. 207 | 208 | 3.5. Application of Additional Terms 209 | 210 | You may choose to offer, and to charge a fee for, warranty, support, 211 | indemnity or liability obligations to one or more recipients of Covered 212 | Software. However, You may do so only on Your own behalf, and not on 213 | behalf of any Contributor. You must make it absolutely clear that any 214 | such warranty, support, indemnity, or liability obligation is offered by 215 | You alone, and You hereby agree to indemnify every Contributor for any 216 | liability incurred by such Contributor as a result of warranty, support, 217 | indemnity or liability terms You offer. You may include additional 218 | disclaimers of warranty and limitations of liability specific to any 219 | jurisdiction. 220 | 221 | 4. Inability to Comply Due to Statute or Regulation 222 | --------------------------------------------------- 223 | 224 | If it is impossible for You to comply with any of the terms of this 225 | License with respect to some or all of the Covered Software due to 226 | statute, judicial order, or regulation then You must: (a) comply with 227 | the terms of this License to the maximum extent possible; and (b) 228 | describe the limitations and the code they affect. Such description must 229 | be placed in a text file included with all distributions of the Covered 230 | Software under this License. Except to the extent prohibited by statute 231 | or regulation, such description must be sufficiently detailed for a 232 | recipient of ordinary skill to be able to understand it. 233 | 234 | 5. Termination 235 | -------------- 236 | 237 | 5.1. The rights granted under this License will terminate automatically 238 | if You fail to comply with any of its terms. However, if You become 239 | compliant, then the rights granted under this License from a particular 240 | Contributor are reinstated (a) provisionally, unless and until such 241 | Contributor explicitly and finally terminates Your grants, and (b) on an 242 | ongoing basis, if such Contributor fails to notify You of the 243 | non-compliance by some reasonable means prior to 60 days after You have 244 | come back into compliance. Moreover, Your grants from a particular 245 | Contributor are reinstated on an ongoing basis if such Contributor 246 | notifies You of the non-compliance by some reasonable means, this is the 247 | first time You have received notice of non-compliance with this License 248 | from such Contributor, and You become compliant prior to 30 days after 249 | Your receipt of the notice. 250 | 251 | 5.2. If You initiate litigation against any entity by asserting a patent 252 | infringement claim (excluding declaratory judgment actions, 253 | counter-claims, and cross-claims) alleging that a Contributor Version 254 | directly or indirectly infringes any patent, then the rights granted to 255 | You by any and all Contributors for the Covered Software under Section 256 | 2.1 of this License shall terminate. 257 | 258 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 259 | end user license agreements (excluding distributors and resellers) which 260 | have been validly granted by You or Your distributors under this License 261 | prior to termination shall survive termination. 262 | 263 | ************************************************************************ 264 | * * 265 | * 6. Disclaimer of Warranty * 266 | * ------------------------- * 267 | * * 268 | * Covered Software is provided under this License on an "as is" * 269 | * basis, without warranty of any kind, either expressed, implied, or * 270 | * statutory, including, without limitation, warranties that the * 271 | * Covered Software is free of defects, merchantable, fit for a * 272 | * particular purpose or non-infringing. The entire risk as to the * 273 | * quality and performance of the Covered Software is with You. * 274 | * Should any Covered Software prove defective in any respect, You * 275 | * (not any Contributor) assume the cost of any necessary servicing, * 276 | * repair, or correction. This disclaimer of warranty constitutes an * 277 | * essential part of this License. No use of any Covered Software is * 278 | * authorized under this License except under this disclaimer. * 279 | * * 280 | ************************************************************************ 281 | 282 | ************************************************************************ 283 | * * 284 | * 7. Limitation of Liability * 285 | * -------------------------- * 286 | * * 287 | * Under no circumstances and under no legal theory, whether tort * 288 | * (including negligence), contract, or otherwise, shall any * 289 | * Contributor, or anyone who distributes Covered Software as * 290 | * permitted above, be liable to You for any direct, indirect, * 291 | * special, incidental, or consequential damages of any character * 292 | * including, without limitation, damages for lost profits, loss of * 293 | * goodwill, work stoppage, computer failure or malfunction, or any * 294 | * and all other commercial damages or losses, even if such party * 295 | * shall have been informed of the possibility of such damages. This * 296 | * limitation of liability shall not apply to liability for death or * 297 | * personal injury resulting from such party's negligence to the * 298 | * extent applicable law prohibits such limitation. Some * 299 | * jurisdictions do not allow the exclusion or limitation of * 300 | * incidental or consequential damages, so this exclusion and * 301 | * limitation may not apply to You. * 302 | * * 303 | ************************************************************************ 304 | 305 | 8. Litigation 306 | ------------- 307 | 308 | Any litigation relating to this License may be brought only in the 309 | courts of a jurisdiction where the defendant maintains its principal 310 | place of business and such litigation shall be governed by laws of that 311 | jurisdiction, without reference to its conflict-of-law provisions. 312 | Nothing in this Section shall prevent a party's ability to bring 313 | cross-claims or counter-claims. 314 | 315 | 9. Miscellaneous 316 | ---------------- 317 | 318 | This License represents the complete agreement concerning the subject 319 | matter hereof. If any provision of this License is held to be 320 | unenforceable, such provision shall be reformed only to the extent 321 | necessary to make it enforceable. Any law or regulation which provides 322 | that the language of a contract shall be construed against the drafter 323 | shall not be used to construe this License against a Contributor. 324 | 325 | 10. Versions of the License 326 | --------------------------- 327 | 328 | 10.1. New Versions 329 | 330 | Mozilla Foundation is the license steward. Except as provided in Section 331 | 10.3, no one other than the license steward has the right to modify or 332 | publish new versions of this License. Each version will be given a 333 | distinguishing version number. 334 | 335 | 10.2. Effect of New Versions 336 | 337 | You may distribute the Covered Software under the terms of the version 338 | of the License under which You originally received the Covered Software, 339 | or under the terms of any subsequent version published by the license 340 | steward. 341 | 342 | 10.3. Modified Versions 343 | 344 | If you create software not governed by this License, and you want to 345 | create a new license for such software, you may create and use a 346 | modified version of this License if you rename the license and remove 347 | any references to the name of the license steward (except to note that 348 | such modified license differs from this License). 349 | 350 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 351 | Licenses 352 | 353 | If You choose to distribute Source Code Form that is Incompatible With 354 | Secondary Licenses under the terms of this version of the License, the 355 | notice described in Exhibit B of this License must be attached. 356 | 357 | Exhibit A - Source Code Form License Notice 358 | ------------------------------------------- 359 | 360 | This Source Code Form is subject to the terms of the Mozilla Public 361 | License, v. 2.0. If a copy of the MPL was not distributed with this 362 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 363 | 364 | If it is not possible or desirable to put the notice in a particular 365 | file, then You may include the notice in a location (such as a LICENSE 366 | file in a relevant directory) where a recipient would be likely to look 367 | for such a notice. 368 | 369 | You may add additional accurate notices of copyright ownership. 370 | 371 | Exhibit B - "Incompatible With Secondary Licenses" Notice 372 | --------------------------------------------------------- 373 | 374 | This Source Code Form is "Incompatible With Secondary Licenses", as 375 | defined by the Mozilla Public License, v. 2.0. 376 | -------------------------------------------------------------------------------- /LICENSE-Go: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XTLS 2 | 3 | ## The latest developement of XTLS has moved to [Xray-core v1.7.0](https://github.com/XTLS/Xray-core/releases/tag/v1.7.0) and https://github.com/XTLS/Xray-core/commit/6f61021f7a7337b2997c442495cb8654d145cf8f 4 | 5 | THE FUTURE 6 | 7 | ## Based on go1.19 8 | -------------------------------------------------------------------------------- /alert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import "strconv" 8 | 9 | type alert uint8 10 | 11 | const ( 12 | // alert level 13 | alertLevelWarning = 1 14 | alertLevelError = 2 15 | ) 16 | 17 | const ( 18 | alertCloseNotify alert = 0 19 | alertUnexpectedMessage alert = 10 20 | alertBadRecordMAC alert = 20 21 | alertDecryptionFailed alert = 21 22 | alertRecordOverflow alert = 22 23 | alertDecompressionFailure alert = 30 24 | alertHandshakeFailure alert = 40 25 | alertBadCertificate alert = 42 26 | alertUnsupportedCertificate alert = 43 27 | alertCertificateRevoked alert = 44 28 | alertCertificateExpired alert = 45 29 | alertCertificateUnknown alert = 46 30 | alertIllegalParameter alert = 47 31 | alertUnknownCA alert = 48 32 | alertAccessDenied alert = 49 33 | alertDecodeError alert = 50 34 | alertDecryptError alert = 51 35 | alertExportRestriction alert = 60 36 | alertProtocolVersion alert = 70 37 | alertInsufficientSecurity alert = 71 38 | alertInternalError alert = 80 39 | alertInappropriateFallback alert = 86 40 | alertUserCanceled alert = 90 41 | alertNoRenegotiation alert = 100 42 | alertMissingExtension alert = 109 43 | alertUnsupportedExtension alert = 110 44 | alertCertificateUnobtainable alert = 111 45 | alertUnrecognizedName alert = 112 46 | alertBadCertificateStatusResponse alert = 113 47 | alertBadCertificateHashValue alert = 114 48 | alertUnknownPSKIdentity alert = 115 49 | alertCertificateRequired alert = 116 50 | alertNoApplicationProtocol alert = 120 51 | ) 52 | 53 | var alertText = map[alert]string{ 54 | alertCloseNotify: "close notify", 55 | alertUnexpectedMessage: "unexpected message", 56 | alertBadRecordMAC: "bad record MAC", 57 | alertDecryptionFailed: "decryption failed", 58 | alertRecordOverflow: "record overflow", 59 | alertDecompressionFailure: "decompression failure", 60 | alertHandshakeFailure: "handshake failure", 61 | alertBadCertificate: "bad certificate", 62 | alertUnsupportedCertificate: "unsupported certificate", 63 | alertCertificateRevoked: "revoked certificate", 64 | alertCertificateExpired: "expired certificate", 65 | alertCertificateUnknown: "unknown certificate", 66 | alertIllegalParameter: "illegal parameter", 67 | alertUnknownCA: "unknown certificate authority", 68 | alertAccessDenied: "access denied", 69 | alertDecodeError: "error decoding message", 70 | alertDecryptError: "error decrypting message", 71 | alertExportRestriction: "export restriction", 72 | alertProtocolVersion: "protocol version not supported", 73 | alertInsufficientSecurity: "insufficient security level", 74 | alertInternalError: "internal error", 75 | alertInappropriateFallback: "inappropriate fallback", 76 | alertUserCanceled: "user canceled", 77 | alertNoRenegotiation: "no renegotiation", 78 | alertMissingExtension: "missing extension", 79 | alertUnsupportedExtension: "unsupported extension", 80 | alertCertificateUnobtainable: "certificate unobtainable", 81 | alertUnrecognizedName: "unrecognized name", 82 | alertBadCertificateStatusResponse: "bad certificate status response", 83 | alertBadCertificateHashValue: "bad certificate hash value", 84 | alertUnknownPSKIdentity: "unknown PSK identity", 85 | alertCertificateRequired: "certificate required", 86 | alertNoApplicationProtocol: "no application protocol", 87 | } 88 | 89 | func (e alert) String() string { 90 | s, ok := alertText[e] 91 | if ok { 92 | return "tls: " + s 93 | } 94 | return "tls: alert(" + strconv.Itoa(int(e)) + ")" 95 | } 96 | 97 | func (e alert) Error() string { 98 | return e.String() 99 | } 100 | -------------------------------------------------------------------------------- /auth.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "bytes" 9 | "crypto" 10 | "crypto/ecdsa" 11 | "crypto/ed25519" 12 | "crypto/elliptic" 13 | "crypto/rsa" 14 | "errors" 15 | "fmt" 16 | "hash" 17 | "io" 18 | ) 19 | 20 | // verifyHandshakeSignature verifies a signature against pre-hashed 21 | // (if required) handshake contents. 22 | func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error { 23 | switch sigType { 24 | case signatureECDSA: 25 | pubKey, ok := pubkey.(*ecdsa.PublicKey) 26 | if !ok { 27 | return fmt.Errorf("expected an ECDSA public key, got %T", pubkey) 28 | } 29 | if !ecdsa.VerifyASN1(pubKey, signed, sig) { 30 | return errors.New("ECDSA verification failure") 31 | } 32 | case signatureEd25519: 33 | pubKey, ok := pubkey.(ed25519.PublicKey) 34 | if !ok { 35 | return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey) 36 | } 37 | if !ed25519.Verify(pubKey, signed, sig) { 38 | return errors.New("Ed25519 verification failure") 39 | } 40 | case signaturePKCS1v15: 41 | pubKey, ok := pubkey.(*rsa.PublicKey) 42 | if !ok { 43 | return fmt.Errorf("expected an RSA public key, got %T", pubkey) 44 | } 45 | if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil { 46 | return err 47 | } 48 | case signatureRSAPSS: 49 | pubKey, ok := pubkey.(*rsa.PublicKey) 50 | if !ok { 51 | return fmt.Errorf("expected an RSA public key, got %T", pubkey) 52 | } 53 | signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} 54 | if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil { 55 | return err 56 | } 57 | default: 58 | return errors.New("internal error: unknown signature type") 59 | } 60 | return nil 61 | } 62 | 63 | const ( 64 | serverSignatureContext = "TLS 1.3, server CertificateVerify\x00" 65 | clientSignatureContext = "TLS 1.3, client CertificateVerify\x00" 66 | ) 67 | 68 | var signaturePadding = []byte{ 69 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 70 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 71 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 72 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 73 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 74 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 75 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 76 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 77 | } 78 | 79 | // signedMessage returns the pre-hashed (if necessary) message to be signed by 80 | // certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3. 81 | func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte { 82 | if sigHash == directSigning { 83 | b := &bytes.Buffer{} 84 | b.Write(signaturePadding) 85 | io.WriteString(b, context) 86 | b.Write(transcript.Sum(nil)) 87 | return b.Bytes() 88 | } 89 | h := sigHash.New() 90 | h.Write(signaturePadding) 91 | io.WriteString(h, context) 92 | h.Write(transcript.Sum(nil)) 93 | return h.Sum(nil) 94 | } 95 | 96 | // typeAndHashFromSignatureScheme returns the corresponding signature type and 97 | // crypto.Hash for a given TLS SignatureScheme. 98 | func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) { 99 | switch signatureAlgorithm { 100 | case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: 101 | sigType = signaturePKCS1v15 102 | case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: 103 | sigType = signatureRSAPSS 104 | case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: 105 | sigType = signatureECDSA 106 | case Ed25519: 107 | sigType = signatureEd25519 108 | default: 109 | return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) 110 | } 111 | switch signatureAlgorithm { 112 | case PKCS1WithSHA1, ECDSAWithSHA1: 113 | hash = crypto.SHA1 114 | case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: 115 | hash = crypto.SHA256 116 | case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: 117 | hash = crypto.SHA384 118 | case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: 119 | hash = crypto.SHA512 120 | case Ed25519: 121 | hash = directSigning 122 | default: 123 | return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) 124 | } 125 | return sigType, hash, nil 126 | } 127 | 128 | // legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for 129 | // a given public key used with TLS 1.0 and 1.1, before the introduction of 130 | // signature algorithm negotiation. 131 | func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) { 132 | switch pub.(type) { 133 | case *rsa.PublicKey: 134 | return signaturePKCS1v15, crypto.MD5SHA1, nil 135 | case *ecdsa.PublicKey: 136 | return signatureECDSA, crypto.SHA1, nil 137 | case ed25519.PublicKey: 138 | // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1, 139 | // but it requires holding on to a handshake transcript to do a 140 | // full signature, and not even OpenSSL bothers with the 141 | // complexity, so we can't even test it properly. 142 | return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2") 143 | default: 144 | return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub) 145 | } 146 | } 147 | 148 | var rsaSignatureSchemes = []struct { 149 | scheme SignatureScheme 150 | minModulusBytes int 151 | maxVersion uint16 152 | }{ 153 | // RSA-PSS is used with PSSSaltLengthEqualsHash, and requires 154 | // emLen >= hLen + sLen + 2 155 | {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13}, 156 | {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13}, 157 | {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13}, 158 | // PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires 159 | // emLen >= len(prefix) + hLen + 11 160 | // TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS. 161 | {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12}, 162 | {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12}, 163 | {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12}, 164 | {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12}, 165 | } 166 | 167 | // signatureSchemesForCertificate returns the list of supported SignatureSchemes 168 | // for a given certificate, based on the public key and the protocol version, 169 | // and optionally filtered by its explicit SupportedSignatureAlgorithms. 170 | // 171 | // This function must be kept in sync with supportedSignatureAlgorithms. 172 | func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { 173 | priv, ok := cert.PrivateKey.(crypto.Signer) 174 | if !ok { 175 | return nil 176 | } 177 | 178 | var sigAlgs []SignatureScheme 179 | switch pub := priv.Public().(type) { 180 | case *ecdsa.PublicKey: 181 | if version != VersionTLS13 { 182 | // In TLS 1.2 and earlier, ECDSA algorithms are not 183 | // constrained to a single curve. 184 | sigAlgs = []SignatureScheme{ 185 | ECDSAWithP256AndSHA256, 186 | ECDSAWithP384AndSHA384, 187 | ECDSAWithP521AndSHA512, 188 | ECDSAWithSHA1, 189 | } 190 | break 191 | } 192 | switch pub.Curve { 193 | case elliptic.P256(): 194 | sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} 195 | case elliptic.P384(): 196 | sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} 197 | case elliptic.P521(): 198 | sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} 199 | default: 200 | return nil 201 | } 202 | case *rsa.PublicKey: 203 | size := pub.Size() 204 | sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes)) 205 | for _, candidate := range rsaSignatureSchemes { 206 | if size >= candidate.minModulusBytes && version <= candidate.maxVersion { 207 | sigAlgs = append(sigAlgs, candidate.scheme) 208 | } 209 | } 210 | case ed25519.PublicKey: 211 | sigAlgs = []SignatureScheme{Ed25519} 212 | default: 213 | return nil 214 | } 215 | 216 | if cert.SupportedSignatureAlgorithms != nil { 217 | var filteredSigAlgs []SignatureScheme 218 | for _, sigAlg := range sigAlgs { 219 | if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) { 220 | filteredSigAlgs = append(filteredSigAlgs, sigAlg) 221 | } 222 | } 223 | return filteredSigAlgs 224 | } 225 | return sigAlgs 226 | } 227 | 228 | // selectSignatureScheme picks a SignatureScheme from the peer's preference list 229 | // that works with the selected certificate. It's only called for protocol 230 | // versions that support signature algorithms, so TLS 1.2 and 1.3. 231 | func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) { 232 | supportedAlgs := signatureSchemesForCertificate(vers, c) 233 | if len(supportedAlgs) == 0 { 234 | return 0, unsupportedCertificateError(c) 235 | } 236 | if len(peerAlgs) == 0 && vers == VersionTLS12 { 237 | // For TLS 1.2, if the client didn't send signature_algorithms then we 238 | // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. 239 | peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1} 240 | } 241 | // Pick signature scheme in the peer's preference order, as our 242 | // preference order is not configurable. 243 | for _, preferredAlg := range peerAlgs { 244 | if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { 245 | return preferredAlg, nil 246 | } 247 | } 248 | return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms") 249 | } 250 | 251 | // unsupportedCertificateError returns a helpful error for certificates with 252 | // an unsupported private key. 253 | func unsupportedCertificateError(cert *Certificate) error { 254 | switch cert.PrivateKey.(type) { 255 | case rsa.PrivateKey, ecdsa.PrivateKey: 256 | return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T", 257 | cert.PrivateKey, cert.PrivateKey) 258 | case *ed25519.PrivateKey: 259 | return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey") 260 | } 261 | 262 | signer, ok := cert.PrivateKey.(crypto.Signer) 263 | if !ok { 264 | return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer", 265 | cert.PrivateKey) 266 | } 267 | 268 | switch pub := signer.Public().(type) { 269 | case *ecdsa.PublicKey: 270 | switch pub.Curve { 271 | case elliptic.P256(): 272 | case elliptic.P384(): 273 | case elliptic.P521(): 274 | default: 275 | return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) 276 | } 277 | case *rsa.PublicKey: 278 | return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms") 279 | case ed25519.PublicKey: 280 | default: 281 | return fmt.Errorf("tls: unsupported certificate key (%T)", pub) 282 | } 283 | 284 | if cert.SupportedSignatureAlgorithms != nil { 285 | return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms") 286 | } 287 | 288 | return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) 289 | } 290 | -------------------------------------------------------------------------------- /cipher_suites.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "crypto" 9 | "crypto/aes" 10 | "crypto/cipher" 11 | "crypto/des" 12 | "crypto/hmac" 13 | "crypto/rc4" 14 | "crypto/sha1" 15 | "crypto/sha256" 16 | "fmt" 17 | "hash" 18 | "runtime" 19 | 20 | "golang.org/x/crypto/chacha20poly1305" 21 | "golang.org/x/sys/cpu" 22 | ) 23 | 24 | // CipherSuite is a TLS cipher suite. Note that most functions in this package 25 | // accept and expose cipher suite IDs instead of this type. 26 | type CipherSuite struct { 27 | ID uint16 28 | Name string 29 | 30 | // Supported versions is the list of TLS protocol versions that can 31 | // negotiate this cipher suite. 32 | SupportedVersions []uint16 33 | 34 | // Insecure is true if the cipher suite has known security issues 35 | // due to its primitives, design, or implementation. 36 | Insecure bool 37 | } 38 | 39 | var ( 40 | supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12} 41 | supportedOnlyTLS12 = []uint16{VersionTLS12} 42 | supportedOnlyTLS13 = []uint16{VersionTLS13} 43 | ) 44 | 45 | // CipherSuites returns a list of cipher suites currently implemented by this 46 | // package, excluding those with security issues, which are returned by 47 | // InsecureCipherSuites. 48 | // 49 | // The list is sorted by ID. Note that the default cipher suites selected by 50 | // this package might depend on logic that can't be captured by a static list, 51 | // and might not match those returned by this function. 52 | func CipherSuites() []*CipherSuite { 53 | return []*CipherSuite{ 54 | {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, 55 | {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, 56 | {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, 57 | {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, 58 | 59 | {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false}, 60 | {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false}, 61 | {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false}, 62 | 63 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, 64 | {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, 65 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, 66 | {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, 67 | {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, 68 | {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, 69 | {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, 70 | {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, 71 | {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, 72 | {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, 73 | } 74 | } 75 | 76 | // InsecureCipherSuites returns a list of cipher suites currently implemented by 77 | // this package and which have security issues. 78 | // 79 | // Most applications should not use the cipher suites in this list, and should 80 | // only use those returned by CipherSuites. 81 | func InsecureCipherSuites() []*CipherSuite { 82 | // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See 83 | // cipherSuitesPreferenceOrder for details. 84 | return []*CipherSuite{ 85 | {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, 86 | {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true}, 87 | {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, 88 | {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, 89 | {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, 90 | {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true}, 91 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, 92 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, 93 | } 94 | } 95 | 96 | // CipherSuiteName returns the standard name for the passed cipher suite ID 97 | // (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation 98 | // of the ID value if the cipher suite is not implemented by this package. 99 | func CipherSuiteName(id uint16) string { 100 | for _, c := range CipherSuites() { 101 | if c.ID == id { 102 | return c.Name 103 | } 104 | } 105 | for _, c := range InsecureCipherSuites() { 106 | if c.ID == id { 107 | return c.Name 108 | } 109 | } 110 | return fmt.Sprintf("0x%04X", id) 111 | } 112 | 113 | const ( 114 | // suiteECDHE indicates that the cipher suite involves elliptic curve 115 | // Diffie-Hellman. This means that it should only be selected when the 116 | // client indicates that it supports ECC with a curve and point format 117 | // that we're happy with. 118 | suiteECDHE = 1 << iota 119 | // suiteECSign indicates that the cipher suite involves an ECDSA or 120 | // EdDSA signature and therefore may only be selected when the server's 121 | // certificate is ECDSA or EdDSA. If this is not set then the cipher suite 122 | // is RSA based. 123 | suiteECSign 124 | // suiteTLS12 indicates that the cipher suite should only be advertised 125 | // and accepted when using TLS 1.2. 126 | suiteTLS12 127 | // suiteSHA384 indicates that the cipher suite uses SHA384 as the 128 | // handshake hash. 129 | suiteSHA384 130 | ) 131 | 132 | // A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange 133 | // mechanism, as well as the cipher+MAC pair or the AEAD. 134 | type cipherSuite struct { 135 | id uint16 136 | // the lengths, in bytes, of the key material needed for each component. 137 | keyLen int 138 | macLen int 139 | ivLen int 140 | ka func(version uint16) keyAgreement 141 | // flags is a bitmask of the suite* values, above. 142 | flags int 143 | cipher func(key, iv []byte, isRead bool) any 144 | mac func(key []byte) hash.Hash 145 | aead func(key, fixedNonce []byte) aead 146 | } 147 | 148 | var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter. 149 | {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, 150 | {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, 151 | {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, 152 | {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM}, 153 | {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, 154 | {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, 155 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil}, 156 | {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, 157 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil}, 158 | {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, 159 | {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, 160 | {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, 161 | {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, 162 | {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, 163 | {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, 164 | {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, 165 | {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, 166 | {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, 167 | {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, 168 | {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil}, 169 | {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil}, 170 | {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil}, 171 | } 172 | 173 | // selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which 174 | // is also in supportedIDs and passes the ok filter. 175 | func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite { 176 | for _, id := range ids { 177 | candidate := cipherSuiteByID(id) 178 | if candidate == nil || !ok(candidate) { 179 | continue 180 | } 181 | 182 | for _, suppID := range supportedIDs { 183 | if id == suppID { 184 | return candidate 185 | } 186 | } 187 | } 188 | return nil 189 | } 190 | 191 | // A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash 192 | // algorithm to be used with HKDF. See RFC 8446, Appendix B.4. 193 | type cipherSuiteTLS13 struct { 194 | id uint16 195 | keyLen int 196 | aead func(key, fixedNonce []byte) aead 197 | hash crypto.Hash 198 | } 199 | 200 | var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map. 201 | {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256}, 202 | {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256}, 203 | {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384}, 204 | } 205 | 206 | // cipherSuitesPreferenceOrder is the order in which we'll select (on the 207 | // server) or advertise (on the client) TLS 1.0–1.2 cipher suites. 208 | // 209 | // Cipher suites are filtered but not reordered based on the application and 210 | // peer's preferences, meaning we'll never select a suite lower in this list if 211 | // any higher one is available. This makes it more defensible to keep weaker 212 | // cipher suites enabled, especially on the server side where we get the last 213 | // word, since there are no known downgrade attacks on cipher suites selection. 214 | // 215 | // The list is sorted by applying the following priority rules, stopping at the 216 | // first (most important) applicable one: 217 | // 218 | // - Anything else comes before RC4 219 | // 220 | // RC4 has practically exploitable biases. See https://www.rc4nomore.com. 221 | // 222 | // - Anything else comes before CBC_SHA256 223 | // 224 | // SHA-256 variants of the CBC ciphersuites don't implement any Lucky13 225 | // countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and 226 | // https://www.imperialviolet.org/2013/02/04/luckythirteen.html. 227 | // 228 | // - Anything else comes before 3DES 229 | // 230 | // 3DES has 64-bit blocks, which makes it fundamentally susceptible to 231 | // birthday attacks. See https://sweet32.info. 232 | // 233 | // - ECDHE comes before anything else 234 | // 235 | // Once we got the broken stuff out of the way, the most important 236 | // property a cipher suite can have is forward secrecy. We don't 237 | // implement FFDHE, so that means ECDHE. 238 | // 239 | // - AEADs come before CBC ciphers 240 | // 241 | // Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites 242 | // are fundamentally fragile, and suffered from an endless sequence of 243 | // padding oracle attacks. See https://eprint.iacr.org/2015/1129, 244 | // https://www.imperialviolet.org/2014/12/08/poodleagain.html, and 245 | // https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/. 246 | // 247 | // - AES comes before ChaCha20 248 | // 249 | // When AES hardware is available, AES-128-GCM and AES-256-GCM are faster 250 | // than ChaCha20Poly1305. 251 | // 252 | // When AES hardware is not available, AES-128-GCM is one or more of: much 253 | // slower, way more complex, and less safe (because not constant time) 254 | // than ChaCha20Poly1305. 255 | // 256 | // We use this list if we think both peers have AES hardware, and 257 | // cipherSuitesPreferenceOrderNoAES otherwise. 258 | // 259 | // - AES-128 comes before AES-256 260 | // 261 | // The only potential advantages of AES-256 are better multi-target 262 | // margins, and hypothetical post-quantum properties. Neither apply to 263 | // TLS, and AES-256 is slower due to its four extra rounds (which don't 264 | // contribute to the advantages above). 265 | // 266 | // - ECDSA comes before RSA 267 | // 268 | // The relative order of ECDSA and RSA cipher suites doesn't matter, 269 | // as they depend on the certificate. Pick one to get a stable order. 270 | var cipherSuitesPreferenceOrder = []uint16{ 271 | // AEADs w/ ECDHE 272 | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 273 | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 274 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 275 | 276 | // CBC w/ ECDHE 277 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 278 | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 279 | 280 | // AEADs w/o ECDHE 281 | TLS_RSA_WITH_AES_128_GCM_SHA256, 282 | TLS_RSA_WITH_AES_256_GCM_SHA384, 283 | 284 | // CBC w/o ECDHE 285 | TLS_RSA_WITH_AES_128_CBC_SHA, 286 | TLS_RSA_WITH_AES_256_CBC_SHA, 287 | 288 | // 3DES 289 | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 290 | TLS_RSA_WITH_3DES_EDE_CBC_SHA, 291 | 292 | // CBC_SHA256 293 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 294 | TLS_RSA_WITH_AES_128_CBC_SHA256, 295 | 296 | // RC4 297 | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, 298 | TLS_RSA_WITH_RC4_128_SHA, 299 | } 300 | 301 | var cipherSuitesPreferenceOrderNoAES = []uint16{ 302 | // ChaCha20Poly1305 303 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 304 | 305 | // AES-GCM w/ ECDHE 306 | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 307 | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 308 | 309 | // The rest of cipherSuitesPreferenceOrder. 310 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 311 | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 312 | TLS_RSA_WITH_AES_128_GCM_SHA256, 313 | TLS_RSA_WITH_AES_256_GCM_SHA384, 314 | TLS_RSA_WITH_AES_128_CBC_SHA, 315 | TLS_RSA_WITH_AES_256_CBC_SHA, 316 | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 317 | TLS_RSA_WITH_3DES_EDE_CBC_SHA, 318 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 319 | TLS_RSA_WITH_AES_128_CBC_SHA256, 320 | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, 321 | TLS_RSA_WITH_RC4_128_SHA, 322 | } 323 | 324 | // disabledCipherSuites are not used unless explicitly listed in 325 | // Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder. 326 | var disabledCipherSuites = []uint16{ 327 | // CBC_SHA256 328 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 329 | TLS_RSA_WITH_AES_128_CBC_SHA256, 330 | 331 | // RC4 332 | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, 333 | TLS_RSA_WITH_RC4_128_SHA, 334 | } 335 | 336 | var ( 337 | defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites) 338 | defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen] 339 | ) 340 | 341 | // defaultCipherSuitesTLS13 is also the preference order, since there are no 342 | // disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as 343 | // cipherSuitesPreferenceOrder applies. 344 | var defaultCipherSuitesTLS13 = []uint16{ 345 | TLS_AES_128_GCM_SHA256, 346 | TLS_AES_256_GCM_SHA384, 347 | TLS_CHACHA20_POLY1305_SHA256, 348 | } 349 | 350 | var defaultCipherSuitesTLS13NoAES = []uint16{ 351 | TLS_CHACHA20_POLY1305_SHA256, 352 | TLS_AES_128_GCM_SHA256, 353 | TLS_AES_256_GCM_SHA384, 354 | } 355 | 356 | var ( 357 | hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ 358 | hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL 359 | // Keep in sync with crypto/aes/cipher_s390x.go. 360 | hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && 361 | (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) 362 | 363 | hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 || 364 | runtime.GOARCH == "arm64" && hasGCMAsmARM64 || 365 | runtime.GOARCH == "s390x" && hasGCMAsmS390X 366 | ) 367 | 368 | var aesgcmCiphers = map[uint16]bool{ 369 | // TLS 1.2 370 | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true, 371 | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true, 372 | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true, 373 | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true, 374 | // TLS 1.3 375 | TLS_AES_128_GCM_SHA256: true, 376 | TLS_AES_256_GCM_SHA384: true, 377 | } 378 | 379 | var nonAESGCMAEADCiphers = map[uint16]bool{ 380 | // TLS 1.2 381 | TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true, 382 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true, 383 | // TLS 1.3 384 | TLS_CHACHA20_POLY1305_SHA256: true, 385 | } 386 | 387 | // aesgcmPreferred returns whether the first known cipher in the preference list 388 | // is an AES-GCM cipher, implying the peer has hardware support for it. 389 | func aesgcmPreferred(ciphers []uint16) bool { 390 | for _, cID := range ciphers { 391 | if c := cipherSuiteByID(cID); c != nil { 392 | return aesgcmCiphers[cID] 393 | } 394 | if c := cipherSuiteTLS13ByID(cID); c != nil { 395 | return aesgcmCiphers[cID] 396 | } 397 | } 398 | return false 399 | } 400 | 401 | func cipherRC4(key, iv []byte, isRead bool) any { 402 | cipher, _ := rc4.NewCipher(key) 403 | return cipher 404 | } 405 | 406 | func cipher3DES(key, iv []byte, isRead bool) any { 407 | block, _ := des.NewTripleDESCipher(key) 408 | if isRead { 409 | return cipher.NewCBCDecrypter(block, iv) 410 | } 411 | return cipher.NewCBCEncrypter(block, iv) 412 | } 413 | 414 | func cipherAES(key, iv []byte, isRead bool) any { 415 | block, _ := aes.NewCipher(key) 416 | if isRead { 417 | return cipher.NewCBCDecrypter(block, iv) 418 | } 419 | return cipher.NewCBCEncrypter(block, iv) 420 | } 421 | 422 | // macSHA1 returns a SHA-1 based constant time MAC. 423 | func macSHA1(key []byte) hash.Hash { 424 | return hmac.New(newConstantTimeHash(sha1.New), key) 425 | } 426 | 427 | // macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and 428 | // is currently only used in disabled-by-default cipher suites. 429 | func macSHA256(key []byte) hash.Hash { 430 | return hmac.New(sha256.New, key) 431 | } 432 | 433 | type aead interface { 434 | cipher.AEAD 435 | 436 | // explicitNonceLen returns the number of bytes of explicit nonce 437 | // included in each record. This is eight for older AEADs and 438 | // zero for modern ones. 439 | explicitNonceLen() int 440 | } 441 | 442 | const ( 443 | aeadNonceLength = 12 444 | noncePrefixLength = 4 445 | ) 446 | 447 | // prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to 448 | // each call. 449 | type prefixNonceAEAD struct { 450 | // nonce contains the fixed part of the nonce in the first four bytes. 451 | nonce [aeadNonceLength]byte 452 | aead cipher.AEAD 453 | } 454 | 455 | func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength } 456 | func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() } 457 | func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() } 458 | 459 | func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { 460 | copy(f.nonce[4:], nonce) 461 | return f.aead.Seal(out, f.nonce[:], plaintext, additionalData) 462 | } 463 | 464 | func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { 465 | copy(f.nonce[4:], nonce) 466 | return f.aead.Open(out, f.nonce[:], ciphertext, additionalData) 467 | } 468 | 469 | // xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce 470 | // before each call. 471 | type xorNonceAEAD struct { 472 | nonceMask [aeadNonceLength]byte 473 | aead cipher.AEAD 474 | } 475 | 476 | func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number 477 | func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() } 478 | func (f *xorNonceAEAD) explicitNonceLen() int { return 0 } 479 | 480 | func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { 481 | for i, b := range nonce { 482 | f.nonceMask[4+i] ^= b 483 | } 484 | result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData) 485 | for i, b := range nonce { 486 | f.nonceMask[4+i] ^= b 487 | } 488 | 489 | return result 490 | } 491 | 492 | func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { 493 | for i, b := range nonce { 494 | f.nonceMask[4+i] ^= b 495 | } 496 | result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData) 497 | for i, b := range nonce { 498 | f.nonceMask[4+i] ^= b 499 | } 500 | 501 | return result, err 502 | } 503 | 504 | func aeadAESGCM(key, noncePrefix []byte) aead { 505 | if len(noncePrefix) != noncePrefixLength { 506 | panic("tls: internal error: wrong nonce length") 507 | } 508 | aes, err := aes.NewCipher(key) 509 | if err != nil { 510 | panic(err) 511 | } 512 | aead, err := cipher.NewGCM(aes) 513 | if err != nil { 514 | panic(err) 515 | } 516 | 517 | ret := &prefixNonceAEAD{aead: aead} 518 | copy(ret.nonce[:], noncePrefix) 519 | return ret 520 | } 521 | 522 | func aeadAESGCMTLS13(key, nonceMask []byte) aead { 523 | if len(nonceMask) != aeadNonceLength { 524 | panic("tls: internal error: wrong nonce length") 525 | } 526 | aes, err := aes.NewCipher(key) 527 | if err != nil { 528 | panic(err) 529 | } 530 | aead, err := cipher.NewGCM(aes) 531 | if err != nil { 532 | panic(err) 533 | } 534 | 535 | ret := &xorNonceAEAD{aead: aead} 536 | copy(ret.nonceMask[:], nonceMask) 537 | return ret 538 | } 539 | 540 | func aeadChaCha20Poly1305(key, nonceMask []byte) aead { 541 | if len(nonceMask) != aeadNonceLength { 542 | panic("tls: internal error: wrong nonce length") 543 | } 544 | aead, err := chacha20poly1305.New(key) 545 | if err != nil { 546 | panic(err) 547 | } 548 | 549 | ret := &xorNonceAEAD{aead: aead} 550 | copy(ret.nonceMask[:], nonceMask) 551 | return ret 552 | } 553 | 554 | type constantTimeHash interface { 555 | hash.Hash 556 | ConstantTimeSum(b []byte) []byte 557 | } 558 | 559 | // cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces 560 | // with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC. 561 | type cthWrapper struct { 562 | h constantTimeHash 563 | } 564 | 565 | func (c *cthWrapper) Size() int { return c.h.Size() } 566 | func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() } 567 | func (c *cthWrapper) Reset() { c.h.Reset() } 568 | func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) } 569 | func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) } 570 | 571 | func newConstantTimeHash(h func() hash.Hash) func() hash.Hash { 572 | return func() hash.Hash { 573 | return &cthWrapper{h().(constantTimeHash)} 574 | } 575 | } 576 | 577 | // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3. 578 | func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte { 579 | h.Reset() 580 | h.Write(seq) 581 | h.Write(header) 582 | h.Write(data) 583 | res := h.Sum(out) 584 | if extra != nil { 585 | h.Write(extra) 586 | } 587 | return res 588 | } 589 | 590 | func rsaKA(version uint16) keyAgreement { 591 | return rsaKeyAgreement{} 592 | } 593 | 594 | func ecdheECDSAKA(version uint16) keyAgreement { 595 | return &ecdheKeyAgreement{ 596 | isRSA: false, 597 | version: version, 598 | } 599 | } 600 | 601 | func ecdheRSAKA(version uint16) keyAgreement { 602 | return &ecdheKeyAgreement{ 603 | isRSA: true, 604 | version: version, 605 | } 606 | } 607 | 608 | // mutualCipherSuite returns a cipherSuite given a list of supported 609 | // ciphersuites and the id requested by the peer. 610 | func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { 611 | for _, id := range have { 612 | if id == want { 613 | return cipherSuiteByID(id) 614 | } 615 | } 616 | return nil 617 | } 618 | 619 | func cipherSuiteByID(id uint16) *cipherSuite { 620 | for _, cipherSuite := range cipherSuites { 621 | if cipherSuite.id == id { 622 | return cipherSuite 623 | } 624 | } 625 | return nil 626 | } 627 | 628 | func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 { 629 | for _, id := range have { 630 | if id == want { 631 | return cipherSuiteTLS13ByID(id) 632 | } 633 | } 634 | return nil 635 | } 636 | 637 | func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 { 638 | for _, cipherSuite := range cipherSuitesTLS13 { 639 | if cipherSuite.id == id { 640 | return cipherSuite 641 | } 642 | } 643 | return nil 644 | } 645 | 646 | // A list of cipher suite IDs that are, or have been, implemented by this 647 | // package. 648 | // 649 | // See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml 650 | const ( 651 | // TLS 1.0 - 1.2 cipher suites. 652 | TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 653 | TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a 654 | TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f 655 | TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 656 | TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c 657 | TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c 658 | TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d 659 | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 660 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 661 | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a 662 | TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 663 | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 664 | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 665 | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 666 | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 667 | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 668 | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f 669 | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b 670 | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 671 | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c 672 | TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8 673 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9 674 | 675 | // TLS 1.3 cipher suites. 676 | TLS_AES_128_GCM_SHA256 uint16 = 0x1301 677 | TLS_AES_256_GCM_SHA384 uint16 = 0x1302 678 | TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303 679 | 680 | // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator 681 | // that the client is doing version fallback. See RFC 7507. 682 | TLS_FALLBACK_SCSV uint16 = 0x5600 683 | 684 | // Legacy names for the corresponding cipher suites with the correct _SHA256 685 | // suffix, retained for backward compatibility. 686 | TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 687 | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 688 | ) 689 | -------------------------------------------------------------------------------- /common_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go"; DO NOT EDIT. 2 | 3 | package xtls 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[PKCS1WithSHA256-1025] 12 | _ = x[PKCS1WithSHA384-1281] 13 | _ = x[PKCS1WithSHA512-1537] 14 | _ = x[PSSWithSHA256-2052] 15 | _ = x[PSSWithSHA384-2053] 16 | _ = x[PSSWithSHA512-2054] 17 | _ = x[ECDSAWithP256AndSHA256-1027] 18 | _ = x[ECDSAWithP384AndSHA384-1283] 19 | _ = x[ECDSAWithP521AndSHA512-1539] 20 | _ = x[Ed25519-2055] 21 | _ = x[PKCS1WithSHA1-513] 22 | _ = x[ECDSAWithSHA1-515] 23 | } 24 | 25 | const ( 26 | _SignatureScheme_name_0 = "PKCS1WithSHA1" 27 | _SignatureScheme_name_1 = "ECDSAWithSHA1" 28 | _SignatureScheme_name_2 = "PKCS1WithSHA256" 29 | _SignatureScheme_name_3 = "ECDSAWithP256AndSHA256" 30 | _SignatureScheme_name_4 = "PKCS1WithSHA384" 31 | _SignatureScheme_name_5 = "ECDSAWithP384AndSHA384" 32 | _SignatureScheme_name_6 = "PKCS1WithSHA512" 33 | _SignatureScheme_name_7 = "ECDSAWithP521AndSHA512" 34 | _SignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519" 35 | ) 36 | 37 | var ( 38 | _SignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46} 39 | ) 40 | 41 | func (i SignatureScheme) String() string { 42 | switch { 43 | case i == 513: 44 | return _SignatureScheme_name_0 45 | case i == 515: 46 | return _SignatureScheme_name_1 47 | case i == 1025: 48 | return _SignatureScheme_name_2 49 | case i == 1027: 50 | return _SignatureScheme_name_3 51 | case i == 1281: 52 | return _SignatureScheme_name_4 53 | case i == 1283: 54 | return _SignatureScheme_name_5 55 | case i == 1537: 56 | return _SignatureScheme_name_6 57 | case i == 1539: 58 | return _SignatureScheme_name_7 59 | case 2052 <= i && i <= 2055: 60 | i -= 2052 61 | return _SignatureScheme_name_8[_SignatureScheme_index_8[i]:_SignatureScheme_index_8[i+1]] 62 | default: 63 | return "SignatureScheme(" + strconv.FormatInt(int64(i), 10) + ")" 64 | } 65 | } 66 | func _() { 67 | // An "invalid array index" compiler error signifies that the constant values have changed. 68 | // Re-run the stringer command to generate them again. 69 | var x [1]struct{} 70 | _ = x[CurveP256-23] 71 | _ = x[CurveP384-24] 72 | _ = x[CurveP521-25] 73 | _ = x[X25519-29] 74 | } 75 | 76 | const ( 77 | _CurveID_name_0 = "CurveP256CurveP384CurveP521" 78 | _CurveID_name_1 = "X25519" 79 | ) 80 | 81 | var ( 82 | _CurveID_index_0 = [...]uint8{0, 9, 18, 27} 83 | ) 84 | 85 | func (i CurveID) String() string { 86 | switch { 87 | case 23 <= i && i <= 25: 88 | i -= 23 89 | return _CurveID_name_0[_CurveID_index_0[i]:_CurveID_index_0[i+1]] 90 | case i == 29: 91 | return _CurveID_name_1 92 | default: 93 | return "CurveID(" + strconv.FormatInt(int64(i), 10) + ")" 94 | } 95 | } 96 | func _() { 97 | // An "invalid array index" compiler error signifies that the constant values have changed. 98 | // Re-run the stringer command to generate them again. 99 | var x [1]struct{} 100 | _ = x[NoClientCert-0] 101 | _ = x[RequestClientCert-1] 102 | _ = x[RequireAnyClientCert-2] 103 | _ = x[VerifyClientCertIfGiven-3] 104 | _ = x[RequireAndVerifyClientCert-4] 105 | } 106 | 107 | const _ClientAuthType_name = "NoClientCertRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert" 108 | 109 | var _ClientAuthType_index = [...]uint8{0, 12, 29, 49, 72, 98} 110 | 111 | func (i ClientAuthType) String() string { 112 | if i < 0 || i >= ClientAuthType(len(_ClientAuthType_index)-1) { 113 | return "ClientAuthType(" + strconv.FormatInt(int64(i), 10) + ")" 114 | } 115 | return _ClientAuthType_name[_ClientAuthType_index[i]:_ClientAuthType_index[i+1]] 116 | } 117 | -------------------------------------------------------------------------------- /generate_cert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go 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-Go file. 4 | 5 | //go:build ignore 6 | 7 | // Generate a self-signed X.509 certificate for a TLS server. Outputs to 8 | // 'cert.pem' and 'key.pem' and will overwrite existing files. 9 | 10 | package main 11 | 12 | import ( 13 | "crypto/ecdsa" 14 | "crypto/ed25519" 15 | "crypto/elliptic" 16 | "crypto/rand" 17 | "crypto/rsa" 18 | "crypto/x509" 19 | "crypto/x509/pkix" 20 | "encoding/pem" 21 | "flag" 22 | "log" 23 | "math/big" 24 | "net" 25 | "os" 26 | "strings" 27 | "time" 28 | ) 29 | 30 | var ( 31 | host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") 32 | validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") 33 | validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") 34 | isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") 35 | rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") 36 | ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521") 37 | ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key") 38 | ) 39 | 40 | func publicKey(priv any) any { 41 | switch k := priv.(type) { 42 | case *rsa.PrivateKey: 43 | return &k.PublicKey 44 | case *ecdsa.PrivateKey: 45 | return &k.PublicKey 46 | case ed25519.PrivateKey: 47 | return k.Public().(ed25519.PublicKey) 48 | default: 49 | return nil 50 | } 51 | } 52 | 53 | func main() { 54 | flag.Parse() 55 | 56 | if len(*host) == 0 { 57 | log.Fatalf("Missing required --host parameter") 58 | } 59 | 60 | var priv any 61 | var err error 62 | switch *ecdsaCurve { 63 | case "": 64 | if *ed25519Key { 65 | _, priv, err = ed25519.GenerateKey(rand.Reader) 66 | } else { 67 | priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) 68 | } 69 | case "P224": 70 | priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) 71 | case "P256": 72 | priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 73 | case "P384": 74 | priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 75 | case "P521": 76 | priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) 77 | default: 78 | log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve) 79 | } 80 | if err != nil { 81 | log.Fatalf("Failed to generate private key: %v", err) 82 | } 83 | 84 | // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature 85 | // KeyUsage bits set in the x509.Certificate template 86 | keyUsage := x509.KeyUsageDigitalSignature 87 | // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In 88 | // the context of TLS this KeyUsage is particular to RSA key exchange and 89 | // authentication. 90 | if _, isRSA := priv.(*rsa.PrivateKey); isRSA { 91 | keyUsage |= x509.KeyUsageKeyEncipherment 92 | } 93 | 94 | var notBefore time.Time 95 | if len(*validFrom) == 0 { 96 | notBefore = time.Now() 97 | } else { 98 | notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) 99 | if err != nil { 100 | log.Fatalf("Failed to parse creation date: %v", err) 101 | } 102 | } 103 | 104 | notAfter := notBefore.Add(*validFor) 105 | 106 | serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 107 | serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 108 | if err != nil { 109 | log.Fatalf("Failed to generate serial number: %v", err) 110 | } 111 | 112 | template := x509.Certificate{ 113 | SerialNumber: serialNumber, 114 | Subject: pkix.Name{ 115 | Organization: []string{"Acme Co"}, 116 | }, 117 | NotBefore: notBefore, 118 | NotAfter: notAfter, 119 | 120 | KeyUsage: keyUsage, 121 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 122 | BasicConstraintsValid: true, 123 | } 124 | 125 | hosts := strings.Split(*host, ",") 126 | for _, h := range hosts { 127 | if ip := net.ParseIP(h); ip != nil { 128 | template.IPAddresses = append(template.IPAddresses, ip) 129 | } else { 130 | template.DNSNames = append(template.DNSNames, h) 131 | } 132 | } 133 | 134 | if *isCA { 135 | template.IsCA = true 136 | template.KeyUsage |= x509.KeyUsageCertSign 137 | } 138 | 139 | derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) 140 | if err != nil { 141 | log.Fatalf("Failed to create certificate: %v", err) 142 | } 143 | 144 | certOut, err := os.Create("cert.pem") 145 | if err != nil { 146 | log.Fatalf("Failed to open cert.pem for writing: %v", err) 147 | } 148 | if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { 149 | log.Fatalf("Failed to write data to cert.pem: %v", err) 150 | } 151 | if err := certOut.Close(); err != nil { 152 | log.Fatalf("Error closing cert.pem: %v", err) 153 | } 154 | log.Print("wrote cert.pem\n") 155 | 156 | keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 157 | if err != nil { 158 | log.Fatalf("Failed to open key.pem for writing: %v", err) 159 | } 160 | privBytes, err := x509.MarshalPKCS8PrivateKey(priv) 161 | if err != nil { 162 | log.Fatalf("Unable to marshal private key: %v", err) 163 | } 164 | if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { 165 | log.Fatalf("Failed to write data to key.pem: %v", err) 166 | } 167 | if err := keyOut.Close(); err != nil { 168 | log.Fatalf("Error closing key.pem: %v", err) 169 | } 170 | log.Print("wrote key.pem\n") 171 | } 172 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/xtls/go 2 | 3 | go 1.19 4 | 5 | require ( 6 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 7 | golang.org/x/sys v0.0.0-20220913175220-63ea55921009 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= 2 | golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 3 | golang.org/x/sys v0.0.0-20220913175220-63ea55921009 h1:PuvuRMeLWqsf/ZdT1UUZz0syhioyv1mzuFZsXs4fvhw= 4 | golang.org/x/sys v0.0.0-20220913175220-63ea55921009/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 5 | -------------------------------------------------------------------------------- /handshake_client_tls13.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "bytes" 9 | "context" 10 | "crypto" 11 | "crypto/hmac" 12 | "crypto/rsa" 13 | "errors" 14 | "hash" 15 | "sync/atomic" 16 | "time" 17 | ) 18 | 19 | type clientHandshakeStateTLS13 struct { 20 | c *Conn 21 | ctx context.Context 22 | serverHello *serverHelloMsg 23 | hello *clientHelloMsg 24 | ecdheParams ecdheParameters 25 | 26 | session *ClientSessionState 27 | earlySecret []byte 28 | binderKey []byte 29 | 30 | certReq *certificateRequestMsgTLS13 31 | usingPSK bool 32 | sentDummyCCS bool 33 | suite *cipherSuiteTLS13 34 | transcript hash.Hash 35 | masterSecret []byte 36 | trafficSecret []byte // client_application_traffic_secret_0 37 | } 38 | 39 | // handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and, 40 | // optionally, hs.session, hs.earlySecret and hs.binderKey to be set. 41 | func (hs *clientHandshakeStateTLS13) handshake() error { 42 | c := hs.c 43 | 44 | // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, 45 | // sections 4.1.2 and 4.1.3. 46 | if c.handshakes > 0 { 47 | c.sendAlert(alertProtocolVersion) 48 | return errors.New("tls: server selected TLS 1.3 in a renegotiation") 49 | } 50 | 51 | // Consistency check on the presence of a keyShare and its parameters. 52 | if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 { 53 | return c.sendAlert(alertInternalError) 54 | } 55 | 56 | if err := hs.checkServerHelloOrHRR(); err != nil { 57 | return err 58 | } 59 | 60 | hs.transcript = hs.suite.hash.New() 61 | hs.transcript.Write(hs.hello.marshal()) 62 | 63 | if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { 64 | if err := hs.sendDummyChangeCipherSpec(); err != nil { 65 | return err 66 | } 67 | if err := hs.processHelloRetryRequest(); err != nil { 68 | return err 69 | } 70 | } 71 | 72 | hs.transcript.Write(hs.serverHello.marshal()) 73 | 74 | c.buffering = true 75 | if err := hs.processServerHello(); err != nil { 76 | return err 77 | } 78 | if err := hs.sendDummyChangeCipherSpec(); err != nil { 79 | return err 80 | } 81 | if err := hs.establishHandshakeKeys(); err != nil { 82 | return err 83 | } 84 | if err := hs.readServerParameters(); err != nil { 85 | return err 86 | } 87 | if err := hs.readServerCertificate(); err != nil { 88 | return err 89 | } 90 | if err := hs.readServerFinished(); err != nil { 91 | return err 92 | } 93 | if err := hs.sendClientCertificate(); err != nil { 94 | return err 95 | } 96 | if err := hs.sendClientFinished(); err != nil { 97 | return err 98 | } 99 | if _, err := c.flush(); err != nil { 100 | return err 101 | } 102 | 103 | atomic.StoreUint32(&c.handshakeStatus, 1) 104 | 105 | return nil 106 | } 107 | 108 | // checkServerHelloOrHRR does validity checks that apply to both ServerHello and 109 | // HelloRetryRequest messages. It sets hs.suite. 110 | func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { 111 | c := hs.c 112 | 113 | if hs.serverHello.supportedVersion == 0 { 114 | c.sendAlert(alertMissingExtension) 115 | return errors.New("tls: server selected TLS 1.3 using the legacy version field") 116 | } 117 | 118 | if hs.serverHello.supportedVersion != VersionTLS13 { 119 | c.sendAlert(alertIllegalParameter) 120 | return errors.New("tls: server selected an invalid version after a HelloRetryRequest") 121 | } 122 | 123 | if hs.serverHello.vers != VersionTLS12 { 124 | c.sendAlert(alertIllegalParameter) 125 | return errors.New("tls: server sent an incorrect legacy version") 126 | } 127 | 128 | if hs.serverHello.ocspStapling || 129 | hs.serverHello.ticketSupported || 130 | hs.serverHello.secureRenegotiationSupported || 131 | len(hs.serverHello.secureRenegotiation) != 0 || 132 | len(hs.serverHello.alpnProtocol) != 0 || 133 | len(hs.serverHello.scts) != 0 { 134 | c.sendAlert(alertUnsupportedExtension) 135 | return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3") 136 | } 137 | 138 | if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { 139 | c.sendAlert(alertIllegalParameter) 140 | return errors.New("tls: server did not echo the legacy session ID") 141 | } 142 | 143 | if hs.serverHello.compressionMethod != compressionNone { 144 | c.sendAlert(alertIllegalParameter) 145 | return errors.New("tls: server selected unsupported compression format") 146 | } 147 | 148 | selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) 149 | if hs.suite != nil && selectedSuite != hs.suite { 150 | c.sendAlert(alertIllegalParameter) 151 | return errors.New("tls: server changed cipher suite after a HelloRetryRequest") 152 | } 153 | if selectedSuite == nil { 154 | c.sendAlert(alertIllegalParameter) 155 | return errors.New("tls: server chose an unconfigured cipher suite") 156 | } 157 | hs.suite = selectedSuite 158 | c.cipherSuite = hs.suite.id 159 | 160 | return nil 161 | } 162 | 163 | // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility 164 | // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. 165 | func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error { 166 | if hs.sentDummyCCS { 167 | return nil 168 | } 169 | hs.sentDummyCCS = true 170 | 171 | _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 172 | return err 173 | } 174 | 175 | // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and 176 | // resends hs.hello, and reads the new ServerHello into hs.serverHello. 177 | func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { 178 | c := hs.c 179 | 180 | // The first ClientHello gets double-hashed into the transcript upon a 181 | // HelloRetryRequest. (The idea is that the server might offload transcript 182 | // storage to the client in the cookie.) See RFC 8446, Section 4.4.1. 183 | chHash := hs.transcript.Sum(nil) 184 | hs.transcript.Reset() 185 | hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 186 | hs.transcript.Write(chHash) 187 | hs.transcript.Write(hs.serverHello.marshal()) 188 | 189 | // The only HelloRetryRequest extensions we support are key_share and 190 | // cookie, and clients must abort the handshake if the HRR would not result 191 | // in any change in the ClientHello. 192 | if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil { 193 | c.sendAlert(alertIllegalParameter) 194 | return errors.New("tls: server sent an unnecessary HelloRetryRequest message") 195 | } 196 | 197 | if hs.serverHello.cookie != nil { 198 | hs.hello.cookie = hs.serverHello.cookie 199 | } 200 | 201 | if hs.serverHello.serverShare.group != 0 { 202 | c.sendAlert(alertDecodeError) 203 | return errors.New("tls: received malformed key_share extension") 204 | } 205 | 206 | // If the server sent a key_share extension selecting a group, ensure it's 207 | // a group we advertised but did not send a key share for, and send a key 208 | // share for it this time. 209 | if curveID := hs.serverHello.selectedGroup; curveID != 0 { 210 | curveOK := false 211 | for _, id := range hs.hello.supportedCurves { 212 | if id == curveID { 213 | curveOK = true 214 | break 215 | } 216 | } 217 | if !curveOK { 218 | c.sendAlert(alertIllegalParameter) 219 | return errors.New("tls: server selected unsupported group") 220 | } 221 | if hs.ecdheParams.CurveID() == curveID { 222 | c.sendAlert(alertIllegalParameter) 223 | return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share") 224 | } 225 | if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { 226 | c.sendAlert(alertInternalError) 227 | return errors.New("tls: CurvePreferences includes unsupported curve") 228 | } 229 | params, err := generateECDHEParameters(c.config.rand(), curveID) 230 | if err != nil { 231 | c.sendAlert(alertInternalError) 232 | return err 233 | } 234 | hs.ecdheParams = params 235 | hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} 236 | } 237 | 238 | hs.hello.raw = nil 239 | if len(hs.hello.pskIdentities) > 0 { 240 | pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) 241 | if pskSuite == nil { 242 | return c.sendAlert(alertInternalError) 243 | } 244 | if pskSuite.hash == hs.suite.hash { 245 | // Update binders and obfuscated_ticket_age. 246 | ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond) 247 | hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd 248 | 249 | transcript := hs.suite.hash.New() 250 | transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 251 | transcript.Write(chHash) 252 | transcript.Write(hs.serverHello.marshal()) 253 | transcript.Write(hs.hello.marshalWithoutBinders()) 254 | pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} 255 | hs.hello.updateBinders(pskBinders) 256 | } else { 257 | // Server selected a cipher suite incompatible with the PSK. 258 | hs.hello.pskIdentities = nil 259 | hs.hello.pskBinders = nil 260 | } 261 | } 262 | 263 | hs.transcript.Write(hs.hello.marshal()) 264 | if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 265 | return err 266 | } 267 | 268 | msg, err := c.readHandshake() 269 | if err != nil { 270 | return err 271 | } 272 | 273 | serverHello, ok := msg.(*serverHelloMsg) 274 | if !ok { 275 | c.sendAlert(alertUnexpectedMessage) 276 | return unexpectedMessageError(serverHello, msg) 277 | } 278 | hs.serverHello = serverHello 279 | 280 | if err := hs.checkServerHelloOrHRR(); err != nil { 281 | return err 282 | } 283 | 284 | return nil 285 | } 286 | 287 | func (hs *clientHandshakeStateTLS13) processServerHello() error { 288 | c := hs.c 289 | 290 | if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { 291 | c.sendAlert(alertUnexpectedMessage) 292 | return errors.New("tls: server sent two HelloRetryRequest messages") 293 | } 294 | 295 | if len(hs.serverHello.cookie) != 0 { 296 | c.sendAlert(alertUnsupportedExtension) 297 | return errors.New("tls: server sent a cookie in a normal ServerHello") 298 | } 299 | 300 | if hs.serverHello.selectedGroup != 0 { 301 | c.sendAlert(alertDecodeError) 302 | return errors.New("tls: malformed key_share extension") 303 | } 304 | 305 | if hs.serverHello.serverShare.group == 0 { 306 | c.sendAlert(alertIllegalParameter) 307 | return errors.New("tls: server did not send a key share") 308 | } 309 | if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() { 310 | c.sendAlert(alertIllegalParameter) 311 | return errors.New("tls: server selected unsupported group") 312 | } 313 | 314 | if !hs.serverHello.selectedIdentityPresent { 315 | return nil 316 | } 317 | 318 | if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) { 319 | c.sendAlert(alertIllegalParameter) 320 | return errors.New("tls: server selected an invalid PSK") 321 | } 322 | 323 | if len(hs.hello.pskIdentities) != 1 || hs.session == nil { 324 | return c.sendAlert(alertInternalError) 325 | } 326 | pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) 327 | if pskSuite == nil { 328 | return c.sendAlert(alertInternalError) 329 | } 330 | if pskSuite.hash != hs.suite.hash { 331 | c.sendAlert(alertIllegalParameter) 332 | return errors.New("tls: server selected an invalid PSK and cipher suite pair") 333 | } 334 | 335 | hs.usingPSK = true 336 | c.didResume = true 337 | c.peerCertificates = hs.session.serverCertificates 338 | c.verifiedChains = hs.session.verifiedChains 339 | c.ocspResponse = hs.session.ocspResponse 340 | c.scts = hs.session.scts 341 | return nil 342 | } 343 | 344 | func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error { 345 | c := hs.c 346 | 347 | sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data) 348 | if sharedKey == nil { 349 | c.sendAlert(alertIllegalParameter) 350 | return errors.New("tls: invalid server key share") 351 | } 352 | 353 | earlySecret := hs.earlySecret 354 | if !hs.usingPSK { 355 | earlySecret = hs.suite.extract(nil, nil) 356 | } 357 | handshakeSecret := hs.suite.extract(sharedKey, 358 | hs.suite.deriveSecret(earlySecret, "derived", nil)) 359 | 360 | clientSecret := hs.suite.deriveSecret(handshakeSecret, 361 | clientHandshakeTrafficLabel, hs.transcript) 362 | c.out.setTrafficSecret(hs.suite, clientSecret) 363 | serverSecret := hs.suite.deriveSecret(handshakeSecret, 364 | serverHandshakeTrafficLabel, hs.transcript) 365 | c.in.setTrafficSecret(hs.suite, serverSecret) 366 | 367 | err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret) 368 | if err != nil { 369 | c.sendAlert(alertInternalError) 370 | return err 371 | } 372 | err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret) 373 | if err != nil { 374 | c.sendAlert(alertInternalError) 375 | return err 376 | } 377 | 378 | hs.masterSecret = hs.suite.extract(nil, 379 | hs.suite.deriveSecret(handshakeSecret, "derived", nil)) 380 | 381 | return nil 382 | } 383 | 384 | func (hs *clientHandshakeStateTLS13) readServerParameters() error { 385 | c := hs.c 386 | 387 | msg, err := c.readHandshake() 388 | if err != nil { 389 | return err 390 | } 391 | 392 | encryptedExtensions, ok := msg.(*encryptedExtensionsMsg) 393 | if !ok { 394 | c.sendAlert(alertUnexpectedMessage) 395 | return unexpectedMessageError(encryptedExtensions, msg) 396 | } 397 | hs.transcript.Write(encryptedExtensions.marshal()) 398 | 399 | if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil { 400 | c.sendAlert(alertUnsupportedExtension) 401 | return err 402 | } 403 | c.clientProtocol = encryptedExtensions.alpnProtocol 404 | 405 | return nil 406 | } 407 | 408 | func (hs *clientHandshakeStateTLS13) readServerCertificate() error { 409 | c := hs.c 410 | 411 | // Either a PSK or a certificate is always used, but not both. 412 | // See RFC 8446, Section 4.1.1. 413 | if hs.usingPSK { 414 | // Make sure the connection is still being verified whether or not this 415 | // is a resumption. Resumptions currently don't reverify certificates so 416 | // they don't call verifyServerCertificate. See Issue 31641. 417 | if c.config.VerifyConnection != nil { 418 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 419 | c.sendAlert(alertBadCertificate) 420 | return err 421 | } 422 | } 423 | return nil 424 | } 425 | 426 | msg, err := c.readHandshake() 427 | if err != nil { 428 | return err 429 | } 430 | 431 | certReq, ok := msg.(*certificateRequestMsgTLS13) 432 | if ok { 433 | hs.transcript.Write(certReq.marshal()) 434 | 435 | hs.certReq = certReq 436 | 437 | msg, err = c.readHandshake() 438 | if err != nil { 439 | return err 440 | } 441 | } 442 | 443 | certMsg, ok := msg.(*certificateMsgTLS13) 444 | if !ok { 445 | c.sendAlert(alertUnexpectedMessage) 446 | return unexpectedMessageError(certMsg, msg) 447 | } 448 | if len(certMsg.certificate.Certificate) == 0 { 449 | c.sendAlert(alertDecodeError) 450 | return errors.New("tls: received empty certificates message") 451 | } 452 | hs.transcript.Write(certMsg.marshal()) 453 | 454 | c.scts = certMsg.certificate.SignedCertificateTimestamps 455 | c.ocspResponse = certMsg.certificate.OCSPStaple 456 | 457 | if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil { 458 | return err 459 | } 460 | 461 | msg, err = c.readHandshake() 462 | if err != nil { 463 | return err 464 | } 465 | 466 | certVerify, ok := msg.(*certificateVerifyMsg) 467 | if !ok { 468 | c.sendAlert(alertUnexpectedMessage) 469 | return unexpectedMessageError(certVerify, msg) 470 | } 471 | 472 | // See RFC 8446, Section 4.4.3. 473 | if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { 474 | c.sendAlert(alertIllegalParameter) 475 | return errors.New("tls: certificate used with invalid signature algorithm") 476 | } 477 | sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) 478 | if err != nil { 479 | return c.sendAlert(alertInternalError) 480 | } 481 | if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { 482 | c.sendAlert(alertIllegalParameter) 483 | return errors.New("tls: certificate used with invalid signature algorithm") 484 | } 485 | signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) 486 | if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, 487 | sigHash, signed, certVerify.signature); err != nil { 488 | c.sendAlert(alertDecryptError) 489 | return errors.New("tls: invalid signature by the server certificate: " + err.Error()) 490 | } 491 | 492 | hs.transcript.Write(certVerify.marshal()) 493 | 494 | return nil 495 | } 496 | 497 | func (hs *clientHandshakeStateTLS13) readServerFinished() error { 498 | c := hs.c 499 | 500 | msg, err := c.readHandshake() 501 | if err != nil { 502 | return err 503 | } 504 | 505 | finished, ok := msg.(*finishedMsg) 506 | if !ok { 507 | c.sendAlert(alertUnexpectedMessage) 508 | return unexpectedMessageError(finished, msg) 509 | } 510 | 511 | expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) 512 | if !hmac.Equal(expectedMAC, finished.verifyData) { 513 | c.sendAlert(alertDecryptError) 514 | return errors.New("tls: invalid server finished hash") 515 | } 516 | 517 | hs.transcript.Write(finished.marshal()) 518 | 519 | // Derive secrets that take context through the server Finished. 520 | 521 | hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, 522 | clientApplicationTrafficLabel, hs.transcript) 523 | serverSecret := hs.suite.deriveSecret(hs.masterSecret, 524 | serverApplicationTrafficLabel, hs.transcript) 525 | c.in.setTrafficSecret(hs.suite, serverSecret) 526 | 527 | err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret) 528 | if err != nil { 529 | c.sendAlert(alertInternalError) 530 | return err 531 | } 532 | err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret) 533 | if err != nil { 534 | c.sendAlert(alertInternalError) 535 | return err 536 | } 537 | 538 | c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) 539 | 540 | return nil 541 | } 542 | 543 | func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { 544 | c := hs.c 545 | 546 | if hs.certReq == nil { 547 | return nil 548 | } 549 | 550 | cert, err := c.getClientCertificate(&CertificateRequestInfo{ 551 | AcceptableCAs: hs.certReq.certificateAuthorities, 552 | SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, 553 | Version: c.vers, 554 | ctx: hs.ctx, 555 | }) 556 | if err != nil { 557 | return err 558 | } 559 | 560 | certMsg := new(certificateMsgTLS13) 561 | 562 | certMsg.certificate = *cert 563 | certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 564 | certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 565 | 566 | hs.transcript.Write(certMsg.marshal()) 567 | if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 568 | return err 569 | } 570 | 571 | // If we sent an empty certificate message, skip the CertificateVerify. 572 | if len(cert.Certificate) == 0 { 573 | return nil 574 | } 575 | 576 | certVerifyMsg := new(certificateVerifyMsg) 577 | certVerifyMsg.hasSignatureAlgorithm = true 578 | 579 | certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms) 580 | if err != nil { 581 | // getClientCertificate returned a certificate incompatible with the 582 | // CertificateRequestInfo supported signature algorithms. 583 | c.sendAlert(alertHandshakeFailure) 584 | return err 585 | } 586 | 587 | sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) 588 | if err != nil { 589 | return c.sendAlert(alertInternalError) 590 | } 591 | 592 | signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) 593 | signOpts := crypto.SignerOpts(sigHash) 594 | if sigType == signatureRSAPSS { 595 | signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} 596 | } 597 | sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) 598 | if err != nil { 599 | c.sendAlert(alertInternalError) 600 | return errors.New("tls: failed to sign handshake: " + err.Error()) 601 | } 602 | certVerifyMsg.signature = sig 603 | 604 | hs.transcript.Write(certVerifyMsg.marshal()) 605 | if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { 606 | return err 607 | } 608 | 609 | return nil 610 | } 611 | 612 | func (hs *clientHandshakeStateTLS13) sendClientFinished() error { 613 | c := hs.c 614 | 615 | finished := &finishedMsg{ 616 | verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), 617 | } 618 | 619 | hs.transcript.Write(finished.marshal()) 620 | if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 621 | return err 622 | } 623 | 624 | c.out.setTrafficSecret(hs.suite, hs.trafficSecret) 625 | 626 | if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil { 627 | c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, 628 | resumptionLabel, hs.transcript) 629 | } 630 | 631 | return nil 632 | } 633 | 634 | func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { 635 | if !c.isClient { 636 | c.sendAlert(alertUnexpectedMessage) 637 | return errors.New("tls: received new session ticket from a client") 638 | } 639 | 640 | if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { 641 | return nil 642 | } 643 | 644 | // See RFC 8446, Section 4.6.1. 645 | if msg.lifetime == 0 { 646 | return nil 647 | } 648 | lifetime := time.Duration(msg.lifetime) * time.Second 649 | if lifetime > maxSessionTicketLifetime { 650 | c.sendAlert(alertIllegalParameter) 651 | return errors.New("tls: received a session ticket with invalid lifetime") 652 | } 653 | 654 | cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) 655 | if cipherSuite == nil || c.resumptionSecret == nil { 656 | return c.sendAlert(alertInternalError) 657 | } 658 | 659 | // Save the resumption_master_secret and nonce instead of deriving the PSK 660 | // to do the least amount of work on NewSessionTicket messages before we 661 | // know if the ticket will be used. Forward secrecy of resumed connections 662 | // is guaranteed by the requirement for pskModeDHE. 663 | session := &ClientSessionState{ 664 | sessionTicket: msg.label, 665 | vers: c.vers, 666 | cipherSuite: c.cipherSuite, 667 | masterSecret: c.resumptionSecret, 668 | serverCertificates: c.peerCertificates, 669 | verifiedChains: c.verifiedChains, 670 | receivedAt: c.config.time(), 671 | nonce: msg.nonce, 672 | useBy: c.config.time().Add(lifetime), 673 | ageAdd: msg.ageAdd, 674 | ocspResponse: c.ocspResponse, 675 | scts: c.scts, 676 | } 677 | 678 | cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) 679 | c.config.ClientSessionCache.Put(cacheKey, session) 680 | 681 | return nil 682 | } 683 | -------------------------------------------------------------------------------- /handshake_server.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "context" 9 | "crypto" 10 | "crypto/ecdsa" 11 | "crypto/ed25519" 12 | "crypto/rsa" 13 | "crypto/subtle" 14 | "crypto/x509" 15 | "errors" 16 | "fmt" 17 | "hash" 18 | "io" 19 | "sync/atomic" 20 | "time" 21 | ) 22 | 23 | // serverHandshakeState contains details of a server handshake in progress. 24 | // It's discarded once the handshake has completed. 25 | type serverHandshakeState struct { 26 | c *Conn 27 | ctx context.Context 28 | clientHello *clientHelloMsg 29 | hello *serverHelloMsg 30 | suite *cipherSuite 31 | ecdheOk bool 32 | ecSignOk bool 33 | rsaDecryptOk bool 34 | rsaSignOk bool 35 | sessionState *sessionState 36 | finishedHash finishedHash 37 | masterSecret []byte 38 | cert *Certificate 39 | } 40 | 41 | // serverHandshake performs a TLS handshake as a server. 42 | func (c *Conn) serverHandshake(ctx context.Context) error { 43 | clientHello, err := c.readClientHello(ctx) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | if c.vers == VersionTLS13 { 49 | hs := serverHandshakeStateTLS13{ 50 | c: c, 51 | ctx: ctx, 52 | clientHello: clientHello, 53 | } 54 | return hs.handshake() 55 | } 56 | 57 | hs := serverHandshakeState{ 58 | c: c, 59 | ctx: ctx, 60 | clientHello: clientHello, 61 | } 62 | return hs.handshake() 63 | } 64 | 65 | func (hs *serverHandshakeState) handshake() error { 66 | c := hs.c 67 | 68 | if err := hs.processClientHello(); err != nil { 69 | return err 70 | } 71 | 72 | // For an overview of TLS handshaking, see RFC 5246, Section 7.3. 73 | c.buffering = true 74 | if hs.checkForResumption() { 75 | // The client has included a session ticket and so we do an abbreviated handshake. 76 | c.didResume = true 77 | if err := hs.doResumeHandshake(); err != nil { 78 | return err 79 | } 80 | if err := hs.establishKeys(); err != nil { 81 | return err 82 | } 83 | if err := hs.sendSessionTicket(); err != nil { 84 | return err 85 | } 86 | if err := hs.sendFinished(c.serverFinished[:]); err != nil { 87 | return err 88 | } 89 | if _, err := c.flush(); err != nil { 90 | return err 91 | } 92 | c.clientFinishedIsFirst = false 93 | if err := hs.readFinished(nil); err != nil { 94 | return err 95 | } 96 | } else { 97 | // The client didn't include a session ticket, or it wasn't 98 | // valid so we do a full handshake. 99 | if err := hs.pickCipherSuite(); err != nil { 100 | return err 101 | } 102 | if err := hs.doFullHandshake(); err != nil { 103 | return err 104 | } 105 | if err := hs.establishKeys(); err != nil { 106 | return err 107 | } 108 | if err := hs.readFinished(c.clientFinished[:]); err != nil { 109 | return err 110 | } 111 | c.clientFinishedIsFirst = true 112 | c.buffering = true 113 | if err := hs.sendSessionTicket(); err != nil { 114 | return err 115 | } 116 | if err := hs.sendFinished(nil); err != nil { 117 | return err 118 | } 119 | if _, err := c.flush(); err != nil { 120 | return err 121 | } 122 | } 123 | 124 | c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random) 125 | atomic.StoreUint32(&c.handshakeStatus, 1) 126 | 127 | return nil 128 | } 129 | 130 | // readClientHello reads a ClientHello message and selects the protocol version. 131 | func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) { 132 | msg, err := c.readHandshake() 133 | if err != nil { 134 | return nil, err 135 | } 136 | clientHello, ok := msg.(*clientHelloMsg) 137 | if !ok { 138 | c.sendAlert(alertUnexpectedMessage) 139 | return nil, unexpectedMessageError(clientHello, msg) 140 | } 141 | 142 | var configForClient *Config 143 | originalConfig := c.config 144 | if c.config.GetConfigForClient != nil { 145 | chi := clientHelloInfo(ctx, c, clientHello) 146 | if configForClient, err = c.config.GetConfigForClient(chi); err != nil { 147 | c.sendAlert(alertInternalError) 148 | return nil, err 149 | } else if configForClient != nil { 150 | c.config = configForClient 151 | } 152 | } 153 | c.ticketKeys = originalConfig.ticketKeys(configForClient) 154 | 155 | clientVersions := clientHello.supportedVersions 156 | if len(clientHello.supportedVersions) == 0 { 157 | clientVersions = supportedVersionsFromMax(clientHello.vers) 158 | } 159 | c.vers, ok = c.config.mutualVersion(roleClient, clientVersions) 160 | if !ok { 161 | c.sendAlert(alertProtocolVersion) 162 | return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions) 163 | } 164 | c.haveVers = true 165 | c.in.version = c.vers 166 | c.out.version = c.vers 167 | 168 | return clientHello, nil 169 | } 170 | 171 | func (hs *serverHandshakeState) processClientHello() error { 172 | c := hs.c 173 | 174 | hs.hello = new(serverHelloMsg) 175 | hs.hello.vers = c.vers 176 | 177 | foundCompression := false 178 | // We only support null compression, so check that the client offered it. 179 | for _, compression := range hs.clientHello.compressionMethods { 180 | if compression == compressionNone { 181 | foundCompression = true 182 | break 183 | } 184 | } 185 | 186 | if !foundCompression { 187 | c.sendAlert(alertHandshakeFailure) 188 | return errors.New("tls: client does not support uncompressed connections") 189 | } 190 | 191 | hs.hello.random = make([]byte, 32) 192 | serverRandom := hs.hello.random 193 | // Downgrade protection canaries. See RFC 8446, Section 4.1.3. 194 | maxVers := c.config.maxSupportedVersion(roleClient) 195 | if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary { 196 | if c.vers == VersionTLS12 { 197 | copy(serverRandom[24:], downgradeCanaryTLS12) 198 | } else { 199 | copy(serverRandom[24:], downgradeCanaryTLS11) 200 | } 201 | serverRandom = serverRandom[:24] 202 | } 203 | _, err := io.ReadFull(c.config.rand(), serverRandom) 204 | if err != nil { 205 | c.sendAlert(alertInternalError) 206 | return err 207 | } 208 | 209 | if len(hs.clientHello.secureRenegotiation) != 0 { 210 | c.sendAlert(alertHandshakeFailure) 211 | return errors.New("tls: initial handshake had non-empty renegotiation extension") 212 | } 213 | 214 | hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported 215 | hs.hello.compressionMethod = compressionNone 216 | if len(hs.clientHello.serverName) > 0 { 217 | c.serverName = hs.clientHello.serverName 218 | } 219 | 220 | selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols) 221 | if err != nil { 222 | c.sendAlert(alertNoApplicationProtocol) 223 | return err 224 | } 225 | hs.hello.alpnProtocol = selectedProto 226 | c.clientProtocol = selectedProto 227 | 228 | hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) 229 | if err != nil { 230 | if err == errNoCertificates { 231 | c.sendAlert(alertUnrecognizedName) 232 | } else { 233 | c.sendAlert(alertInternalError) 234 | } 235 | return err 236 | } 237 | if hs.clientHello.scts { 238 | hs.hello.scts = hs.cert.SignedCertificateTimestamps 239 | } 240 | 241 | hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) 242 | 243 | if hs.ecdheOk { 244 | // Although omitting the ec_point_formats extension is permitted, some 245 | // old OpenSSL version will refuse to handshake if not present. 246 | // 247 | // Per RFC 4492, section 5.1.2, implementations MUST support the 248 | // uncompressed point format. See golang.org/issue/31943. 249 | hs.hello.supportedPoints = []uint8{pointFormatUncompressed} 250 | } 251 | 252 | if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { 253 | switch priv.Public().(type) { 254 | case *ecdsa.PublicKey: 255 | hs.ecSignOk = true 256 | case ed25519.PublicKey: 257 | hs.ecSignOk = true 258 | case *rsa.PublicKey: 259 | hs.rsaSignOk = true 260 | default: 261 | c.sendAlert(alertInternalError) 262 | return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public()) 263 | } 264 | } 265 | if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok { 266 | switch priv.Public().(type) { 267 | case *rsa.PublicKey: 268 | hs.rsaDecryptOk = true 269 | default: 270 | c.sendAlert(alertInternalError) 271 | return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public()) 272 | } 273 | } 274 | 275 | return nil 276 | } 277 | 278 | // negotiateALPN picks a shared ALPN protocol that both sides support in server 279 | // preference order. If ALPN is not configured or the peer doesn't support it, 280 | // it returns "" and no error. 281 | func negotiateALPN(serverProtos, clientProtos []string) (string, error) { 282 | if len(serverProtos) == 0 || len(clientProtos) == 0 { 283 | return "", nil 284 | } 285 | var http11fallback bool 286 | for _, s := range serverProtos { 287 | for _, c := range clientProtos { 288 | if s == c { 289 | return s, nil 290 | } 291 | if s == "h2" && c == "http/1.1" { 292 | http11fallback = true 293 | } 294 | } 295 | } 296 | // As a special case, let http/1.1 clients connect to h2 servers as if they 297 | // didn't support ALPN. We used not to enforce protocol overlap, so over 298 | // time a number of HTTP servers were configured with only "h2", but 299 | // expected to accept connections from "http/1.1" clients. See Issue 46310. 300 | if http11fallback { 301 | return "", nil 302 | } 303 | return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos) 304 | } 305 | 306 | // supportsECDHE returns whether ECDHE key exchanges can be used with this 307 | // pre-TLS 1.3 client. 308 | func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool { 309 | supportsCurve := false 310 | for _, curve := range supportedCurves { 311 | if c.supportsCurve(curve) { 312 | supportsCurve = true 313 | break 314 | } 315 | } 316 | 317 | supportsPointFormat := false 318 | for _, pointFormat := range supportedPoints { 319 | if pointFormat == pointFormatUncompressed { 320 | supportsPointFormat = true 321 | break 322 | } 323 | } 324 | 325 | return supportsCurve && supportsPointFormat 326 | } 327 | 328 | func (hs *serverHandshakeState) pickCipherSuite() error { 329 | c := hs.c 330 | 331 | preferenceOrder := cipherSuitesPreferenceOrder 332 | if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { 333 | preferenceOrder = cipherSuitesPreferenceOrderNoAES 334 | } 335 | 336 | configCipherSuites := c.config.cipherSuites() 337 | preferenceList := make([]uint16, 0, len(configCipherSuites)) 338 | for _, suiteID := range preferenceOrder { 339 | for _, id := range configCipherSuites { 340 | if id == suiteID { 341 | preferenceList = append(preferenceList, id) 342 | break 343 | } 344 | } 345 | } 346 | 347 | hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk) 348 | if hs.suite == nil { 349 | c.sendAlert(alertHandshakeFailure) 350 | return errors.New("tls: no cipher suite supported by both client and server") 351 | } 352 | c.cipherSuite = hs.suite.id 353 | 354 | for _, id := range hs.clientHello.cipherSuites { 355 | if id == TLS_FALLBACK_SCSV { 356 | // The client is doing a fallback connection. See RFC 7507. 357 | if hs.clientHello.vers < c.config.maxSupportedVersion(roleClient) { 358 | c.sendAlert(alertInappropriateFallback) 359 | return errors.New("tls: client using inappropriate protocol fallback") 360 | } 361 | break 362 | } 363 | } 364 | 365 | return nil 366 | } 367 | 368 | func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool { 369 | if c.flags&suiteECDHE != 0 { 370 | if !hs.ecdheOk { 371 | return false 372 | } 373 | if c.flags&suiteECSign != 0 { 374 | if !hs.ecSignOk { 375 | return false 376 | } 377 | } else if !hs.rsaSignOk { 378 | return false 379 | } 380 | } else if !hs.rsaDecryptOk { 381 | return false 382 | } 383 | if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { 384 | return false 385 | } 386 | return true 387 | } 388 | 389 | // checkForResumption reports whether we should perform resumption on this connection. 390 | func (hs *serverHandshakeState) checkForResumption() bool { 391 | c := hs.c 392 | 393 | if c.config.SessionTicketsDisabled { 394 | return false 395 | } 396 | 397 | plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket) 398 | if plaintext == nil { 399 | return false 400 | } 401 | hs.sessionState = &sessionState{usedOldKey: usedOldKey} 402 | ok := hs.sessionState.unmarshal(plaintext) 403 | if !ok { 404 | return false 405 | } 406 | 407 | createdAt := time.Unix(int64(hs.sessionState.createdAt), 0) 408 | if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { 409 | return false 410 | } 411 | 412 | // Never resume a session for a different TLS version. 413 | if c.vers != hs.sessionState.vers { 414 | return false 415 | } 416 | 417 | cipherSuiteOk := false 418 | // Check that the client is still offering the ciphersuite in the session. 419 | for _, id := range hs.clientHello.cipherSuites { 420 | if id == hs.sessionState.cipherSuite { 421 | cipherSuiteOk = true 422 | break 423 | } 424 | } 425 | if !cipherSuiteOk { 426 | return false 427 | } 428 | 429 | // Check that we also support the ciphersuite from the session. 430 | hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite}, 431 | c.config.cipherSuites(), hs.cipherSuiteOk) 432 | if hs.suite == nil { 433 | return false 434 | } 435 | 436 | sessionHasClientCerts := len(hs.sessionState.certificates) != 0 437 | needClientCerts := requiresClientCert(c.config.ClientAuth) 438 | if needClientCerts && !sessionHasClientCerts { 439 | return false 440 | } 441 | if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 442 | return false 443 | } 444 | 445 | return true 446 | } 447 | 448 | func (hs *serverHandshakeState) doResumeHandshake() error { 449 | c := hs.c 450 | 451 | hs.hello.cipherSuite = hs.suite.id 452 | c.cipherSuite = hs.suite.id 453 | // We echo the client's session ID in the ServerHello to let it know 454 | // that we're doing a resumption. 455 | hs.hello.sessionId = hs.clientHello.sessionId 456 | hs.hello.ticketSupported = hs.sessionState.usedOldKey 457 | hs.finishedHash = newFinishedHash(c.vers, hs.suite) 458 | hs.finishedHash.discardHandshakeBuffer() 459 | hs.finishedHash.Write(hs.clientHello.marshal()) 460 | hs.finishedHash.Write(hs.hello.marshal()) 461 | if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 462 | return err 463 | } 464 | 465 | if err := c.processCertsFromClient(Certificate{ 466 | Certificate: hs.sessionState.certificates, 467 | }); err != nil { 468 | return err 469 | } 470 | 471 | if c.config.VerifyConnection != nil { 472 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 473 | c.sendAlert(alertBadCertificate) 474 | return err 475 | } 476 | } 477 | 478 | hs.masterSecret = hs.sessionState.masterSecret 479 | 480 | return nil 481 | } 482 | 483 | func (hs *serverHandshakeState) doFullHandshake() error { 484 | c := hs.c 485 | 486 | if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { 487 | hs.hello.ocspStapling = true 488 | } 489 | 490 | hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled 491 | hs.hello.cipherSuite = hs.suite.id 492 | 493 | hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite) 494 | if c.config.ClientAuth == NoClientCert { 495 | // No need to keep a full record of the handshake if client 496 | // certificates won't be used. 497 | hs.finishedHash.discardHandshakeBuffer() 498 | } 499 | hs.finishedHash.Write(hs.clientHello.marshal()) 500 | hs.finishedHash.Write(hs.hello.marshal()) 501 | if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 502 | return err 503 | } 504 | 505 | certMsg := new(certificateMsg) 506 | certMsg.certificates = hs.cert.Certificate 507 | hs.finishedHash.Write(certMsg.marshal()) 508 | if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 509 | return err 510 | } 511 | 512 | if hs.hello.ocspStapling { 513 | certStatus := new(certificateStatusMsg) 514 | certStatus.response = hs.cert.OCSPStaple 515 | hs.finishedHash.Write(certStatus.marshal()) 516 | if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { 517 | return err 518 | } 519 | } 520 | 521 | keyAgreement := hs.suite.ka(c.vers) 522 | skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello) 523 | if err != nil { 524 | c.sendAlert(alertHandshakeFailure) 525 | return err 526 | } 527 | if skx != nil { 528 | hs.finishedHash.Write(skx.marshal()) 529 | if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { 530 | return err 531 | } 532 | } 533 | 534 | var certReq *certificateRequestMsg 535 | if c.config.ClientAuth >= RequestClientCert { 536 | // Request a client certificate 537 | certReq = new(certificateRequestMsg) 538 | certReq.certificateTypes = []byte{ 539 | byte(certTypeRSASign), 540 | byte(certTypeECDSASign), 541 | } 542 | if c.vers >= VersionTLS12 { 543 | certReq.hasSignatureAlgorithm = true 544 | certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms 545 | } 546 | 547 | // An empty list of certificateAuthorities signals to 548 | // the client that it may send any certificate in response 549 | // to our request. When we know the CAs we trust, then 550 | // we can send them down, so that the client can choose 551 | // an appropriate certificate to give to us. 552 | if c.config.ClientCAs != nil { 553 | certReq.certificateAuthorities = c.config.ClientCAs.Subjects() 554 | } 555 | hs.finishedHash.Write(certReq.marshal()) 556 | if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { 557 | return err 558 | } 559 | } 560 | 561 | helloDone := new(serverHelloDoneMsg) 562 | hs.finishedHash.Write(helloDone.marshal()) 563 | if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { 564 | return err 565 | } 566 | 567 | if _, err := c.flush(); err != nil { 568 | return err 569 | } 570 | 571 | var pub crypto.PublicKey // public key for client auth, if any 572 | 573 | msg, err := c.readHandshake() 574 | if err != nil { 575 | return err 576 | } 577 | 578 | // If we requested a client certificate, then the client must send a 579 | // certificate message, even if it's empty. 580 | if c.config.ClientAuth >= RequestClientCert { 581 | certMsg, ok := msg.(*certificateMsg) 582 | if !ok { 583 | c.sendAlert(alertUnexpectedMessage) 584 | return unexpectedMessageError(certMsg, msg) 585 | } 586 | hs.finishedHash.Write(certMsg.marshal()) 587 | 588 | if err := c.processCertsFromClient(Certificate{ 589 | Certificate: certMsg.certificates, 590 | }); err != nil { 591 | return err 592 | } 593 | if len(certMsg.certificates) != 0 { 594 | pub = c.peerCertificates[0].PublicKey 595 | } 596 | 597 | msg, err = c.readHandshake() 598 | if err != nil { 599 | return err 600 | } 601 | } 602 | if c.config.VerifyConnection != nil { 603 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 604 | c.sendAlert(alertBadCertificate) 605 | return err 606 | } 607 | } 608 | 609 | // Get client key exchange 610 | ckx, ok := msg.(*clientKeyExchangeMsg) 611 | if !ok { 612 | c.sendAlert(alertUnexpectedMessage) 613 | return unexpectedMessageError(ckx, msg) 614 | } 615 | hs.finishedHash.Write(ckx.marshal()) 616 | 617 | preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) 618 | if err != nil { 619 | c.sendAlert(alertHandshakeFailure) 620 | return err 621 | } 622 | hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) 623 | if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { 624 | c.sendAlert(alertInternalError) 625 | return err 626 | } 627 | 628 | // If we received a client cert in response to our certificate request message, 629 | // the client will send us a certificateVerifyMsg immediately after the 630 | // clientKeyExchangeMsg. This message is a digest of all preceding 631 | // handshake-layer messages that is signed using the private key corresponding 632 | // to the client's certificate. This allows us to verify that the client is in 633 | // possession of the private key of the certificate. 634 | if len(c.peerCertificates) > 0 { 635 | msg, err = c.readHandshake() 636 | if err != nil { 637 | return err 638 | } 639 | certVerify, ok := msg.(*certificateVerifyMsg) 640 | if !ok { 641 | c.sendAlert(alertUnexpectedMessage) 642 | return unexpectedMessageError(certVerify, msg) 643 | } 644 | 645 | var sigType uint8 646 | var sigHash crypto.Hash 647 | if c.vers >= VersionTLS12 { 648 | if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) { 649 | c.sendAlert(alertIllegalParameter) 650 | return errors.New("tls: client certificate used with invalid signature algorithm") 651 | } 652 | sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) 653 | if err != nil { 654 | return c.sendAlert(alertInternalError) 655 | } 656 | } else { 657 | sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub) 658 | if err != nil { 659 | c.sendAlert(alertIllegalParameter) 660 | return err 661 | } 662 | } 663 | 664 | signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) 665 | if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil { 666 | c.sendAlert(alertDecryptError) 667 | return errors.New("tls: invalid signature by the client certificate: " + err.Error()) 668 | } 669 | 670 | hs.finishedHash.Write(certVerify.marshal()) 671 | } 672 | 673 | hs.finishedHash.discardHandshakeBuffer() 674 | 675 | return nil 676 | } 677 | 678 | func (hs *serverHandshakeState) establishKeys() error { 679 | c := hs.c 680 | 681 | clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 682 | keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 683 | 684 | var clientCipher, serverCipher any 685 | var clientHash, serverHash hash.Hash 686 | 687 | if hs.suite.aead == nil { 688 | clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) 689 | clientHash = hs.suite.mac(clientMAC) 690 | serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) 691 | serverHash = hs.suite.mac(serverMAC) 692 | } else { 693 | clientCipher = hs.suite.aead(clientKey, clientIV) 694 | serverCipher = hs.suite.aead(serverKey, serverIV) 695 | } 696 | 697 | c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) 698 | c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) 699 | 700 | return nil 701 | } 702 | 703 | func (hs *serverHandshakeState) readFinished(out []byte) error { 704 | c := hs.c 705 | 706 | if err := c.readChangeCipherSpec(); err != nil { 707 | return err 708 | } 709 | 710 | msg, err := c.readHandshake() 711 | if err != nil { 712 | return err 713 | } 714 | clientFinished, ok := msg.(*finishedMsg) 715 | if !ok { 716 | c.sendAlert(alertUnexpectedMessage) 717 | return unexpectedMessageError(clientFinished, msg) 718 | } 719 | 720 | verify := hs.finishedHash.clientSum(hs.masterSecret) 721 | if len(verify) != len(clientFinished.verifyData) || 722 | subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { 723 | c.sendAlert(alertHandshakeFailure) 724 | return errors.New("tls: client's Finished message is incorrect") 725 | } 726 | 727 | hs.finishedHash.Write(clientFinished.marshal()) 728 | copy(out, verify) 729 | return nil 730 | } 731 | 732 | func (hs *serverHandshakeState) sendSessionTicket() error { 733 | // ticketSupported is set in a resumption handshake if the 734 | // ticket from the client was encrypted with an old session 735 | // ticket key and thus a refreshed ticket should be sent. 736 | if !hs.hello.ticketSupported { 737 | return nil 738 | } 739 | 740 | c := hs.c 741 | m := new(newSessionTicketMsg) 742 | 743 | createdAt := uint64(c.config.time().Unix()) 744 | if hs.sessionState != nil { 745 | // If this is re-wrapping an old key, then keep 746 | // the original time it was created. 747 | createdAt = hs.sessionState.createdAt 748 | } 749 | 750 | var certsFromClient [][]byte 751 | for _, cert := range c.peerCertificates { 752 | certsFromClient = append(certsFromClient, cert.Raw) 753 | } 754 | state := sessionState{ 755 | vers: c.vers, 756 | cipherSuite: hs.suite.id, 757 | createdAt: createdAt, 758 | masterSecret: hs.masterSecret, 759 | certificates: certsFromClient, 760 | } 761 | var err error 762 | m.ticket, err = c.encryptTicket(state.marshal()) 763 | if err != nil { 764 | return err 765 | } 766 | 767 | hs.finishedHash.Write(m.marshal()) 768 | if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { 769 | return err 770 | } 771 | 772 | return nil 773 | } 774 | 775 | func (hs *serverHandshakeState) sendFinished(out []byte) error { 776 | c := hs.c 777 | 778 | if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { 779 | return err 780 | } 781 | 782 | finished := new(finishedMsg) 783 | finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) 784 | hs.finishedHash.Write(finished.marshal()) 785 | if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 786 | return err 787 | } 788 | 789 | copy(out, finished.verifyData) 790 | 791 | return nil 792 | } 793 | 794 | // processCertsFromClient takes a chain of client certificates either from a 795 | // Certificates message or from a sessionState and verifies them. It returns 796 | // the public key of the leaf certificate. 797 | func (c *Conn) processCertsFromClient(certificate Certificate) error { 798 | certificates := certificate.Certificate 799 | certs := make([]*x509.Certificate, len(certificates)) 800 | var err error 801 | for i, asn1Data := range certificates { 802 | if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { 803 | c.sendAlert(alertBadCertificate) 804 | return errors.New("tls: failed to parse client certificate: " + err.Error()) 805 | } 806 | } 807 | 808 | if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) { 809 | c.sendAlert(alertBadCertificate) 810 | return errors.New("tls: client didn't provide a certificate") 811 | } 812 | 813 | if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { 814 | opts := x509.VerifyOptions{ 815 | Roots: c.config.ClientCAs, 816 | CurrentTime: c.config.time(), 817 | Intermediates: x509.NewCertPool(), 818 | KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 819 | } 820 | 821 | for _, cert := range certs[1:] { 822 | opts.Intermediates.AddCert(cert) 823 | } 824 | 825 | chains, err := certs[0].Verify(opts) 826 | if err != nil { 827 | c.sendAlert(alertBadCertificate) 828 | return errors.New("tls: failed to verify client certificate: " + err.Error()) 829 | } 830 | 831 | c.verifiedChains = chains 832 | } 833 | 834 | c.peerCertificates = certs 835 | c.ocspResponse = certificate.OCSPStaple 836 | c.scts = certificate.SignedCertificateTimestamps 837 | 838 | if len(certs) > 0 { 839 | switch certs[0].PublicKey.(type) { 840 | case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: 841 | default: 842 | c.sendAlert(alertUnsupportedCertificate) 843 | return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) 844 | } 845 | } 846 | 847 | if c.config.VerifyPeerCertificate != nil { 848 | if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { 849 | c.sendAlert(alertBadCertificate) 850 | return err 851 | } 852 | } 853 | 854 | return nil 855 | } 856 | 857 | func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { 858 | supportedVersions := clientHello.supportedVersions 859 | if len(clientHello.supportedVersions) == 0 { 860 | supportedVersions = supportedVersionsFromMax(clientHello.vers) 861 | } 862 | 863 | return &ClientHelloInfo{ 864 | CipherSuites: clientHello.cipherSuites, 865 | ServerName: clientHello.serverName, 866 | SupportedCurves: clientHello.supportedCurves, 867 | SupportedPoints: clientHello.supportedPoints, 868 | SignatureSchemes: clientHello.supportedSignatureAlgorithms, 869 | SupportedProtos: clientHello.alpnProtocols, 870 | SupportedVersions: supportedVersions, 871 | Conn: c.conn, 872 | config: c.config, 873 | ctx: ctx, 874 | } 875 | } 876 | -------------------------------------------------------------------------------- /handshake_server_tls13.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "bytes" 9 | "context" 10 | "crypto" 11 | "crypto/hmac" 12 | "crypto/rsa" 13 | "encoding/binary" 14 | "errors" 15 | "hash" 16 | "io" 17 | "sync/atomic" 18 | "time" 19 | ) 20 | 21 | // maxClientPSKIdentities is the number of client PSK identities the server will 22 | // attempt to validate. It will ignore the rest not to let cheap ClientHello 23 | // messages cause too much work in session ticket decryption attempts. 24 | const maxClientPSKIdentities = 5 25 | 26 | type serverHandshakeStateTLS13 struct { 27 | c *Conn 28 | ctx context.Context 29 | clientHello *clientHelloMsg 30 | hello *serverHelloMsg 31 | sentDummyCCS bool 32 | usingPSK bool 33 | suite *cipherSuiteTLS13 34 | cert *Certificate 35 | sigAlg SignatureScheme 36 | earlySecret []byte 37 | sharedKey []byte 38 | handshakeSecret []byte 39 | masterSecret []byte 40 | trafficSecret []byte // client_application_traffic_secret_0 41 | transcript hash.Hash 42 | clientFinished []byte 43 | } 44 | 45 | func (hs *serverHandshakeStateTLS13) handshake() error { 46 | c := hs.c 47 | 48 | // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. 49 | if err := hs.processClientHello(); err != nil { 50 | return err 51 | } 52 | if err := hs.checkForResumption(); err != nil { 53 | return err 54 | } 55 | if err := hs.pickCertificate(); err != nil { 56 | return err 57 | } 58 | c.buffering = true 59 | if err := hs.sendServerParameters(); err != nil { 60 | return err 61 | } 62 | if err := hs.sendServerCertificate(); err != nil { 63 | return err 64 | } 65 | if err := hs.sendServerFinished(); err != nil { 66 | return err 67 | } 68 | // Note that at this point we could start sending application data without 69 | // waiting for the client's second flight, but the application might not 70 | // expect the lack of replay protection of the ClientHello parameters. 71 | if _, err := c.flush(); err != nil { 72 | return err 73 | } 74 | if err := hs.readClientCertificate(); err != nil { 75 | return err 76 | } 77 | if err := hs.readClientFinished(); err != nil { 78 | return err 79 | } 80 | 81 | atomic.StoreUint32(&c.handshakeStatus, 1) 82 | 83 | return nil 84 | } 85 | 86 | func (hs *serverHandshakeStateTLS13) processClientHello() error { 87 | c := hs.c 88 | 89 | hs.hello = new(serverHelloMsg) 90 | 91 | // TLS 1.3 froze the ServerHello.legacy_version field, and uses 92 | // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. 93 | hs.hello.vers = VersionTLS12 94 | hs.hello.supportedVersion = c.vers 95 | 96 | if len(hs.clientHello.supportedVersions) == 0 { 97 | c.sendAlert(alertIllegalParameter) 98 | return errors.New("tls: client used the legacy version field to negotiate TLS 1.3") 99 | } 100 | 101 | // Abort if the client is doing a fallback and landing lower than what we 102 | // support. See RFC 7507, which however does not specify the interaction 103 | // with supported_versions. The only difference is that with 104 | // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] 105 | // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, 106 | // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to 107 | // TLS 1.2, because a TLS 1.3 server would abort here. The situation before 108 | // supported_versions was not better because there was just no way to do a 109 | // TLS 1.4 handshake without risking the server selecting TLS 1.3. 110 | for _, id := range hs.clientHello.cipherSuites { 111 | if id == TLS_FALLBACK_SCSV { 112 | // Use c.vers instead of max(supported_versions) because an attacker 113 | // could defeat this by adding an arbitrary high version otherwise. 114 | if c.vers < c.config.maxSupportedVersion(roleClient) { 115 | c.sendAlert(alertInappropriateFallback) 116 | return errors.New("tls: client using inappropriate protocol fallback") 117 | } 118 | break 119 | } 120 | } 121 | 122 | if len(hs.clientHello.compressionMethods) != 1 || 123 | hs.clientHello.compressionMethods[0] != compressionNone { 124 | c.sendAlert(alertIllegalParameter) 125 | return errors.New("tls: TLS 1.3 client supports illegal compression methods") 126 | } 127 | 128 | hs.hello.random = make([]byte, 32) 129 | if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { 130 | c.sendAlert(alertInternalError) 131 | return err 132 | } 133 | 134 | if len(hs.clientHello.secureRenegotiation) != 0 { 135 | c.sendAlert(alertHandshakeFailure) 136 | return errors.New("tls: initial handshake had non-empty renegotiation extension") 137 | } 138 | 139 | if hs.clientHello.earlyData { 140 | // See RFC 8446, Section 4.2.10 for the complicated behavior required 141 | // here. The scenario is that a different server at our address offered 142 | // to accept early data in the past, which we can't handle. For now, all 143 | // 0-RTT enabled session tickets need to expire before a Go server can 144 | // replace a server or join a pool. That's the same requirement that 145 | // applies to mixing or replacing with any TLS 1.2 server. 146 | c.sendAlert(alertUnsupportedExtension) 147 | return errors.New("tls: client sent unexpected early data") 148 | } 149 | 150 | hs.hello.sessionId = hs.clientHello.sessionId 151 | hs.hello.compressionMethod = compressionNone 152 | 153 | preferenceList := defaultCipherSuitesTLS13 154 | if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { 155 | preferenceList = defaultCipherSuitesTLS13NoAES 156 | } 157 | for _, suiteID := range preferenceList { 158 | hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID) 159 | if hs.suite != nil { 160 | break 161 | } 162 | } 163 | if hs.suite == nil { 164 | c.sendAlert(alertHandshakeFailure) 165 | return errors.New("tls: no cipher suite supported by both client and server") 166 | } 167 | c.cipherSuite = hs.suite.id 168 | hs.hello.cipherSuite = hs.suite.id 169 | hs.transcript = hs.suite.hash.New() 170 | 171 | // Pick the ECDHE group in server preference order, but give priority to 172 | // groups with a key share, to avoid a HelloRetryRequest round-trip. 173 | var selectedGroup CurveID 174 | var clientKeyShare *keyShare 175 | GroupSelection: 176 | for _, preferredGroup := range c.config.curvePreferences() { 177 | for _, ks := range hs.clientHello.keyShares { 178 | if ks.group == preferredGroup { 179 | selectedGroup = ks.group 180 | clientKeyShare = &ks 181 | break GroupSelection 182 | } 183 | } 184 | if selectedGroup != 0 { 185 | continue 186 | } 187 | for _, group := range hs.clientHello.supportedCurves { 188 | if group == preferredGroup { 189 | selectedGroup = group 190 | break 191 | } 192 | } 193 | } 194 | if selectedGroup == 0 { 195 | c.sendAlert(alertHandshakeFailure) 196 | return errors.New("tls: no ECDHE curve supported by both client and server") 197 | } 198 | if clientKeyShare == nil { 199 | if err := hs.doHelloRetryRequest(selectedGroup); err != nil { 200 | return err 201 | } 202 | clientKeyShare = &hs.clientHello.keyShares[0] 203 | } 204 | 205 | if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok { 206 | c.sendAlert(alertInternalError) 207 | return errors.New("tls: CurvePreferences includes unsupported curve") 208 | } 209 | params, err := generateECDHEParameters(c.config.rand(), selectedGroup) 210 | if err != nil { 211 | c.sendAlert(alertInternalError) 212 | return err 213 | } 214 | hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()} 215 | hs.sharedKey = params.SharedKey(clientKeyShare.data) 216 | if hs.sharedKey == nil { 217 | c.sendAlert(alertIllegalParameter) 218 | return errors.New("tls: invalid client key share") 219 | } 220 | 221 | c.serverName = hs.clientHello.serverName 222 | return nil 223 | } 224 | 225 | func (hs *serverHandshakeStateTLS13) checkForResumption() error { 226 | c := hs.c 227 | 228 | if c.config.SessionTicketsDisabled { 229 | return nil 230 | } 231 | 232 | modeOK := false 233 | for _, mode := range hs.clientHello.pskModes { 234 | if mode == pskModeDHE { 235 | modeOK = true 236 | break 237 | } 238 | } 239 | if !modeOK { 240 | return nil 241 | } 242 | 243 | if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { 244 | c.sendAlert(alertIllegalParameter) 245 | return errors.New("tls: invalid or missing PSK binders") 246 | } 247 | if len(hs.clientHello.pskIdentities) == 0 { 248 | return nil 249 | } 250 | 251 | for i, identity := range hs.clientHello.pskIdentities { 252 | if i >= maxClientPSKIdentities { 253 | break 254 | } 255 | 256 | plaintext, _ := c.decryptTicket(identity.label) 257 | if plaintext == nil { 258 | continue 259 | } 260 | sessionState := new(sessionStateTLS13) 261 | if ok := sessionState.unmarshal(plaintext); !ok { 262 | continue 263 | } 264 | 265 | createdAt := time.Unix(int64(sessionState.createdAt), 0) 266 | if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { 267 | continue 268 | } 269 | 270 | // We don't check the obfuscated ticket age because it's affected by 271 | // clock skew and it's only a freshness signal useful for shrinking the 272 | // window for replay attacks, which don't affect us as we don't do 0-RTT. 273 | 274 | pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) 275 | if pskSuite == nil || pskSuite.hash != hs.suite.hash { 276 | continue 277 | } 278 | 279 | // PSK connections don't re-establish client certificates, but carry 280 | // them over in the session ticket. Ensure the presence of client certs 281 | // in the ticket is consistent with the configured requirements. 282 | sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 283 | needClientCerts := requiresClientCert(c.config.ClientAuth) 284 | if needClientCerts && !sessionHasClientCerts { 285 | continue 286 | } 287 | if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { 288 | continue 289 | } 290 | 291 | psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption", 292 | nil, hs.suite.hash.Size()) 293 | hs.earlySecret = hs.suite.extract(psk, nil) 294 | binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) 295 | // Clone the transcript in case a HelloRetryRequest was recorded. 296 | transcript := cloneHash(hs.transcript, hs.suite.hash) 297 | if transcript == nil { 298 | c.sendAlert(alertInternalError) 299 | return errors.New("tls: internal error: failed to clone hash") 300 | } 301 | transcript.Write(hs.clientHello.marshalWithoutBinders()) 302 | pskBinder := hs.suite.finishedHash(binderKey, transcript) 303 | if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { 304 | c.sendAlert(alertDecryptError) 305 | return errors.New("tls: invalid PSK binder") 306 | } 307 | 308 | c.didResume = true 309 | if err := c.processCertsFromClient(sessionState.certificate); err != nil { 310 | return err 311 | } 312 | 313 | hs.hello.selectedIdentityPresent = true 314 | hs.hello.selectedIdentity = uint16(i) 315 | hs.usingPSK = true 316 | return nil 317 | } 318 | 319 | return nil 320 | } 321 | 322 | // cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler 323 | // interfaces implemented by standard library hashes to clone the state of in 324 | // to a new instance of h. It returns nil if the operation fails. 325 | func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { 326 | // Recreate the interface to avoid importing encoding. 327 | type binaryMarshaler interface { 328 | MarshalBinary() (data []byte, err error) 329 | UnmarshalBinary(data []byte) error 330 | } 331 | marshaler, ok := in.(binaryMarshaler) 332 | if !ok { 333 | return nil 334 | } 335 | state, err := marshaler.MarshalBinary() 336 | if err != nil { 337 | return nil 338 | } 339 | out := h.New() 340 | unmarshaler, ok := out.(binaryMarshaler) 341 | if !ok { 342 | return nil 343 | } 344 | if err := unmarshaler.UnmarshalBinary(state); err != nil { 345 | return nil 346 | } 347 | return out 348 | } 349 | 350 | func (hs *serverHandshakeStateTLS13) pickCertificate() error { 351 | c := hs.c 352 | 353 | // Only one of PSK and certificates are used at a time. 354 | if hs.usingPSK { 355 | return nil 356 | } 357 | 358 | // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. 359 | if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { 360 | return c.sendAlert(alertMissingExtension) 361 | } 362 | 363 | certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) 364 | if err != nil { 365 | if err == errNoCertificates { 366 | c.sendAlert(alertUnrecognizedName) 367 | } else { 368 | c.sendAlert(alertInternalError) 369 | } 370 | return err 371 | } 372 | hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) 373 | if err != nil { 374 | // getCertificate returned a certificate that is unsupported or 375 | // incompatible with the client's signature algorithms. 376 | c.sendAlert(alertHandshakeFailure) 377 | return err 378 | } 379 | hs.cert = certificate 380 | 381 | return nil 382 | } 383 | 384 | // sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility 385 | // with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. 386 | func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { 387 | if hs.sentDummyCCS { 388 | return nil 389 | } 390 | hs.sentDummyCCS = true 391 | 392 | _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) 393 | return err 394 | } 395 | 396 | func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { 397 | c := hs.c 398 | 399 | // The first ClientHello gets double-hashed into the transcript upon a 400 | // HelloRetryRequest. See RFC 8446, Section 4.4.1. 401 | hs.transcript.Write(hs.clientHello.marshal()) 402 | chHash := hs.transcript.Sum(nil) 403 | hs.transcript.Reset() 404 | hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) 405 | hs.transcript.Write(chHash) 406 | 407 | helloRetryRequest := &serverHelloMsg{ 408 | vers: hs.hello.vers, 409 | random: helloRetryRequestRandom, 410 | sessionId: hs.hello.sessionId, 411 | cipherSuite: hs.hello.cipherSuite, 412 | compressionMethod: hs.hello.compressionMethod, 413 | supportedVersion: hs.hello.supportedVersion, 414 | selectedGroup: selectedGroup, 415 | } 416 | 417 | hs.transcript.Write(helloRetryRequest.marshal()) 418 | if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { 419 | return err 420 | } 421 | 422 | if err := hs.sendDummyChangeCipherSpec(); err != nil { 423 | return err 424 | } 425 | 426 | msg, err := c.readHandshake() 427 | if err != nil { 428 | return err 429 | } 430 | 431 | clientHello, ok := msg.(*clientHelloMsg) 432 | if !ok { 433 | c.sendAlert(alertUnexpectedMessage) 434 | return unexpectedMessageError(clientHello, msg) 435 | } 436 | 437 | if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup { 438 | c.sendAlert(alertIllegalParameter) 439 | return errors.New("tls: client sent invalid key share in second ClientHello") 440 | } 441 | 442 | if clientHello.earlyData { 443 | c.sendAlert(alertIllegalParameter) 444 | return errors.New("tls: client indicated early data in second ClientHello") 445 | } 446 | 447 | if illegalClientHelloChange(clientHello, hs.clientHello) { 448 | c.sendAlert(alertIllegalParameter) 449 | return errors.New("tls: client illegally modified second ClientHello") 450 | } 451 | 452 | hs.clientHello = clientHello 453 | return nil 454 | } 455 | 456 | // illegalClientHelloChange reports whether the two ClientHello messages are 457 | // different, with the exception of the changes allowed before and after a 458 | // HelloRetryRequest. See RFC 8446, Section 4.1.2. 459 | func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { 460 | if len(ch.supportedVersions) != len(ch1.supportedVersions) || 461 | len(ch.cipherSuites) != len(ch1.cipherSuites) || 462 | len(ch.supportedCurves) != len(ch1.supportedCurves) || 463 | len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || 464 | len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || 465 | len(ch.alpnProtocols) != len(ch1.alpnProtocols) { 466 | return true 467 | } 468 | for i := range ch.supportedVersions { 469 | if ch.supportedVersions[i] != ch1.supportedVersions[i] { 470 | return true 471 | } 472 | } 473 | for i := range ch.cipherSuites { 474 | if ch.cipherSuites[i] != ch1.cipherSuites[i] { 475 | return true 476 | } 477 | } 478 | for i := range ch.supportedCurves { 479 | if ch.supportedCurves[i] != ch1.supportedCurves[i] { 480 | return true 481 | } 482 | } 483 | for i := range ch.supportedSignatureAlgorithms { 484 | if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { 485 | return true 486 | } 487 | } 488 | for i := range ch.supportedSignatureAlgorithmsCert { 489 | if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { 490 | return true 491 | } 492 | } 493 | for i := range ch.alpnProtocols { 494 | if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { 495 | return true 496 | } 497 | } 498 | return ch.vers != ch1.vers || 499 | !bytes.Equal(ch.random, ch1.random) || 500 | !bytes.Equal(ch.sessionId, ch1.sessionId) || 501 | !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || 502 | ch.serverName != ch1.serverName || 503 | ch.ocspStapling != ch1.ocspStapling || 504 | !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || 505 | ch.ticketSupported != ch1.ticketSupported || 506 | !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || 507 | ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || 508 | !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || 509 | ch.scts != ch1.scts || 510 | !bytes.Equal(ch.cookie, ch1.cookie) || 511 | !bytes.Equal(ch.pskModes, ch1.pskModes) 512 | } 513 | 514 | func (hs *serverHandshakeStateTLS13) sendServerParameters() error { 515 | c := hs.c 516 | 517 | hs.transcript.Write(hs.clientHello.marshal()) 518 | hs.transcript.Write(hs.hello.marshal()) 519 | if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 520 | return err 521 | } 522 | 523 | if err := hs.sendDummyChangeCipherSpec(); err != nil { 524 | return err 525 | } 526 | 527 | earlySecret := hs.earlySecret 528 | if earlySecret == nil { 529 | earlySecret = hs.suite.extract(nil, nil) 530 | } 531 | hs.handshakeSecret = hs.suite.extract(hs.sharedKey, 532 | hs.suite.deriveSecret(earlySecret, "derived", nil)) 533 | 534 | clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, 535 | clientHandshakeTrafficLabel, hs.transcript) 536 | c.in.setTrafficSecret(hs.suite, clientSecret) 537 | serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, 538 | serverHandshakeTrafficLabel, hs.transcript) 539 | c.out.setTrafficSecret(hs.suite, serverSecret) 540 | 541 | err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) 542 | if err != nil { 543 | c.sendAlert(alertInternalError) 544 | return err 545 | } 546 | err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) 547 | if err != nil { 548 | c.sendAlert(alertInternalError) 549 | return err 550 | } 551 | 552 | encryptedExtensions := new(encryptedExtensionsMsg) 553 | 554 | selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols) 555 | if err != nil { 556 | c.sendAlert(alertNoApplicationProtocol) 557 | return err 558 | } 559 | encryptedExtensions.alpnProtocol = selectedProto 560 | c.clientProtocol = selectedProto 561 | 562 | hs.transcript.Write(encryptedExtensions.marshal()) 563 | if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil { 564 | return err 565 | } 566 | 567 | return nil 568 | } 569 | 570 | func (hs *serverHandshakeStateTLS13) requestClientCert() bool { 571 | return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK 572 | } 573 | 574 | func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { 575 | c := hs.c 576 | 577 | // Only one of PSK and certificates are used at a time. 578 | if hs.usingPSK { 579 | return nil 580 | } 581 | 582 | if hs.requestClientCert() { 583 | // Request a client certificate 584 | certReq := new(certificateRequestMsgTLS13) 585 | certReq.ocspStapling = true 586 | certReq.scts = true 587 | certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms 588 | if c.config.ClientCAs != nil { 589 | certReq.certificateAuthorities = c.config.ClientCAs.Subjects() 590 | } 591 | 592 | hs.transcript.Write(certReq.marshal()) 593 | if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { 594 | return err 595 | } 596 | } 597 | 598 | certMsg := new(certificateMsgTLS13) 599 | 600 | certMsg.certificate = *hs.cert 601 | certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 602 | certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 603 | 604 | hs.transcript.Write(certMsg.marshal()) 605 | if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 606 | return err 607 | } 608 | 609 | certVerifyMsg := new(certificateVerifyMsg) 610 | certVerifyMsg.hasSignatureAlgorithm = true 611 | certVerifyMsg.signatureAlgorithm = hs.sigAlg 612 | 613 | sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) 614 | if err != nil { 615 | return c.sendAlert(alertInternalError) 616 | } 617 | 618 | signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) 619 | signOpts := crypto.SignerOpts(sigHash) 620 | if sigType == signatureRSAPSS { 621 | signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} 622 | } 623 | sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) 624 | if err != nil { 625 | public := hs.cert.PrivateKey.(crypto.Signer).Public() 626 | if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && 627 | rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS 628 | c.sendAlert(alertHandshakeFailure) 629 | } else { 630 | c.sendAlert(alertInternalError) 631 | } 632 | return errors.New("tls: failed to sign handshake: " + err.Error()) 633 | } 634 | certVerifyMsg.signature = sig 635 | 636 | hs.transcript.Write(certVerifyMsg.marshal()) 637 | if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { 638 | return err 639 | } 640 | 641 | return nil 642 | } 643 | 644 | func (hs *serverHandshakeStateTLS13) sendServerFinished() error { 645 | c := hs.c 646 | 647 | finished := &finishedMsg{ 648 | verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), 649 | } 650 | 651 | hs.transcript.Write(finished.marshal()) 652 | if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 653 | return err 654 | } 655 | 656 | // Derive secrets that take context through the server Finished. 657 | 658 | hs.masterSecret = hs.suite.extract(nil, 659 | hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) 660 | 661 | hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, 662 | clientApplicationTrafficLabel, hs.transcript) 663 | serverSecret := hs.suite.deriveSecret(hs.masterSecret, 664 | serverApplicationTrafficLabel, hs.transcript) 665 | c.out.setTrafficSecret(hs.suite, serverSecret) 666 | 667 | err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) 668 | if err != nil { 669 | c.sendAlert(alertInternalError) 670 | return err 671 | } 672 | err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) 673 | if err != nil { 674 | c.sendAlert(alertInternalError) 675 | return err 676 | } 677 | 678 | c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) 679 | 680 | // If we did not request client certificates, at this point we can 681 | // precompute the client finished and roll the transcript forward to send 682 | // session tickets in our first flight. 683 | if !hs.requestClientCert() { 684 | if err := hs.sendSessionTickets(); err != nil { 685 | return err 686 | } 687 | } 688 | 689 | return nil 690 | } 691 | 692 | func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { 693 | if hs.c.config.SessionTicketsDisabled { 694 | return false 695 | } 696 | 697 | // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. 698 | for _, pskMode := range hs.clientHello.pskModes { 699 | if pskMode == pskModeDHE { 700 | return true 701 | } 702 | } 703 | return false 704 | } 705 | 706 | func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { 707 | c := hs.c 708 | 709 | hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) 710 | finishedMsg := &finishedMsg{ 711 | verifyData: hs.clientFinished, 712 | } 713 | hs.transcript.Write(finishedMsg.marshal()) 714 | 715 | if !hs.shouldSendSessionTickets() { 716 | return nil 717 | } 718 | 719 | resumptionSecret := hs.suite.deriveSecret(hs.masterSecret, 720 | resumptionLabel, hs.transcript) 721 | 722 | m := new(newSessionTicketMsgTLS13) 723 | 724 | var certsFromClient [][]byte 725 | for _, cert := range c.peerCertificates { 726 | certsFromClient = append(certsFromClient, cert.Raw) 727 | } 728 | state := sessionStateTLS13{ 729 | cipherSuite: hs.suite.id, 730 | createdAt: uint64(c.config.time().Unix()), 731 | resumptionSecret: resumptionSecret, 732 | certificate: Certificate{ 733 | Certificate: certsFromClient, 734 | OCSPStaple: c.ocspResponse, 735 | SignedCertificateTimestamps: c.scts, 736 | }, 737 | } 738 | var err error 739 | m.label, err = c.encryptTicket(state.marshal()) 740 | if err != nil { 741 | return err 742 | } 743 | m.lifetime = uint32(maxSessionTicketLifetime / time.Second) 744 | 745 | // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1 746 | // The value is not stored anywhere; we never need to check the ticket age 747 | // because 0-RTT is not supported. 748 | ageAdd := make([]byte, 4) 749 | _, err = hs.c.config.rand().Read(ageAdd) 750 | if err != nil { 751 | return err 752 | } 753 | m.ageAdd = binary.LittleEndian.Uint32(ageAdd) 754 | 755 | // ticket_nonce, which must be unique per connection, is always left at 756 | // zero because we only ever send one ticket per connection. 757 | 758 | if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { 759 | return err 760 | } 761 | 762 | return nil 763 | } 764 | 765 | func (hs *serverHandshakeStateTLS13) readClientCertificate() error { 766 | c := hs.c 767 | 768 | if !hs.requestClientCert() { 769 | // Make sure the connection is still being verified whether or not 770 | // the server requested a client certificate. 771 | if c.config.VerifyConnection != nil { 772 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 773 | c.sendAlert(alertBadCertificate) 774 | return err 775 | } 776 | } 777 | return nil 778 | } 779 | 780 | // If we requested a client certificate, then the client must send a 781 | // certificate message. If it's empty, no CertificateVerify is sent. 782 | 783 | msg, err := c.readHandshake() 784 | if err != nil { 785 | return err 786 | } 787 | 788 | certMsg, ok := msg.(*certificateMsgTLS13) 789 | if !ok { 790 | c.sendAlert(alertUnexpectedMessage) 791 | return unexpectedMessageError(certMsg, msg) 792 | } 793 | hs.transcript.Write(certMsg.marshal()) 794 | 795 | if err := c.processCertsFromClient(certMsg.certificate); err != nil { 796 | return err 797 | } 798 | 799 | if c.config.VerifyConnection != nil { 800 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { 801 | c.sendAlert(alertBadCertificate) 802 | return err 803 | } 804 | } 805 | 806 | if len(certMsg.certificate.Certificate) != 0 { 807 | msg, err = c.readHandshake() 808 | if err != nil { 809 | return err 810 | } 811 | 812 | certVerify, ok := msg.(*certificateVerifyMsg) 813 | if !ok { 814 | c.sendAlert(alertUnexpectedMessage) 815 | return unexpectedMessageError(certVerify, msg) 816 | } 817 | 818 | // See RFC 8446, Section 4.4.3. 819 | if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { 820 | c.sendAlert(alertIllegalParameter) 821 | return errors.New("tls: client certificate used with invalid signature algorithm") 822 | } 823 | sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) 824 | if err != nil { 825 | return c.sendAlert(alertInternalError) 826 | } 827 | if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { 828 | c.sendAlert(alertIllegalParameter) 829 | return errors.New("tls: client certificate used with invalid signature algorithm") 830 | } 831 | signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) 832 | if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, 833 | sigHash, signed, certVerify.signature); err != nil { 834 | c.sendAlert(alertDecryptError) 835 | return errors.New("tls: invalid signature by the client certificate: " + err.Error()) 836 | } 837 | 838 | hs.transcript.Write(certVerify.marshal()) 839 | } 840 | 841 | // If we waited until the client certificates to send session tickets, we 842 | // are ready to do it now. 843 | if err := hs.sendSessionTickets(); err != nil { 844 | return err 845 | } 846 | 847 | return nil 848 | } 849 | 850 | func (hs *serverHandshakeStateTLS13) readClientFinished() error { 851 | c := hs.c 852 | 853 | msg, err := c.readHandshake() 854 | if err != nil { 855 | return err 856 | } 857 | 858 | finished, ok := msg.(*finishedMsg) 859 | if !ok { 860 | c.sendAlert(alertUnexpectedMessage) 861 | return unexpectedMessageError(finished, msg) 862 | } 863 | 864 | if !hmac.Equal(hs.clientFinished, finished.verifyData) { 865 | c.sendAlert(alertDecryptError) 866 | return errors.New("tls: invalid client finished hash") 867 | } 868 | 869 | c.in.setTrafficSecret(hs.suite, hs.trafficSecret) 870 | 871 | return nil 872 | } 873 | -------------------------------------------------------------------------------- /key_agreement.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "crypto" 9 | "crypto/md5" 10 | "crypto/rsa" 11 | "crypto/sha1" 12 | "crypto/x509" 13 | "errors" 14 | "fmt" 15 | "io" 16 | ) 17 | 18 | // a keyAgreement implements the client and server side of a TLS key agreement 19 | // protocol by generating and processing key exchange messages. 20 | type keyAgreement interface { 21 | // On the server side, the first two methods are called in order. 22 | 23 | // In the case that the key agreement protocol doesn't use a 24 | // ServerKeyExchange message, generateServerKeyExchange can return nil, 25 | // nil. 26 | generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) 27 | processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) 28 | 29 | // On the client side, the next two methods are called in order. 30 | 31 | // This method may not be called if the server doesn't send a 32 | // ServerKeyExchange message. 33 | processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error 34 | generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) 35 | } 36 | 37 | var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") 38 | var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") 39 | 40 | // rsaKeyAgreement implements the standard TLS key agreement where the client 41 | // encrypts the pre-master secret to the server's public key. 42 | type rsaKeyAgreement struct{} 43 | 44 | func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 45 | return nil, nil 46 | } 47 | 48 | func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 49 | if len(ckx.ciphertext) < 2 { 50 | return nil, errClientKeyExchange 51 | } 52 | ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) 53 | if ciphertextLen != len(ckx.ciphertext)-2 { 54 | return nil, errClientKeyExchange 55 | } 56 | ciphertext := ckx.ciphertext[2:] 57 | 58 | priv, ok := cert.PrivateKey.(crypto.Decrypter) 59 | if !ok { 60 | return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") 61 | } 62 | // Perform constant time RSA PKCS #1 v1.5 decryption 63 | preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) 64 | if err != nil { 65 | return nil, err 66 | } 67 | // We don't check the version number in the premaster secret. For one, 68 | // by checking it, we would leak information about the validity of the 69 | // encrypted pre-master secret. Secondly, it provides only a small 70 | // benefit against a downgrade attack and some implementations send the 71 | // wrong version anyway. See the discussion at the end of section 72 | // 7.4.7.1 of RFC 4346. 73 | return preMasterSecret, nil 74 | } 75 | 76 | func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { 77 | return errors.New("tls: unexpected ServerKeyExchange") 78 | } 79 | 80 | func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 81 | preMasterSecret := make([]byte, 48) 82 | preMasterSecret[0] = byte(clientHello.vers >> 8) 83 | preMasterSecret[1] = byte(clientHello.vers) 84 | _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) 85 | if err != nil { 86 | return nil, nil, err 87 | } 88 | 89 | rsaKey, ok := cert.PublicKey.(*rsa.PublicKey) 90 | if !ok { 91 | return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite") 92 | } 93 | encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret) 94 | if err != nil { 95 | return nil, nil, err 96 | } 97 | ckx := new(clientKeyExchangeMsg) 98 | ckx.ciphertext = make([]byte, len(encrypted)+2) 99 | ckx.ciphertext[0] = byte(len(encrypted) >> 8) 100 | ckx.ciphertext[1] = byte(len(encrypted)) 101 | copy(ckx.ciphertext[2:], encrypted) 102 | return preMasterSecret, ckx, nil 103 | } 104 | 105 | // sha1Hash calculates a SHA1 hash over the given byte slices. 106 | func sha1Hash(slices [][]byte) []byte { 107 | hsha1 := sha1.New() 108 | for _, slice := range slices { 109 | hsha1.Write(slice) 110 | } 111 | return hsha1.Sum(nil) 112 | } 113 | 114 | // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the 115 | // concatenation of an MD5 and SHA1 hash. 116 | func md5SHA1Hash(slices [][]byte) []byte { 117 | md5sha1 := make([]byte, md5.Size+sha1.Size) 118 | hmd5 := md5.New() 119 | for _, slice := range slices { 120 | hmd5.Write(slice) 121 | } 122 | copy(md5sha1, hmd5.Sum(nil)) 123 | copy(md5sha1[md5.Size:], sha1Hash(slices)) 124 | return md5sha1 125 | } 126 | 127 | // hashForServerKeyExchange hashes the given slices and returns their digest 128 | // using the given hash function (for >= TLS 1.2) or using a default based on 129 | // the sigType (for earlier TLS versions). For Ed25519 signatures, which don't 130 | // do pre-hashing, it returns the concatenation of the slices. 131 | func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte { 132 | if sigType == signatureEd25519 { 133 | var signed []byte 134 | for _, slice := range slices { 135 | signed = append(signed, slice...) 136 | } 137 | return signed 138 | } 139 | if version >= VersionTLS12 { 140 | h := hashFunc.New() 141 | for _, slice := range slices { 142 | h.Write(slice) 143 | } 144 | digest := h.Sum(nil) 145 | return digest 146 | } 147 | if sigType == signatureECDSA { 148 | return sha1Hash(slices) 149 | } 150 | return md5SHA1Hash(slices) 151 | } 152 | 153 | // ecdheKeyAgreement implements a TLS key agreement where the server 154 | // generates an ephemeral EC public/private key pair and signs it. The 155 | // pre-master secret is then calculated using ECDH. The signature may 156 | // be ECDSA, Ed25519 or RSA. 157 | type ecdheKeyAgreement struct { 158 | version uint16 159 | isRSA bool 160 | params ecdheParameters 161 | 162 | // ckx and preMasterSecret are generated in processServerKeyExchange 163 | // and returned in generateClientKeyExchange. 164 | ckx *clientKeyExchangeMsg 165 | preMasterSecret []byte 166 | } 167 | 168 | func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { 169 | var curveID CurveID 170 | for _, c := range clientHello.supportedCurves { 171 | if config.supportsCurve(c) { 172 | curveID = c 173 | break 174 | } 175 | } 176 | 177 | if curveID == 0 { 178 | return nil, errors.New("tls: no supported elliptic curves offered") 179 | } 180 | if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { 181 | return nil, errors.New("tls: CurvePreferences includes unsupported curve") 182 | } 183 | 184 | params, err := generateECDHEParameters(config.rand(), curveID) 185 | if err != nil { 186 | return nil, err 187 | } 188 | ka.params = params 189 | 190 | // See RFC 4492, Section 5.4. 191 | ecdhePublic := params.PublicKey() 192 | serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) 193 | serverECDHEParams[0] = 3 // named curve 194 | serverECDHEParams[1] = byte(curveID >> 8) 195 | serverECDHEParams[2] = byte(curveID) 196 | serverECDHEParams[3] = byte(len(ecdhePublic)) 197 | copy(serverECDHEParams[4:], ecdhePublic) 198 | 199 | priv, ok := cert.PrivateKey.(crypto.Signer) 200 | if !ok { 201 | return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) 202 | } 203 | 204 | var signatureAlgorithm SignatureScheme 205 | var sigType uint8 206 | var sigHash crypto.Hash 207 | if ka.version >= VersionTLS12 { 208 | signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) 209 | if err != nil { 210 | return nil, err 211 | } 212 | sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) 213 | if err != nil { 214 | return nil, err 215 | } 216 | } else { 217 | sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) 218 | if err != nil { 219 | return nil, err 220 | } 221 | } 222 | if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { 223 | return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") 224 | } 225 | 226 | signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams) 227 | 228 | signOpts := crypto.SignerOpts(sigHash) 229 | if sigType == signatureRSAPSS { 230 | signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} 231 | } 232 | sig, err := priv.Sign(config.rand(), signed, signOpts) 233 | if err != nil { 234 | return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) 235 | } 236 | 237 | skx := new(serverKeyExchangeMsg) 238 | sigAndHashLen := 0 239 | if ka.version >= VersionTLS12 { 240 | sigAndHashLen = 2 241 | } 242 | skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig)) 243 | copy(skx.key, serverECDHEParams) 244 | k := skx.key[len(serverECDHEParams):] 245 | if ka.version >= VersionTLS12 { 246 | k[0] = byte(signatureAlgorithm >> 8) 247 | k[1] = byte(signatureAlgorithm) 248 | k = k[2:] 249 | } 250 | k[0] = byte(len(sig) >> 8) 251 | k[1] = byte(len(sig)) 252 | copy(k[2:], sig) 253 | 254 | return skx, nil 255 | } 256 | 257 | func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { 258 | if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { 259 | return nil, errClientKeyExchange 260 | } 261 | 262 | preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:]) 263 | if preMasterSecret == nil { 264 | return nil, errClientKeyExchange 265 | } 266 | 267 | return preMasterSecret, nil 268 | } 269 | 270 | func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { 271 | if len(skx.key) < 4 { 272 | return errServerKeyExchange 273 | } 274 | if skx.key[0] != 3 { // named curve 275 | return errors.New("tls: server selected unsupported curve") 276 | } 277 | curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) 278 | 279 | publicLen := int(skx.key[3]) 280 | if publicLen+4 > len(skx.key) { 281 | return errServerKeyExchange 282 | } 283 | serverECDHEParams := skx.key[:4+publicLen] 284 | publicKey := serverECDHEParams[4:] 285 | 286 | sig := skx.key[4+publicLen:] 287 | if len(sig) < 2 { 288 | return errServerKeyExchange 289 | } 290 | 291 | if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { 292 | return errors.New("tls: server selected unsupported curve") 293 | } 294 | 295 | params, err := generateECDHEParameters(config.rand(), curveID) 296 | if err != nil { 297 | return err 298 | } 299 | ka.params = params 300 | 301 | ka.preMasterSecret = params.SharedKey(publicKey) 302 | if ka.preMasterSecret == nil { 303 | return errServerKeyExchange 304 | } 305 | 306 | ourPublicKey := params.PublicKey() 307 | ka.ckx = new(clientKeyExchangeMsg) 308 | ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey)) 309 | ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) 310 | copy(ka.ckx.ciphertext[1:], ourPublicKey) 311 | 312 | var sigType uint8 313 | var sigHash crypto.Hash 314 | if ka.version >= VersionTLS12 { 315 | signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) 316 | sig = sig[2:] 317 | if len(sig) < 2 { 318 | return errServerKeyExchange 319 | } 320 | 321 | if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) { 322 | return errors.New("tls: certificate used with invalid signature algorithm") 323 | } 324 | sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) 325 | if err != nil { 326 | return err 327 | } 328 | } else { 329 | sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey) 330 | if err != nil { 331 | return err 332 | } 333 | } 334 | if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { 335 | return errServerKeyExchange 336 | } 337 | 338 | sigLen := int(sig[0])<<8 | int(sig[1]) 339 | if sigLen+2 != len(sig) { 340 | return errServerKeyExchange 341 | } 342 | sig = sig[2:] 343 | 344 | signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams) 345 | if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil { 346 | return errors.New("tls: invalid signature by the server certificate: " + err.Error()) 347 | } 348 | return nil 349 | } 350 | 351 | func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { 352 | if ka.ckx == nil { 353 | return nil, nil, errors.New("tls: missing ServerKeyExchange message") 354 | } 355 | 356 | return ka.preMasterSecret, ka.ckx, nil 357 | } 358 | -------------------------------------------------------------------------------- /key_schedule.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "crypto/elliptic" 9 | "crypto/hmac" 10 | "errors" 11 | "hash" 12 | "io" 13 | "math/big" 14 | 15 | "golang.org/x/crypto/cryptobyte" 16 | "golang.org/x/crypto/curve25519" 17 | "golang.org/x/crypto/hkdf" 18 | ) 19 | 20 | // This file contains the functions necessary to compute the TLS 1.3 key 21 | // schedule. See RFC 8446, Section 7. 22 | 23 | const ( 24 | resumptionBinderLabel = "res binder" 25 | clientHandshakeTrafficLabel = "c hs traffic" 26 | serverHandshakeTrafficLabel = "s hs traffic" 27 | clientApplicationTrafficLabel = "c ap traffic" 28 | serverApplicationTrafficLabel = "s ap traffic" 29 | exporterLabel = "exp master" 30 | resumptionLabel = "res master" 31 | trafficUpdateLabel = "traffic upd" 32 | ) 33 | 34 | // expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1. 35 | func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte { 36 | var hkdfLabel cryptobyte.Builder 37 | hkdfLabel.AddUint16(uint16(length)) 38 | hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { 39 | b.AddBytes([]byte("tls13 ")) 40 | b.AddBytes([]byte(label)) 41 | }) 42 | hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { 43 | b.AddBytes(context) 44 | }) 45 | out := make([]byte, length) 46 | n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out) 47 | if err != nil || n != length { 48 | panic("tls: HKDF-Expand-Label invocation failed unexpectedly") 49 | } 50 | return out 51 | } 52 | 53 | // deriveSecret implements Derive-Secret from RFC 8446, Section 7.1. 54 | func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte { 55 | if transcript == nil { 56 | transcript = c.hash.New() 57 | } 58 | return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size()) 59 | } 60 | 61 | // extract implements HKDF-Extract with the cipher suite hash. 62 | func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { 63 | if newSecret == nil { 64 | newSecret = make([]byte, c.hash.Size()) 65 | } 66 | return hkdf.Extract(c.hash.New, newSecret, currentSecret) 67 | } 68 | 69 | // nextTrafficSecret generates the next traffic secret, given the current one, 70 | // according to RFC 8446, Section 7.2. 71 | func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte { 72 | return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size()) 73 | } 74 | 75 | // trafficKey generates traffic keys according to RFC 8446, Section 7.3. 76 | func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { 77 | key = c.expandLabel(trafficSecret, "key", nil, c.keyLen) 78 | iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength) 79 | return 80 | } 81 | 82 | // finishedHash generates the Finished verify_data or PskBinderEntry according 83 | // to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey 84 | // selection. 85 | func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte { 86 | finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size()) 87 | verifyData := hmac.New(c.hash.New, finishedKey) 88 | verifyData.Write(transcript.Sum(nil)) 89 | return verifyData.Sum(nil) 90 | } 91 | 92 | // exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to 93 | // RFC 8446, Section 7.5. 94 | func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) { 95 | expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript) 96 | return func(label string, context []byte, length int) ([]byte, error) { 97 | secret := c.deriveSecret(expMasterSecret, label, nil) 98 | h := c.hash.New() 99 | h.Write(context) 100 | return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil 101 | } 102 | } 103 | 104 | // ecdheParameters implements Diffie-Hellman with either NIST curves or X25519, 105 | // according to RFC 8446, Section 4.2.8.2. 106 | type ecdheParameters interface { 107 | CurveID() CurveID 108 | PublicKey() []byte 109 | SharedKey(peerPublicKey []byte) []byte 110 | } 111 | 112 | func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) { 113 | if curveID == X25519 { 114 | privateKey := make([]byte, curve25519.ScalarSize) 115 | if _, err := io.ReadFull(rand, privateKey); err != nil { 116 | return nil, err 117 | } 118 | publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint) 119 | if err != nil { 120 | return nil, err 121 | } 122 | return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil 123 | } 124 | 125 | curve, ok := curveForCurveID(curveID) 126 | if !ok { 127 | return nil, errors.New("tls: internal error: unsupported curve") 128 | } 129 | 130 | p := &nistParameters{curveID: curveID} 131 | var err error 132 | p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand) 133 | if err != nil { 134 | return nil, err 135 | } 136 | return p, nil 137 | } 138 | 139 | func curveForCurveID(id CurveID) (elliptic.Curve, bool) { 140 | switch id { 141 | case CurveP256: 142 | return elliptic.P256(), true 143 | case CurveP384: 144 | return elliptic.P384(), true 145 | case CurveP521: 146 | return elliptic.P521(), true 147 | default: 148 | return nil, false 149 | } 150 | } 151 | 152 | type nistParameters struct { 153 | privateKey []byte 154 | x, y *big.Int // public key 155 | curveID CurveID 156 | } 157 | 158 | func (p *nistParameters) CurveID() CurveID { 159 | return p.curveID 160 | } 161 | 162 | func (p *nistParameters) PublicKey() []byte { 163 | curve, _ := curveForCurveID(p.curveID) 164 | return elliptic.Marshal(curve, p.x, p.y) 165 | } 166 | 167 | func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { 168 | curve, _ := curveForCurveID(p.curveID) 169 | // Unmarshal also checks whether the given point is on the curve. 170 | x, y := elliptic.Unmarshal(curve, peerPublicKey) 171 | if x == nil { 172 | return nil 173 | } 174 | 175 | xShared, _ := curve.ScalarMult(x, y, p.privateKey) 176 | sharedKey := make([]byte, (curve.Params().BitSize+7)/8) 177 | return xShared.FillBytes(sharedKey) 178 | } 179 | 180 | type x25519Parameters struct { 181 | privateKey []byte 182 | publicKey []byte 183 | } 184 | 185 | func (p *x25519Parameters) CurveID() CurveID { 186 | return X25519 187 | } 188 | 189 | func (p *x25519Parameters) PublicKey() []byte { 190 | return p.publicKey[:] 191 | } 192 | 193 | func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte { 194 | sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey) 195 | if err != nil { 196 | return nil 197 | } 198 | return sharedKey 199 | } 200 | -------------------------------------------------------------------------------- /prf.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "crypto" 9 | "crypto/hmac" 10 | "crypto/md5" 11 | "crypto/sha1" 12 | "crypto/sha256" 13 | "crypto/sha512" 14 | "errors" 15 | "fmt" 16 | "hash" 17 | ) 18 | 19 | // Split a premaster secret in two as specified in RFC 4346, Section 5. 20 | func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { 21 | s1 = secret[0 : (len(secret)+1)/2] 22 | s2 = secret[len(secret)/2:] 23 | return 24 | } 25 | 26 | // pHash implements the P_hash function, as defined in RFC 4346, Section 5. 27 | func pHash(result, secret, seed []byte, hash func() hash.Hash) { 28 | h := hmac.New(hash, secret) 29 | h.Write(seed) 30 | a := h.Sum(nil) 31 | 32 | j := 0 33 | for j < len(result) { 34 | h.Reset() 35 | h.Write(a) 36 | h.Write(seed) 37 | b := h.Sum(nil) 38 | copy(result[j:], b) 39 | j += len(b) 40 | 41 | h.Reset() 42 | h.Write(a) 43 | a = h.Sum(nil) 44 | } 45 | } 46 | 47 | // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. 48 | func prf10(result, secret, label, seed []byte) { 49 | hashSHA1 := sha1.New 50 | hashMD5 := md5.New 51 | 52 | labelAndSeed := make([]byte, len(label)+len(seed)) 53 | copy(labelAndSeed, label) 54 | copy(labelAndSeed[len(label):], seed) 55 | 56 | s1, s2 := splitPreMasterSecret(secret) 57 | pHash(result, s1, labelAndSeed, hashMD5) 58 | result2 := make([]byte, len(result)) 59 | pHash(result2, s2, labelAndSeed, hashSHA1) 60 | 61 | for i, b := range result2 { 62 | result[i] ^= b 63 | } 64 | } 65 | 66 | // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. 67 | func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { 68 | return func(result, secret, label, seed []byte) { 69 | labelAndSeed := make([]byte, len(label)+len(seed)) 70 | copy(labelAndSeed, label) 71 | copy(labelAndSeed[len(label):], seed) 72 | 73 | pHash(result, secret, labelAndSeed, hashFunc) 74 | } 75 | } 76 | 77 | const ( 78 | masterSecretLength = 48 // Length of a master secret in TLS 1.1. 79 | finishedVerifyLength = 12 // Length of verify_data in a Finished message. 80 | ) 81 | 82 | var masterSecretLabel = []byte("master secret") 83 | var keyExpansionLabel = []byte("key expansion") 84 | var clientFinishedLabel = []byte("client finished") 85 | var serverFinishedLabel = []byte("server finished") 86 | 87 | func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { 88 | switch version { 89 | case VersionTLS10, VersionTLS11: 90 | return prf10, crypto.Hash(0) 91 | case VersionTLS12: 92 | if suite.flags&suiteSHA384 != 0 { 93 | return prf12(sha512.New384), crypto.SHA384 94 | } 95 | return prf12(sha256.New), crypto.SHA256 96 | default: 97 | panic("unknown version") 98 | } 99 | } 100 | 101 | func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { 102 | prf, _ := prfAndHashForVersion(version, suite) 103 | return prf 104 | } 105 | 106 | // masterFromPreMasterSecret generates the master secret from the pre-master 107 | // secret. See RFC 5246, Section 8.1. 108 | func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { 109 | seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) 110 | seed = append(seed, clientRandom...) 111 | seed = append(seed, serverRandom...) 112 | 113 | masterSecret := make([]byte, masterSecretLength) 114 | prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) 115 | return masterSecret 116 | } 117 | 118 | // keysFromMasterSecret generates the connection keys from the master 119 | // secret, given the lengths of the MAC key, cipher key and IV, as defined in 120 | // RFC 2246, Section 6.3. 121 | func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { 122 | seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) 123 | seed = append(seed, serverRandom...) 124 | seed = append(seed, clientRandom...) 125 | 126 | n := 2*macLen + 2*keyLen + 2*ivLen 127 | keyMaterial := make([]byte, n) 128 | prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) 129 | clientMAC = keyMaterial[:macLen] 130 | keyMaterial = keyMaterial[macLen:] 131 | serverMAC = keyMaterial[:macLen] 132 | keyMaterial = keyMaterial[macLen:] 133 | clientKey = keyMaterial[:keyLen] 134 | keyMaterial = keyMaterial[keyLen:] 135 | serverKey = keyMaterial[:keyLen] 136 | keyMaterial = keyMaterial[keyLen:] 137 | clientIV = keyMaterial[:ivLen] 138 | keyMaterial = keyMaterial[ivLen:] 139 | serverIV = keyMaterial[:ivLen] 140 | return 141 | } 142 | 143 | func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { 144 | var buffer []byte 145 | if version >= VersionTLS12 { 146 | buffer = []byte{} 147 | } 148 | 149 | prf, hash := prfAndHashForVersion(version, cipherSuite) 150 | if hash != 0 { 151 | return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf} 152 | } 153 | 154 | return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf} 155 | } 156 | 157 | // A finishedHash calculates the hash of a set of handshake messages suitable 158 | // for including in a Finished message. 159 | type finishedHash struct { 160 | client hash.Hash 161 | server hash.Hash 162 | 163 | // Prior to TLS 1.2, an additional MD5 hash is required. 164 | clientMD5 hash.Hash 165 | serverMD5 hash.Hash 166 | 167 | // In TLS 1.2, a full buffer is sadly required. 168 | buffer []byte 169 | 170 | version uint16 171 | prf func(result, secret, label, seed []byte) 172 | } 173 | 174 | func (h *finishedHash) Write(msg []byte) (n int, err error) { 175 | h.client.Write(msg) 176 | h.server.Write(msg) 177 | 178 | if h.version < VersionTLS12 { 179 | h.clientMD5.Write(msg) 180 | h.serverMD5.Write(msg) 181 | } 182 | 183 | if h.buffer != nil { 184 | h.buffer = append(h.buffer, msg...) 185 | } 186 | 187 | return len(msg), nil 188 | } 189 | 190 | func (h finishedHash) Sum() []byte { 191 | if h.version >= VersionTLS12 { 192 | return h.client.Sum(nil) 193 | } 194 | 195 | out := make([]byte, 0, md5.Size+sha1.Size) 196 | out = h.clientMD5.Sum(out) 197 | return h.client.Sum(out) 198 | } 199 | 200 | // clientSum returns the contents of the verify_data member of a client's 201 | // Finished message. 202 | func (h finishedHash) clientSum(masterSecret []byte) []byte { 203 | out := make([]byte, finishedVerifyLength) 204 | h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) 205 | return out 206 | } 207 | 208 | // serverSum returns the contents of the verify_data member of a server's 209 | // Finished message. 210 | func (h finishedHash) serverSum(masterSecret []byte) []byte { 211 | out := make([]byte, finishedVerifyLength) 212 | h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) 213 | return out 214 | } 215 | 216 | // hashForClientCertificate returns the handshake messages so far, pre-hashed if 217 | // necessary, suitable for signing by a TLS client certificate. 218 | func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte { 219 | if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { 220 | panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer") 221 | } 222 | 223 | if sigType == signatureEd25519 { 224 | return h.buffer 225 | } 226 | 227 | if h.version >= VersionTLS12 { 228 | hash := hashAlg.New() 229 | hash.Write(h.buffer) 230 | return hash.Sum(nil) 231 | } 232 | 233 | if sigType == signatureECDSA { 234 | return h.server.Sum(nil) 235 | } 236 | 237 | return h.Sum() 238 | } 239 | 240 | // discardHandshakeBuffer is called when there is no more need to 241 | // buffer the entirety of the handshake messages. 242 | func (h *finishedHash) discardHandshakeBuffer() { 243 | h.buffer = nil 244 | } 245 | 246 | // noExportedKeyingMaterial is used as a value of 247 | // ConnectionState.ekm when renegotiation is enabled and thus 248 | // we wish to fail all key-material export requests. 249 | func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { 250 | return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") 251 | } 252 | 253 | // ekmFromMasterSecret generates exported keying material as defined in RFC 5705. 254 | func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { 255 | return func(label string, context []byte, length int) ([]byte, error) { 256 | switch label { 257 | case "client finished", "server finished", "master secret", "key expansion": 258 | // These values are reserved and may not be used. 259 | return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) 260 | } 261 | 262 | seedLen := len(serverRandom) + len(clientRandom) 263 | if context != nil { 264 | seedLen += 2 + len(context) 265 | } 266 | seed := make([]byte, 0, seedLen) 267 | 268 | seed = append(seed, clientRandom...) 269 | seed = append(seed, serverRandom...) 270 | 271 | if context != nil { 272 | if len(context) >= 1<<16 { 273 | return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") 274 | } 275 | seed = append(seed, byte(len(context)>>8), byte(len(context))) 276 | seed = append(seed, context...) 277 | } 278 | 279 | keyMaterial := make([]byte, length) 280 | prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) 281 | return keyMaterial, nil 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /ticket.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go 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-Go file. 4 | 5 | package xtls 6 | 7 | import ( 8 | "bytes" 9 | "crypto/aes" 10 | "crypto/cipher" 11 | "crypto/hmac" 12 | "crypto/sha256" 13 | "crypto/subtle" 14 | "errors" 15 | "io" 16 | 17 | "golang.org/x/crypto/cryptobyte" 18 | ) 19 | 20 | // sessionState contains the information that is serialized into a session 21 | // ticket in order to later resume a connection. 22 | type sessionState struct { 23 | vers uint16 24 | cipherSuite uint16 25 | createdAt uint64 26 | masterSecret []byte // opaque master_secret<1..2^16-1>; 27 | // struct { opaque certificate<1..2^24-1> } Certificate; 28 | certificates [][]byte // Certificate certificate_list<0..2^24-1>; 29 | 30 | // usedOldKey is true if the ticket from which this session came from 31 | // was encrypted with an older key and thus should be refreshed. 32 | usedOldKey bool 33 | } 34 | 35 | func (m *sessionState) marshal() []byte { 36 | var b cryptobyte.Builder 37 | b.AddUint16(m.vers) 38 | b.AddUint16(m.cipherSuite) 39 | addUint64(&b, m.createdAt) 40 | b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { 41 | b.AddBytes(m.masterSecret) 42 | }) 43 | b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { 44 | for _, cert := range m.certificates { 45 | b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { 46 | b.AddBytes(cert) 47 | }) 48 | } 49 | }) 50 | return b.BytesOrPanic() 51 | } 52 | 53 | func (m *sessionState) unmarshal(data []byte) bool { 54 | *m = sessionState{usedOldKey: m.usedOldKey} 55 | s := cryptobyte.String(data) 56 | if ok := s.ReadUint16(&m.vers) && 57 | s.ReadUint16(&m.cipherSuite) && 58 | readUint64(&s, &m.createdAt) && 59 | readUint16LengthPrefixed(&s, &m.masterSecret) && 60 | len(m.masterSecret) != 0; !ok { 61 | return false 62 | } 63 | var certList cryptobyte.String 64 | if !s.ReadUint24LengthPrefixed(&certList) { 65 | return false 66 | } 67 | for !certList.Empty() { 68 | var cert []byte 69 | if !readUint24LengthPrefixed(&certList, &cert) { 70 | return false 71 | } 72 | m.certificates = append(m.certificates, cert) 73 | } 74 | return s.Empty() 75 | } 76 | 77 | // sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first 78 | // version (revision = 0) doesn't carry any of the information needed for 0-RTT 79 | // validation and the nonce is always empty. 80 | type sessionStateTLS13 struct { 81 | // uint8 version = 0x0304; 82 | // uint8 revision = 0; 83 | cipherSuite uint16 84 | createdAt uint64 85 | resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>; 86 | certificate Certificate // CertificateEntry certificate_list<0..2^24-1>; 87 | } 88 | 89 | func (m *sessionStateTLS13) marshal() []byte { 90 | var b cryptobyte.Builder 91 | b.AddUint16(VersionTLS13) 92 | b.AddUint8(0) // revision 93 | b.AddUint16(m.cipherSuite) 94 | addUint64(&b, m.createdAt) 95 | b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { 96 | b.AddBytes(m.resumptionSecret) 97 | }) 98 | marshalCertificate(&b, m.certificate) 99 | return b.BytesOrPanic() 100 | } 101 | 102 | func (m *sessionStateTLS13) unmarshal(data []byte) bool { 103 | *m = sessionStateTLS13{} 104 | s := cryptobyte.String(data) 105 | var version uint16 106 | var revision uint8 107 | return s.ReadUint16(&version) && 108 | version == VersionTLS13 && 109 | s.ReadUint8(&revision) && 110 | revision == 0 && 111 | s.ReadUint16(&m.cipherSuite) && 112 | readUint64(&s, &m.createdAt) && 113 | readUint8LengthPrefixed(&s, &m.resumptionSecret) && 114 | len(m.resumptionSecret) != 0 && 115 | unmarshalCertificate(&s, &m.certificate) && 116 | s.Empty() 117 | } 118 | 119 | func (c *Conn) encryptTicket(state []byte) ([]byte, error) { 120 | if len(c.ticketKeys) == 0 { 121 | return nil, errors.New("tls: internal error: session ticket keys unavailable") 122 | } 123 | 124 | encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size) 125 | keyName := encrypted[:ticketKeyNameLen] 126 | iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] 127 | macBytes := encrypted[len(encrypted)-sha256.Size:] 128 | 129 | if _, err := io.ReadFull(c.config.rand(), iv); err != nil { 130 | return nil, err 131 | } 132 | key := c.ticketKeys[0] 133 | copy(keyName, key.keyName[:]) 134 | block, err := aes.NewCipher(key.aesKey[:]) 135 | if err != nil { 136 | return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) 137 | } 138 | cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state) 139 | 140 | mac := hmac.New(sha256.New, key.hmacKey[:]) 141 | mac.Write(encrypted[:len(encrypted)-sha256.Size]) 142 | mac.Sum(macBytes[:0]) 143 | 144 | return encrypted, nil 145 | } 146 | 147 | func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) { 148 | if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size { 149 | return nil, false 150 | } 151 | 152 | keyName := encrypted[:ticketKeyNameLen] 153 | iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] 154 | macBytes := encrypted[len(encrypted)-sha256.Size:] 155 | ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size] 156 | 157 | keyIndex := -1 158 | for i, candidateKey := range c.ticketKeys { 159 | if bytes.Equal(keyName, candidateKey.keyName[:]) { 160 | keyIndex = i 161 | break 162 | } 163 | } 164 | if keyIndex == -1 { 165 | return nil, false 166 | } 167 | key := &c.ticketKeys[keyIndex] 168 | 169 | mac := hmac.New(sha256.New, key.hmacKey[:]) 170 | mac.Write(encrypted[:len(encrypted)-sha256.Size]) 171 | expected := mac.Sum(nil) 172 | 173 | if subtle.ConstantTimeCompare(macBytes, expected) != 1 { 174 | return nil, false 175 | } 176 | 177 | block, err := aes.NewCipher(key.aesKey[:]) 178 | if err != nil { 179 | return nil, false 180 | } 181 | plaintext = make([]byte, len(ciphertext)) 182 | cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) 183 | 184 | return plaintext, keyIndex > 0 185 | } 186 | -------------------------------------------------------------------------------- /tls.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go 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-Go file. 4 | 5 | // package xtls partially implements TLS 1.2, as specified in RFC 5246, 6 | // and TLS 1.3, as specified in RFC 8446. 7 | package xtls 8 | 9 | // BUG(agl): The crypto/tls package only implements some countermeasures 10 | // against Lucky13 attacks on CBC-mode encryption, and only on SHA1 11 | // variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and 12 | // https://www.imperialviolet.org/2013/02/04/luckythirteen.html. 13 | 14 | import ( 15 | "bytes" 16 | "context" 17 | "crypto" 18 | "crypto/ecdsa" 19 | "crypto/ed25519" 20 | "crypto/rsa" 21 | "crypto/x509" 22 | "encoding/pem" 23 | "errors" 24 | "fmt" 25 | "net" 26 | "os" 27 | "strings" 28 | ) 29 | 30 | // Server returns a new TLS server side connection 31 | // using conn as the underlying transport. 32 | // The configuration config must be non-nil and must include 33 | // at least one certificate or else set GetCertificate. 34 | func Server(conn net.Conn, config *Config) *Conn { 35 | c := &Conn{ 36 | conn: conn, 37 | config: config, 38 | } 39 | c.handshakeFn = c.serverHandshake 40 | return c 41 | } 42 | 43 | // Client returns a new TLS client side connection 44 | // using conn as the underlying transport. 45 | // The config cannot be nil: users must set either ServerName or 46 | // InsecureSkipVerify in the config. 47 | func Client(conn net.Conn, config *Config) *Conn { 48 | c := &Conn{ 49 | conn: conn, 50 | config: config, 51 | isClient: true, 52 | } 53 | c.handshakeFn = c.clientHandshake 54 | return c 55 | } 56 | 57 | // A listener implements a network listener (net.Listener) for TLS connections. 58 | type listener struct { 59 | net.Listener 60 | config *Config 61 | } 62 | 63 | // Accept waits for and returns the next incoming TLS connection. 64 | // The returned connection is of type *Conn. 65 | func (l *listener) Accept() (net.Conn, error) { 66 | c, err := l.Listener.Accept() 67 | if err != nil { 68 | return nil, err 69 | } 70 | return Server(c, l.config), nil 71 | } 72 | 73 | // NewListener creates a Listener which accepts connections from an inner 74 | // Listener and wraps each connection with Server. 75 | // The configuration config must be non-nil and must include 76 | // at least one certificate or else set GetCertificate. 77 | func NewListener(inner net.Listener, config *Config) net.Listener { 78 | l := new(listener) 79 | l.Listener = inner 80 | l.config = config 81 | return l 82 | } 83 | 84 | // Listen creates a TLS listener accepting connections on the 85 | // given network address using net.Listen. 86 | // The configuration config must be non-nil and must include 87 | // at least one certificate or else set GetCertificate. 88 | func Listen(network, laddr string, config *Config) (net.Listener, error) { 89 | if config == nil || len(config.Certificates) == 0 && 90 | config.GetCertificate == nil && config.GetConfigForClient == nil { 91 | return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config") 92 | } 93 | l, err := net.Listen(network, laddr) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return NewListener(l, config), nil 98 | } 99 | 100 | type timeoutError struct{} 101 | 102 | func (timeoutError) Error() string { return "tls: DialWithDialer timed out" } 103 | func (timeoutError) Timeout() bool { return true } 104 | func (timeoutError) Temporary() bool { return true } 105 | 106 | // DialWithDialer connects to the given network address using dialer.Dial and 107 | // then initiates a TLS handshake, returning the resulting TLS connection. Any 108 | // timeout or deadline given in the dialer apply to connection and TLS 109 | // handshake as a whole. 110 | // 111 | // DialWithDialer interprets a nil configuration as equivalent to the zero 112 | // configuration; see the documentation of Config for the defaults. 113 | // 114 | // DialWithDialer uses context.Background internally; to specify the context, 115 | // use Dialer.DialContext with NetDialer set to the desired dialer. 116 | func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { 117 | return dial(context.Background(), dialer, network, addr, config) 118 | } 119 | 120 | func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { 121 | if netDialer.Timeout != 0 { 122 | var cancel context.CancelFunc 123 | ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout) 124 | defer cancel() 125 | } 126 | 127 | if !netDialer.Deadline.IsZero() { 128 | var cancel context.CancelFunc 129 | ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline) 130 | defer cancel() 131 | } 132 | 133 | rawConn, err := netDialer.DialContext(ctx, network, addr) 134 | if err != nil { 135 | return nil, err 136 | } 137 | 138 | colonPos := strings.LastIndex(addr, ":") 139 | if colonPos == -1 { 140 | colonPos = len(addr) 141 | } 142 | hostname := addr[:colonPos] 143 | 144 | if config == nil { 145 | config = defaultConfig() 146 | } 147 | // If no ServerName is set, infer the ServerName 148 | // from the hostname we're connecting to. 149 | if config.ServerName == "" { 150 | // Make a copy to avoid polluting argument or default. 151 | c := config.Clone() 152 | c.ServerName = hostname 153 | config = c 154 | } 155 | 156 | conn := Client(rawConn, config) 157 | if err := conn.HandshakeContext(ctx); err != nil { 158 | rawConn.Close() 159 | return nil, err 160 | } 161 | return conn, nil 162 | } 163 | 164 | // Dial connects to the given network address using net.Dial 165 | // and then initiates a TLS handshake, returning the resulting 166 | // TLS connection. 167 | // Dial interprets a nil configuration as equivalent to 168 | // the zero configuration; see the documentation of Config 169 | // for the defaults. 170 | func Dial(network, addr string, config *Config) (*Conn, error) { 171 | return DialWithDialer(new(net.Dialer), network, addr, config) 172 | } 173 | 174 | // Dialer dials TLS connections given a configuration and a Dialer for the 175 | // underlying connection. 176 | type Dialer struct { 177 | // NetDialer is the optional dialer to use for the TLS connections' 178 | // underlying TCP connections. 179 | // A nil NetDialer is equivalent to the net.Dialer zero value. 180 | NetDialer *net.Dialer 181 | 182 | // Config is the TLS configuration to use for new connections. 183 | // A nil configuration is equivalent to the zero 184 | // configuration; see the documentation of Config for the 185 | // defaults. 186 | Config *Config 187 | } 188 | 189 | // Dial connects to the given network address and initiates a TLS 190 | // handshake, returning the resulting TLS connection. 191 | // 192 | // The returned Conn, if any, will always be of type *Conn. 193 | // 194 | // Dial uses context.Background internally; to specify the context, 195 | // use DialContext. 196 | func (d *Dialer) Dial(network, addr string) (net.Conn, error) { 197 | return d.DialContext(context.Background(), network, addr) 198 | } 199 | 200 | func (d *Dialer) netDialer() *net.Dialer { 201 | if d.NetDialer != nil { 202 | return d.NetDialer 203 | } 204 | return new(net.Dialer) 205 | } 206 | 207 | // DialContext connects to the given network address and initiates a TLS 208 | // handshake, returning the resulting TLS connection. 209 | // 210 | // The provided Context must be non-nil. If the context expires before 211 | // the connection is complete, an error is returned. Once successfully 212 | // connected, any expiration of the context will not affect the 213 | // connection. 214 | // 215 | // The returned Conn, if any, will always be of type *Conn. 216 | func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { 217 | c, err := dial(ctx, d.netDialer(), network, addr, d.Config) 218 | if err != nil { 219 | // Don't return c (a typed nil) in an interface. 220 | return nil, err 221 | } 222 | return c, nil 223 | } 224 | 225 | // LoadX509KeyPair reads and parses a public/private key pair from a pair 226 | // of files. The files must contain PEM encoded data. The certificate file 227 | // may contain intermediate certificates following the leaf certificate to 228 | // form a certificate chain. On successful return, Certificate.Leaf will 229 | // be nil because the parsed form of the certificate is not retained. 230 | func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { 231 | certPEMBlock, err := os.ReadFile(certFile) 232 | if err != nil { 233 | return Certificate{}, err 234 | } 235 | keyPEMBlock, err := os.ReadFile(keyFile) 236 | if err != nil { 237 | return Certificate{}, err 238 | } 239 | return X509KeyPair(certPEMBlock, keyPEMBlock) 240 | } 241 | 242 | // X509KeyPair parses a public/private key pair from a pair of 243 | // PEM encoded data. On successful return, Certificate.Leaf will be nil because 244 | // the parsed form of the certificate is not retained. 245 | func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { 246 | fail := func(err error) (Certificate, error) { return Certificate{}, err } 247 | 248 | var cert Certificate 249 | var skippedBlockTypes []string 250 | for { 251 | var certDERBlock *pem.Block 252 | certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) 253 | if certDERBlock == nil { 254 | break 255 | } 256 | if certDERBlock.Type == "CERTIFICATE" { 257 | cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) 258 | } else { 259 | skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) 260 | } 261 | } 262 | 263 | if len(cert.Certificate) == 0 { 264 | if len(skippedBlockTypes) == 0 { 265 | return fail(errors.New("tls: failed to find any PEM data in certificate input")) 266 | } 267 | if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { 268 | return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) 269 | } 270 | return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) 271 | } 272 | 273 | skippedBlockTypes = skippedBlockTypes[:0] 274 | var keyDERBlock *pem.Block 275 | for { 276 | keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) 277 | if keyDERBlock == nil { 278 | if len(skippedBlockTypes) == 0 { 279 | return fail(errors.New("tls: failed to find any PEM data in key input")) 280 | } 281 | if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { 282 | return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) 283 | } 284 | return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) 285 | } 286 | if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { 287 | break 288 | } 289 | skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) 290 | } 291 | 292 | // We don't need to parse the public key for TLS, but we so do anyway 293 | // to check that it looks sane and matches the private key. 294 | x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 295 | if err != nil { 296 | return fail(err) 297 | } 298 | 299 | cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) 300 | if err != nil { 301 | return fail(err) 302 | } 303 | 304 | switch pub := x509Cert.PublicKey.(type) { 305 | case *rsa.PublicKey: 306 | priv, ok := cert.PrivateKey.(*rsa.PrivateKey) 307 | if !ok { 308 | return fail(errors.New("tls: private key type does not match public key type")) 309 | } 310 | if pub.N.Cmp(priv.N) != 0 { 311 | return fail(errors.New("tls: private key does not match public key")) 312 | } 313 | case *ecdsa.PublicKey: 314 | priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) 315 | if !ok { 316 | return fail(errors.New("tls: private key type does not match public key type")) 317 | } 318 | if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { 319 | return fail(errors.New("tls: private key does not match public key")) 320 | } 321 | case ed25519.PublicKey: 322 | priv, ok := cert.PrivateKey.(ed25519.PrivateKey) 323 | if !ok { 324 | return fail(errors.New("tls: private key type does not match public key type")) 325 | } 326 | if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) { 327 | return fail(errors.New("tls: private key does not match public key")) 328 | } 329 | default: 330 | return fail(errors.New("tls: unknown public key algorithm")) 331 | } 332 | 333 | return cert, nil 334 | } 335 | 336 | // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates 337 | // PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. 338 | // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. 339 | func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { 340 | if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 341 | return key, nil 342 | } 343 | if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { 344 | switch key := key.(type) { 345 | case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey: 346 | return key, nil 347 | default: 348 | return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") 349 | } 350 | } 351 | if key, err := x509.ParseECPrivateKey(der); err == nil { 352 | return key, nil 353 | } 354 | 355 | return nil, errors.New("tls: failed to parse private key") 356 | } 357 | --------------------------------------------------------------------------------