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 auto param_a = BigInt.decode(reader.getRange!ubyte(2, 0, 65535)); 925 m_pre_master = srp.step2(¶m_a).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 auto cert = X509Certificate(cast(DataSource)cert_buf); 1294 m_certs.pushBack(cert); 1295 1296 certs += cert_size + 3; 1297 } 1298 } 1299 1300 protected: 1301 /** 1302 * Serialize a Certificate message 1303 */ 1304 override Vector!ubyte serialize() const 1305 { 1306 Vector!ubyte buf; 1307 buf.reserve(2048); 1308 buf.length = 3; 1309 for (size_t i = 0; i != m_certs.length; ++i) 1310 { 1311 auto cert = m_certs[i]; 1312 if (!cert.isValid()) continue; 1313 Vector!ubyte raw_cert = cert.BER_encode(); 1314 const size_t cert_size = raw_cert.length; 1315 foreach (size_t j; 0 .. 3) 1316 buf.pushBack(get_byte!uint(j+1, cast(uint) cert_size)); 1317 buf ~= raw_cert; 1318 } 1319 1320 const size_t buf_size = buf.length - 3; 1321 foreach (size_t i; 0 .. 3) 1322 buf[i] = get_byte!uint(i+1, cast(uint) buf_size); 1323 1324 return buf.move(); 1325 } 1326 1327 private: 1328 Array!X509Certificate m_certs; 1329 } 1330 1331 /** 1332 * Certificate Request Message 1333 */ 1334 final class CertificateReq : HandshakeMessage 1335 { 1336 public: 1337 override const(HandshakeType) type() const { return CERTIFICATE_REQUEST; } 1338 1339 ref const(Vector!string) acceptableCertTypes() const 1340 { return m_cert_key_types; } 1341 1342 ref const(Vector!X509DN) acceptableCAs() const { return m_names; } 1343 1344 Vector!( Pair!(string, string) ) supportedAlgos() const 1345 { return m_supported_algos.dup; } 1346 1347 /** 1348 * Create a new Certificate Request message 1349 */ 1350 this(HandshakeIO io, 1351 ref HandshakeHash hash, 1352 in TLSPolicy policy, 1353 Vector!X509DN ca_certs, 1354 TLSProtocolVersion _version) 1355 { 1356 m_names = ca_certs.move(); 1357 m_cert_key_types = [ "RSA", "DSA", "ECDSA" ]; 1358 static Vector!( Pair!(string, string) ) last_supported_algos; 1359 static TLSPolicy last_tls_policy; 1360 static TLSProtocolVersion last_version; 1361 if (policy is last_tls_policy && _version == last_version) 1362 m_supported_algos = last_supported_algos.dup; 1363 else { 1364 m_supported_algos.reserve(16); 1365 if (_version.supportsNegotiableSignatureAlgorithms()) 1366 { 1367 Vector!string hashes = policy.allowedSignatureHashes(); 1368 Vector!string sigs = policy.allowedSignatureMethods(); 1369 1370 for (size_t i = 0; i != hashes.length; ++i) 1371 for (size_t j = 0; j != sigs.length; ++j) 1372 m_supported_algos.pushBack(makePair(hashes[i], sigs[j])); 1373 } 1374 last_tls_policy = cast() policy; 1375 last_version = _version; 1376 last_supported_algos = m_supported_algos.dup; 1377 } 1378 1379 hash.update(io.send(this)); 1380 } 1381 1382 /** 1383 * Deserialize a Certificate Request message 1384 */ 1385 this(const ref Vector!ubyte buf, TLSProtocolVersion _version) 1386 { 1387 if (buf.length < 4) 1388 throw new DecodingError("Certificate_Req: Bad certificate request"); 1389 1390 TLSDataReader reader = TLSDataReader("CertificateRequest", buf); 1391 1392 Vector!ubyte cert_type_codes = reader.getRangeVector!ubyte(1, 1, 255); 1393 1394 for (size_t i = 0; i != cert_type_codes.length; ++i) 1395 { 1396 const string cert_type_name = certTypeCodeToName(cert_type_codes[i]); 1397 1398 if (cert_type_name == "") // something we don't know 1399 continue; 1400 1401 m_cert_key_types.pushBack(cert_type_name); 1402 } 1403 1404 if (_version.supportsNegotiableSignatureAlgorithms()) 1405 { 1406 Vector!ubyte sig_hash_algs = reader.getRangeVector!ubyte(2, 2, 65534); 1407 1408 if (sig_hash_algs.length % 2 != 0) 1409 throw new DecodingError("Bad length for signature IDs in certificate request"); 1410 1411 for (size_t i = 0; i != sig_hash_algs.length; i += 2) 1412 { 1413 string hash = SignatureAlgorithms.hashAlgoName(sig_hash_algs[i]); 1414 string sig = SignatureAlgorithms.sigAlgoName(sig_hash_algs[i+1]); 1415 m_supported_algos.pushBack(makePair(hash, sig)); 1416 } 1417 } 1418 1419 const ushort purported_size = reader.get_ushort(); 1420 1421 if (reader.remainingBytes() != purported_size) 1422 throw new DecodingError("Inconsistent length in certificate request"); 1423 1424 while (reader.hasRemaining()) 1425 { 1426 Vector!ubyte name_bits = reader.getRangeVector!ubyte(2, 0, 65535); 1427 1428 BERDecoder decoder = BERDecoder(name_bits.ptr, name_bits.length); 1429 X509DN name = X509DN(); 1430 decoder.decode(name); 1431 m_names.pushBack(name); 1432 } 1433 } 1434 1435 protected: 1436 1437 /** 1438 * Serialize a Certificate Request message 1439 */ 1440 override Vector!ubyte serialize() const 1441 { 1442 Vector!ubyte buf; 1443 buf.reserve(256); 1444 Vector!ubyte cert_types; 1445 cert_types.reserve(64); 1446 for (size_t i = 0; i != m_cert_key_types.length; ++i) 1447 cert_types.pushBack(certTypeNameToCode(m_cert_key_types[i])); 1448 1449 appendTlsLengthValue(buf, cert_types, 1); 1450 1451 if (!m_supported_algos.empty) { 1452 Unique!SignatureAlgorithms sig_algos = new SignatureAlgorithms(m_supported_algos.dup); 1453 buf ~= sig_algos.serialize(); 1454 } 1455 1456 Vector!ubyte encoded_names; 1457 1458 for (size_t i = 0; i != m_names.length; ++i) 1459 { 1460 DEREncoder encoder = DEREncoder(); 1461 encoder.encode(m_names[i]); 1462 1463 appendTlsLengthValue(encoded_names, encoder.getContents(), 2); 1464 } 1465 1466 appendTlsLengthValue(buf, encoded_names, 2); 1467 1468 return buf.move(); 1469 } 1470 1471 private: 1472 Vector!X509DN m_names; 1473 Vector!string m_cert_key_types; 1474 1475 Vector!( Pair!(string, string) ) m_supported_algos; 1476 } 1477 1478 /** 1479 * Certificate Verify Message 1480 */ 1481 final class CertificateVerify : HandshakeMessage 1482 { 1483 public: 1484 override const(HandshakeType) type() const { return CERTIFICATE_VERIFY; } 1485 1486 /** 1487 * Check the signature on a certificate verify message 1488 * Params: 1489 * cert = the purported certificate 1490 * state = the handshake state 1491 */ 1492 bool verify(const X509Certificate cert, 1493 const HandshakeState state) const 1494 { 1495 Unique!PublicKey key = cert.subjectPublicKey(); 1496 1497 Pair!(string, SignatureFormat) format = state.understandSigFormat(*key, m_hash_algo, m_sig_algo, true); 1498 1499 PKVerifier verifier = PKVerifier(*key, format.first, format.second); 1500 1501 return verifier.verifyMessage(state.hash().getContents(), m_signature); 1502 } 1503 1504 /* 1505 * Create a new Certificate Verify message 1506 */ 1507 this(HandshakeIO io, 1508 HandshakeState state, 1509 in TLSPolicy policy, 1510 RandomNumberGenerator rng, 1511 const PrivateKey priv_key) 1512 { 1513 assert(priv_key, "No private key defined"); 1514 1515 Pair!(string, SignatureFormat) format = state.chooseSigFormat(priv_key, m_hash_algo, m_sig_algo, true, policy); 1516 1517 PKSigner signer = PKSigner(priv_key, format.first, format.second); 1518 1519 m_signature = signer.signMessage(state.hash().getContents(), rng); 1520 1521 state.hash().update(io.send(this)); 1522 } 1523 1524 /* 1525 * Deserialize a Certificate Verify message 1526 */ 1527 this(const ref Vector!ubyte buf, 1528 TLSProtocolVersion _version) 1529 { 1530 TLSDataReader reader = TLSDataReader("CertificateVerify", buf); 1531 1532 if (_version.supportsNegotiableSignatureAlgorithms()) 1533 { 1534 m_hash_algo = SignatureAlgorithms.hashAlgoName(reader.get_byte()); 1535 m_sig_algo = SignatureAlgorithms.sigAlgoName(reader.get_byte()); 1536 } 1537 1538 m_signature = reader.getRange!ubyte(2, 0, 65535); 1539 } 1540 1541 protected: 1542 /* 1543 * Serialize a Certificate Verify message 1544 */ 1545 override Vector!ubyte serialize() const 1546 { 1547 Vector!ubyte buf; 1548 1549 if (m_hash_algo != "" && m_sig_algo != "") 1550 { 1551 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1552 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1553 } 1554 1555 const ushort sig_len = cast(ushort) m_signature.length; 1556 buf.pushBack(get_byte(0, sig_len)); 1557 buf.pushBack(get_byte(1, sig_len)); 1558 buf ~= m_signature[]; 1559 1560 return buf.move(); 1561 } 1562 1563 private: 1564 string m_sig_algo; // sig algo used to create signature 1565 string m_hash_algo; // hash used to create signature 1566 Vector!ubyte m_signature; 1567 } 1568 1569 /** 1570 * Finished Message 1571 */ 1572 final class Finished : HandshakeMessage 1573 { 1574 public: 1575 override const(HandshakeType) type() const { return FINISHED; } 1576 1577 ref const(Vector!ubyte) verifyData() const 1578 { return m_verification_data; } 1579 1580 const(ubyte[]) verifyDataBytes() const { return m_verification_data[]; } 1581 1582 /* 1583 * Verify a Finished message 1584 */ 1585 bool verify(in HandshakeState state, ConnectionSide side) const 1586 { 1587 return (m_verification_data == finishedComputeVerify(state, side)); 1588 } 1589 1590 /* 1591 * Create a new Finished message 1592 */ 1593 this(HandshakeIO io, 1594 HandshakeState state, 1595 ConnectionSide side) 1596 { 1597 m_verification_data = finishedComputeVerify(state, side); 1598 state.hash().update(io.send(this)); 1599 } 1600 1601 /* 1602 * Deserialize a Finished message 1603 */ 1604 this(Vector!ubyte buf) 1605 { 1606 m_verification_data = buf.move(); 1607 } 1608 1609 protected: 1610 /* 1611 * Serialize a Finished message 1612 */ 1613 override Vector!ubyte serialize() const 1614 { 1615 return m_verification_data.dup; 1616 } 1617 1618 private: 1619 Vector!ubyte m_verification_data; 1620 } 1621 1622 /** 1623 * Hello Request Message 1624 */ 1625 final class HelloRequest : HandshakeMessage 1626 { 1627 public: 1628 override const(HandshakeType) type() const { return HELLO_REQUEST; } 1629 1630 /* 1631 * Create a new Hello Request message 1632 */ 1633 this(HandshakeIO io) 1634 { 1635 io.send(this); 1636 } 1637 1638 /* 1639 * Deserialize a Hello Request message 1640 */ 1641 this(const ref Vector!ubyte buf) 1642 { 1643 if (buf.length) 1644 throw new DecodingError("Bad HelloRequest, has non-zero size"); 1645 } 1646 1647 protected: 1648 /* 1649 * Serialize a Hello Request message 1650 */ 1651 override Vector!ubyte serialize() const 1652 { 1653 return Vector!ubyte(); 1654 } 1655 } 1656 1657 /** 1658 * TLSServer Key Exchange Message 1659 */ 1660 final class ServerKeyExchange : HandshakeMessage 1661 { 1662 public: 1663 override const(HandshakeType) type() const { return SERVER_KEX; } 1664 1665 ref const(Vector!ubyte) params() const { return m_params; } 1666 1667 /** 1668 * Verify a TLSServer Key Exchange message 1669 */ 1670 bool verify(in PublicKey server_key, 1671 const HandshakeState state) const 1672 { 1673 Pair!(string, SignatureFormat) format = state.understandSigFormat(server_key, m_hash_algo, m_sig_algo, false); 1674 1675 PKVerifier verifier = PKVerifier(server_key, format.first, format.second); 1676 verifier.update(state.clientHello().random()); 1677 verifier.update(state.serverHello().random()); 1678 verifier.update(params()); 1679 return verifier.checkSignature(m_signature); 1680 } 1681 1682 // Only valid for certain kex types 1683 const(PrivateKey) serverKexKey() const 1684 { 1685 assert(m_kex_key, "PrivateKey cannot be null"); 1686 return *m_kex_key; 1687 } 1688 1689 static if (BOTAN_HAS_SRP6) { 1690 // Only valid for SRP negotiation 1691 const(SRP6ServerSession) serverSrpParams() const 1692 { 1693 assert(m_srp_params, "SRP6ServerSession cannot be null"); 1694 return *m_srp_params; 1695 } 1696 } 1697 1698 /** 1699 * Deserialize a TLSServer Key Exchange message 1700 */ 1701 this(const ref Vector!ubyte buf, 1702 in string kex_algo, 1703 in string sig_algo, 1704 TLSProtocolVersion _version) 1705 { 1706 m_kex_key.free(); 1707 static if (BOTAN_HAS_SRP6) 1708 m_srp_params.free(); 1709 if (buf.length < 6) 1710 throw new DecodingError("ServerKeyExchange: Packet corrupted"); 1711 1712 TLSDataReader reader = TLSDataReader("ServerKeyExchange", buf); 1713 1714 /* 1715 * We really are just serializing things back to what they were 1716 * before, but unfortunately to know where the signature is we need 1717 * to be able to parse the whole thing anyway. 1718 */ 1719 1720 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1721 { 1722 const string identity_hint = reader.getString(2, 0, 65535); 1723 appendTlsLengthValue(m_params, identity_hint, 2); 1724 } 1725 1726 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1727 { 1728 // 3 bigints, DH p, g, Y 1729 1730 foreach (size_t i; 0 .. 3) 1731 { 1732 BigInt v = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1733 appendTlsLengthValue(m_params, BigInt.encode(v), 2); 1734 } 1735 } 1736 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1737 { 1738 const ubyte curve_type = reader.get_byte(); 1739 1740 if (curve_type != 3) 1741 throw new DecodingError("ServerKeyExchange: TLSServer sent non-named ECC curve"); 1742 1743 const ushort curve_id = reader.get_ushort(); 1744 1745 const string name = SupportedEllipticCurves.curveIdToName(curve_id); 1746 1747 Vector!ubyte ecdh_key = reader.getRange!ubyte(1, 1, 255); 1748 1749 if (name == "") 1750 throw new DecodingError("ServerKeyExchange: TLSServer sent unknown named curve " ~ 1751 to!string(curve_id)); 1752 1753 m_params.pushBack(curve_type); 1754 m_params.pushBack(get_byte(0, curve_id)); 1755 m_params.pushBack(get_byte(1, curve_id)); 1756 appendTlsLengthValue(m_params, ecdh_key, 1); 1757 } 1758 else if (kex_algo == "SRP_SHA") 1759 { 1760 // 2 bigints (N,g) then salt, then server B 1761 1762 const BigInt N = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1763 const BigInt g = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1764 Vector!ubyte salt = reader.getRange!ubyte(1, 1, 255); 1765 const BigInt B = BigInt.decode(reader.getRange!ubyte(2, 1, 65535)); 1766 1767 appendTlsLengthValue(m_params, BigInt.encode(N), 2); 1768 appendTlsLengthValue(m_params, BigInt.encode(g), 2); 1769 appendTlsLengthValue(m_params, salt, 1); 1770 appendTlsLengthValue(m_params, BigInt.encode(B), 2); 1771 } 1772 else if (kex_algo != "PSK") 1773 throw new DecodingError("ServerKeyExchange: Unsupported kex type " ~ kex_algo); 1774 1775 if (sig_algo != "") 1776 { 1777 if (_version.supportsNegotiableSignatureAlgorithms()) 1778 { 1779 ubyte hash_byte = reader.get_byte(); 1780 ubyte sig_byte = reader.get_byte(); 1781 if (hash_byte == 8) { 1782 m_hash_algo = SignatureAlgorithms.hashAlgoName(sig_byte); 1783 m_sig_algo = SignatureAlgorithms.sigAlgoName(hash_byte); 1784 } 1785 else { 1786 m_hash_algo = SignatureAlgorithms.hashAlgoName(hash_byte); 1787 m_sig_algo = SignatureAlgorithms.sigAlgoName(sig_byte); 1788 } 1789 } 1790 m_signature = reader.getRange!ubyte(2, 0, 65535); 1791 } 1792 1793 reader.assertDone(); 1794 } 1795 1796 /** 1797 * Create a new TLSServer Key Exchange message 1798 */ 1799 this(HandshakeIO io, 1800 HandshakeState state, 1801 in TLSPolicy policy, 1802 TLSCredentialsManager creds, 1803 RandomNumberGenerator rng, 1804 in PrivateKey signing_key = null) 1805 { 1806 const string hostname = state.clientHello().sniHostname(); 1807 const string kex_algo = state.ciphersuite().kexAlgo(); 1808 1809 if (kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK") 1810 { 1811 string identity_hint = creds.pskIdentityHint("tls-server", hostname); 1812 1813 appendTlsLengthValue(m_params, identity_hint, 2); 1814 } 1815 1816 if (kex_algo == "DH" || kex_algo == "DHE_PSK") 1817 { 1818 auto dh = DHPrivateKey(rng, policy.dhGroup()); 1819 1820 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getP()), 2); 1821 appendTlsLengthValue(m_params, BigInt.encode(dh.getDomain().getG()), 2); 1822 appendTlsLengthValue(m_params, dh.publicValue(), 2); 1823 m_kex_key = dh.release(); 1824 } 1825 else if (kex_algo == "ECDH" || kex_algo == "ECDHE_PSK") 1826 { 1827 Vector!string curves = state.clientHello().supportedEccCurves(); 1828 1829 if (curves.empty) 1830 throw new InternalError("TLSClient sent no ECC extension but we negotiated ECDH"); 1831 1832 const string curve_name = policy.chooseCurve(curves.move()); 1833 1834 if (curve_name == "") 1835 throw new TLSException(TLSAlert.HANDSHAKE_FAILURE, "Could not agree on an ECC curve with the client"); 1836 const ushort named_curve_id = SupportedEllipticCurves.nameToCurveId(curve_name); 1837 if (named_curve_id == 0) 1838 throw new InternalError("TLS does not support ECC with " ~ curve_name); 1839 Vector!ubyte ecdh_public_val; 1840 1841 if (curve_name == "x25519") { 1842 import botan.pubkey.algo.curve25519; 1843 Curve25519PrivateKey x25519 = Curve25519PrivateKey(rng); 1844 ecdh_public_val = x25519.publicValue(); 1845 m_kex_key = x25519.release(); 1846 } else { 1847 ECGroup ec_group = ECGroup(curve_name); 1848 auto ecdh = ECDHPrivateKey(rng, ec_group); 1849 ecdh_public_val = ecdh.publicValue(); 1850 1851 m_kex_key = ecdh.release(); 1852 } 1853 m_params.pushBack(3); // named curve 1854 m_params.pushBack(get_byte(0, named_curve_id)); 1855 m_params.pushBack(get_byte(1, named_curve_id)); 1856 1857 appendTlsLengthValue(m_params, ecdh_public_val, 1); 1858 1859 } 1860 else if (kex_algo == "SRP_SHA") 1861 { 1862 static if (BOTAN_HAS_SRP6) { 1863 const string srp_identifier = state.clientHello().srpIdentifier(); 1864 1865 string group_id; 1866 BigInt v; 1867 Vector!ubyte salt; 1868 1869 const bool found = creds.srpVerifier("tls-server", hostname, 1870 srp_identifier, 1871 group_id, v, salt, 1872 policy.hideUnknownUsers()); 1873 1874 if (!found) 1875 throw new TLSException(TLSAlert.UNKNOWN_PSK_IDENTITY, "Unknown SRP user " ~ srp_identifier); 1876 1877 m_srp_params = new SRP6ServerSession; 1878 1879 const BigInt* B = &m_srp_params.step1(v, group_id, "SHA-1", rng); 1880 1881 DLGroup group = DLGroup(group_id); 1882 1883 appendTlsLengthValue(m_params, BigInt.encode(group.getP()), 2); 1884 appendTlsLengthValue(m_params, BigInt.encode(group.getG()), 2); 1885 appendTlsLengthValue(m_params, salt, 1); 1886 appendTlsLengthValue(m_params, BigInt.encode(*B), 2); 1887 } else { 1888 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1889 } 1890 } 1891 else if (kex_algo != "PSK") 1892 throw new InternalError("ServerKeyExchange: Unknown kex type " ~ kex_algo); 1893 1894 if (state.ciphersuite().sigAlgo() != "") 1895 { 1896 assert(signing_key, "Signing key was set"); 1897 1898 Pair!(string, SignatureFormat) format = state.chooseSigFormat(signing_key, m_hash_algo, m_sig_algo, false, policy); 1899 1900 PKSigner signer = PKSigner(signing_key, format.first, format.second); 1901 1902 signer.update(state.clientHello().random()); 1903 signer.update(state.serverHello().random()); 1904 signer.update(params()); 1905 m_signature = signer.signature(rng); 1906 } 1907 1908 state.hash().update(io.send(this)); 1909 } 1910 1911 protected: 1912 /** 1913 * Serialize a TLSServer Key Exchange message 1914 */ 1915 override Vector!ubyte serialize() const 1916 { 1917 Vector!ubyte buf = params().dup; 1918 1919 if (m_signature.length) 1920 { 1921 // This should be an explicit version check 1922 if (m_hash_algo != "" && m_sig_algo != "") 1923 { 1924 buf.pushBack(SignatureAlgorithms.hashAlgoCode(m_hash_algo)); 1925 buf.pushBack(SignatureAlgorithms.sigAlgoCode(m_sig_algo)); 1926 } 1927 1928 appendTlsLengthValue(buf, m_signature, 2); 1929 } 1930 1931 return buf.move(); 1932 } 1933 1934 private: 1935 Unique!PrivateKey m_kex_key; 1936 static if (BOTAN_HAS_SRP6) 1937 Unique!SRP6ServerSession m_srp_params; 1938 1939 Vector!ubyte m_params; 1940 1941 string m_sig_algo; // sig algo used to create signature 1942 string m_hash_algo; // hash used to create signature 1943 Vector!ubyte m_signature; 1944 } 1945 1946 /** 1947 * TLSServer Hello Done Message 1948 */ 1949 final class ServerHelloDone : HandshakeMessage 1950 { 1951 public: 1952 override const(HandshakeType) type() const { return SERVER_HELLO_DONE; } 1953 1954 /* 1955 * Create a new TLSServer Hello Done message 1956 */ 1957 this(HandshakeIO io, ref HandshakeHash hash) 1958 { 1959 hash.update(io.send(this)); 1960 } 1961 1962 /* 1963 * Deserialize a TLSServer Hello Done message 1964 */ 1965 this(const ref Vector!ubyte buf) 1966 { 1967 if (buf.length) 1968 throw new DecodingError("ServerHello_Done: Must be empty, and is not"); 1969 } 1970 protected: 1971 /* 1972 * Serialize a TLSServer Hello Done message 1973 */ 1974 override Vector!ubyte serialize() const 1975 { 1976 return Vector!ubyte(); 1977 } 1978 } 1979 1980 /** 1981 * New EncryptedExtensions Message used mainly for ChannelIDExtension 1982 */ 1983 final class ChannelID : HandshakeMessage 1984 { 1985 override const(HandshakeType) type() const { return CHANNEL_ID; } 1986 1987 this(HandshakeIO io, 1988 ref HandshakeHash hash, 1989 TLSCredentialsManager creds, 1990 string hostname, 1991 SecureVector!ubyte hs_hash, 1992 SecureVector!ubyte orig_hs_hash = SecureVector!ubyte()) 1993 { 1994 m_channel_id = new EncryptedChannelID(creds.channelPrivateKey(hostname), hs_hash.move(), orig_hs_hash.move()); 1995 hash.update(io.send(this)); 1996 } 1997 1998 override Vector!ubyte serialize() const 1999 { 2000 Vector!ubyte buf; 2001 buf.reserve(130); 2002 2003 const ushort extn_code = m_channel_id.type(); 2004 const Vector!ubyte extn_val = m_channel_id.serialize(); 2005 2006 buf.pushBack(get_byte(0, extn_code)); 2007 buf.pushBack(get_byte(1, extn_code)); 2008 2009 buf.pushBack(get_byte(0, cast(ushort) extn_val.length)); 2010 buf.pushBack(get_byte(1, cast(ushort) extn_val.length)); 2011 2012 buf ~= extn_val[]; 2013 return buf.move(); 2014 } 2015 2016 private: 2017 Unique!EncryptedChannelID m_channel_id; 2018 } 2019 2020 /** 2021 * New TLS Session Ticket Message 2022 */ 2023 final class NewSessionTicket : HandshakeMessage 2024 { 2025 public: 2026 override const(HandshakeType) type() const { return NEW_SESSION_TICKET; } 2027 2028 const(Duration) ticketLifetimeHint() const { return m_ticket_lifetime_hint; } 2029 ref const(Vector!ubyte) ticket() const { return m_ticket; } 2030 2031 this(HandshakeIO io, 2032 ref HandshakeHash hash, 2033 Vector!ubyte ticket, 2034 Duration lifetime) 2035 2036 { 2037 m_ticket_lifetime_hint = lifetime; 2038 m_ticket = ticket.move(); 2039 hash.update = io.send(this); 2040 } 2041 2042 this(const ref Vector!ubyte buf) 2043 { 2044 if (buf.length < 6) 2045 throw new DecodingError("TLSSession ticket message too short to be valid"); 2046 2047 TLSDataReader reader = TLSDataReader("SessionTicket", buf); 2048 2049 m_ticket_lifetime_hint = reader.get_uint().seconds; 2050 m_ticket = reader.getRange!ubyte(2, 0, 65535); 2051 } 2052 2053 this(HandshakeIO io, ref HandshakeHash hash) 2054 { 2055 hash.update(io.send(this)); 2056 } 2057 2058 protected: 2059 override Vector!ubyte serialize() const 2060 { 2061 Vector!ubyte buf = Vector!ubyte(4); 2062 storeBigEndian(m_ticket_lifetime_hint.total!"seconds", buf.ptr); 2063 appendTlsLengthValue(buf, m_ticket, 2); 2064 return buf.move(); 2065 } 2066 2067 private: 2068 Duration m_ticket_lifetime_hint; 2069 Vector!ubyte m_ticket; 2070 } 2071 2072 /** 2073 * Change Cipher Spec 2074 */ 2075 final class ChangeCipherSpec : HandshakeMessage 2076 { 2077 public: 2078 override const(HandshakeType) type() const { return HANDSHAKE_CCS; } 2079 2080 override Vector!ubyte serialize() const 2081 { return Vector!ubyte(cast(ubyte[])[1]); } 2082 } 2083 2084 2085 package: 2086 2087 string certTypeCodeToName(ubyte code) 2088 { 2089 switch(code) 2090 { 2091 case 1: 2092 return "RSA"; 2093 case 2: 2094 return "DSA"; 2095 case 64: 2096 return "ECDSA"; 2097 default: 2098 return ""; // DH or something else 2099 } 2100 } 2101 2102 ubyte certTypeNameToCode(in string name) 2103 { 2104 if (name == "RSA") 2105 return 1; 2106 if (name == "DSA") 2107 return 2; 2108 if (name == "ECDSA") 2109 return 64; 2110 2111 throw new InvalidArgument("Unknown cert type " ~ name); 2112 } 2113 2114 2115 SecureVector!ubyte stripLeadingZeros()(auto const ref SecureVector!ubyte input) 2116 { 2117 size_t leading_zeros = 0; 2118 2119 for (size_t i = 0; i != input.length; ++i) 2120 { 2121 if (input[i] != 0) 2122 break; 2123 ++leading_zeros; 2124 } 2125 2126 SecureVector!ubyte output = SecureVector!ubyte(input.ptr[leading_zeros .. input.length]); 2127 return output; 2128 } 2129 2130 2131 /* 2132 * Compute the verifyData 2133 */ 2134 Vector!ubyte finishedComputeVerify(in HandshakeState state, ConnectionSide side) 2135 { 2136 __gshared immutable const(ubyte)[] TLS_CLIENT_LABEL = [ 2137 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69, 2138 0x73, 0x68, 0x65, 0x64 ]; 2139 2140 __gshared immutable const(ubyte)[] TLS_SERVER_LABEL = [ 2141 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x66, 0x69, 0x6E, 0x69, 2142 0x73, 0x68, 0x65, 0x64 ]; 2143 2144 Unique!KDF prf = state.protocolSpecificPrf(); 2145 2146 Vector!ubyte input; 2147 input.reserve(64); 2148 if (side == CLIENT) 2149 input ~= cast(ubyte[])TLS_CLIENT_LABEL; 2150 else 2151 input ~= cast(ubyte[])TLS_SERVER_LABEL; 2152 2153 auto vec = state.hash().flushInto(state.Version(), state.ciphersuite().prfAlgo()); 2154 input ~= vec[]; 2155 return unlock(prf.deriveKey(12, state.sessionKeys().masterSecret(), input)); 2156 2157 } 2158 2159 Vector!ubyte makeHelloRandom(RandomNumberGenerator rng, in TLSPolicy policy) 2160 { 2161 Vector!ubyte buf = Vector!ubyte(32); 2162 rng.randomize(&buf[0], buf.length); 2163 2164 if (policy.includeTimeInHelloRandom()) 2165 { 2166 const uint time32 = cast(uint)(Clock.currTime(UTC()).toUnixTime); 2167 storeBigEndian(time32, buf.ptr); 2168 } 2169 2170 return buf; 2171 }