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