1 /** 2 * TLS Messages 3 * 4 * Copyright: 5 * (C) 2004-2011,2015 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.tls.messages; 12 13 import botan.constants; 14 static if (BOTAN_HAS_TLS): 15 package: 16 17 import botan.tls.handshake_state; 18 import botan.tls.session_key; 19 import std.algorithm : canFind; 20 import botan.tls.alert : TLSAlert; 21 import memutils.dictionarylist; 22 23 public import botan.algo_base.sym_algo; 24 public import botan.tls.session; 25 public import botan.tls.policy; 26 public import botan.tls.ciphersuite; 27 public import botan.tls.reader; 28 public import botan.tls.extensions; 29 public import botan.tls.handshake_io; 30 public import botan.tls.version_; 31 public import botan.tls.handshake_hash; 32 public import botan.tls.magic; 33 public import botan.tls.credentials_manager; 34 import botan.constructs.srp6; 35 import botan.utils.loadstor; 36 import botan.constructs.srp6; 37 import botan.math.bigint.bigint; 38 import botan.pubkey.algo.ec_group; 39 import botan.math.ec_gfp.point_gfp; 40 import botan.pubkey.pkcs8; 41 import botan.pubkey.pubkey; 42 import botan.pubkey.algo.dh; 43 import botan.pubkey.algo.ecdh; 44 import botan.pubkey.algo.rsa; 45 import botan.cert.x509.x509cert; 46 import botan.asn1.oids; 47 import botan.asn1.der_enc; 48 import botan.asn1.ber_dec; 49 import botan.utils.loadstor; 50 import botan.utils.types; 51 import botan.libstate.lookup; 52 import botan.rng.rng; 53 import botan.utils.types : Unique; 54 import std.datetime; 55 import botan.utils.types; 56 57 // import string; 58 59 enum { 60 TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF, 61 TLS_FALLBACK_SCSV = 0x5600 62 } 63 64 /** 65 * TLS Handshake Message Base Class 66 */ 67 interface HandshakeMessage 68 { 69 public: 70 abstract HandshakeType type() const; 71 72 abstract Vector!ubyte serialize() const; 73 } 74 75 /** 76 * DTLS Hello Verify Request 77 */ 78 final class HelloVerifyRequest : HandshakeMessage 79 { 80 public: 81 override Vector!ubyte serialize() const 82 { 83 /* DTLS 1.2 server implementations SHOULD use DTLS version 1.0 84 regardless of the version of TLS that is expected to be 85 negotiated (RFC 6347, section 4.2.1) 86 */ 87 88 TLSProtocolVersion format_version = TLSProtocolVersion(TLSProtocolVersion.DTLS_V10); 89 90 Vector!ubyte bits; 91 bits.pushBack(format_version.majorVersion()); 92 bits.pushBack(format_version.minorVersion()); 93 bits.pushBack(cast(ubyte) m_cookie.length); 94 bits ~= m_cookie[]; 95 return bits.move(); 96 } 97 98 override HandshakeType type() const { return HELLO_VERIFY_REQUEST; } 99 100 ref const(Vector!ubyte) cookie() const { return m_cookie; } 101 102 this(const ref Vector!ubyte buf) 103 { 104 if (buf.length < 3) 105 throw new DecodingError("Hello verify request too small"); 106 107 TLSProtocolVersion version_ = TLSProtocolVersion(buf[0], buf[1]); 108 109 if (version_ != TLSProtocolVersion.DTLS_V10 && 110 version_ != TLSProtocolVersion.DTLS_V12) 111 { 112 throw new DecodingError("Unknown version from server in hello verify request"); 113 } 114 115 if ((cast(size_t) buf[2]) + 3 != buf.length) 116 throw new DecodingError("Bad length in hello verify request"); 117 118 m_cookie[] = buf.ptr[3 .. buf.length]; 119 } 120 121 this(const ref Vector!ubyte client_hello_bits, in string client_identity, in SymmetricKey secret_key) 122 { 123 Unique!MessageAuthenticationCode hmac = retrieveMac("HMAC(SHA-256)").clone(); 124 hmac.setKey(secret_key); 125 126 hmac.updateBigEndian(client_hello_bits.length); 127 hmac.update(client_hello_bits); 128 hmac.updateBigEndian(client_identity.length); 129 hmac.update(client_identity); 130 131 m_cookie = unlock(hmac.finished()); 132 } 133 private: 134 Vector!ubyte m_cookie; 135 } 136 137 /** 138 * TLSClient Hello Message 139 */ 140 final class ClientHello : HandshakeMessage 141 { 142 public: 143 override HandshakeType type() const { return CLIENT_HELLO; } 144 145 const(TLSProtocolVersion) Version() const { return m_version; } 146 147 ref const(Vector!ubyte) random() const { return m_random; } 148 149 const(ubyte[]) randomBytes() const { return m_random[]; } 150 151 ref const(Vector!ubyte) sessionId() const { return m_session_id; } 152 153 const(ubyte[]) sessionIdBytes() const { return m_session_id[]; } 154 155 ref const(Vector!ushort) ciphersuites() const { return m_suites; } 156 157 const(ushort[]) ciphersuitesData() const { return m_suites[]; } 158 159 ref const(Vector!ubyte) compressionMethods() const { return m_comp_methods; } 160 161 /* 162 * Check if we offered this ciphersuite 163 */ 164 bool offeredSuite(ushort ciphersuite) const 165 { 166 for (size_t i = 0; i != m_suites.length; ++i) 167 if (m_suites[i] == ciphersuite) 168 return true; 169 return false; 170 } 171 172 Vector!( Pair!(string, string) ) supportedAlgos() const 173 { 174 if (SignatureAlgorithms sigs = m_extensions.get!SignatureAlgorithms()) 175 return sigs.supportedSignatureAlgorthms().dup(); 176 return Vector!( Pair!(string, string) )(); 177 } 178 179 Vector!string supportedEccCurves() const 180 { 181 if (SupportedEllipticCurves ecc = m_extensions.get!SupportedEllipticCurves()) 182 return ecc.curves().dup(); 183 return Vector!string(); 184 } 185 186 string sniHostname() const 187 { 188 if (ServerNameIndicator sni = m_extensions.get!ServerNameIndicator()) 189 return sni.hostName(); 190 return ""; 191 } 192 193 string srpIdentifier() const 194 { 195 if (SRPIdentifier srp = m_extensions.get!SRPIdentifier()) 196 return srp.identifier(); 197 return ""; 198 } 199 200 bool sentFallbackSCSV() const 201 { 202 return offeredSuite(cast(ushort) TLS_FALLBACK_SCSV); 203 } 204 205 bool secureRenegotiation() const 206 { 207 return m_extensions.get!RenegotiationExtension() !is null; 208 } 209 210 Vector!ubyte renegotiationInfo() const 211 { 212 if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension()) 213 return reneg.renegotiationInfo().dup(); 214 return Vector!ubyte(); 215 } 216 217 size_t fragmentSize() const 218 { 219 if (MaximumFragmentLength frag = m_extensions.get!MaximumFragmentLength()) 220 return frag.fragmentSize(); 221 return 0; 222 } 223 224 bool supportsSessionTicket() const 225 { 226 return m_extensions.get!SessionTicket() !is null; 227 } 228 229 Vector!ubyte sessionTicket() const 230 { 231 if (SessionTicket ticket = m_extensions.get!SessionTicket()) 232 return ticket.contents().dup(); 233 return Vector!ubyte(); 234 } 235 236 bool supportsAlpn() const 237 { 238 return m_extensions.get!ApplicationLayerProtocolNotification() !is null; 239 } 240 241 bool supportsExtendedMasterSecret() const 242 { 243 return m_extensions.get!ExtendedMasterSecret() !is null; 244 } 245 246 const(Vector!string) nextProtocols() const 247 { 248 if (auto alpn = m_extensions.get!ApplicationLayerProtocolNotification()) 249 return alpn.protocols().dup; 250 return Vector!string(); 251 } 252 253 bool supportsHeartbeats() const 254 { 255 return m_extensions.get!HeartbeatSupportIndicator() !is null; 256 } 257 258 bool peerCanSendHeartbeats() const 259 { 260 if (HeartbeatSupportIndicator hb = m_extensions.get!HeartbeatSupportIndicator()) 261 return hb.peerAllowedToSend(); 262 return false; 263 } 264 265 bool supportsChannelID() const 266 { 267 return m_extensions.get!ChannelIDSupport() !is null; 268 } 269 270 void updateHelloCookie(in HelloVerifyRequest hello_verify) 271 { 272 if (!m_version.isDatagramProtocol()) 273 throw new Exception("Cannot use hello cookie with stream protocol"); 274 275 m_hello_cookie = hello_verify.cookie().dup; 276 } 277 278 const(Vector!HandshakeExtensionType) extensionTypes() const 279 { return m_extensions.extensionTypes(); } 280 281 /* 282 * Create a new TLSClient Hello message 283 */ 284 this(HandshakeIO io, 285 ref HandshakeHash hash, 286 TLSProtocolVersion _version, 287 in TLSPolicy policy, 288 RandomNumberGenerator rng, 289 Vector!ubyte reneg_info, 290 Vector!string next_protocols, 291 in string hostname, 292 in string srp_identifier) 293 { 294 //logDebug("ClientHello with hostname: ", hostname); 295 296 bool reneg_empty = reneg_info.empty; 297 m_version = _version; 298 299 assert(policy.acceptableProtocolVersion(_version), "Our policy accepts the version we are offering"); 300 301 m_random = makeHelloRandom(rng, policy); 302 m_suites = policy.ciphersuiteList(m_version, (srp_identifier != "")); 303 m_comp_methods = policy.compression(); 304 305 foreach (extension_; policy.enabledExtensions()) { 306 switch (extension_) { 307 case TLSEXT_SAFE_RENEGOTIATION: 308 m_extensions.add(new RenegotiationExtension(reneg_info.move())); 309 break; 310 case TLSEXT_SERVER_NAME_INDICATION: 311 m_extensions.add(new ServerNameIndicator(hostname)); 312 break; 313 case TLSEXT_EC_POINT_FORMATS: 314 m_extensions.add(new SupportedPointFormats); 315 break; 316 case TLSEXT_USABLE_ELLIPTIC_CURVES: 317 m_extensions.add(new SupportedEllipticCurves(policy.allowedEccCurves())); 318 break; 319 case TLSEXT_EXTENDED_MASTER_SECRET: 320 m_extensions.add(new ExtendedMasterSecret); 321 break; 322 case TLSEXT_SESSION_TICKET: 323 m_extensions.add(new SessionTicket()); 324 break; 325 case TLSEXT_SIGNATURE_ALGORITHMS: 326 if (m_version.supportsNegotiableSignatureAlgorithms()) 327 m_extensions.add(new SignatureAlgorithms(policy.allowedSignatureHashes(), 328 policy.allowedSignatureMethods())); 329 break; 330 case TLSEXT_STATUS_REQUEST: //todo: Complete support 331 m_extensions.add(new StatusRequest); 332 break; 333 case TLSEXT_NPN: 334 m_extensions.add(new NPN); 335 break; 336 case TLSEXT_SIGNED_CERT_TIMESTAMP: 337 m_extensions.add(new SignedCertificateTimestamp); 338 break; 339 case TLSEXT_ALPN: 340 if (reneg_empty && !next_protocols.empty) 341 m_extensions.add(new ApplicationLayerProtocolNotification(next_protocols.move)); 342 break; 343 case TLSEXT_CHANNEL_ID: 344 m_extensions.add(new ChannelIDSupport); 345 break; 346 case TLSEXT_SRP_IDENTIFIER: 347 m_extensions.add(new SRPIdentifier(srp_identifier)); 348 break; 349 case TLSEXT_HEARTBEAT_SUPPORT: 350 if (policy.negotiateHeartbeatSupport()) 351 m_extensions.add(new HeartbeatSupportIndicator(true)); 352 break; 353 default: 354 break; 355 } 356 357 } 358 359 if (policy.sendFallbackSCSV(_version)) 360 m_suites.pushBack(TLS_FALLBACK_SCSV); 361 else m_suites.pushBack(TLS_EMPTY_RENEGOTIATION_INFO_SCSV); 362 363 hash.update(io.send(this)); 364 } 365 366 367 /* 368 * Create a new TLSClient Hello message (session resumption case) 369 */ 370 this(HandshakeIO io, 371 ref HandshakeHash hash, 372 in TLSPolicy policy, 373 RandomNumberGenerator rng, 374 Vector!ubyte reneg_info, 375 in TLSSession session, 376 Vector!string next_protocols) 377 { 378 bool reneg_empty = reneg_info.empty; 379 380 m_version = session.Version(); 381 m_session_id = session.sessionId().dup; 382 m_random = makeHelloRandom(rng, policy); 383 m_suites = policy.ciphersuiteList(m_version, (session.srpIdentifier() != "")); 384 m_comp_methods = policy.compression(); 385 if (!valueExists(m_suites, session.ciphersuiteCode())) 386 m_suites.pushBack(session.ciphersuiteCode()); 387 388 if (!valueExists(m_comp_methods, session.compressionMethod())) 389 m_comp_methods.pushBack(session.compressionMethod()); 390 391 foreach (extension_; policy.enabledExtensions()) { 392 switch (extension_) { 393 case TLSEXT_SAFE_RENEGOTIATION: 394 m_extensions.add(new RenegotiationExtension(reneg_info.move())); 395 break; 396 case TLSEXT_SERVER_NAME_INDICATION: 397 m_extensions.add(new ServerNameIndicator(session.serverInfo().hostname())); 398 break; 399 case TLSEXT_EC_POINT_FORMATS: 400 m_extensions.add(new SupportedPointFormats); 401 break; 402 case TLSEXT_USABLE_ELLIPTIC_CURVES: 403 m_extensions.add(new SupportedEllipticCurves(policy.allowedEccCurves())); 404 break; 405 case TLSEXT_EXTENDED_MASTER_SECRET: 406 m_extensions.add(new ExtendedMasterSecret); 407 break; 408 case TLSEXT_SESSION_TICKET: 409 m_extensions.add(new SessionTicket(session.sessionTicket().dup)); 410 break; 411 case TLSEXT_SIGNATURE_ALGORITHMS: 412 if (m_version.supportsNegotiableSignatureAlgorithms()) 413 m_extensions.add(new SignatureAlgorithms(policy.allowedSignatureHashes(), 414 policy.allowedSignatureMethods())); 415 break; 416 case TLSEXT_STATUS_REQUEST: //todo: Complete support 417 m_extensions.add(new StatusRequest); 418 break; 419 case TLSEXT_NPN: 420 m_extensions.add(new NPN); 421 break; 422 case TLSEXT_SIGNED_CERT_TIMESTAMP: 423 m_extensions.add(new SignedCertificateTimestamp); 424 break; 425 case TLSEXT_ALPN: 426 if (reneg_empty && !next_protocols.empty) 427 m_extensions.add(new ApplicationLayerProtocolNotification(next_protocols.move)); 428 break; 429 case TLSEXT_CHANNEL_ID: 430 m_extensions.add(new ChannelIDSupport); 431 break; 432 case TLSEXT_SRP_IDENTIFIER: 433 m_extensions.add(new SRPIdentifier(session.srpIdentifier())); 434 break; 435 case TLSEXT_HEARTBEAT_SUPPORT: 436 if (policy.negotiateHeartbeatSupport()) 437 m_extensions.add(new HeartbeatSupportIndicator(true)); 438 break; 439 case TLSEXT_MAX_FRAGMENT_LENGTH: 440 if (session.fragmentSize() != 0) 441 m_extensions.add(new MaximumFragmentLength(session.fragmentSize())); 442 break; 443 default: 444 break; 445 } 446 } 447 448 449 if (policy.sendFallbackSCSV(m_version)) 450 m_suites.pushBack(TLS_FALLBACK_SCSV); 451 else 452 m_suites.pushBack(TLS_EMPTY_RENEGOTIATION_INFO_SCSV); 453 454 hash.update(io.send(this)); 455 } 456 bool deserialized; 457 /* 458 * Read a counterparty client hello 459 */ 460 this(const ref Vector!ubyte buf, HandshakeType type) 461 { 462 deserialized = true; 463 if (type == CLIENT_HELLO) 464 deserialize(buf); 465 } 466 467 protected: 468 /* 469 * Serialize a TLSClient Hello message 470 */ 471 override Vector!ubyte serialize() const 472 { 473 474 /*logDebug("Ciphersuites: ", ciphersuites()[]); 475 logDebug("Supported ECC curves: ", supportedEccCurves()[]); 476 logDebug("SupportedAlgos: ", supportedAlgos()[]); 477 logDebug("Session ID: ", sessionId[]); 478 logDebug("Random: ", random()[]); 479 logDebug("sni Hostname: ", sniHostname); 480 logDebug("sentFallback SCSV: ", sentFallbackSCSV()); 481 logDebug("Secure renegotiation: ", secureRenegotiation()); 482 logDebug("NextProtocol: ", nextProtocols[]); 483 */ 484 Vector!ubyte buf; 485 buf.reserve(512); 486 487 buf.pushBack(m_version.majorVersion()); 488 buf.pushBack(m_version.minorVersion()); 489 buf ~= m_random[]; 490 491 appendTlsLengthValue(buf, m_session_id, 1); 492 493 if (m_version.isDatagramProtocol()) 494 appendTlsLengthValue(buf, m_hello_cookie, 1); 495 496 appendTlsLengthValue(buf, m_suites, 2); 497 appendTlsLengthValue(buf, m_comp_methods, 1); 498 499 /* 500 * May not want to send extensions at all in some cases. If so, 501 * should include SCSV value (if reneg info is empty, if not we are 502 * renegotiating with a modern server) 503 */ 504 505 auto vec = m_extensions.serialize(); 506 // pad when between 256 and 511 (inclusive) bytes long 507 if ((buf.length+4) + vec.length <= 511 && (buf.length+4) + vec.length >= 256) 508 { 509 long pad = 512L - cast(long)vec.length - (cast(long)buf.length+4L) - 4L; 510 if (pad <= 0) 511 pad = 1; 512 ushort extn_size = cast(ushort)(vec.length+pad+4-2); 513 vec[0] = get_byte(0, extn_size); 514 vec[1] = get_byte(1, extn_size); 515 vec.pushBack(get_byte(0, cast(ushort) 21)); 516 vec.pushBack(get_byte(1, cast(ushort) 21)); // padding extension identifier 517 vec.pushBack(get_byte(0, cast(ushort) pad)); 518 vec.pushBack(get_byte(1, cast(ushort) pad)); 519 foreach (i; 0 .. pad) 520 vec ~= cast(ubyte)0x00; 521 } 522 buf ~= vec[]; 523 524 return buf.move(); 525 } 526 527 /* 528 * Deserialize a TLSClient Hello message 529 */ 530 void deserialize(const ref Vector!ubyte buf) 531 { 532 if (buf.length == 0) 533 throw new DecodingError("ClientHello: Packet corrupted"); 534 535 if (buf.length < 41) 536 throw new DecodingError("ClientHello: Packet corrupted"); 537 538 TLSDataReader reader = TLSDataReader("ClientHello", buf); 539 540 const ubyte major_version = reader.get_byte(); 541 const ubyte minor_version = reader.get_byte(); 542 543 m_version = TLSProtocolVersion(major_version, minor_version); 544 m_random = reader.getFixed!ubyte(32); 545 546 if (m_version.isDatagramProtocol()) 547 m_hello_cookie = reader.getRange!ubyte(1, 0, 255); 548 549 m_session_id = reader.getRange!ubyte(1, 0, 32); 550 551 m_suites = reader.getRangeVector!ushort(2, 1, 32767); 552 553 m_comp_methods = reader.getRangeVector!ubyte(1, 1, 255); 554 555 m_extensions.reserve(8); 556 m_extensions.deserialize(reader); 557 558 if (offeredSuite(cast(ushort)(TLS_EMPTY_RENEGOTIATION_INFO_SCSV))) 559 { 560 if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension()) 561 { 562 if (!reneg.renegotiationInfo().empty) 563 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, 564 "Client sent renegotiation SCSV and non-empty extension"); 565 } 566 else 567 { 568 // add fake extension 569 m_extensions.add(new RenegotiationExtension()); 570 } 571 } 572 /*logDebug("Ciphersuites: ", ciphersuites()[]); 573 logDebug("Session ID: ", sessionId[]); 574 logDebug("Random: ", random()[]); 575 logDebug("sni Hostname: ", sniHostname); 576 logDebug("sentFallback SCSV: ", sentFallbackSCSV()); 577 logDebug("Secure renegotiation: ", secureRenegotiation());*/ 578 //logDebug("NextProtocol: ", nextProtocols[]); 579 } 580 581 private: 582 TLSProtocolVersion m_version; 583 Vector!ubyte m_session_id; 584 Vector!ubyte m_random; 585 Vector!ushort m_suites; 586 Vector!ubyte m_comp_methods; 587 Vector!ubyte m_hello_cookie; // DTLS only 588 589 TLSExtensions m_extensions; 590 } 591 592 /** 593 * TLSServer Hello Message 594 */ 595 final class ServerHello : HandshakeMessage 596 { 597 public: 598 override const(HandshakeType) type() const { return SERVER_HELLO; } 599 600 TLSProtocolVersion Version() const { return m_version; } 601 602 ref const(Vector!ubyte) random() const { return m_random; } 603 604 const(ubyte[]) randomBytes() const { return m_random[]; } 605 606 ref const(Vector!ubyte) sessionId() const { return m_session_id; } 607 608 const(ubyte[]) sessionIdBytes() const { return m_session_id[]; } 609 610 ushort ciphersuite() const { return m_ciphersuite; } 611 612 ubyte compressionMethod() const { return m_comp_method; } 613 614 bool secureRenegotiation() const 615 { 616 return m_extensions.get!RenegotiationExtension() !is null; 617 } 618 619 Vector!ubyte renegotiationInfo() const 620 { 621 if (RenegotiationExtension reneg = m_extensions.get!RenegotiationExtension()) 622 return reneg.renegotiationInfo().dup; 623 return Vector!ubyte(); 624 } 625 626 size_t fragmentSize() const 627 { 628 if (MaximumFragmentLength frag = m_extensions.get!MaximumFragmentLength()) 629 return frag.fragmentSize(); 630 return 0; 631 } 632 633 bool supportsExtendedMasterSecret() const 634 { 635 return m_extensions.get!ExtendedMasterSecret() !is null; 636 } 637 638 bool supportsSessionTicket() const 639 { 640 return m_extensions.get!SessionTicket() !is null; 641 } 642 643 bool supportsHeartbeats() const 644 { 645 return m_extensions.get!HeartbeatSupportIndicator() !is null; 646 } 647 648 bool supportsChannelID() const 649 { 650 return m_extensions.get!ChannelIDSupport() !is null; 651 } 652 653 bool peerCanSendHeartbeats() const 654 { 655 if (auto hb = m_extensions.get!HeartbeatSupportIndicator()) 656 return hb.peerAllowedToSend(); 657 return false; 658 } 659 660 string nextProtocol() const 661 { 662 if (auto alpn = m_extensions.get!ApplicationLayerProtocolNotification()) 663 return alpn.singleProtocol(); 664 return ""; 665 } 666 667 const(Vector!HandshakeExtensionType) extensionTypes() const 668 { return m_extensions.extensionTypes(); } 669 670 /* 671 * Create a new TLSServer Hello message 672 */ 673 this(HandshakeIO io, 674 ref HandshakeHash hash, 675 in TLSPolicy policy, 676 Vector!ubyte session_id, 677 TLSProtocolVersion ver, 678 ushort ciphersuite, 679 ubyte compression, 680 size_t max_fragment_size, 681 bool client_has_secure_renegotiation, 682 bool client_has_extended_master_secret, 683 Vector!ubyte reneg_info, 684 bool offer_session_ticket, 685 bool client_has_alpn, 686 in string next_protocol, 687 bool client_has_heartbeat, 688 RandomNumberGenerator rng) 689 { 690 m_version = ver; 691 m_session_id = session_id.move(); 692 m_random = makeHelloRandom(rng, policy); 693 m_ciphersuite = ciphersuite; 694 m_comp_method = compression; 695 m_extensions.reserve(8); 696 697 if (client_has_extended_master_secret) 698 m_extensions.add(new ExtendedMasterSecret); 699 700 if (client_has_heartbeat && policy.negotiateHeartbeatSupport()) 701 m_extensions.add(new HeartbeatSupportIndicator(true)); 702 703 if (client_has_secure_renegotiation) 704 m_extensions.add(new RenegotiationExtension(reneg_info.move())); 705 706 if (max_fragment_size) 707 m_extensions.add(new MaximumFragmentLength(max_fragment_size)); 708 709 if (next_protocol != "" && client_has_alpn) 710 m_extensions.add(new ApplicationLayerProtocolNotification(next_protocol)); 711 712 if (offer_session_ticket) 713 m_extensions.add(new SessionTicket()); 714 715 hash.update(io.send(this)); 716 } 717 718 /* 719 * Deserialize a TLSServer Hello message 720 */ 721 this(const ref Vector!ubyte buf) 722 { 723 if (buf.length < 38) 724 throw new DecodingError("ServerHello: Packet corrupted"); 725 726 TLSDataReader reader = TLSDataReader("ServerHello", buf); 727 728 const ubyte major_version = reader.get_byte(); 729 const ubyte minor_version = reader.get_byte(); 730 731 m_version = TLSProtocolVersion(major_version, minor_version); 732 733 m_random = reader.getFixed!ubyte(32); 734 735 m_session_id = reader.getRange!ubyte(1, 0, 32); 736 737 m_ciphersuite = reader.get_ushort(); 738 739 m_comp_method = reader.get_byte(); 740 741 m_extensions.reserve(8); 742 m_extensions.deserialize(reader); 743 } 744 745 protected: 746 /* 747 * Serialize a TLSServer Hello message 748 */ 749 override Vector!ubyte serialize() const 750 { 751 Vector!ubyte buf; 752 buf.reserve(512); 753 754 buf.pushBack(m_version.majorVersion()); 755 buf.pushBack(m_version.minorVersion()); 756 buf ~= m_random[]; 757 758 appendTlsLengthValue(buf, m_session_id, 1); 759 760 buf.pushBack(get_byte(0, m_ciphersuite)); 761 buf.pushBack(get_byte(1, m_ciphersuite)); 762 763 buf.pushBack(m_comp_method); 764 765 auto vec = m_extensions.serialize(); 766 buf ~= vec[]; 767 return buf.move(); 768 } 769 770 private: 771 TLSProtocolVersion m_version; 772 Vector!ubyte m_session_id, m_random; 773 ushort m_ciphersuite; 774 ubyte m_comp_method; 775 776 TLSExtensions m_extensions; 777 } 778 779 /** 780 * TLSClient Key Exchange Message 781 */ 782 final class ClientKeyExchange : HandshakeMessage 783 { 784 public: 785 override HandshakeType type() const { return CLIENT_KEX; } 786 787 ref const(SecureVector!ubyte) preMasterSecret() const 788 { return m_pre_master; } 789 790 /* 791 * Read a TLSClient Key Exchange message 792 */ 793 this(const ref Vector!ubyte contents, 794 in HandshakeState state, 795 in PrivateKey server_rsa_kex_key, 796 TLSCredentialsManager creds, 797 in TLSPolicy policy, 798 RandomNumberGenerator rng) 799 { 800 const string kex_algo = state.ciphersuite().kexAlgo(); 801 802 if (kex_algo == "RSA") 803 { 804 assert(state.serverCerts() && !state.serverCerts().certChain().empty, 805 "RSA key exchange negotiated so server sent a certificate"); 806 807 if (!server_rsa_kex_key) 808 throw new InternalError("Expected RSA kex but no server kex key set"); 809 810 if (server_rsa_kex_key.algoName != "RSA") 811 throw new InternalError("Expected RSA key but got " ~ server_rsa_kex_key.algoName); 812 813 auto decryptor = scoped!PKDecryptorEME(server_rsa_kex_key, "PKCS1v15"); 814 815 TLSProtocolVersion client_version = state.clientHello().Version(); 816 817 /* 818 * This is used as the pre-master if RSA decryption fails. 819 * Otherwise we can be used as an oracle. See Bleichenbacher 820 * "Chosen Ciphertext Attacks against Protocols Based on RSA 821 * Encryption Standard PKCS #1", Crypto 98 822 * 823 * Create it here instead if in the catch clause as otherwise we 824 * expose a timing channel WRT the generation of the fake value. 825 * Some timing channel likely remains due to exception handling 826 * and the like. 827 */ 828 SecureVector!ubyte fake_pre_master = rng.randomVec(48); 829 fake_pre_master[0] = client_version.majorVersion(); 830 fake_pre_master[1] = client_version.minorVersion(); 831 832 try 833 { 834 TLSDataReader reader = TLSDataReader("ClientKeyExchange", contents); 835 m_pre_master = decryptor.decrypt(reader.getRange!ubyte(2, 0, 65535)); 836 837 if (m_pre_master.length != 48 || 838 client_version.majorVersion() != m_pre_master[0] || 839 client_version.minorVersion() != m_pre_master[1]) 840 { 841 throw new DecodingError("ClientKeyExchange: Secret corrupted"); 842 } 843 } 844 catch (Exception) 845 { 846 m_pre_master = fake_pre_master; 847 } 848 } 849 else 850 { 851 TLSDataReader reader = TLSDataReader("ClientKeyExchange", contents); 852 853 auto psk = SymmetricKey(); 854 855 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 856 { 857 const string psk_identity = reader.getString(2, 0, 65535); 858 859 psk = creds.psk("tls-server", 860 state.clientHello().sniHostname(), 861 psk_identity); 862 863 if (psk.length == 0) 864 { 865 if (policy.hideUnknownUsers()) 866 psk = SymmetricKey(rng, 16); 867 else 868 throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, 869 "No PSK for identifier " ~ psk_identity); 870 } 871 } 872 873 if (kex_algo == "PSK") 874 { 875 Vector!ubyte zeros = Vector!ubyte(psk.length); 876 appendTlsLengthValue(m_pre_master, zeros, 2); 877 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 878 } 879 else if (kex_algo == "SRP_SHA") 880 { 881 static if (BOTAN_HAS_SRP6) { 882 SRP6ServerSession srp = cast(SRP6ServerSession) state.serverKex().serverSrpParams(); 883 884 m_pre_master = srp.step2(BigInt.decode(reader.getRange!ubyte(2, 0, 65535))).bitsOf(); 885 } 886 else { 887 throw new InternalError("ClientKeyExchange: Unknown kex type " ~ kex_algo); 888 } 889 } 890 else if (kex_algo == "DH" || kex_algo == "DHE_PSK" || 891 kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 892 { 893 const PrivateKey private_key = state.serverKex().serverKexKey(); 894 895 const PKKeyAgreementKey ka_key = cast(const PKKeyAgreementKey)(private_key); 896 897 if (!ka_key) 898 throw new InternalError("Expected key agreement key type but got " ~ 899 private_key.algoName); 900 901 try 902 { 903 auto ka = scoped!PKKeyAgreement(ka_key, "Raw"); 904 905 Vector!ubyte client_pubkey; 906 907 if (ka_key.algoName == "DH") 908 client_pubkey = reader.getRange!ubyte(2, 0, 65535); 909 else 910 client_pubkey = reader.getRange!ubyte(1, 0, 255); 911 auto derived_key = ka.deriveKey(0, client_pubkey); 912 SecureVector!ubyte shared_secret = derived_key.bitsOf(); 913 914 if (ka_key.algoName == "DH") 915 shared_secret = stripLeadingZeros(shared_secret); 916 917 if (kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 918 { 919 appendTlsLengthValue(m_pre_master, shared_secret, 2); 920 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 921 } 922 else 923 m_pre_master = shared_secret.move(); 924 } 925 catch(Exception e) 926 { 927 /* 928 * Something failed in the DH computation. To avoid possible 929 * timing attacks, randomize the pre-master output and carry 930 * on, allowing the protocol to fail later in the finished 931 * checks. 932 */ 933 m_pre_master = rng.randomVec(ka_key.publicValue().length); 934 } 935 } 936 else 937 throw new InternalError("ClientKeyExchange: Unknown kex type " ~ kex_algo); 938 } 939 } 940 941 /* 942 * Create a new TLSClient Key Exchange message 943 */ 944 this(HandshakeIO io, 945 HandshakeState state, 946 in TLSPolicy policy, 947 TLSCredentialsManager creds, 948 const PublicKey server_public_key, 949 in string hostname, 950 RandomNumberGenerator rng) 951 { 952 const string kex_algo = state.ciphersuite().kexAlgo(); 953 954 if (kex_algo == "PSK") 955 { 956 string identity_hint = ""; 957 958 if (state.serverKex()) 959 { 960 TLSDataReader reader = TLSDataReader("ClientKeyExchange", state.serverKex().params()); 961 identity_hint = reader.getString(2, 0, 65535); 962 } 963 964 const string hostname_ = state.clientHello().sniHostname(); 965 966 const string psk_identity = creds.pskIdentity("tls-client", 967 hostname_, 968 identity_hint); 969 970 appendTlsLengthValue(m_key_material, psk_identity, 2); 971 972 SymmetricKey psk = creds.psk("tls-client", hostname_, psk_identity); 973 974 Vector!ubyte zeros = Vector!ubyte(psk.length); 975 976 appendTlsLengthValue(m_pre_master, zeros, 2); 977 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 978 } 979 else if (state.serverKex()) 980 { 981 TLSDataReader reader = TLSDataReader("ClientKeyExchange", state.serverKex().params()); 982 983 auto psk = SymmetricKey(); 984 985 if (kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 986 { 987 string identity_hint = reader.getString(2, 0, 65535); 988 989 const string hostname_ = state.clientHello().sniHostname(); 990 991 const string psk_identity = creds.pskIdentity("tls-client", 992 hostname_, 993 identity_hint); 994 995 appendTlsLengthValue(m_key_material, psk_identity, 2); 996 997 psk = creds.psk("tls-client", hostname_, psk_identity); 998 } 999 1000 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1001 { 1002 BigInt p = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1003 BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1004 BigInt Y = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1005 1006 if (reader.remainingBytes()) 1007 throw new DecodingError("Bad params size for DH key exchange"); 1008 1009 if (p.bits() < policy.minimumDhGroupSize()) 1010 throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY, 1011 "TLSServer sent DH group of " ~ 1012 to!string(p.bits()) ~ 1013 " bits, policy requires at least " ~ 1014 to!string(policy.minimumDhGroupSize())); 1015 1016 /* 1017 * A basic check for key validity. As we do not know q here we 1018 * cannot check that Y is in the right subgroup. However since 1019 * our key is ephemeral there does not seem to be any 1020 * advantage to bogus keys anyway. 1021 */ 1022 if (Y <= 1 || Y >= p - 1) 1023 throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY, 1024 "TLSServer sent bad DH key for DHE exchange"); 1025 1026 DLGroup group = DLGroup(p, g); 1027 1028 if (!group.verifyGroup(rng, false)) 1029 throw new TLSException(TLSAlert.INSUFFICIENT_SECURITY, "DH group failed validation, possible attack"); 1030 auto counterparty_key = DHPublicKey(group.dup, Y.move); 1031 1032 auto priv_key = DHPrivateKey(rng, group.move); 1033 1034 auto ka = scoped!PKKeyAgreement(priv_key, "Raw"); 1035 1036 auto octet_string = ka.deriveKey(0, counterparty_key.publicValue()); 1037 SecureVector!ubyte dh_secret = stripLeadingZeros(octet_string.bitsOf()); 1038 1039 if (kex_algo == "DH") 1040 m_pre_master = dh_secret.move(); 1041 else 1042 { 1043 appendTlsLengthValue(m_pre_master, dh_secret, 2); 1044 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 1045 } 1046 1047 appendTlsLengthValue(m_key_material, priv_key.publicValue(), 2); 1048 } 1049 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1050 { 1051 const ubyte curve_type = reader.get_byte(); 1052 1053 if (curve_type != 3) 1054 throw new DecodingError("TLSServer sent non-named ECC curve"); 1055 1056 const ushort curve_id = reader.get_ushort(); 1057 1058 const string curve_name = SupportedEllipticCurves.curveIdToName(curve_id); 1059 1060 if (curve_name == "") 1061 throw new DecodingError("TLSServer sent unknown named curve " ~ to!string(curve_id)); 1062 { 1063 Vector!string allowed_curves = policy.allowedEccCurves(); 1064 if(!(allowed_curves[]).canFind(curve_name)) 1065 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Server sent ECC curve prohibited by policy"); 1066 } 1067 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255); 1068 1069 Vector!ubyte our_ecdh_public; 1070 SecureVector!ubyte ecdh_secret; 1071 1072 if (curve_name == "x25519") { 1073 import botan.pubkey.algo.curve25519; 1074 if (ecdh_key.length != 32) 1075 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Invalid X25519 key size"); 1076 Curve25519PublicKey counterparty_key = Curve25519PublicKey(ecdh_key); 1077 Curve25519PrivateKey priv_key = Curve25519PrivateKey(rng); 1078 1079 auto ka = scoped!PKKeyAgreement(priv_key, "Raw"); 1080 auto public_value = counterparty_key.publicValue(); 1081 auto derived_key = ka.deriveKey(0, public_value); 1082 1083 ecdh_secret = derived_key.bitsOf(); 1084 our_ecdh_public = priv_key.publicValue(); 1085 1086 } else { 1087 ECGroup group = ECGroup(curve_name); 1088 1089 1090 auto counterparty_key = ECDHPublicKey(group, OS2ECP(ecdh_key, group.getCurve())); 1091 auto priv_key = ECDHPrivateKey(rng, group); 1092 1093 auto ka = scoped!PKKeyAgreement(priv_key, "Raw"); 1094 auto public_value = counterparty_key.publicValue(); 1095 auto derived_key = ka.deriveKey(0, public_value); 1096 1097 ecdh_secret = derived_key.bitsOf(); 1098 our_ecdh_public = priv_key.publicValue(); 1099 } 1100 if (kex_algo == "ECDH") 1101 m_pre_master = ecdh_secret.move(); 1102 else 1103 { 1104 appendTlsLengthValue(m_pre_master, ecdh_secret, 2); 1105 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 1106 } 1107 1108 appendTlsLengthValue(m_key_material, our_ecdh_public, 1); 1109 } 1110 else if (kex_algo == "SRP_SHA") 1111 { 1112 static if (BOTAN_HAS_SRP6) { 1113 const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1114 const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1115 Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255); 1116 const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1117 1118 const string srp_group = srp6GroupIdentifier(N, g); 1119 1120 const string srp_identifier = creds.srpIdentifier("tls-client", hostname); 1121 1122 const string srp_password = creds.srpPassword("tls-client", hostname, srp_identifier); 1123 1124 SRP6KeyPair srp_vals = srp6ClientAgree(srp_identifier, 1125 srp_password, 1126 srp_group, 1127 "SHA-1", 1128 salt, 1129 B, 1130 rng); 1131 1132 appendTlsLengthValue(m_key_material, BigInt.encode(srp_vals.privkey), 2); 1133 m_pre_master = srp_vals.pubkey.bitsOf(); 1134 } else { 1135 throw new InternalError("ClientKeyExchange: Unknown kex " ~ kex_algo); 1136 } 1137 } 1138 else 1139 { 1140 throw new InternalError("ClientKeyExchange: Unknown kex " ~ 1141 kex_algo); 1142 } 1143 1144 reader.assertDone(); 1145 } 1146 else 1147 { 1148 // No server key exchange msg better mean RSA kex + RSA key in cert 1149 1150 if (kex_algo != "RSA") 1151 throw new TLSUnexpectedMessage("No server kex but negotiated kex " ~ kex_algo); 1152 1153 if (!server_public_key) 1154 throw new InternalError("No server public key for RSA exchange"); 1155 1156 if (server_public_key.algoName == "RSA") 1157 { 1158 auto rsa_pub = RSAPublicKey(cast(PublicKey)server_public_key); 1159 const TLSProtocolVersion offered_version = state.clientHello().Version(); 1160 1161 m_pre_master = rng.randomVec(48); 1162 m_pre_master[0] = offered_version.majorVersion(); 1163 m_pre_master[1] = offered_version.minorVersion(); 1164 1165 auto encryptor = scoped!PKEncryptorEME(rsa_pub, "PKCS1v15"); 1166 1167 Vector!ubyte encrypted_key = encryptor.encrypt(m_pre_master, rng); 1168 1169 appendTlsLengthValue(m_key_material, encrypted_key, 2); 1170 } 1171 else 1172 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, 1173 "Expected a RSA key in server cert but got " ~ 1174 server_public_key.algoName); 1175 } 1176 1177 state.hash().update(io.send(this)); 1178 } 1179 1180 1181 protected: 1182 override Vector!ubyte serialize() const { return m_key_material.dup; } 1183 1184 private: 1185 Vector!ubyte m_key_material; 1186 SecureVector!ubyte m_pre_master; 1187 } 1188 1189 /** 1190 * Certificate Message 1191 */ 1192 final class Certificate : HandshakeMessage 1193 { 1194 public: 1195 override const(HandshakeType) type() const { return CERTIFICATE; } 1196 ref const(Vector!X509Certificate) certChain() const { return *m_certs; } 1197 1198 size_t count() const { return m_certs.length; } 1199 @property bool empty() const { return m_certs.empty; } 1200 1201 /** 1202 * Create a new Certificate message 1203 */ 1204 this()(HandshakeIO io, 1205 ref HandshakeHash hash, 1206 auto ref Array!X509Certificate cert_list) 1207 { 1208 m_certs = cert_list; 1209 hash.update(io.send(this)); 1210 } 1211 1212 /** 1213 * Create a new Certificate message 1214 */ 1215 this()(HandshakeIO io, 1216 ref HandshakeHash hash, 1217 auto ref Vector!X509Certificate cert_list) 1218 { 1219 m_certs = cert_list.dupr; 1220 hash.update(io.send(this)); 1221 } 1222 1223 /** 1224 * Deserialize a Certificate message 1225 */ 1226 this()(auto const ref Vector!ubyte buf) 1227 { 1228 if (buf.length < 3) 1229 throw new DecodingError("Certificate: Message malformed"); 1230 1231 const size_t total_size = make_uint(0, buf[0], buf[1], buf[2]); 1232 1233 if (total_size != buf.length - 3) 1234 throw new DecodingError("Certificate: Message malformed"); 1235 1236 const(ubyte)* certs = buf.ptr + 3; 1237 1238 while (true) 1239 { 1240 size_t remaining_bytes = buf.ptr + buf.length - certs; 1241 if (remaining_bytes <= 0) 1242 break; 1243 if (remaining_bytes < 3) 1244 throw new DecodingError("Certificate: Message malformed"); 1245 1246 const size_t cert_size = make_uint(0, certs[0], certs[1], certs[2]); 1247 1248 if (remaining_bytes < (3 + cert_size)) 1249 throw new DecodingError("Certificate: Message malformed"); 1250 1251 auto cert_buf = DataSourceMemory(&certs[3], cert_size); 1252 m_certs.pushBack(X509Certificate(cast(DataSource)cert_buf)); 1253 1254 certs += cert_size + 3; 1255 } 1256 } 1257 1258 protected: 1259 /** 1260 * Serialize a Certificate message 1261 */ 1262 override Vector!ubyte serialize() const 1263 { 1264 Vector!ubyte buf; 1265 buf.reserve(2048); 1266 buf.length = 3; 1267 for (size_t i = 0; i != m_certs.length; ++i) 1268 { 1269 Vector!ubyte raw_cert = m_certs[i].BER_encode(); 1270 const size_t cert_size = raw_cert.length; 1271 foreach (size_t j; 0 .. 3) 1272 buf.pushBack(get_byte!uint(j+1, cast(uint) cert_size)); 1273 buf ~= raw_cert; 1274 } 1275 1276 const size_t buf_size = buf.length - 3; 1277 foreach (size_t i; 0 .. 3) 1278 buf[i] = get_byte!uint(i+1, cast(uint) buf_size); 1279 1280 return buf.move(); 1281 } 1282 1283 private: 1284 Array!X509Certificate m_certs; 1285 } 1286 1287 /** 1288 * Certificate Request Message 1289 */ 1290 final class CertificateReq : HandshakeMessage 1291 { 1292 public: 1293 override const(HandshakeType) type() const { return CERTIFICATE_REQUEST; } 1294 1295 ref const(Vector!string) acceptableCertTypes() const 1296 { return m_cert_key_types; } 1297 1298 ref const(Vector!X509DN) acceptableCAs() const { return m_names; } 1299 1300 Vector!( Pair!(string, string) ) supportedAlgos() const 1301 { return m_supported_algos.dup; } 1302 1303 /** 1304 * Create a new Certificate Request message 1305 */ 1306 this(HandshakeIO io, 1307 ref HandshakeHash hash, 1308 in TLSPolicy policy, 1309 Vector!X509DN ca_certs, 1310 TLSProtocolVersion _version) 1311 { 1312 m_names = ca_certs.move(); 1313 m_cert_key_types = [ "RSA", "DSA", "ECDSA" ]; 1314 static Vector!( Pair!(string, string) ) last_supported_algos; 1315 static TLSPolicy last_tls_policy; 1316 static TLSProtocolVersion last_version; 1317 if (policy is last_tls_policy && _version == last_version) 1318 m_supported_algos = last_supported_algos.dup; 1319 else { 1320 m_supported_algos.reserve(16); 1321 if (_version.supportsNegotiableSignatureAlgorithms()) 1322 { 1323 Vector!string hashes = policy.allowedSignatureHashes(); 1324 Vector!string sigs = policy.allowedSignatureMethods(); 1325 1326 for (size_t i = 0; i != hashes.length; ++i) 1327 for (size_t j = 0; j != sigs.length; ++j) 1328 m_supported_algos.pushBack(makePair(hashes[i], sigs[j])); 1329 } 1330 last_tls_policy = cast() policy; 1331 last_version = _version; 1332 last_supported_algos = m_supported_algos.dup; 1333 } 1334 1335 hash.update(io.send(this)); 1336 } 1337 1338 /** 1339 * Deserialize a Certificate Request message 1340 */ 1341 this(const ref Vector!ubyte buf, TLSProtocolVersion _version) 1342 { 1343 if (buf.length < 4) 1344 throw new DecodingError("Certificate_Req: Bad certificate request"); 1345 1346 TLSDataReader reader = TLSDataReader("CertificateRequest", buf); 1347 1348 Vector!ubyte cert_type_codes = reader.getRangeVector!ubyte(1, 1, 255); 1349 1350 for (size_t i = 0; i != cert_type_codes.length; ++i) 1351 { 1352 const string cert_type_name = certTypeCodeToName(cert_type_codes[i]); 1353 1354 if (cert_type_name == "") // something we don't know 1355 continue; 1356 1357 m_cert_key_types.pushBack(cert_type_name); 1358 } 1359 1360 if (_version.supportsNegotiableSignatureAlgorithms()) 1361 { 1362 Vector!ubyte sig_hash_algs = reader.getRangeVector!ubyte(2, 2, 65534); 1363 1364 if (sig_hash_algs.length % 2 != 0) 1365 throw new DecodingError("Bad length for signature IDs in certificate request"); 1366 1367 for (size_t i = 0; i != sig_hash_algs.length; i += 2) 1368 { 1369 string hash = SignatureAlgorithms.hashAlgoName(sig_hash_algs[i]); 1370 string sig = SignatureAlgorithms.sigAlgoName(sig_hash_algs[i+1]); 1371 m_supported_algos.pushBack(makePair(hash, sig)); 1372 } 1373 } 1374 1375 const ushort purported_size = reader.get_ushort(); 1376 1377 if (reader.remainingBytes() != purported_size) 1378 throw new DecodingError("Inconsistent length in certificate request"); 1379 1380 while (reader.hasRemaining()) 1381 { 1382 Vector!ubyte name_bits = reader.getRangeVector!ubyte(2, 0, 65535); 1383 1384 BERDecoder decoder = BERDecoder(name_bits.ptr, name_bits.length); 1385 X509DN name = X509DN(); 1386 decoder.decode(name); 1387 m_names.pushBack(name); 1388 } 1389 } 1390 1391 protected: 1392 1393 /** 1394 * Serialize a Certificate Request message 1395 */ 1396 override Vector!ubyte serialize() const 1397 { 1398 Vector!ubyte buf; 1399 buf.reserve(256); 1400 Vector!ubyte cert_types; 1401 cert_types.reserve(64); 1402 for (size_t i = 0; i != m_cert_key_types.length; ++i) 1403 cert_types.pushBack(certTypeNameToCode(m_cert_key_types[i])); 1404 1405 appendTlsLengthValue(buf, cert_types, 1); 1406 1407 if (!m_supported_algos.empty) { 1408 Unique!SignatureAlgorithms sig_algos = new SignatureAlgorithms(m_supported_algos.dup); 1409 buf ~= sig_algos.serialize(); 1410 } 1411 1412 Vector!ubyte encoded_names; 1413 1414 for (size_t i = 0; i != m_names.length; ++i) 1415 { 1416 DEREncoder encoder = DEREncoder(); 1417 encoder.encode(m_names[i]); 1418 1419 appendTlsLengthValue(encoded_names, encoder.getContents(), 2); 1420 } 1421 1422 appendTlsLengthValue(buf, encoded_names, 2); 1423 1424 return buf.move(); 1425 } 1426 1427 private: 1428 Vector!X509DN m_names; 1429 Vector!string m_cert_key_types; 1430 1431 Vector!( Pair!(string, string) ) m_supported_algos; 1432 } 1433 1434 /** 1435 * Certificate Verify Message 1436 */ 1437 final class CertificateVerify : HandshakeMessage 1438 { 1439 public: 1440 override const(HandshakeType) type() const { return CERTIFICATE_VERIFY; } 1441 1442 /** 1443 * Check the signature on a certificate verify message 1444 * Params: 1445 * cert = the purported certificate 1446 * state = the handshake state 1447 */ 1448 bool verify(const X509Certificate cert, 1449 const HandshakeState state) const 1450 { 1451 Unique!PublicKey key = cert.subjectPublicKey(); 1452 1453 Pair!(string, SignatureFormat) format = state.understandSigFormat(*key, m_hash_algo, m_sig_algo, true); 1454 1455 PKVerifier verifier = PKVerifier(*key, format.first, format.second); 1456 1457 return verifier.verifyMessage(state.hash().getContents(), m_signature); 1458 } 1459 1460 /* 1461 * Create a new Certificate Verify message 1462 */ 1463 this(HandshakeIO io, 1464 HandshakeState state, 1465 in TLSPolicy policy, 1466 RandomNumberGenerator rng, 1467 const PrivateKey priv_key) 1468 { 1469 assert(priv_key, "No private key defined"); 1470 1471 Pair!(string, SignatureFormat) format = state.chooseSigFormat(priv_key, m_hash_algo, m_sig_algo, true, policy); 1472 1473 PKSigner signer = PKSigner(priv_key, format.first, format.second); 1474 1475 m_signature = signer.signMessage(state.hash().getContents(), rng); 1476 1477 state.hash().update(io.send(this)); 1478 } 1479 1480 /* 1481 * Deserialize a Certificate Verify message 1482 */ 1483 this(const ref Vector!ubyte buf, 1484 TLSProtocolVersion _version) 1485 { 1486 TLSDataReader reader = TLSDataReader("CertificateVerify", buf); 1487 1488 if (_version.supportsNegotiableSignatureAlgorithms()) 1489 { 1490 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte()); 1491 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte()); 1492 } 1493 1494 m_signature = reader.getRange!ubyte(2, 0, 65535); 1495 } 1496 1497 protected: 1498 /* 1499 * Serialize a Certificate Verify message 1500 */ 1501 override Vector!ubyte serialize() const 1502 { 1503 Vector!ubyte buf; 1504 1505 if (m_hash_algo != "" && m_sig_algo != "") 1506 { 1507 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1508 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1509 } 1510 1511 const ushort sig_len = cast(ushort) m_signature.length; 1512 buf.pushBack(get_byte(0, sig_len)); 1513 buf.pushBack(get_byte(1, sig_len)); 1514 buf ~= m_signature[]; 1515 1516 return buf.move(); 1517 } 1518 1519 private: 1520 string m_sig_algo; // sig algo used to create signature 1521 string m_hash_algo; // hash used to create signature 1522 Vector!ubyte m_signature; 1523 } 1524 1525 /** 1526 * Finished Message 1527 */ 1528 final class Finished : HandshakeMessage 1529 { 1530 public: 1531 override const(HandshakeType) type() const { return FINISHED; } 1532 1533 ref const(Vector!ubyte) verifyData() const 1534 { return m_verification_data; } 1535 1536 const(ubyte[]) verifyDataBytes() const { return m_verification_data[]; } 1537 1538 /* 1539 * Verify a Finished message 1540 */ 1541 bool verify(in HandshakeState state, ConnectionSide side) const 1542 { 1543 return (m_verification_data == finishedComputeVerify(state, side)); 1544 } 1545 1546 /* 1547 * Create a new Finished message 1548 */ 1549 this(HandshakeIO io, 1550 HandshakeState state, 1551 ConnectionSide side) 1552 { 1553 m_verification_data = finishedComputeVerify(state, side); 1554 state.hash().update(io.send(this)); 1555 } 1556 1557 /* 1558 * Deserialize a Finished message 1559 */ 1560 this(Vector!ubyte buf) 1561 { 1562 m_verification_data = buf.move(); 1563 } 1564 1565 protected: 1566 /* 1567 * Serialize a Finished message 1568 */ 1569 override Vector!ubyte serialize() const 1570 { 1571 return m_verification_data.dup; 1572 } 1573 1574 private: 1575 Vector!ubyte m_verification_data; 1576 } 1577 1578 /** 1579 * Hello Request Message 1580 */ 1581 final class HelloRequest : HandshakeMessage 1582 { 1583 public: 1584 override const(HandshakeType) type() const { return HELLO_REQUEST; } 1585 1586 /* 1587 * Create a new Hello Request message 1588 */ 1589 this(HandshakeIO io) 1590 { 1591 io.send(this); 1592 } 1593 1594 /* 1595 * Deserialize a Hello Request message 1596 */ 1597 this(const ref Vector!ubyte buf) 1598 { 1599 if (buf.length) 1600 throw new DecodingError("Bad HelloRequest, has non-zero size"); 1601 } 1602 1603 protected: 1604 /* 1605 * Serialize a Hello Request message 1606 */ 1607 override Vector!ubyte serialize() const 1608 { 1609 return Vector!ubyte(); 1610 } 1611 } 1612 1613 /** 1614 * TLSServer Key Exchange Message 1615 */ 1616 final class ServerKeyExchange : HandshakeMessage 1617 { 1618 public: 1619 override const(HandshakeType) type() const { return SERVER_KEX; } 1620 1621 ref const(Vector!ubyte) params() const { return m_params; } 1622 1623 /** 1624 * Verify a TLSServer Key Exchange message 1625 */ 1626 bool verify(in PublicKey server_key, 1627 const HandshakeState state) const 1628 { 1629 Pair!(string, SignatureFormat) format = state.understandSigFormat(server_key, m_hash_algo, m_sig_algo, false); 1630 1631 PKVerifier verifier = PKVerifier(server_key, format.first, format.second); 1632 verifier.update(state.clientHello().random()); 1633 verifier.update(state.serverHello().random()); 1634 verifier.update(params()); 1635 return verifier.checkSignature(m_signature); 1636 } 1637 1638 // Only valid for certain kex types 1639 const(PrivateKey) serverKexKey() const 1640 { 1641 assert(m_kex_key, "PrivateKey cannot be null"); 1642 return *m_kex_key; 1643 } 1644 1645 static if (BOTAN_HAS_SRP6) { 1646 // Only valid for SRP negotiation 1647 const(SRP6ServerSession) serverSrpParams() const 1648 { 1649 assert(m_srp_params, "SRP6ServerSession cannot be null"); 1650 return *m_srp_params; 1651 } 1652 } 1653 1654 /** 1655 * Deserialize a TLSServer Key Exchange message 1656 */ 1657 this(const ref Vector!ubyte buf, 1658 in string kex_algo, 1659 in string sig_algo, 1660 TLSProtocolVersion _version) 1661 { 1662 m_kex_key.free(); 1663 static if (BOTAN_HAS_SRP6) 1664 m_srp_params.free(); 1665 if (buf.length < 6) 1666 throw new DecodingError("ServerKeyExchange: Packet corrupted"); 1667 1668 TLSDataReader reader = TLSDataReader("ServerKeyExchange", buf); 1669 1670 /* 1671 * We really are just serializing things back to what they were 1672 * before, but unfortunately to know where the signature is we need 1673 * to be able to parse the whole thing anyway. 1674 */ 1675 1676 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1677 { 1678 const string identity_hint = reader.getString(2, 0, 65535); 1679 appendTlsLengthValue(m_params, identity_hint, 2); 1680 } 1681 1682 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1683 { 1684 // 3 bigints, DH p, g, Y 1685 1686 foreach (size_t i; 0 .. 3) 1687 { 1688 BigInt v = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1689 appendTlsLengthValue(m_params, BigInt.encode(v), 2); 1690 } 1691 } 1692 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1693 { 1694 const ubyte curve_type = reader.get_byte(); 1695 1696 if (curve_type != 3) 1697 throw new DecodingError("ServerKeyExchange: TLSServer sent non-named ECC curve"); 1698 1699 const ushort curve_id = reader.get_ushort(); 1700 1701 const string name = SupportedEllipticCurves.curveIdToName(curve_id); 1702 1703 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255); 1704 1705 if (name == "") 1706 throw new DecodingError("ServerKeyExchange: TLSServer sent unknown named curve " ~ 1707 to!string(curve_id)); 1708 1709 m_params.pushBack(curve_type); 1710 m_params.pushBack(get_byte(0, curve_id)); 1711 m_params.pushBack(get_byte(1, curve_id)); 1712 appendTlsLengthValue(m_params, ecdh_key, 1); 1713 } 1714 else if (kex_algo == "SRP_SHA") 1715 { 1716 // 2 bigints (N,g) then salt, then server B 1717 1718 const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1719 const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1720 Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255); 1721 const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1722 1723 appendTlsLengthValue(m_params, BigInt.encode(N), 2); 1724 appendTlsLengthValue(m_params, BigInt.encode(g), 2); 1725 appendTlsLengthValue(m_params, salt, 1); 1726 appendTlsLengthValue(m_params, BigInt.encode(B), 2); 1727 } 1728 else if (kex_algo != "PSK") 1729 throw new DecodingError("ServerKeyExchange: Unsupported kex type " ~ kex_algo); 1730 1731 if (sig_algo != "") 1732 { 1733 if (_version.supportsNegotiableSignatureAlgorithms()) 1734 { 1735 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte()); 1736 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte()); 1737 } 1738 1739 m_signature = reader.getRange!ubyte(2, 0, 65535); 1740 } 1741 1742 reader.assertDone(); 1743 } 1744 1745 /** 1746 * Create a new TLSServer Key Exchange message 1747 */ 1748 this(HandshakeIO io, 1749 HandshakeState state, 1750 in TLSPolicy policy, 1751 TLSCredentialsManager creds, 1752 RandomNumberGenerator rng, 1753 in PrivateKey signing_key = null) 1754 { 1755 const string hostname = state.clientHello().sniHostname(); 1756 const string kex_algo = state.ciphersuite().kexAlgo(); 1757 1758 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1759 { 1760 string identity_hint = creds.pskIdentityHint("tls-server", hostname); 1761 1762 appendTlsLengthValue(m_params, identity_hint, 2); 1763 } 1764 1765 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1766 { 1767 auto dh = DHPrivateKey(rng, policy.dhGroup()); 1768 1769 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getP()), 2); 1770 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getG()), 2); 1771 appendTlsLengthValue(m_params, dh.publicValue(), 2); 1772 m_kex_key = dh.release(); 1773 } 1774 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1775 { 1776 Vector!string curves = state.clientHello().supportedEccCurves(); 1777 1778 if (curves.empty) 1779 throw new InternalError("TLSClient sent no ECC extension but we negotiated ECDH"); 1780 1781 const string curve_name = policy.chooseCurve(curves.move()); 1782 1783 if (curve_name == "") 1784 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client"); 1785 const ushort named_curve_id = SupportedEllipticCurves.nameToCurveId(curve_name); 1786 if (named_curve_id == 0) 1787 throw new InternalError("TLS does not support ECC with " ~ curve_name); 1788 Vector!ubyte ecdh_public_val; 1789 1790 if (curve_name == "x25519") { 1791 import botan.pubkey.algo.curve25519; 1792 Curve25519PrivateKey x25519 = Curve25519PrivateKey(rng); 1793 ecdh_public_val = x25519.publicValue(); 1794 m_kex_key = x25519.release(); 1795 } else { 1796 ECGroup ec_group = ECGroup(curve_name); 1797 auto ecdh = ECDHPrivateKey(rng, ec_group); 1798 ecdh_public_val = ecdh.publicValue(); 1799 1800 m_kex_key = ecdh.release(); 1801 } 1802 m_params.pushBack(3); // named curve 1803 m_params.pushBack(get_byte(0, named_curve_id)); 1804 m_params.pushBack(get_byte(1, named_curve_id)); 1805 1806 appendTlsLengthValue(m_params, ecdh_public_val, 1); 1807 1808 } 1809 else if (kex_algo == "SRP_SHA") 1810 { 1811 static if (BOTAN_HAS_SRP6) { 1812 const string srp_identifier = state.clientHello().srpIdentifier(); 1813 1814 string group_id; 1815 BigInt v; 1816 Vector!ubyte salt; 1817 1818 const bool found = creds.srpVerifier("tls-server", hostname, 1819 srp_identifier, 1820 group_id, v, salt, 1821 policy.hideUnknownUsers()); 1822 1823 if (!found) 1824 throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, "Unknown SRP user " ~ srp_identifier); 1825 1826 m_srp_params = new SRP6ServerSession; 1827 1828 const BigInt* B = &m_srp_params.step1(v, group_id, "SHA-1", rng); 1829 1830 DLGroup group = DLGroup(group_id); 1831 1832 appendTlsLengthValue(m_params, BigInt.encode(group.getP()), 2); 1833 appendTlsLengthValue(m_params, BigInt.encode(group.getG()), 2); 1834 appendTlsLengthValue(m_params, salt, 1); 1835 appendTlsLengthValue(m_params, BigInt.encode(*B), 2); 1836 } else { 1837 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1838 } 1839 } 1840 else if (kex_algo != "PSK") 1841 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1842 1843 if (state.ciphersuite().sigAlgo() != "") 1844 { 1845 assert(signing_key, "Signing key was set"); 1846 1847 Pair!(string, SignatureFormat) format = state.chooseSigFormat(signing_key, m_hash_algo, m_sig_algo, false, policy); 1848 1849 PKSigner signer = PKSigner(signing_key, format.first, format.second); 1850 1851 signer.update(state.clientHello().random()); 1852 signer.update(state.serverHello().random()); 1853 signer.update(params()); 1854 m_signature = signer.signature(rng); 1855 } 1856 1857 state.hash().update(io.send(this)); 1858 } 1859 1860 protected: 1861 /** 1862 * Serialize a TLSServer Key Exchange message 1863 */ 1864 override Vector!ubyte serialize() const 1865 { 1866 Vector!ubyte buf = params().dup; 1867 1868 if (m_signature.length) 1869 { 1870 // This should be an explicit version check 1871 if (m_hash_algo != "" && m_sig_algo != "") 1872 { 1873 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1874 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1875 } 1876 1877 appendTlsLengthValue(buf, m_signature, 2); 1878 } 1879 1880 return buf.move(); 1881 } 1882 1883 private: 1884 Unique!PrivateKey m_kex_key; 1885 static if (BOTAN_HAS_SRP6) 1886 Unique!SRP6ServerSession m_srp_params; 1887 1888 Vector!ubyte m_params; 1889 1890 string m_sig_algo; // sig algo used to create signature 1891 string m_hash_algo; // hash used to create signature 1892 Vector!ubyte m_signature; 1893 } 1894 1895 /** 1896 * TLSServer Hello Done Message 1897 */ 1898 final class ServerHelloDone : HandshakeMessage 1899 { 1900 public: 1901 override const(HandshakeType) type() const { return SERVER_HELLO_DONE; } 1902 1903 /* 1904 * Create a new TLSServer Hello Done message 1905 */ 1906 this(HandshakeIO io, ref HandshakeHash hash) 1907 { 1908 hash.update(io.send(this)); 1909 } 1910 1911 /* 1912 * Deserialize a TLSServer Hello Done message 1913 */ 1914 this(const ref Vector!ubyte buf) 1915 { 1916 if (buf.length) 1917 throw new DecodingError("ServerHello_Done: Must be empty, and is not"); 1918 } 1919 protected: 1920 /* 1921 * Serialize a TLSServer Hello Done message 1922 */ 1923 override Vector!ubyte serialize() const 1924 { 1925 return Vector!ubyte(); 1926 } 1927 } 1928 1929 /** 1930 * New EncryptedExtensions Message used mainly for ChannelIDExtension 1931 */ 1932 final class ChannelID : HandshakeMessage 1933 { 1934 override const(HandshakeType) type() const { return CHANNEL_ID; } 1935 1936 this(HandshakeIO io, 1937 ref HandshakeHash hash, 1938 TLSCredentialsManager creds, 1939 string hostname, 1940 SecureVector!ubyte hs_hash, 1941 SecureVector!ubyte orig_hs_hash = SecureVector!ubyte()) 1942 { 1943 m_channel_id = new EncryptedChannelID(creds.channelPrivateKey(hostname), hs_hash.move(), orig_hs_hash.move()); 1944 hash.update(io.send(this)); 1945 } 1946 1947 override Vector!ubyte serialize() const 1948 { 1949 Vector!ubyte buf; 1950 buf.reserve(130); 1951 1952 const ushort extn_code = m_channel_id.type(); 1953 const Vector!ubyte extn_val = m_channel_id.serialize(); 1954 1955 buf.pushBack(get_byte(0, extn_code)); 1956 buf.pushBack(get_byte(1, extn_code)); 1957 1958 buf.pushBack(get_byte(0, cast(ushort) extn_val.length)); 1959 buf.pushBack(get_byte(1, cast(ushort) extn_val.length)); 1960 1961 buf ~= extn_val[]; 1962 return buf.move(); 1963 } 1964 1965 private: 1966 Unique!EncryptedChannelID m_channel_id; 1967 } 1968 1969 /** 1970 * New TLS Session Ticket Message 1971 */ 1972 final class NewSessionTicket : HandshakeMessage 1973 { 1974 public: 1975 override const(HandshakeType) type() const { return NEW_SESSION_TICKET; } 1976 1977 const(Duration) ticketLifetimeHint() const { return m_ticket_lifetime_hint; } 1978 ref const(Vector!ubyte) ticket() const { return m_ticket; } 1979 1980 this(HandshakeIO io, 1981 ref HandshakeHash hash, 1982 Vector!ubyte ticket, 1983 Duration lifetime) 1984 1985 { 1986 m_ticket_lifetime_hint = lifetime; 1987 m_ticket = ticket.move(); 1988 hash.update = io.send(this); 1989 } 1990 1991 this(const ref Vector!ubyte buf) 1992 { 1993 if (buf.length < 6) 1994 throw new DecodingError("TLSSession ticket message too short to be valid"); 1995 1996 TLSDataReader reader = TLSDataReader("SessionTicket", buf); 1997 1998 m_ticket_lifetime_hint = reader.get_uint().seconds; 1999 m_ticket = reader.getRange!ubyte(2, 0, 65535); 2000 } 2001 2002 this(HandshakeIO io, ref HandshakeHash hash) 2003 { 2004 hash.update(io.send(this)); 2005 } 2006 2007 protected: 2008 override Vector!ubyte serialize() const 2009 { 2010 Vector!ubyte buf = Vector!ubyte(4); 2011 storeBigEndian(m_ticket_lifetime_hint.total!"seconds", buf.ptr); 2012 appendTlsLengthValue(buf, m_ticket, 2); 2013 return buf.move(); 2014 } 2015 2016 private: 2017 Duration m_ticket_lifetime_hint; 2018 Vector!ubyte m_ticket; 2019 } 2020 2021 /** 2022 * Change Cipher Spec 2023 */ 2024 final class ChangeCipherSpec : HandshakeMessage 2025 { 2026 public: 2027 override const(HandshakeType) type() const { return HANDSHAKE_CCS; } 2028 2029 override Vector!ubyte serialize() const 2030 { return Vector!ubyte(cast(ubyte[])[1]); } 2031 } 2032 2033 2034 package: 2035 2036 string certTypeCodeToName(ubyte code) 2037 { 2038 switch(code) 2039 { 2040 case 1: 2041 return "RSA"; 2042 case 2: 2043 return "DSA"; 2044 case 64: 2045 return "ECDSA"; 2046 default: 2047 return ""; // DH or something else 2048 } 2049 } 2050 2051 ubyte certTypeNameToCode(in string name) 2052 { 2053 if (name == "RSA") 2054 return 1; 2055 if (name == "DSA") 2056 return 2; 2057 if (name == "ECDSA") 2058 return 64; 2059 2060 throw new InvalidArgument("Unknown cert type " ~ name); 2061 } 2062 2063 2064 SecureVector!ubyte stripLeadingZeros()(auto const ref SecureVector!ubyte input) 2065 { 2066 size_t leading_zeros = 0; 2067 2068 for (size_t i = 0; i != input.length; ++i) 2069 { 2070 if (input[i] != 0) 2071 break; 2072 ++leading_zeros; 2073 } 2074 2075 SecureVector!ubyte output = SecureVector!ubyte(input.ptr[leading_zeros .. input.length]); 2076 return output; 2077 } 2078 2079 2080 /* 2081 * Compute the verifyData 2082 */ 2083 Vector!ubyte finishedComputeVerify(in HandshakeState state, ConnectionSide side) 2084 { 2085 __gshared immutable const(ubyte)[] TLS_CLIENT_LABEL = [ 2086 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69, 2087 0x73, 0x68, 0x65, 0x64 ]; 2088 2089 __gshared immutable const(ubyte)[] TLS_SERVER_LABEL = [ 2090 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69, 2091 0x73, 0x68, 0x65, 0x64 ]; 2092 2093 Unique!KDF prf = state.protocolSpecificPrf(); 2094 2095 Vector!ubyte input; 2096 input.reserve(64); 2097 if (side == CLIENT) 2098 input ~= cast(ubyte[])TLS_CLIENT_LABEL; 2099 else 2100 input ~= cast(ubyte[])TLS_SERVER_LABEL; 2101 2102 auto vec = state.hash().flushInto(state.Version(), state.ciphersuite().prfAlgo()); 2103 input ~= vec[]; 2104 return unlock(prf.deriveKey(12, state.sessionKeys().masterSecret(), input)); 2105 2106 } 2107 2108 Vector!ubyte makeHelloRandom(RandomNumberGenerator rng, in TLSPolicy policy) 2109 { 2110 Vector!ubyte buf = Vector!ubyte(32); 2111 rng.randomize(&buf[0], buf.length); 2112 2113 if (policy.includeTimeInHelloRandom()) 2114 { 2115 const uint time32 = cast(uint)(Clock.currTime(UTC()).toUnixTime); 2116 storeBigEndian(time32, buf.ptr); 2117 } 2118 2119 return buf; 2120 }