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