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 name = SupportedEllipticCurves.curveIdToName(curve_id); 1059 1060 if (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(name)) 1065 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Server sent ECC curve prohibited by policy"); 1066 } 1067 1068 ECGroup group = ECGroup(name); 1069 1070 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255); 1071 1072 auto counterparty_key = ECDHPublicKey(group, OS2ECP(ecdh_key, group.getCurve())); 1073 1074 auto priv_key = ECDHPrivateKey(rng, group); 1075 SecureVector!ubyte ecdh_secret; 1076 { 1077 auto ka = scoped!PKKeyAgreement(priv_key, "Raw"); 1078 auto public_value = counterparty_key.publicValue(); 1079 auto derived_key = ka.deriveKey(0, public_value); 1080 ecdh_secret = derived_key.bitsOf(); 1081 } 1082 1083 if (kex_algo == "ECDH") 1084 m_pre_master = ecdh_secret.move(); 1085 else 1086 { 1087 appendTlsLengthValue(m_pre_master, ecdh_secret, 2); 1088 appendTlsLengthValue(m_pre_master, psk.bitsOf(), 2); 1089 } 1090 1091 appendTlsLengthValue(m_key_material, priv_key.publicValue(), 1); 1092 } 1093 else if (kex_algo == "SRP_SHA") 1094 { 1095 static if (BOTAN_HAS_SRP6) { 1096 const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1097 const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1098 Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255); 1099 const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1100 1101 const string srp_group = srp6GroupIdentifier(N, g); 1102 1103 const string srp_identifier = creds.srpIdentifier("tls-client", hostname); 1104 1105 const string srp_password = creds.srpPassword("tls-client", hostname, srp_identifier); 1106 1107 SRP6KeyPair srp_vals = srp6ClientAgree(srp_identifier, 1108 srp_password, 1109 srp_group, 1110 "SHA-1", 1111 salt, 1112 B, 1113 rng); 1114 1115 appendTlsLengthValue(m_key_material, BigInt.encode(srp_vals.privkey), 2); 1116 m_pre_master = srp_vals.pubkey.bitsOf(); 1117 } else { 1118 throw new InternalError("ClientKeyExchange: Unknown kex " ~ kex_algo); 1119 } 1120 } 1121 else 1122 { 1123 throw new InternalError("ClientKeyExchange: Unknown kex " ~ 1124 kex_algo); 1125 } 1126 1127 reader.assertDone(); 1128 } 1129 else 1130 { 1131 // No server key exchange msg better mean RSA kex + RSA key in cert 1132 1133 if (kex_algo != "RSA") 1134 throw new TLSUnexpectedMessage("No server kex but negotiated kex " ~ kex_algo); 1135 1136 if (!server_public_key) 1137 throw new InternalError("No server public key for RSA exchange"); 1138 1139 if (server_public_key.algoName == "RSA") 1140 { 1141 auto rsa_pub = RSAPublicKey(cast(PublicKey)server_public_key); 1142 const TLSProtocolVersion offered_version = state.clientHello().Version(); 1143 1144 m_pre_master = rng.randomVec(48); 1145 m_pre_master[0] = offered_version.majorVersion(); 1146 m_pre_master[1] = offered_version.minorVersion(); 1147 1148 auto encryptor = scoped!PKEncryptorEME(rsa_pub, "PKCS1v15"); 1149 1150 Vector!ubyte encrypted_key = encryptor.encrypt(m_pre_master, rng); 1151 1152 appendTlsLengthValue(m_key_material, encrypted_key, 2); 1153 } 1154 else 1155 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, 1156 "Expected a RSA key in server cert but got " ~ 1157 server_public_key.algoName); 1158 } 1159 1160 state.hash().update(io.send(this)); 1161 } 1162 1163 1164 protected: 1165 override Vector!ubyte serialize() const { return m_key_material.dup; } 1166 1167 private: 1168 Vector!ubyte m_key_material; 1169 SecureVector!ubyte m_pre_master; 1170 } 1171 1172 /** 1173 * Certificate Message 1174 */ 1175 final class Certificate : HandshakeMessage 1176 { 1177 public: 1178 override const(HandshakeType) type() const { return CERTIFICATE; } 1179 ref const(Vector!X509Certificate) certChain() const { return *m_certs; } 1180 1181 size_t count() const { return m_certs.length; } 1182 @property bool empty() const { return m_certs.empty; } 1183 1184 /** 1185 * Create a new Certificate message 1186 */ 1187 this()(HandshakeIO io, 1188 ref HandshakeHash hash, 1189 auto ref Array!X509Certificate cert_list) 1190 { 1191 m_certs = cert_list; 1192 hash.update(io.send(this)); 1193 } 1194 1195 /** 1196 * Create a new Certificate message 1197 */ 1198 this()(HandshakeIO io, 1199 ref HandshakeHash hash, 1200 auto ref Vector!X509Certificate cert_list) 1201 { 1202 m_certs = cert_list.dupr; 1203 hash.update(io.send(this)); 1204 } 1205 1206 /** 1207 * Deserialize a Certificate message 1208 */ 1209 this()(auto const ref Vector!ubyte buf) 1210 { 1211 if (buf.length < 3) 1212 throw new DecodingError("Certificate: Message malformed"); 1213 1214 const size_t total_size = make_uint(0, buf[0], buf[1], buf[2]); 1215 1216 if (total_size != buf.length - 3) 1217 throw new DecodingError("Certificate: Message malformed"); 1218 1219 const(ubyte)* certs = buf.ptr + 3; 1220 1221 while (true) 1222 { 1223 size_t remaining_bytes = buf.ptr + buf.length - certs; 1224 if (remaining_bytes <= 0) 1225 break; 1226 if (remaining_bytes < 3) 1227 throw new DecodingError("Certificate: Message malformed"); 1228 1229 const size_t cert_size = make_uint(0, certs[0], certs[1], certs[2]); 1230 1231 if (remaining_bytes < (3 + cert_size)) 1232 throw new DecodingError("Certificate: Message malformed"); 1233 1234 auto cert_buf = DataSourceMemory(&certs[3], cert_size); 1235 m_certs.pushBack(X509Certificate(cast(DataSource)cert_buf)); 1236 1237 certs += cert_size + 3; 1238 } 1239 } 1240 1241 protected: 1242 /** 1243 * Serialize a Certificate message 1244 */ 1245 override Vector!ubyte serialize() const 1246 { 1247 Vector!ubyte buf; 1248 buf.reserve(2048); 1249 buf.length = 3; 1250 for (size_t i = 0; i != m_certs.length; ++i) 1251 { 1252 Vector!ubyte raw_cert = m_certs[i].BER_encode(); 1253 const size_t cert_size = raw_cert.length; 1254 foreach (size_t j; 0 .. 3) 1255 buf.pushBack(get_byte!uint(j+1, cast(uint) cert_size)); 1256 buf ~= raw_cert; 1257 } 1258 1259 const size_t buf_size = buf.length - 3; 1260 foreach (size_t i; 0 .. 3) 1261 buf[i] = get_byte!uint(i+1, cast(uint) buf_size); 1262 1263 return buf.move(); 1264 } 1265 1266 private: 1267 Array!X509Certificate m_certs; 1268 } 1269 1270 /** 1271 * Certificate Request Message 1272 */ 1273 final class CertificateReq : HandshakeMessage 1274 { 1275 public: 1276 override const(HandshakeType) type() const { return CERTIFICATE_REQUEST; } 1277 1278 ref const(Vector!string) acceptableCertTypes() const 1279 { return m_cert_key_types; } 1280 1281 ref const(Vector!X509DN) acceptableCAs() const { return m_names; } 1282 1283 Vector!( Pair!(string, string) ) supportedAlgos() const 1284 { return m_supported_algos.dup; } 1285 1286 /** 1287 * Create a new Certificate Request message 1288 */ 1289 this(HandshakeIO io, 1290 ref HandshakeHash hash, 1291 in TLSPolicy policy, 1292 Vector!X509DN ca_certs, 1293 TLSProtocolVersion _version) 1294 { 1295 m_names = ca_certs.move(); 1296 m_cert_key_types = [ "RSA", "DSA", "ECDSA" ]; 1297 static Vector!( Pair!(string, string) ) last_supported_algos; 1298 static TLSPolicy last_tls_policy; 1299 static TLSProtocolVersion last_version; 1300 if (policy is last_tls_policy && _version == last_version) 1301 m_supported_algos = last_supported_algos.dup; 1302 else { 1303 m_supported_algos.reserve(16); 1304 if (_version.supportsNegotiableSignatureAlgorithms()) 1305 { 1306 Vector!string hashes = policy.allowedSignatureHashes(); 1307 Vector!string sigs = policy.allowedSignatureMethods(); 1308 1309 for (size_t i = 0; i != hashes.length; ++i) 1310 for (size_t j = 0; j != sigs.length; ++j) 1311 m_supported_algos.pushBack(makePair(hashes[i], sigs[j])); 1312 } 1313 last_tls_policy = cast() policy; 1314 last_version = _version; 1315 last_supported_algos = m_supported_algos.dup; 1316 } 1317 1318 hash.update(io.send(this)); 1319 } 1320 1321 /** 1322 * Deserialize a Certificate Request message 1323 */ 1324 this(const ref Vector!ubyte buf, TLSProtocolVersion _version) 1325 { 1326 if (buf.length < 4) 1327 throw new DecodingError("Certificate_Req: Bad certificate request"); 1328 1329 TLSDataReader reader = TLSDataReader("CertificateRequest", buf); 1330 1331 Vector!ubyte cert_type_codes = reader.getRangeVector!ubyte(1, 1, 255); 1332 1333 for (size_t i = 0; i != cert_type_codes.length; ++i) 1334 { 1335 const string cert_type_name = certTypeCodeToName(cert_type_codes[i]); 1336 1337 if (cert_type_name == "") // something we don't know 1338 continue; 1339 1340 m_cert_key_types.pushBack(cert_type_name); 1341 } 1342 1343 if (_version.supportsNegotiableSignatureAlgorithms()) 1344 { 1345 Vector!ubyte sig_hash_algs = reader.getRangeVector!ubyte(2, 2, 65534); 1346 1347 if (sig_hash_algs.length % 2 != 0) 1348 throw new DecodingError("Bad length for signature IDs in certificate request"); 1349 1350 for (size_t i = 0; i != sig_hash_algs.length; i += 2) 1351 { 1352 string hash = SignatureAlgorithms.hashAlgoName(sig_hash_algs[i]); 1353 string sig = SignatureAlgorithms.sigAlgoName(sig_hash_algs[i+1]); 1354 m_supported_algos.pushBack(makePair(hash, sig)); 1355 } 1356 } 1357 1358 const ushort purported_size = reader.get_ushort(); 1359 1360 if (reader.remainingBytes() != purported_size) 1361 throw new DecodingError("Inconsistent length in certificate request"); 1362 1363 while (reader.hasRemaining()) 1364 { 1365 Vector!ubyte name_bits = reader.getRangeVector!ubyte(2, 0, 65535); 1366 1367 BERDecoder decoder = BERDecoder(name_bits.ptr, name_bits.length); 1368 X509DN name = X509DN(); 1369 decoder.decode(name); 1370 m_names.pushBack(name); 1371 } 1372 } 1373 1374 protected: 1375 1376 /** 1377 * Serialize a Certificate Request message 1378 */ 1379 override Vector!ubyte serialize() const 1380 { 1381 Vector!ubyte buf; 1382 buf.reserve(256); 1383 Vector!ubyte cert_types; 1384 cert_types.reserve(64); 1385 for (size_t i = 0; i != m_cert_key_types.length; ++i) 1386 cert_types.pushBack(certTypeNameToCode(m_cert_key_types[i])); 1387 1388 appendTlsLengthValue(buf, cert_types, 1); 1389 1390 if (!m_supported_algos.empty) { 1391 Unique!SignatureAlgorithms sig_algos = new SignatureAlgorithms(m_supported_algos.dup); 1392 buf ~= sig_algos.serialize(); 1393 } 1394 1395 Vector!ubyte encoded_names; 1396 1397 for (size_t i = 0; i != m_names.length; ++i) 1398 { 1399 DEREncoder encoder = DEREncoder(); 1400 encoder.encode(m_names[i]); 1401 1402 appendTlsLengthValue(encoded_names, encoder.getContents(), 2); 1403 } 1404 1405 appendTlsLengthValue(buf, encoded_names, 2); 1406 1407 return buf.move(); 1408 } 1409 1410 private: 1411 Vector!X509DN m_names; 1412 Vector!string m_cert_key_types; 1413 1414 Vector!( Pair!(string, string) ) m_supported_algos; 1415 } 1416 1417 /** 1418 * Certificate Verify Message 1419 */ 1420 final class CertificateVerify : HandshakeMessage 1421 { 1422 public: 1423 override const(HandshakeType) type() const { return CERTIFICATE_VERIFY; } 1424 1425 /** 1426 * Check the signature on a certificate verify message 1427 * Params: 1428 * cert = the purported certificate 1429 * state = the handshake state 1430 */ 1431 bool verify(const X509Certificate cert, 1432 const HandshakeState state) const 1433 { 1434 Unique!PublicKey key = cert.subjectPublicKey(); 1435 1436 Pair!(string, SignatureFormat) format = state.understandSigFormat(*key, m_hash_algo, m_sig_algo, true); 1437 1438 PKVerifier verifier = PKVerifier(*key, format.first, format.second); 1439 1440 return verifier.verifyMessage(state.hash().getContents(), m_signature); 1441 } 1442 1443 /* 1444 * Create a new Certificate Verify message 1445 */ 1446 this(HandshakeIO io, 1447 HandshakeState state, 1448 in TLSPolicy policy, 1449 RandomNumberGenerator rng, 1450 const PrivateKey priv_key) 1451 { 1452 assert(priv_key, "No private key defined"); 1453 1454 Pair!(string, SignatureFormat) format = state.chooseSigFormat(priv_key, m_hash_algo, m_sig_algo, true, policy); 1455 1456 PKSigner signer = PKSigner(priv_key, format.first, format.second); 1457 1458 m_signature = signer.signMessage(state.hash().getContents(), rng); 1459 1460 state.hash().update(io.send(this)); 1461 } 1462 1463 /* 1464 * Deserialize a Certificate Verify message 1465 */ 1466 this(const ref Vector!ubyte buf, 1467 TLSProtocolVersion _version) 1468 { 1469 TLSDataReader reader = TLSDataReader("CertificateVerify", buf); 1470 1471 if (_version.supportsNegotiableSignatureAlgorithms()) 1472 { 1473 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte()); 1474 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte()); 1475 } 1476 1477 m_signature = reader.getRange!ubyte(2, 0, 65535); 1478 } 1479 1480 protected: 1481 /* 1482 * Serialize a Certificate Verify message 1483 */ 1484 override Vector!ubyte serialize() const 1485 { 1486 Vector!ubyte buf; 1487 1488 if (m_hash_algo != "" && m_sig_algo != "") 1489 { 1490 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1491 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1492 } 1493 1494 const ushort sig_len = cast(ushort) m_signature.length; 1495 buf.pushBack(get_byte(0, sig_len)); 1496 buf.pushBack(get_byte(1, sig_len)); 1497 buf ~= m_signature[]; 1498 1499 return buf.move(); 1500 } 1501 1502 private: 1503 string m_sig_algo; // sig algo used to create signature 1504 string m_hash_algo; // hash used to create signature 1505 Vector!ubyte m_signature; 1506 } 1507 1508 /** 1509 * Finished Message 1510 */ 1511 final class Finished : HandshakeMessage 1512 { 1513 public: 1514 override const(HandshakeType) type() const { return FINISHED; } 1515 1516 ref const(Vector!ubyte) verifyData() const 1517 { return m_verification_data; } 1518 1519 const(ubyte[]) verifyDataBytes() const { return m_verification_data[]; } 1520 1521 /* 1522 * Verify a Finished message 1523 */ 1524 bool verify(in HandshakeState state, ConnectionSide side) const 1525 { 1526 return (m_verification_data == finishedComputeVerify(state, side)); 1527 } 1528 1529 /* 1530 * Create a new Finished message 1531 */ 1532 this(HandshakeIO io, 1533 HandshakeState state, 1534 ConnectionSide side) 1535 { 1536 m_verification_data = finishedComputeVerify(state, side); 1537 state.hash().update(io.send(this)); 1538 } 1539 1540 /* 1541 * Deserialize a Finished message 1542 */ 1543 this(Vector!ubyte buf) 1544 { 1545 m_verification_data = buf.move(); 1546 } 1547 1548 protected: 1549 /* 1550 * Serialize a Finished message 1551 */ 1552 override Vector!ubyte serialize() const 1553 { 1554 return m_verification_data.dup; 1555 } 1556 1557 private: 1558 Vector!ubyte m_verification_data; 1559 } 1560 1561 /** 1562 * Hello Request Message 1563 */ 1564 final class HelloRequest : HandshakeMessage 1565 { 1566 public: 1567 override const(HandshakeType) type() const { return HELLO_REQUEST; } 1568 1569 /* 1570 * Create a new Hello Request message 1571 */ 1572 this(HandshakeIO io) 1573 { 1574 io.send(this); 1575 } 1576 1577 /* 1578 * Deserialize a Hello Request message 1579 */ 1580 this(const ref Vector!ubyte buf) 1581 { 1582 if (buf.length) 1583 throw new DecodingError("Bad HelloRequest, has non-zero size"); 1584 } 1585 1586 protected: 1587 /* 1588 * Serialize a Hello Request message 1589 */ 1590 override Vector!ubyte serialize() const 1591 { 1592 return Vector!ubyte(); 1593 } 1594 } 1595 1596 /** 1597 * TLSServer Key Exchange Message 1598 */ 1599 final class ServerKeyExchange : HandshakeMessage 1600 { 1601 public: 1602 override const(HandshakeType) type() const { return SERVER_KEX; } 1603 1604 ref const(Vector!ubyte) params() const { return m_params; } 1605 1606 /** 1607 * Verify a TLSServer Key Exchange message 1608 */ 1609 bool verify(in PublicKey server_key, 1610 const HandshakeState state) const 1611 { 1612 Pair!(string, SignatureFormat) format = state.understandSigFormat(server_key, m_hash_algo, m_sig_algo, false); 1613 1614 PKVerifier verifier = PKVerifier(server_key, format.first, format.second); 1615 verifier.update(state.clientHello().random()); 1616 verifier.update(state.serverHello().random()); 1617 verifier.update(params()); 1618 return verifier.checkSignature(m_signature); 1619 } 1620 1621 // Only valid for certain kex types 1622 const(PrivateKey) serverKexKey() const 1623 { 1624 assert(m_kex_key, "PrivateKey cannot be null"); 1625 return *m_kex_key; 1626 } 1627 1628 static if (BOTAN_HAS_SRP6) { 1629 // Only valid for SRP negotiation 1630 const(SRP6ServerSession) serverSrpParams() const 1631 { 1632 assert(m_srp_params, "SRP6ServerSession cannot be null"); 1633 return *m_srp_params; 1634 } 1635 } 1636 1637 /** 1638 * Deserialize a TLSServer Key Exchange message 1639 */ 1640 this(const ref Vector!ubyte buf, 1641 in string kex_algo, 1642 in string sig_algo, 1643 TLSProtocolVersion _version) 1644 { 1645 m_kex_key.free(); 1646 static if (BOTAN_HAS_SRP6) 1647 m_srp_params.free(); 1648 if (buf.length < 6) 1649 throw new DecodingError("ServerKeyExchange: Packet corrupted"); 1650 1651 TLSDataReader reader = TLSDataReader("ServerKeyExchange", buf); 1652 1653 /* 1654 * We really are just serializing things back to what they were 1655 * before, but unfortunately to know where the signature is we need 1656 * to be able to parse the whole thing anyway. 1657 */ 1658 1659 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1660 { 1661 const string identity_hint = reader.getString(2, 0, 65535); 1662 appendTlsLengthValue(m_params, identity_hint, 2); 1663 } 1664 1665 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1666 { 1667 // 3 bigints, DH p, g, Y 1668 1669 foreach (size_t i; 0 .. 3) 1670 { 1671 BigInt v = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1672 appendTlsLengthValue(m_params, BigInt.encode(v), 2); 1673 } 1674 } 1675 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1676 { 1677 const ubyte curve_type = reader.get_byte(); 1678 1679 if (curve_type != 3) 1680 throw new DecodingError("ServerKeyExchange: TLSServer sent non-named ECC curve"); 1681 1682 const ushort curve_id = reader.get_ushort(); 1683 1684 const string name = SupportedEllipticCurves.curveIdToName(curve_id); 1685 1686 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255); 1687 1688 if (name == "") 1689 throw new DecodingError("ServerKeyExchange: TLSServer sent unknown named curve " ~ 1690 to!string(curve_id)); 1691 1692 m_params.pushBack(curve_type); 1693 m_params.pushBack(get_byte(0, curve_id)); 1694 m_params.pushBack(get_byte(1, curve_id)); 1695 appendTlsLengthValue(m_params, ecdh_key, 1); 1696 } 1697 else if (kex_algo == "SRP_SHA") 1698 { 1699 // 2 bigints (N,g) then salt, then server B 1700 1701 const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1702 const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1703 Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255); 1704 const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1705 1706 appendTlsLengthValue(m_params, BigInt.encode(N), 2); 1707 appendTlsLengthValue(m_params, BigInt.encode(g), 2); 1708 appendTlsLengthValue(m_params, salt, 1); 1709 appendTlsLengthValue(m_params, BigInt.encode(B), 2); 1710 } 1711 else if (kex_algo != "PSK") 1712 throw new DecodingError("ServerKeyExchange: Unsupported kex type " ~ kex_algo); 1713 1714 if (sig_algo != "") 1715 { 1716 if (_version.supportsNegotiableSignatureAlgorithms()) 1717 { 1718 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte()); 1719 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte()); 1720 } 1721 1722 m_signature = reader.getRange!ubyte(2, 0, 65535); 1723 } 1724 1725 reader.assertDone(); 1726 } 1727 1728 /** 1729 * Create a new TLSServer Key Exchange message 1730 */ 1731 this(HandshakeIO io, 1732 HandshakeState state, 1733 in TLSPolicy policy, 1734 TLSCredentialsManager creds, 1735 RandomNumberGenerator rng, 1736 in PrivateKey signing_key = null) 1737 { 1738 const string hostname = state.clientHello().sniHostname(); 1739 const string kex_algo = state.ciphersuite().kexAlgo(); 1740 1741 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1742 { 1743 string identity_hint = creds.pskIdentityHint("tls-server", hostname); 1744 1745 appendTlsLengthValue(m_params, identity_hint, 2); 1746 } 1747 1748 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1749 { 1750 auto dh = DHPrivateKey(rng, policy.dhGroup()); 1751 1752 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getP()), 2); 1753 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getG()), 2); 1754 appendTlsLengthValue(m_params, dh.publicValue(), 2); 1755 m_kex_key = dh.release(); 1756 } 1757 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1758 { 1759 Vector!string curves = state.clientHello().supportedEccCurves(); 1760 1761 if (curves.empty) 1762 throw new InternalError("TLSClient sent no ECC extension but we negotiated ECDH"); 1763 1764 const string curve_name = policy.chooseCurve(curves.move()); 1765 1766 if (curve_name == "") 1767 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client"); 1768 1769 ECGroup ec_group = ECGroup(curve_name); 1770 1771 auto ecdh = ECDHPrivateKey(rng, ec_group); 1772 1773 const string ecdh_domain_oid = ecdh.domain().getOid(); 1774 const string domain = OIDS.lookup(OID(ecdh_domain_oid)); 1775 1776 if (domain == "") 1777 throw new InternalError("Could not find name of ECDH domain " ~ ecdh_domain_oid); 1778 1779 const ushort named_curve_id = SupportedEllipticCurves.nameToCurveId(domain); 1780 1781 m_params.pushBack(3); // named curve 1782 m_params.pushBack(get_byte(0, named_curve_id)); 1783 m_params.pushBack(get_byte(1, named_curve_id)); 1784 1785 appendTlsLengthValue(m_params, ecdh.publicValue(), 1); 1786 1787 m_kex_key = ecdh.release(); 1788 } 1789 else if (kex_algo == "SRP_SHA") 1790 { 1791 static if (BOTAN_HAS_SRP6) { 1792 const string srp_identifier = state.clientHello().srpIdentifier(); 1793 1794 string group_id; 1795 BigInt v; 1796 Vector!ubyte salt; 1797 1798 const bool found = creds.srpVerifier("tls-server", hostname, 1799 srp_identifier, 1800 group_id, v, salt, 1801 policy.hideUnknownUsers()); 1802 1803 if (!found) 1804 throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, "Unknown SRP user " ~ srp_identifier); 1805 1806 m_srp_params = new SRP6ServerSession; 1807 1808 const BigInt* B = &m_srp_params.step1(v, group_id, "SHA-1", rng); 1809 1810 DLGroup group = DLGroup(group_id); 1811 1812 appendTlsLengthValue(m_params, BigInt.encode(group.getP()), 2); 1813 appendTlsLengthValue(m_params, BigInt.encode(group.getG()), 2); 1814 appendTlsLengthValue(m_params, salt, 1); 1815 appendTlsLengthValue(m_params, BigInt.encode(*B), 2); 1816 } else { 1817 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1818 } 1819 } 1820 else if (kex_algo != "PSK") 1821 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1822 1823 if (state.ciphersuite().sigAlgo() != "") 1824 { 1825 assert(signing_key, "Signing key was set"); 1826 1827 Pair!(string, SignatureFormat) format = state.chooseSigFormat(signing_key, m_hash_algo, m_sig_algo, false, policy); 1828 1829 PKSigner signer = PKSigner(signing_key, format.first, format.second); 1830 1831 signer.update(state.clientHello().random()); 1832 signer.update(state.serverHello().random()); 1833 signer.update(params()); 1834 m_signature = signer.signature(rng); 1835 } 1836 1837 state.hash().update(io.send(this)); 1838 } 1839 1840 protected: 1841 /** 1842 * Serialize a TLSServer Key Exchange message 1843 */ 1844 override Vector!ubyte serialize() const 1845 { 1846 Vector!ubyte buf = params().dup; 1847 1848 if (m_signature.length) 1849 { 1850 // This should be an explicit version check 1851 if (m_hash_algo != "" && m_sig_algo != "") 1852 { 1853 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1854 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1855 } 1856 1857 appendTlsLengthValue(buf, m_signature, 2); 1858 } 1859 1860 return buf.move(); 1861 } 1862 1863 private: 1864 Unique!PrivateKey m_kex_key; 1865 static if (BOTAN_HAS_SRP6) 1866 Unique!SRP6ServerSession m_srp_params; 1867 1868 Vector!ubyte m_params; 1869 1870 string m_sig_algo; // sig algo used to create signature 1871 string m_hash_algo; // hash used to create signature 1872 Vector!ubyte m_signature; 1873 } 1874 1875 /** 1876 * TLSServer Hello Done Message 1877 */ 1878 final class ServerHelloDone : HandshakeMessage 1879 { 1880 public: 1881 override const(HandshakeType) type() const { return SERVER_HELLO_DONE; } 1882 1883 /* 1884 * Create a new TLSServer Hello Done message 1885 */ 1886 this(HandshakeIO io, ref HandshakeHash hash) 1887 { 1888 hash.update(io.send(this)); 1889 } 1890 1891 /* 1892 * Deserialize a TLSServer Hello Done message 1893 */ 1894 this(const ref Vector!ubyte buf) 1895 { 1896 if (buf.length) 1897 throw new DecodingError("ServerHello_Done: Must be empty, and is not"); 1898 } 1899 protected: 1900 /* 1901 * Serialize a TLSServer Hello Done message 1902 */ 1903 override Vector!ubyte serialize() const 1904 { 1905 return Vector!ubyte(); 1906 } 1907 } 1908 1909 /** 1910 * New EncryptedExtensions Message used mainly for ChannelIDExtension 1911 */ 1912 final class ChannelID : HandshakeMessage 1913 { 1914 override const(HandshakeType) type() const { return CHANNEL_ID; } 1915 1916 this(HandshakeIO io, 1917 ref HandshakeHash hash, 1918 TLSCredentialsManager creds, 1919 string hostname, 1920 SecureVector!ubyte hs_hash, 1921 SecureVector!ubyte orig_hs_hash = SecureVector!ubyte()) 1922 { 1923 m_channel_id = new EncryptedChannelID(creds.channelPrivateKey(hostname), hs_hash.move(), orig_hs_hash.move()); 1924 hash.update(io.send(this)); 1925 } 1926 1927 override Vector!ubyte serialize() const 1928 { 1929 Vector!ubyte buf; 1930 buf.reserve(130); 1931 1932 const ushort extn_code = m_channel_id.type(); 1933 const Vector!ubyte extn_val = m_channel_id.serialize(); 1934 1935 buf.pushBack(get_byte(0, extn_code)); 1936 buf.pushBack(get_byte(1, extn_code)); 1937 1938 buf.pushBack(get_byte(0, cast(ushort) extn_val.length)); 1939 buf.pushBack(get_byte(1, cast(ushort) extn_val.length)); 1940 1941 buf ~= extn_val[]; 1942 return buf.move(); 1943 } 1944 1945 private: 1946 Unique!EncryptedChannelID m_channel_id; 1947 } 1948 1949 /** 1950 * New TLS Session Ticket Message 1951 */ 1952 final class NewSessionTicket : HandshakeMessage 1953 { 1954 public: 1955 override const(HandshakeType) type() const { return NEW_SESSION_TICKET; } 1956 1957 const(Duration) ticketLifetimeHint() const { return m_ticket_lifetime_hint; } 1958 ref const(Vector!ubyte) ticket() const { return m_ticket; } 1959 1960 this(HandshakeIO io, 1961 ref HandshakeHash hash, 1962 Vector!ubyte ticket, 1963 Duration lifetime) 1964 1965 { 1966 m_ticket_lifetime_hint = lifetime; 1967 m_ticket = ticket.move(); 1968 hash.update = io.send(this); 1969 } 1970 1971 this(const ref Vector!ubyte buf) 1972 { 1973 if (buf.length < 6) 1974 throw new DecodingError("TLSSession ticket message too short to be valid"); 1975 1976 TLSDataReader reader = TLSDataReader("SessionTicket", buf); 1977 1978 m_ticket_lifetime_hint = reader.get_uint().seconds; 1979 m_ticket = reader.getRange!ubyte(2, 0, 65535); 1980 } 1981 1982 this(HandshakeIO io, ref HandshakeHash hash) 1983 { 1984 hash.update(io.send(this)); 1985 } 1986 1987 protected: 1988 override Vector!ubyte serialize() const 1989 { 1990 Vector!ubyte buf = Vector!ubyte(4); 1991 storeBigEndian(m_ticket_lifetime_hint.total!"seconds", buf.ptr); 1992 appendTlsLengthValue(buf, m_ticket, 2); 1993 return buf.move(); 1994 } 1995 1996 private: 1997 Duration m_ticket_lifetime_hint; 1998 Vector!ubyte m_ticket; 1999 } 2000 2001 /** 2002 * Change Cipher Spec 2003 */ 2004 final class ChangeCipherSpec : HandshakeMessage 2005 { 2006 public: 2007 override const(HandshakeType) type() const { return HANDSHAKE_CCS; } 2008 2009 override Vector!ubyte serialize() const 2010 { return Vector!ubyte(cast(ubyte[])[1]); } 2011 } 2012 2013 2014 package: 2015 2016 string certTypeCodeToName(ubyte code) 2017 { 2018 switch(code) 2019 { 2020 case 1: 2021 return "RSA"; 2022 case 2: 2023 return "DSA"; 2024 case 64: 2025 return "ECDSA"; 2026 default: 2027 return ""; // DH or something else 2028 } 2029 } 2030 2031 ubyte certTypeNameToCode(in string name) 2032 { 2033 if (name == "RSA") 2034 return 1; 2035 if (name == "DSA") 2036 return 2; 2037 if (name == "ECDSA") 2038 return 64; 2039 2040 throw new InvalidArgument("Unknown cert type " ~ name); 2041 } 2042 2043 2044 SecureVector!ubyte stripLeadingZeros()(auto const ref SecureVector!ubyte input) 2045 { 2046 size_t leading_zeros = 0; 2047 2048 for (size_t i = 0; i != input.length; ++i) 2049 { 2050 if (input[i] != 0) 2051 break; 2052 ++leading_zeros; 2053 } 2054 2055 SecureVector!ubyte output = SecureVector!ubyte(input.ptr[leading_zeros .. input.length]); 2056 return output; 2057 } 2058 2059 2060 /* 2061 * Compute the verifyData 2062 */ 2063 Vector!ubyte finishedComputeVerify(in HandshakeState state, ConnectionSide side) 2064 { 2065 __gshared immutable const(ubyte)[] TLS_CLIENT_LABEL = [ 2066 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69, 2067 0x73, 0x68, 0x65, 0x64 ]; 2068 2069 __gshared immutable const(ubyte)[] TLS_SERVER_LABEL = [ 2070 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69, 2071 0x73, 0x68, 0x65, 0x64 ]; 2072 2073 Unique!KDF prf = state.protocolSpecificPrf(); 2074 2075 Vector!ubyte input; 2076 input.reserve(64); 2077 if (side == CLIENT) 2078 input ~= cast(ubyte[])TLS_CLIENT_LABEL; 2079 else 2080 input ~= cast(ubyte[])TLS_SERVER_LABEL; 2081 2082 auto vec = state.hash().flushInto(state.Version(), state.ciphersuite().prfAlgo()); 2083 input ~= vec[]; 2084 return unlock(prf.deriveKey(12, state.sessionKeys().masterSecret(), input)); 2085 2086 } 2087 2088 Vector!ubyte makeHelloRandom(RandomNumberGenerator rng, in TLSPolicy policy) 2089 { 2090 Vector!ubyte buf = Vector!ubyte(32); 2091 rng.randomize(&buf[0], buf.length); 2092 2093 if (policy.includeTimeInHelloRandom()) 2094 { 2095 const uint time32 = cast(uint)(Clock.currTime(UTC()).toUnixTime); 2096 storeBigEndian(time32, buf.ptr); 2097 } 2098 2099 return buf; 2100 }