3709192002-03-20Martin Nilsson #pike __REAL_VERSION__
18c01f2004-01-25Martin Nilsson #pragma strict_types
576edc2014-02-14Martin Nilsson #require constant(SSL.Cipher)
3709192002-03-20Martin Nilsson 
f5bb032001-09-17Martin Nilsson //! SSL.handshake keeps the state relevant for SSL handshaking. This //! includes a pointer to a context object (which doesn't change), various //! buffers, a pointer to a session object (reuse or created as //! appropriate), and pending read and write states being negotiated. //!
1cc9c72013-11-23Henrik Grubbström (Grubba) //! Each connection will have two sets of read and write states: The
f5bb032001-09-17Martin Nilsson //! current read and write states used for encryption, and pending read //! and write states to be taken into use when the current keyexchange //! handshake is finished.
c79dc12001-06-14Pär Svensson  //#define SSL3_PROFILING
4f5e1d2003-01-27Martin Nilsson import .Constants;
33ef431997-03-13Niels Möller 
813b392000-08-04Andreas Sigfridsson #ifdef SSL3_DEBUG
6244142003-01-27Martin Nilsson #define SSL3_DEBUG_MSG(X ...) werror(X)
813b392000-08-04Andreas Sigfridsson #else /*! SSL3_DEBUG */
6244142003-01-27Martin Nilsson #define SSL3_DEBUG_MSG(X ...)
813b392000-08-04Andreas Sigfridsson #endif /* SSL3_DEBUG */
b6345f2004-01-23Martin Nilsson .session session; .context context;
33ef431997-03-13Niels Möller 
b6345f2004-01-23Martin Nilsson .state pending_read_state; .state pending_write_state;
33ef431997-03-13Niels Möller  /* State variables */
b9c7862014-04-30Martin Nilsson int handshake_state; // Constant.STATE_*
33ef431997-03-13Niels Möller 
da8a2c2011-01-10Henrik Grubbström (Grubba) int handshake_finished = 0;
33ef431997-03-13Niels Möller constant CERT_none = 0; constant CERT_requested = 1;
b1b57a1997-03-17Niels Möller constant CERT_received = 2;
33ef431997-03-13Niels Möller constant CERT_no_certificate = 3; int certificate_state;
da12091998-08-26Niels Möller int expect_change_cipher; /* Reset to 0 if a change_cipher message is * received */
c09a272013-12-31Henrik Grubbström (Grubba) multiset(int) remote_extensions = (<>);
87740f2011-01-10Henrik Grubbström (Grubba) // RFC 5746-related fields int secure_renegotiation;
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) client_verify_data = ""; string(0..255) server_verify_data = ""; // 3.2: Initially of zero length for both the // ClientHello and the ServerHello.
87740f2011-01-10Henrik Grubbström (Grubba) 
1cc9c72013-11-23Henrik Grubbström (Grubba) //! The active @[Cipher.KeyExchange] (if any). .Cipher.KeyExchange ke;
33ef431997-03-13Niels Möller 
170da92014-04-05Henrik Grubbström (Grubba) ProtocolVersion version; ProtocolVersion client_version; /* Used to check for version roll-back attacks. */
33ef431997-03-13Niels Möller int reuse;
3af33b2011-12-15Henrik Grubbström (Grubba) //! A few storage variables for client certificate handling on the client side.
88cfa12005-10-28H. William Welliver III array(int) client_cert_types;
08fe1f2013-12-08Henrik Grubbström (Grubba) array(string(0..255)) client_cert_distinguished_names;
88cfa12005-10-28H. William Welliver III 
f5bb032001-09-17Martin Nilsson //! Random cookies, sent and received with the hello-messages.
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) client_random; string(0..255) server_random;
33ef431997-03-13Niels Möller 
8dcd741997-03-15Niels Möller constant Session = SSL.session;
f319fc2014-05-01Martin Nilsson #define Packet .Packet
ccb5962014-04-12Henrik Grubbström (Grubba) 
fa017c2014-05-04Martin Nilsson .Alert Alert(int(1..2) level, int(0..255) description, string|void message)
ccb5962014-04-12Henrik Grubbström (Grubba) { // NB: We are always inherited by SSL.connection. return context->alert_factory(this, level, description, version,
0ddaf82014-04-24Martin Nilsson  message);
ccb5962014-04-12Henrik Grubbström (Grubba) }
33ef431997-03-13Niels Möller 
512c842013-09-02Martin Nilsson int has_application_layer_protocol_negotiation;
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) next_protocol;
c79dc12001-06-14Pär Svensson 
8bbd8b2014-04-13Henrik Grubbström (Grubba) string(8bit) get_signature_algorithms() { ADT.struct sign_algs = ADT.struct(); foreach(sort(indices(HASH_lookup)), int h) { sign_algs->put_uint(h, 1); sign_algs->put_uint(SIGNATURE_rsa, 1); sign_algs->put_uint(h, 1); sign_algs->put_uint(SIGNATURE_dsa, 1); #if constant(Crypto.ECC.Curve) // NB: MD5 is not supported with ECDSA signatures. if (h != HASH_md5) { sign_algs->put_uint(h, 1); sign_algs->put_uint(SIGNATURE_ecdsa, 1); } #endif } return sign_algs->pop_data(); }
c79dc12001-06-14Pär Svensson #ifdef SSL3_PROFILING
216b822014-05-02Martin Nilsson System.Timer timer = System.Timer();
c79dc12001-06-14Pär Svensson void addRecord(int t,int s) {
216b822014-05-02Martin Nilsson  Stdio.stdout.write("time: %.6f sender: %d type: %s\n", timer->get(), s, fmt_constant(t, "HANDSHAKE"));
c79dc12001-06-14Pär Svensson } #endif
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) handshake_messages;
33ef431997-03-13Niels Möller 
fa017c2014-05-04Martin Nilsson Packet handshake_packet(int(0..255) type, string data)
33ef431997-03-13Niels Möller {
c79dc12001-06-14Pär Svensson  #ifdef SSL3_PROFILING addRecord(type,1); #endif
33ef431997-03-13Niels Möller  /* Perhaps one need to split large packages? */
b6345f2004-01-23Martin Nilsson  Packet packet = Packet();
33ef431997-03-13Niels Möller  packet->content_type = PACKET_handshake;
fa017c2014-05-04Martin Nilsson  packet->fragment = sprintf("%1c%3H", type, [string(0..255)]data);
33ef431997-03-13Niels Möller  handshake_messages += packet->fragment; return packet; }
18c01f2004-01-25Martin Nilsson Packet server_hello_packet()
33ef431997-03-13Niels Möller {
b6345f2004-01-23Martin Nilsson  ADT.struct struct = ADT.struct();
33ef431997-03-13Niels Möller  /* Build server_hello message */
170da92014-04-05Henrik Grubbström (Grubba)  struct->put_uint(version, 2); /* version */
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Writing server hello, with version: %s\n", fmt_version(version));
813b392000-08-04Andreas Sigfridsson  struct->put_fix_string(server_random);
33ef431997-03-13Niels Möller  struct->put_var_string(session->identity, 1);
5a66b31998-04-20Niels Möller  struct->put_uint(session->cipher_suite, 2); struct->put_uint(session->compression_algorithm, 1);
33ef431997-03-13Niels Möller 
27e1172012-04-07Arne Goedeke  ADT.struct extensions = ADT.struct();
87740f2011-01-10Henrik Grubbström (Grubba) 
27e1172012-04-07Arne Goedeke  if (secure_renegotiation) {
87740f2011-01-10Henrik Grubbström (Grubba)  // RFC 5746 3.7: // The server MUST include a "renegotiation_info" extension // containing the saved client_verify_data and server_verify_data in // the ServerHello.
ce2e5e2011-01-11Henrik Grubbström (Grubba)  extensions->put_uint(EXTENSION_renegotiation_info, 2);
87740f2011-01-10Henrik Grubbström (Grubba)  ADT.struct extension = ADT.struct(); extension->put_var_string(client_verify_data + server_verify_data, 1); extensions->put_var_string(extension->pop_data(), 2); }
de13942014-03-20Henrik Grubbström (Grubba)  if (session->max_packet_size != PACKET_MAX_SIZE) { // RFC 3546 3.2. ADT.struct extension = ADT.struct(); extension->put_uint(EXTENSION_max_fragment_length, 2); switch(session->max_packet_size) { case 512: extension->put_uint(FRAGMENT_512, 1); break; case 1024: extension->put_uint(FRAGMENT_1024, 1); break; case 2048: extension->put_uint(FRAGMENT_2048, 1); break; case 4096: extension->put_uint(FRAGMENT_4096, 1); break; default:
5c12d72014-04-12Martin Nilsson  return Alert(ALERT_fatal, ALERT_illegal_parameter,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Invalid fragment size.\n");
de13942014-03-20Henrik Grubbström (Grubba)  } extensions->put_var_string(extension->pop_data(), 2); }
4d1bb22014-02-02Henrik Grubbström (Grubba)  if (sizeof(session->ecc_curves) && remote_extensions[EXTENSION_ec_point_formats]) {
7de33b2013-12-30Henrik Grubbström (Grubba)  // RFC 4492 5.2: // The Supported Point Formats Extension is included in a // ServerHello message in response to a ClientHello message // containing the Supported Point Formats Extension when // negotiating an ECC cipher suite. ADT.struct extension = ADT.struct(); extension->put_uint(POINT_uncompressed, 1); extension->put_var_string(extension->pop_data(), 1); extensions->put_uint(EXTENSION_ec_point_formats, 2); extensions->put_var_string(extension->pop_data(), 2); }
e91a112014-03-23Henrik Grubbström (Grubba)  if (session->truncated_hmac) { // RFC 3546 3.5 "Truncated HMAC" extensions->put_uint(EXTENSION_truncated_hmac, 2); extensions->put_var_string("", 2); }
1d54432014-03-30Henrik Grubbström (Grubba)  if (session->heartbeat_mode) { // RFC 6520 ADT.struct extension = ADT.struct(); extension->put_uint(HEARTBEAT_MODE_peer_allowed_to_send, 1); extensions->put_uint(EXTENSION_heartbeat, 2); extensions->put_var_string(extension->pop_data(), 2); }
e716632013-09-03Martin Nilsson  if (has_application_layer_protocol_negotiation && next_protocol) {
6888b92013-09-09Martin Nilsson  extensions->put_uint(EXTENSION_application_layer_protocol_negotiation,2);
e716632013-09-03Martin Nilsson  extensions->put_uint(sizeof(next_protocol)+3, 2); extensions->put_uint(sizeof(next_protocol)+1, 2); extensions->put_var_string(next_protocol, 1); }
27e1172012-04-07Arne Goedeke  if (!extensions->is_empty()) struct->put_var_string(extensions->pop_data(), 2);
33ef431997-03-13Niels Möller  string data = struct->pop_data(); return handshake_packet(HANDSHAKE_server_hello, data); }
b6345f2004-01-23Martin Nilsson Packet server_key_exchange_packet()
fada191999-03-09Niels Möller {
1cc9c72013-11-23Henrik Grubbström (Grubba)  if (ke) error("KE!\n");
93034b2013-12-29Henrik Grubbström (Grubba)  ke = session->ke_factory(context, session, this, client_version);
5ed44a2013-11-24Henrik Grubbström (Grubba)  string data = ke->server_key_exchange_packet(client_random, server_random);
1cc9c72013-11-23Henrik Grubbström (Grubba)  return data && handshake_packet(HANDSHAKE_server_key_exchange, data);
fada191999-03-09Niels Möller }
18c01f2004-01-25Martin Nilsson Packet client_key_exchange_packet()
813b392000-08-04Andreas Sigfridsson {
93034b2013-12-29Henrik Grubbström (Grubba)  ke = ke || session->ke_factory(context, session, this, client_version);
5ed44a2013-11-24Henrik Grubbström (Grubba)  string data = ke->client_key_exchange_packet(client_random, server_random, version);
1cc9c72013-11-23Henrik Grubbström (Grubba)  if (!data) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Invalid KEX.\n"));
813b392000-08-04Andreas Sigfridsson  return 0; }
8f489c2013-10-26Henrik Grubbström (Grubba) 
5ed44a2013-11-24Henrik Grubbström (Grubba)  array(.state) res =
9e39102014-04-27Henrik Grubbström (Grubba)  session->new_client_states(this, client_random, server_random, version);
8f489c2013-10-26Henrik Grubbström (Grubba)  pending_read_state = res[0]; pending_write_state = res[1];
813b392000-08-04Andreas Sigfridsson  return handshake_packet(HANDSHAKE_client_key_exchange, data); }
ecec692014-04-10Martin Nilsson // FIXME: The certificate code has changed, so this no longer works, // if it ever did. #if 0
88cfa12005-10-28H. William Welliver III Packet certificate_verify_packet() { ADT.struct struct = ADT.struct();
75b3d42014-03-08Henrik Grubbström (Grubba)  // FIXME: This temporary context is probably not needed.
88cfa12005-10-28H. William Welliver III  .context cx = .context();
75b3d42014-03-08Henrik Grubbström (Grubba)  cx->private_key = context->private_key;
ceff2c2007-11-15H. William Welliver III 
88cfa12005-10-28H. William Welliver III  session->cipher_spec->sign(cx, handshake_messages, struct); return handshake_packet (HANDSHAKE_certificate_verify, struct->pop_data());
7de33b2013-12-30Henrik Grubbström (Grubba) }
ecec692014-04-10Martin Nilsson #endif
7de33b2013-12-30Henrik Grubbström (Grubba)  int(0..1) not_ecc_suite(int cipher_suite) { array(int) suite = [array(int)]CIPHER_SUITES[cipher_suite]; return suite && !(< KE_ecdh_ecdsa, KE_ecdhe_ecdsa, KE_ecdh_rsa, KE_ecdhe_rsa >)[suite[0]];
88cfa12005-10-28H. William Welliver III }
b6345f2004-01-23Martin Nilsson int(-1..0) reply_new_session(array(int) cipher_suites, array(int) compression_methods)
33ef431997-03-13Niels Möller {
06e0312013-10-21Martin Nilsson  SSL3_DEBUG_MSG("ciphers: me:\n%s, client:\n%s",
9d3ded2014-02-12Martin Nilsson  .Constants.fmt_cipher_suites(context->preferred_suites), .Constants.fmt_cipher_suites(cipher_suites));
d816082013-10-21Martin Nilsson  cipher_suites = context->preferred_suites & cipher_suites;
06e0312013-10-21Martin Nilsson  SSL3_DEBUG_MSG("intersection:\n%s\n",
9d3ded2014-02-12Martin Nilsson  .Constants.fmt_cipher_suites((array(int))cipher_suites));
813b392000-08-04Andreas Sigfridsson 
4d1bb22014-02-02Henrik Grubbström (Grubba)  if (!sizeof(session->ecc_curves) || (session->ecc_point_format == -1)) {
7de33b2013-12-30Henrik Grubbström (Grubba)  // No overlapping support for ecc. // Filter the ECC suites from the set. SSL3_DEBUG_MSG("ECC not supported.\n"); cipher_suites = filter(cipher_suites, not_ecc_suite); }
8591b22013-11-26Henrik Grubbström (Grubba)  if (!sizeof(cipher_suites) ||
170da92014-04-05Henrik Grubbström (Grubba)  !session->select_cipher_suite(context, cipher_suites, version)) {
4d4fd82014-02-03Henrik Grubbström (Grubba)  // No overlapping cipher suites, or obsolete cipher suite selected, // or incompatible certificates.
f5b7df2014-03-08Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("No common suites.\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
ccb5962014-04-12Henrik Grubbström (Grubba)  "No common suites!\n"));
33ef431997-03-13Niels Möller  return -1; }
44f2db2014-01-02Henrik Grubbström (Grubba) 
d816082013-10-21Martin Nilsson  compression_methods = context->preferred_compressors & compression_methods;
33ef431997-03-13Niels Möller  if (sizeof(compression_methods)) session->set_compression_method(compression_methods[0]); else {
f5b7df2014-03-08Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Unsupported compression method.\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Unsupported compression method.\n"));
33ef431997-03-13Niels Möller  return -1; } send_packet(server_hello_packet());
c51f9c2012-08-30Bill Welliver 
44f2db2014-01-02Henrik Grubbström (Grubba)  // Don't send any certificate in anonymous mode. if (session->cipher_spec->sign != .Cipher.anon_sign) { /* Send Certificate, ServerKeyExchange and CertificateRequest as * appropriate, and then ServerHelloDone.
4d4fd82014-02-03Henrik Grubbström (Grubba)  * * NB: session->certificate_chain is set by * session->select_cipher_suite() above.
44f2db2014-01-02Henrik Grubbström (Grubba)  */
4d4fd82014-02-03Henrik Grubbström (Grubba)  if (session->certificate_chain)
44f2db2014-01-02Henrik Grubbström (Grubba)  { SSL3_DEBUG_MSG("Sending Certificate.\n");
4d4fd82014-02-03Henrik Grubbström (Grubba)  send_packet(certificate_packet(session->certificate_chain));
44f2db2014-01-02Henrik Grubbström (Grubba)  } else { // Otherwise the server will just silently send an invalid // ServerHello sequence. error ("Certificate(s) missing.\n"); }
33ef431997-03-13Niels Möller  }
da12091998-08-26Niels Möller 
18c01f2004-01-25Martin Nilsson  Packet key_exchange = server_key_exchange_packet();
da12091998-08-26Niels Möller 
aa77d52001-04-18Pär Svensson  if (key_exchange) {
fada191999-03-09Niels Möller  send_packet(key_exchange);
aa77d52001-04-18Pär Svensson  }
671d132004-01-23H. William Welliver III  if (context->auth_level >= AUTHLEVEL_ask)
33ef431997-03-13Niels Möller  {
88cfa12005-10-28H. William Welliver III  // we can send a certificate request packet, even if we don't have // any authorized issuers. send_packet(certificate_request_packet(context));
33ef431997-03-13Niels Möller  certificate_state = CERT_requested; } send_packet(handshake_packet(HANDSHAKE_server_hello_done, "")); return 0; }
b6345f2004-01-23Martin Nilsson  Packet change_cipher_packet()
33ef431997-03-13Niels Möller {
b6345f2004-01-23Martin Nilsson  Packet packet = Packet();
33ef431997-03-13Niels Möller  packet->content_type = PACKET_change_cipher_spec; packet->fragment = "\001"; return packet; }
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) hash_messages(string(0..255) sender)
33ef431997-03-13Niels Möller {
170da92014-04-05Henrik Grubbström (Grubba)  if(version == PROTOCOL_SSL_3_0) {
7593d02014-03-29Martin Nilsson  return .Cipher.MACmd5(session->master_secret)->hash(handshake_messages + sender) + .Cipher.MACsha(session->master_secret)->hash(handshake_messages + sender);
aa77d52001-04-18Pär Svensson  }
170da92014-04-05Henrik Grubbström (Grubba)  else if(version <= PROTOCOL_TLS_1_1) {
6212d12013-11-24Henrik Grubbström (Grubba)  return session->cipher_spec->prf(session->master_secret, sender, Crypto.MD5.hash(handshake_messages)+ Crypto.SHA1.hash(handshake_messages), 12);
170da92014-04-05Henrik Grubbström (Grubba)  } else if(version >= PROTOCOL_TLS_1_2) {
6212d12013-11-24Henrik Grubbström (Grubba)  return session->cipher_spec->prf(session->master_secret, sender,
9a23e92013-12-04Henrik Grubbström (Grubba)  session->cipher_spec->hash->hash(handshake_messages), 12);
aa77d52001-04-18Pär Svensson  }
33ef431997-03-13Niels Möller }
08fe1f2013-12-08Henrik Grubbström (Grubba) Packet finished_packet(string(0..255) sender)
33ef431997-03-13Niels Möller {
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("Sending finished_packet, with sender=\""+sender+"\"\n" );
08fe1f2013-12-08Henrik Grubbström (Grubba)  string(0..255) verify_data = hash_messages(sender);
87740f2011-01-10Henrik Grubbström (Grubba)  if (handshake_state >= STATE_client_min) { // We're the client. client_verify_data = verify_data; } else { // We're the server. server_verify_data = verify_data; } return handshake_packet(HANDSHAKE_finished, verify_data);
33ef431997-03-13Niels Möller }
88cfa12005-10-28H. William Welliver III Packet certificate_request_packet(SSL.context context) { /* Send a CertificateRequest message */ ADT.struct struct = ADT.struct(); struct->put_var_uint_array(context->preferred_auth_methods, 1, 1);
8bbd8b2014-04-13Henrik Grubbström (Grubba)  if (version >= PROTOCOL_TLS_1_2) { // TLS 1.2 has var_uint_array of hash and sign pairs here. struct->put_var_string(get_signature_algorithms(), 2); }
08fe1f2013-12-08Henrik Grubbström (Grubba)  struct->put_var_string([string(0..255)] sprintf("%{%2H%}", context->authorities_cache), 2);
88cfa12005-10-28H. William Welliver III  return handshake_packet(HANDSHAKE_certificate_request, struct->pop_data()); }
08fe1f2013-12-08Henrik Grubbström (Grubba) Packet certificate_packet(array(string(0..255)) certificates)
88cfa12005-10-28H. William Welliver III { ADT.struct struct = ADT.struct(); int len = 0;
c51f9c2012-08-30Bill Welliver 
88cfa12005-10-28H. William Welliver III  if(certificates && sizeof(certificates)) len = `+( @ Array.map(certificates, sizeof));
b06b5d2013-08-01Martin Nilsson  // SSL3_DEBUG_MSG("SSL.handshake: certificate_message size %d\n", len);
88cfa12005-10-28H. William Welliver III  struct->put_uint(len + 3 * sizeof(certificates), 3);
08fe1f2013-12-08Henrik Grubbström (Grubba)  foreach(certificates, string(0..255) cert)
88cfa12005-10-28H. William Welliver III  struct->put_var_string(cert, 3); return handshake_packet(HANDSHAKE_certificate, struct->pop_data()); }
fa017c2014-05-04Martin Nilsson Packet heartbeat_packet(string(8bit) s)
72bffa2014-04-14Henrik Grubbström (Grubba) { Packet packet = Packet(); packet->content_type = PACKET_heartbeat; packet->fragment = s; return packet; } protected Crypto.AES heartbeat_encode; protected Crypto.AES heartbeat_decode; Packet heartbleed_packet() { if (!heartbeat_encode) { // NB: We encrypt the payload with a random AES key // to reduce the amount of known plaintext in // the heartbeat masseages. This is needed now // that many cipher suites (such as GCM and CCM) // use xor with a cipher stream, to reduce risk // of revealing larger segments of the stream. heartbeat_encode = Crypto.AES(); heartbeat_decode = Crypto.AES(); string(8bit) heartbeat_key = random_string(16); heartbeat_encode->set_encrypt_key(heartbeat_key); heartbeat_decode->set_decrypt_key(heartbeat_key); } // This packet probes for the Heartbleed vulnerability (CVE-2014-0160) // by crafting a heartbeat packet with insufficient (0) padding. // // If we get a response, the peer doesn't validate the message sizes // properly, and probably suffers from the Heartbleed vulnerability. // // Note that we don't use negative padding (as per the actual attack), // to avoid actually stealing information from the peer. // // Note that we detect the packet on return by it having all zeros // in the second field. ADT.struct hb_msg = ADT.struct(); hb_msg->put_uint(HEARTBEAT_MESSAGE_request, 1); hb_msg->put_uint(16, 2); int now = gethrtime(); hb_msg->put_fix_string(heartbeat_encode->crypt(sprintf("%8c%8c", now, 0))); // No padding. return heartbeat_packet(hb_msg->pop_data()); }
08fe1f2013-12-08Henrik Grubbström (Grubba) string(0..255) server_derive_master_secret(string(0..255) data)
33ef431997-03-13Niels Möller {
fa017c2014-05-04Martin Nilsson  string(0..255)|int(0..255) res =
5ed44a2013-11-24Henrik Grubbström (Grubba)  ke->server_derive_master_secret(data, client_random, server_random, version);
1cc9c72013-11-23Henrik Grubbström (Grubba)  if (stringp(res)) return [string]res;
fa017c2014-05-04Martin Nilsson  send_packet(Alert(ALERT_fatal, [int(0..255)]res,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Failed to derive master secret.\n"));
1cc9c72013-11-23Henrik Grubbström (Grubba)  return 0;
813b392000-08-04Andreas Sigfridsson }
aa77d52001-04-18Pär Svensson 
7655672004-01-27H. William Welliver III // verify that a certificate chain is acceptable
f591dd2004-01-29H. William Welliver III //
b6345f2004-01-23Martin Nilsson int verify_certificate_chain(array(string) certs)
7e78212004-01-23H. William Welliver III {
526a402004-01-30H. William Welliver III  // do we need to verify the certificate chain? if(!context->verify_certificates) return 1;
88cfa12005-10-28H. William Welliver III  // if we're not requiring the certificate, and we don't provide one, // that should be okay. if((context->auth_level < AUTHLEVEL_require) && !sizeof(certs)) return 1;
868f712012-05-20Martin Nilsson  // a lack of certificates when we reqiure and must verify the // certificates is probably a failure.
88cfa12005-10-28H. William Welliver III  if(!certs || !sizeof(certs)) return 0;
7e78212004-01-23H. William Welliver III 
2977172013-12-04Martin Nilsson  // See if the issuer of the certificate is acceptable. This means // the issuer of the certificate must be one of the authorities.
526a402004-01-30H. William Welliver III  if(sizeof(context->authorities_cache))
7e78212004-01-23H. William Welliver III  {
6c7baf2014-02-15Martin Nilsson  string r=Standards.X509.decode_certificate(certs[-1])->issuer
2977172013-12-04Martin Nilsson  ->get_der(); int issuer_known = 0; foreach(context->authorities_cache, string c)
7e78212004-01-23H. William Welliver III  {
2977172013-12-04Martin Nilsson  if(r == c) // we have a trusted issuer
526a402004-01-30H. William Welliver III  { issuer_known = 1; break; }
7e78212004-01-23H. William Welliver III  }
526a402004-01-30H. William Welliver III  if(issuer_known==0) { return 0; }
f591dd2004-01-29H. William Welliver III  }
7655672004-01-27H. William Welliver III  // ok, so we have a certificate chain whose client certificate is // issued by an authority known to us.
7e78212004-01-23H. William Welliver III 
7655672004-01-27H. William Welliver III  // next we must verify the chain to see if the chain is unbroken
e8a72e2013-11-24Henrik Grubbström (Grubba)  mapping result =
c8ff052013-12-04Martin Nilsson  Standards.X509.verify_certificate_chain(certs, context->trusted_issuers_cache,
e8a72e2013-11-24Henrik Grubbström (Grubba)  context->require_trust);
7655672004-01-27H. William Welliver III  if(result->verified)
f591dd2004-01-29H. William Welliver III  {
c8ff052013-12-04Martin Nilsson  // This data isn't actually used internally.
f591dd2004-01-29H. William Welliver III  session->cert_data = result;
7655672004-01-27H. William Welliver III  return 1;
f591dd2004-01-29H. William Welliver III  }
7e78212004-01-23H. William Welliver III 
868f712012-05-20Martin Nilsson  return 0;
7e78212004-01-23H. William Welliver III }
aa77d52001-04-18Pär Svensson 
f5bb032001-09-17Martin Nilsson //! Do handshake processing. Type is one of HANDSHAKE_*, data is the //! contents of the packet, and raw is the raw packet received (needed //! for supporting SSLv2 hello messages). //!
fc993a2013-10-27Henrik Grubbström (Grubba) //! This function returns 0 if handshake is in progress, 1 if handshake
3a5f8e2010-02-21Stephen R. van den Berg //! is finished, and -1 if a fatal error occurred. It uses the
5f883e2008-09-05Martin Stjernholm //! send_packet() function to transmit packets.
08fe1f2013-12-08Henrik Grubbström (Grubba) int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw)
33ef431997-03-13Niels Möller {
b6345f2004-01-23Martin Nilsson  ADT.struct input = ADT.struct(data);
c79dc12001-06-14Pär Svensson #ifdef SSL3_PROFILING addRecord(type,0); #endif
813b392000-08-04Andreas Sigfridsson #ifdef SSL3_DEBUG_HANDSHAKE_STATE werror("SSL.handshake: state %s, type %s\n",
b9c7862014-04-30Martin Nilsson  fmt_constant(handshake_state, "STATE"), fmt_constant(type, "HANDSHAKE"));
ead9722003-01-20Martin Nilsson  werror("sizeof(data)="+sizeof(data)+"\n");
8dcd741997-03-15Niels Möller #endif
813b392000-08-04Andreas Sigfridsson 
33ef431997-03-13Niels Möller  switch(handshake_state) { default:
6244142003-01-27Martin Nilsson  error( "Internal error\n" );
33ef431997-03-13Niels Möller  case STATE_server_wait_for_hello: { array(int) cipher_suites; /* Reset all extra state variables */ expect_change_cipher = certificate_state = 0;
1cc9c72013-11-23Henrik Grubbström (Grubba)  ke = 0;
ae562d1998-06-27Niels Möller 
33ef431997-03-13Niels Möller  handshake_messages = raw;
717d662013-11-14Martin Nilsson 
3661532013-11-30Martin Nilsson  // The first four bytes of the client_random is specified to be // the timestamp on the client side. This is to guard against bad // random generators, where a client could produce the same // random numbers if the seed is reused. This argument is flawed, // since a broken random generator will make the connection // insecure anyways. The standard explicitly allows these bytes // to not be correct, so sending random data instead is safer and // reduces client fingerprinting. server_random = context->random(32);
33ef431997-03-13Niels Möller  switch(type) { default:
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected client_hello.\n"));
33ef431997-03-13Niels Möller  return -1; case HANDSHAKE_client_hello: { string id; int cipher_len; array(int) cipher_suites; array(int) compression_methods;
aa77d52001-04-18Pär Svensson 
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CLIENT_HELLO\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
aa77d52001-04-18Pär Svensson  if ( catch{
170da92014-04-05Henrik Grubbström (Grubba)  client_version = [int(0x300..0x300)|ProtocolVersion]input->get_uint(2);
813b392000-08-04Andreas Sigfridsson  client_random = input->get_fix_string(32);
33ef431997-03-13Niels Möller  id = input->get_var_string(1);
5a66b31998-04-20Niels Möller  cipher_len = input->get_uint(2); cipher_suites = input->get_fix_uint_array(2, cipher_len/2); compression_methods = input->get_var_uint_array(1, 1);
8970062003-03-12Marcus Agehall  SSL3_DEBUG_MSG("STATE_server_wait_for_hello: received hello\n"
39cf162014-04-05Henrik Grubbström (Grubba)  "version = %s\n"
813b392000-08-04Andreas Sigfridsson  "id=%O\n"
06e0312013-10-21Martin Nilsson  "cipher suites:\n%s\n"
813b392000-08-04Andreas Sigfridsson  "compression methods: %O\n",
39cf162014-04-05Henrik Grubbström (Grubba)  fmt_version(client_version),
9d3ded2014-02-12Martin Nilsson  id, .Constants.fmt_cipher_suites(cipher_suites),
06e0312013-10-21Martin Nilsson  compression_methods);
813b392000-08-04Andreas Sigfridsson 
aa77d52001-04-18Pär Svensson  }
6262d42011-12-15Henrik Grubbström (Grubba)  || (cipher_len & 1))
33ef431997-03-13Niels Möller  {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Invalid client_hello.\n"));
33ef431997-03-13Niels Möller  return -1; }
170da92014-04-05Henrik Grubbström (Grubba)  if (((client_version & ~0xff) != PROTOCOL_SSL_3_0) || (client_version < context->min_version)) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Unsupported version of SSL: %s.\n", fmt_version(client_version));
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_protocol_version,
0ddaf82014-04-24Martin Nilsson  "Unsupported version.\n"));
6262d42011-12-15Henrik Grubbström (Grubba)  return -1; }
170da92014-04-05Henrik Grubbström (Grubba)  if (client_version > version) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Falling back client from %s to %s.\n", fmt_version(client_version), fmt_version(version));
170da92014-04-05Henrik Grubbström (Grubba)  } else if (version > client_version) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Falling back server from %s to %s.\n", fmt_version(version), fmt_version(client_version));
170da92014-04-05Henrik Grubbström (Grubba)  version = client_version;
3149302004-07-05Henrik Grubbström (Grubba)  }
33ef431997-03-13Niels Möller 
4d1bb22014-02-02Henrik Grubbström (Grubba)  ADT.struct extensions;
febdb42011-01-10Henrik Grubbström (Grubba)  if (!input->is_empty()) {
4d1bb22014-02-02Henrik Grubbström (Grubba)  extensions = ADT.struct(input->get_var_string(2)); }
febdb42011-01-10Henrik Grubbström (Grubba) 
4d1bb22014-02-02Henrik Grubbström (Grubba) #ifdef SSL3_DEBUG if (!input->is_empty())
a423622014-03-18Martin Nilsson  werror("SSL.handshake->handle_handshake: "
4d1bb22014-02-02Henrik Grubbström (Grubba)  "extra data in hello message ignored\n"); if (sizeof(id)) werror("SSL.handshake: Looking up session %O\n", id); #endif session = sizeof(id) && context->lookup_session(id);
3e9dd92014-03-22Henrik Grubbström (Grubba)  if (session && has_value(cipher_suites, session->cipher_suite) && has_value(compression_methods, session->compression_algorithm)) { // SSL3 5.6.1.2: // If the session_id field is not empty (implying a session // resumption request) this vector [cipher_suites] must // include at least the cipher_suite from that session. // ... // If the session_id field is not empty (implying a session // resumption request) this vector [compression_methods] // must include at least the compression_method from // that session.
4d1bb22014-02-02Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("SSL.handshake: Reusing session %O\n", id); /* Reuse session */ reuse = 1; } else { session = context->new_session(); reuse = 0; } int missing_secure_renegotiation = secure_renegotiation; if (extensions) {
038e132014-03-23Henrik Grubbström (Grubba)  int maybe_safari_10_8 = 1;
febdb42011-01-10Henrik Grubbström (Grubba)  while (!extensions->is_empty()) { int extension_type = extensions->get_uint(2);
038e132014-03-23Henrik Grubbström (Grubba)  string(8bit) raw = extensions->get_var_string(2); ADT.struct extension_data = ADT.struct(raw);
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake->handle_handshake: "
4af8532014-05-01Martin Nilsson  "Got extension %s.\n", fmt_constant(extension_type, "EXTENSION"));
c09a272013-12-31Henrik Grubbström (Grubba)  remote_extensions[extension_type] = 1;
06e0312013-10-21Martin Nilsson  extensions:
febdb42011-01-10Henrik Grubbström (Grubba)  switch(extension_type) {
3732142013-11-25Henrik Grubbström (Grubba)  case EXTENSION_signature_algorithms:
038e132014-03-23Henrik Grubbström (Grubba)  if (!remote_extensions[EXTENSION_ec_point_formats] || (raw != "\0\12\5\1\4\1\2\1\4\3\2\3") ||
170da92014-04-05Henrik Grubbström (Grubba)  (client_version != PROTOCOL_TLS_1_2)) {
038e132014-03-23Henrik Grubbström (Grubba)  maybe_safari_10_8 = 0; }
3732142013-11-25Henrik Grubbström (Grubba)  // RFC 5246 string bytes = extension_data->get_var_string(2); // Pairs of <hash_alg, signature_alg>.
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->signature_algorithms = ((array(int))bytes)/2;
4d16322014-04-10Martin Nilsson  SSL3_DEBUG_MSG("New signature_algorithms:\n"+ fmt_signature_pairs(session->signature_algorithms));
3732142013-11-25Henrik Grubbström (Grubba)  break;
7de33b2013-12-30Henrik Grubbström (Grubba)  case EXTENSION_elliptic_curves:
038e132014-03-23Henrik Grubbström (Grubba)  if (!remote_extensions[EXTENSION_server_name] || (raw != "\0\6\0\x17\0\x18\0\x19")) { maybe_safari_10_8 = 0; }
7de33b2013-12-30Henrik Grubbström (Grubba)  int sz = extension_data->get_uint(2)/2;
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->ecc_curves =
7de33b2013-12-30Henrik Grubbström (Grubba)  filter(reverse(sort(extension_data->get_fix_uint_array(2, sz))), ECC_CURVES);
7a87de2014-04-10Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Elliptic curves: %O\n", map(session->ecc_curves, fmt_constant, "CURVE"));
7de33b2013-12-30Henrik Grubbström (Grubba)  break; case EXTENSION_ec_point_formats:
038e132014-03-23Henrik Grubbström (Grubba)  if (!remote_extensions[EXTENSION_elliptic_curves] || (raw != "\1\0")) { maybe_safari_10_8 = 0; }
7de33b2013-12-30Henrik Grubbström (Grubba)  array(int) ecc_point_formats = extension_data->get_var_uint_array(1, 1); // NB: We only support the uncompressed point format for now. if (has_value(ecc_point_formats, POINT_uncompressed)) {
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->ecc_point_format = POINT_uncompressed;
7de33b2013-12-30Henrik Grubbström (Grubba)  } else { // Not a supported point format.
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->ecc_point_format = -1;
7de33b2013-12-30Henrik Grubbström (Grubba)  }
4d1bb22014-02-02Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Elliptic point format: %O\n", session->ecc_point_format);
7de33b2013-12-30Henrik Grubbström (Grubba)  break;
0eac202011-01-13Henrik Grubbström (Grubba)  case EXTENSION_server_name:
038e132014-03-23Henrik Grubbström (Grubba)  if (sizeof(remote_extensions) != 1) { maybe_safari_10_8 = 0; }
0eac202011-01-13Henrik Grubbström (Grubba)  // RFC 4366 3.1 "Server Name Indication" // Example: "\0\f\0\0\tlocalhost"
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->server_names = ({});
0eac202011-01-13Henrik Grubbström (Grubba)  while (!extension_data->is_empty()) { ADT.struct server_name = ADT.struct(extension_data->get_var_string(2)); switch(server_name->get_uint(1)) { // name_type case 0: // host_name
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->server_names += ({ server_name->get_var_string(2) });
0eac202011-01-13Henrik Grubbström (Grubba)  break; default: // Ignore other NameTypes for now. break; } }
4d1bb22014-02-02Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("SNI extension: %O\n", session->server_names);
0eac202011-01-13Henrik Grubbström (Grubba)  break;
de13942014-03-20Henrik Grubbström (Grubba)  case EXTENSION_max_fragment_length: // RFC 3546 3.2 "Maximum Fragment Length Negotiation" int mfsz = !extension_data->is_empty() && extension_data->get_uint(1); if (!extension_data->is_empty()) mfsz = 0; switch(mfsz) { case FRAGMENT_512: session->max_packet_size = 512; break; case FRAGMENT_1024: session->max_packet_size = 1024; break; case FRAGMENT_2048: session->max_packet_size = 2048; break; case FRAGMENT_4096: session->max_packet_size = 4096; break; default: send_packet(Alert(ALERT_fatal, ALERT_illegal_parameter,
5c12d72014-04-12Martin Nilsson  "Invalid fragment size.\n"));
de13942014-03-20Henrik Grubbström (Grubba)  return -1; }
4d16322014-04-10Martin Nilsson  SSL3_DEBUG_MSG("Maximum frame size %O.\n", session->max_packet_size);
de13942014-03-20Henrik Grubbström (Grubba)  break;
e91a112014-03-23Henrik Grubbström (Grubba)  case EXTENSION_truncated_hmac: // RFC 3546 3.5 "Truncated HMAC" if (!extension_data->is_empty()) { send_packet(Alert(ALERT_fatal, ALERT_illegal_parameter,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Invalid trusted HMAC extension.\n"));
e91a112014-03-23Henrik Grubbström (Grubba)  } session->truncated_hmac = 1;
4d16322014-04-10Martin Nilsson  SSL3_DEBUG_MSG("Trucated HMAC\n");
e91a112014-03-23Henrik Grubbström (Grubba)  break;
06e0312013-10-21Martin Nilsson 
87740f2011-01-10Henrik Grubbström (Grubba)  case EXTENSION_renegotiation_info: string renegotiated_connection = extension_data->get_var_string(1); if ((renegotiated_connection != client_verify_data) || (handshake_finished && !secure_renegotiation)) { // RFC 5746 3.7: (secure_renegotiation) // The server MUST verify that the value of the // "renegotiated_connection" field is equal to the saved // client_verify_data value; if it is not, the server MUST // abort the handshake. // // RFC 5746 4.4: (!secure_renegotiation) // The server MUST verify that the "renegotiation_info" // extension is not present; if it is, the server MUST // abort the handshake. send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "Invalid renegotiation data.\n"));
87740f2011-01-10Henrik Grubbström (Grubba)  return -1; } secure_renegotiation = 1; missing_secure_renegotiation = 0;
06e0312013-10-21Martin Nilsson  SSL3_DEBUG_MSG("Renego extension: %O\n", renegotiated_connection);
87740f2011-01-10Henrik Grubbström (Grubba)  break;
512c842013-09-02Martin Nilsson  case EXTENSION_application_layer_protocol_negotiation: { has_application_layer_protocol_negotiation = 1; if( !context->advertised_protocols ) break;
5226592014-04-10Martin Nilsson  multiset(string) protocols = (<>);
4d16322014-04-10Martin Nilsson  if( extension_data->get_uint(2) != sizeof(extension_data) ) { send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
5c12d72014-04-12Martin Nilsson  "ALPN: Length mismatch.\n"));
4d16322014-04-10Martin Nilsson  return -1; }
512c842013-09-02Martin Nilsson  while (!extension_data->is_empty()) { string server_name = extension_data->get_var_string(1); if( sizeof(server_name)==0 ) { send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
5c12d72014-04-12Martin Nilsson  "ALPN: Empty protocol.\n"));
512c842013-09-02Martin Nilsson  return -1; }
5226592014-04-10Martin Nilsson  protocols[ server_name ] = 1;
512c842013-09-02Martin Nilsson  } if( !sizeof(protocols) ) { // FIXME: What does an empty list mean? Ignore, no
4d16322014-04-10Martin Nilsson  // protocol failure or handshake failure? Currently // it will hit the no compatible protocol fatal // alert below.
512c842013-09-02Martin Nilsson  } // Although the protocol list is sent in client // preference order, it is the server preference that // wins. next_protocol = 0;
08fe1f2013-12-08Henrik Grubbström (Grubba)  foreach(context->advertised_protocols;; string(0..255) prot)
5226592014-04-10Martin Nilsson  if( protocols[prot] ) {
512c842013-09-02Martin Nilsson  next_protocol = prot;
5226592014-04-10Martin Nilsson  break; }
512c842013-09-02Martin Nilsson  if( !next_protocol ) send_packet(Alert(ALERT_fatal, ALERT_no_application_protocol,
5c12d72014-04-12Martin Nilsson  "ALPN: No compatible protocol.\n"));
ccb5962014-04-12Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("ALPN extension: %O %O\n", protocols, next_protocol);
512c842013-09-02Martin Nilsson  } break;
1d54432014-03-30Henrik Grubbström (Grubba)  case EXTENSION_heartbeat: { int hb_mode; if (extension_data->is_empty() || !(hb_mode = extension_data->get_uint(1)) || !extension_data->is_empty() || ((hb_mode != HEARTBEAT_MODE_peer_allowed_to_send) && (hb_mode != HEARTBEAT_MODE_peer_not_allowed_to_send))) { // RFC 6520 2: // Upon reception of an unknown mode, an error Alert // message using illegal_parameter as its // AlertDescription MUST be sent in response. send_packet(Alert(ALERT_fatal, ALERT_illegal_parameter,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Heartbeat: Invalid extension.\n"));
1d54432014-03-30Henrik Grubbström (Grubba)  } SSL3_DEBUG_MSG("heartbeat extension: %s\n",
7a87de2014-04-10Henrik Grubbström (Grubba)  fmt_constant(hb_mode, "HEARTBEAT_MODE"));
f3fcf42014-04-01Martin Nilsson  session->heartbeat_mode = [int(0..1)]hb_mode;
1d54432014-03-30Henrik Grubbström (Grubba)  } break;
febdb42011-01-10Henrik Grubbström (Grubba)  default:
06e0312013-10-21Martin Nilsson #ifdef SSL3_DEBUG
4af8532014-05-01Martin Nilsson  werror("Unhandled extension %O (%d bytes)\n", extension_data->buffer, sizeof(extension_data->buffer));
06e0312013-10-21Martin Nilsson #endif
febdb42011-01-10Henrik Grubbström (Grubba)  break; } }
038e132014-03-23Henrik Grubbström (Grubba)  if (maybe_safari_10_8) { // According to OpenSSL (ssl/t1_lib.c:ssl_check_for_safari()), // the Safari browser versions 10.8.0..10.8.3 have // broken support for ECDHE_ECDSA, but advertise such // suites anyway. We attempt to fingerprint Safari 10.8 // above by the set of extensions and the order it // sends them in.
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Client version: %s\n"
038e132014-03-23Henrik Grubbström (Grubba)  "Number of extensions: %d\n",
39cf162014-04-05Henrik Grubbström (Grubba)  fmt_version(client_version),
038e132014-03-23Henrik Grubbström (Grubba)  sizeof(remote_extensions));
170da92014-04-05Henrik Grubbström (Grubba)  if (((client_version == PROTOCOL_TLS_1_2) &&
038e132014-03-23Henrik Grubbström (Grubba)  ((sizeof(remote_extensions) != 4) || !remote_extensions[EXTENSION_signature_algorithms])) ||
170da92014-04-05Henrik Grubbström (Grubba)  ((client_version < PROTOCOL_TLS_1_2) &&
038e132014-03-23Henrik Grubbström (Grubba)  ((sizeof(remote_extensions) != 3) || !remote_extensions[EXTENSION_ec_point_formats]))) { maybe_safari_10_8 = 0; } if (maybe_safari_10_8) { SSL3_DEBUG_MSG("Safari 10.8 (or similar) detected.\n"); cipher_suites = filter(cipher_suites, lambda(int suite) { return CIPHER_SUITES[suite] && (CIPHER_SUITES[suite][0] != KE_ecdhe_ecdsa); }); SSL3_DEBUG_MSG("Remaining cipher suites:\n" "%s\n", .Constants.fmt_cipher_suites(cipher_suites)); } }
febdb42011-01-10Henrik Grubbström (Grubba)  }
87740f2011-01-10Henrik Grubbström (Grubba)  if (missing_secure_renegotiation) { // RFC 5746 3.7: (secure_renegotiation) // The server MUST verify that the "renegotiation_info" extension is // present; if it is not, the server MUST abort the handshake.
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "Missing secure renegotiation extension.\n"));
87740f2011-01-10Henrik Grubbström (Grubba)  return -1; } if (has_value(cipher_suites, TLS_empty_renegotiation_info_scsv)) { if (secure_renegotiation || handshake_finished) { // RFC 5746 3.7: (secure_renegotiation) // When a ClientHello is received, the server MUST verify that it // does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If // the SCSV is present, the server MUST abort the handshake. // // RFC 5746 4.4: (!secure_renegotiation) // When a ClientHello is received, the server MUST verify // that it does not contain the // TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If the SCSV is // present, the server MUST abort the handshake.
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "SCSV is present.\n"));
87740f2011-01-10Henrik Grubbström (Grubba)  return -1; } else { // RFC 5746 3.6: // When a ClientHello is received, the server MUST check if it // includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it // does, set the secure_renegotiation flag to TRUE. secure_renegotiation = 1; } }
febdb42011-01-10Henrik Grubbström (Grubba) 
5ab7d72000-04-06Martin Nilsson #ifdef SSL3_DEBUG
33ef431997-03-13Niels Möller  if (!input->is_empty())
a423622014-03-18Martin Nilsson  werror("SSL.handshake->handle_handshake: "
33ef431997-03-13Niels Möller  "extra data in hello message ignored\n");
ead9722003-01-20Martin Nilsson  if (sizeof(id))
6244142003-01-27Martin Nilsson  werror("SSL.handshake: Looking up session %O\n", id);
8dcd741997-03-15Niels Möller #endif
4d1bb22014-02-02Henrik Grubbström (Grubba)  if (reuse) { /* Reuse session */ SSL3_DEBUG_MSG("SSL.handshake: Reusing session %O\n", id);
33ef431997-03-13Niels Möller  if (! ( (cipher_suites & ({ session->cipher_suite })) && (compression_methods & ({ session->compression_algorithm })))) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Unsupported saved session state.\n"));
33ef431997-03-13Niels Möller  return -1; } send_packet(server_hello_packet());
7426b82013-11-29Martin Nilsson  array(.state) res;
ccb5962014-04-12Henrik Grubbström (Grubba)  mixed err;
9e39102014-04-27Henrik Grubbström (Grubba)  if( err = catch(res = session->new_server_states(this, client_random,
ccb5962014-04-12Henrik Grubbström (Grubba)  server_random, version)) )
7426b82013-11-29Martin Nilsson  { // DES/DES3 throws an exception if a weak key is used. We
4d1bb22014-02-02Henrik Grubbström (Grubba)  // could possibly send ALERT_insufficient_security instead.
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_internal_error,
0ddaf82014-04-24Martin Nilsson  "Internal error.\n"));
7426b82013-11-29Martin Nilsson  return -1; }
33ef431997-03-13Niels Möller  pending_read_state = res[0]; pending_write_state = res[1]; send_packet(change_cipher_packet());
170da92014-04-05Henrik Grubbström (Grubba)  if(version == PROTOCOL_SSL_3_0)
18c01f2004-01-25Martin Nilsson  send_packet(finished_packet("SRVR"));
170da92014-04-05Henrik Grubbström (Grubba)  else if(version >= PROTOCOL_TLS_1_0)
18c01f2004-01-25Martin Nilsson  send_packet(finished_packet("server finished"));
aa77d52001-04-18Pär Svensson 
72bffa2014-04-14Henrik Grubbström (Grubba)  if (session->heartbeat_mode == HEARTBEAT_MODE_peer_allowed_to_send) { // Probe for the Heartbleed vulnerability (CVE-2014-0160). send_packet(heartbleed_packet()); }
33ef431997-03-13Niels Möller  expect_change_cipher = 1; handshake_state = STATE_server_wait_for_finish; } else { /* New session, do full handshake. */
b6345f2004-01-23Martin Nilsson  int(-1..0) err = reply_new_session(cipher_suites, compression_methods);
33ef431997-03-13Niels Möller  if (err) return err; handshake_state = STATE_server_wait_for_client; } break; } } break; } case STATE_server_wait_for_finish: switch(type) { default:
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected next protocol or finished.\n"));
33ef431997-03-13Niels Möller  return -1;
27e1172012-04-07Arne Goedeke  case HANDSHAKE_next_protocol: { next_protocol = input->get_var_string(1); handshake_messages += raw; return 1; }
33ef431997-03-13Niels Möller  case HANDSHAKE_finished: {
08fe1f2013-12-08Henrik Grubbström (Grubba)  string(0..255) my_digest; string(0..255) digest;
aa77d52001-04-18Pär Svensson 
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: FINISHED\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
170da92014-04-05Henrik Grubbström (Grubba)  if(version == PROTOCOL_SSL_3_0) {
aa77d52001-04-18Pär Svensson  my_digest=hash_messages("CLNT"); if (catch { digest = input->get_fix_string(36); } || !input->is_empty()) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Invalid handshake finished message.\n"));
aa77d52001-04-18Pär Svensson  return -1; }
170da92014-04-05Henrik Grubbström (Grubba)  } else if(version >= PROTOCOL_TLS_1_0) {
aa77d52001-04-18Pär Svensson  my_digest=hash_messages("client finished"); if (catch { digest = input->get_fix_string(12); } || !input->is_empty()) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Invalid handshake finished message.\n"));
aa77d52001-04-18Pär Svensson  return -1; }
33ef431997-03-13Niels Möller  }
aa77d52001-04-18Pär Svensson 
3e73012013-11-25Henrik Grubbström (Grubba)  if ((ke && ke->message_was_bad) /* Error delayed until now */
ae562d1998-06-27Niels Möller  || (my_digest != digest))
33ef431997-03-13Niels Möller  {
3e73012013-11-25Henrik Grubbström (Grubba)  if(ke && ke->message_was_bad)
ac1d862013-11-23Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("message_was_bad\n");
813b392000-08-04Andreas Sigfridsson  if(my_digest != digest) SSL3_DEBUG_MSG("digests differ\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Key exchange failure.\n"));
33ef431997-03-13Niels Möller  return -1; } handshake_messages += raw; /* Second hash includes this message, * the first doesn't */ /* Handshake complete */
87740f2011-01-10Henrik Grubbström (Grubba)  client_verify_data = digest;
33ef431997-03-13Niels Möller  if (!reuse) { send_packet(change_cipher_packet());
170da92014-04-05Henrik Grubbström (Grubba)  if(version == PROTOCOL_SSL_3_0)
caf60e2011-12-15Henrik Grubbström (Grubba)  send_packet(finished_packet("SRVR"));
170da92014-04-05Henrik Grubbström (Grubba)  else if(version >= PROTOCOL_TLS_1_0)
caf60e2011-12-15Henrik Grubbström (Grubba)  send_packet(finished_packet("server finished"));
72bffa2014-04-14Henrik Grubbström (Grubba)  if (session->heartbeat_mode == HEARTBEAT_MODE_peer_allowed_to_send) { // Probe for the Heartbleed vulnerability (CVE-2014-0160). send_packet(heartbleed_packet()); }
33ef431997-03-13Niels Möller  expect_change_cipher = 1; context->record_session(session); /* Cache this session */ } handshake_state = STATE_server_wait_for_hello; return 1; } } break; case STATE_server_wait_for_client:
3e9dd92014-03-22Henrik Grubbström (Grubba)  // NB: ALERT_no_certificate can be valid in this state, and // is handled directly by connection:handle_alert().
33ef431997-03-13Niels Möller  handshake_messages += raw; switch(type) { default:
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected client KEX or cert.\n"));
33ef431997-03-13Niels Möller  return -1; case HANDSHAKE_client_key_exchange:
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CLIENT_KEY_EXCHANGE\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
33ef431997-03-13Niels Möller  if (certificate_state == CERT_requested)
88cfa12005-10-28H. William Welliver III  { /* Certificate must be sent before key exchange message */
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected client cert.\n"));
33ef431997-03-13Niels Möller  return -1; }
ae562d1998-06-27Niels Möller 
33ef431997-03-13Niels Möller  if (!(session->master_secret = server_derive_master_secret(data))) {
fada191999-03-09Niels Möller  return -1;
ae562d1998-06-27Niels Möller  } else {
813b392000-08-04Andreas Sigfridsson 
ae562d1998-06-27Niels Möller  // trace(1);
5ed44a2013-11-24Henrik Grubbström (Grubba)  array(.state) res =
9e39102014-04-27Henrik Grubbström (Grubba)  session->new_server_states(this, client_random, server_random, version);
ae562d1998-06-27Niels Möller  pending_read_state = res[0]; pending_write_state = res[1];
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("certificate_state: %d\n", certificate_state);
33ef431997-03-13Niels Möller  }
88cfa12005-10-28H. William Welliver III  // TODO: we need to determine whether the certificate has signing abilities. if (certificate_state == CERT_received) { handshake_state = STATE_server_wait_for_verify; } else
33ef431997-03-13Niels Möller  { handshake_state = STATE_server_wait_for_finish; expect_change_cipher = 1; }
45018b2000-10-22Andreas Sigfridsson 
33ef431997-03-13Niels Möller  break; case HANDSHAKE_certificate: {
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CLIENT_CERTIFICATE\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
45018b2000-10-22Andreas Sigfridsson  if (certificate_state != CERT_requested)
33ef431997-03-13Niels Möller  {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Unexpected client cert.\n"));
33ef431997-03-13Niels Möller  return -1; }
88cfa12005-10-28H. William Welliver III  mixed e; if (e = catch {
45018b2000-10-22Andreas Sigfridsson  int certs_len = input->get_uint(3);
88cfa12005-10-28H. William Welliver III #ifdef SSL3_DEBUG
9fcdca2008-01-05Henrik Grubbström (Grubba)  werror("got %d certificate bytes\n", certs_len); #else certs_len; // Fix warning.
88cfa12005-10-28H. William Welliver III #endif
4d4fd82014-02-03Henrik Grubbström (Grubba)  array(string(8bit)) certs = ({ });
45018b2000-10-22Andreas Sigfridsson  while(!input->is_empty()) certs += ({ input->get_var_string(3) });
7e78212004-01-23H. William Welliver III  // we have the certificate chain in hand, now we must verify them.
88cfa12005-10-28H. William Welliver III  if((!sizeof(certs) && context->auth_level == AUTHLEVEL_require) || !verify_certificate_chain(certs))
7e78212004-01-23H. William Welliver III  {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_bad_certificate,
0ddaf82014-04-24Martin Nilsson  "Bad client certificate.\n"));
ccb5962014-04-12Henrik Grubbström (Grubba)  return -1;
7e78212004-01-23H. William Welliver III  } else {
ccb5962014-04-12Henrik Grubbström (Grubba)  session->peer_certificate_chain = certs;
7e78212004-01-23H. William Welliver III  }
33ef431997-03-13Niels Möller  } || !input->is_empty()) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Unexpected client cert.\n"));
33ef431997-03-13Niels Möller  return -1; }
7e78212004-01-23H. William Welliver III 
75b3d42014-03-08Henrik Grubbström (Grubba)  if(session->peer_certificate_chain && sizeof(session->peer_certificate_chain))
88cfa12005-10-28H. William Welliver III  certificate_state = CERT_received; else certificate_state = CERT_no_certificate;
33ef431997-03-13Niels Möller  break; } } break; case STATE_server_wait_for_verify:
45018b2000-10-22Andreas Sigfridsson  // compute challenge first, then update handshake_messages /Sigge
33ef431997-03-13Niels Möller  switch(type) { default:
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected cert verify.\n"));
33ef431997-03-13Niels Möller  return -1; case HANDSHAKE_certificate_verify:
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CERTIFICATE_VERIFY\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
ac1d862013-11-23Henrik Grubbström (Grubba)  if (!ke->message_was_bad)
ae562d1998-06-27Niels Möller  {
18c01f2004-01-25Martin Nilsson  int(0..1) verification_ok;
59a32a2013-11-25Henrik Grubbström (Grubba)  mixed err = catch { ADT.struct handshake_messages_struct = ADT.struct(); handshake_messages_struct->put_fix_string(handshake_messages); verification_ok = session->cipher_spec->verify( session, "", handshake_messages_struct, input); }; #ifdef SSL3_DEBUG if (err) { master()->handle_error(err); } #endif
b92d2f2013-11-25Henrik Grubbström (Grubba)  err = UNDEFINED; // Get rid of warning.
59a32a2013-11-25Henrik Grubbström (Grubba)  if (!verification_ok)
45018b2000-10-22Andreas Sigfridsson  {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Verification of CertificateVerify failed.\n"));
45018b2000-10-22Andreas Sigfridsson  return -1; }
ae562d1998-06-27Niels Möller  }
33ef431997-03-13Niels Möller  handshake_messages += raw; handshake_state = STATE_server_wait_for_finish; expect_change_cipher = 1; break; } break; case STATE_client_wait_for_hello:
813b392000-08-04Andreas Sigfridsson  if(type != HANDSHAKE_server_hello) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected server hello.\n"));
813b392000-08-04Andreas Sigfridsson  return -1; } else {
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: SERVER_HELLO\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
813b392000-08-04Andreas Sigfridsson  handshake_messages += raw; string id; int cipher_suite, compression_method;
170da92014-04-05Henrik Grubbström (Grubba)  version = [int(0x300..0x300)|ProtocolVersion]input->get_uint(2);
813b392000-08-04Andreas Sigfridsson  server_random = input->get_fix_string(32); id = input->get_var_string(1); cipher_suite = input->get_uint(2); compression_method = input->get_uint(1);
7805d12004-07-01Henrik Grubbström (Grubba)  if( !has_value(context->preferred_suites, cipher_suite) ||
6790a12014-03-22Henrik Grubbström (Grubba)  !has_value(context->preferred_compressors, compression_method) ||
170da92014-04-05Henrik Grubbström (Grubba)  !session->is_supported_suite(cipher_suite, ~0, version))
813b392000-08-04Andreas Sigfridsson  { // The server tried to trick us to use some other cipher suite // or compression method than we wanted
170da92014-04-05Henrik Grubbström (Grubba)  version = client_version;
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "Server selected bad suite.\n"));
813b392000-08-04Andreas Sigfridsson  return -1; }
170da92014-04-05Henrik Grubbström (Grubba)  if (((version & ~0xff) != PROTOCOL_SSL_3_0) || (version < context->min_version)) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Unsupported version of SSL: %s.\n", fmt_version(version));
170da92014-04-05Henrik Grubbström (Grubba)  version = client_version;
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_protocol_version,
0ddaf82014-04-24Martin Nilsson  "Unsupported version.\n"));
6262d42011-12-15Henrik Grubbström (Grubba)  return -1; }
170da92014-04-05Henrik Grubbström (Grubba)  if (client_version > version) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Falling back client from %s to %s.\n", fmt_version(client_version), fmt_version(version));
170da92014-04-05Henrik Grubbström (Grubba)  } else if (version > client_version) {
39cf162014-04-05Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Falling back server from %s to %s.\n", fmt_version(version), fmt_version(client_version));
170da92014-04-05Henrik Grubbström (Grubba)  version = client_version;
3149302004-07-05Henrik Grubbström (Grubba)  }
170da92014-04-05Henrik Grubbström (Grubba)  if (!session->set_cipher_suite(cipher_suite, version,
f5b7df2014-03-08Henrik Grubbström (Grubba)  session->signature_algorithms, 512)) {
8591b22013-11-26Henrik Grubbström (Grubba)  // Unsupported or obsolete cipher suite selected.
f5b7df2014-03-08Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Unsupported or obsolete cipher suite selected.\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Unsupported or obsolete cipher suite.\n"));
8591b22013-11-26Henrik Grubbström (Grubba)  return -1; }
813b392000-08-04Andreas Sigfridsson  session->set_compression_method(compression_method);
8970062003-03-12Marcus Agehall  SSL3_DEBUG_MSG("STATE_client_wait_for_hello: received hello\n"
39cf162014-04-05Henrik Grubbström (Grubba)  "version = %s\n"
813b392000-08-04Andreas Sigfridsson  "id=%O\n" "cipher suite: %O\n" "compression method: %O\n",
39cf162014-04-05Henrik Grubbström (Grubba)  fmt_version(version),
813b392000-08-04Andreas Sigfridsson  id, cipher_suite, compression_method);
87740f2011-01-10Henrik Grubbström (Grubba)  int missing_secure_renegotiation = secure_renegotiation;
febdb42011-01-10Henrik Grubbström (Grubba)  if (!input->is_empty()) { ADT.struct extensions = ADT.struct(input->get_var_string(2)); while (!extensions->is_empty()) { int extension_type = extensions->get_uint(2); ADT.struct extension_data = ADT.struct(extensions->get_var_string(2));
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake->handle_handshake: "
4af8532014-05-01Martin Nilsson  "Got extension %s.\n", fmt_constant(extension_type, "EXTENSION"));
febdb42011-01-10Henrik Grubbström (Grubba)  switch(extension_type) {
87740f2011-01-10Henrik Grubbström (Grubba)  case EXTENSION_renegotiation_info: string renegotiated_connection = extension_data->get_var_string(1); if ((renegotiated_connection != (client_verify_data + server_verify_data)) || (handshake_finished && !secure_renegotiation)) { // RFC 5746 3.5: (secure_renegotiation) // The client MUST then verify that the first half of the // "renegotiated_connection" field is equal to the saved // client_verify_data value, and the second half is equal to the // saved server_verify_data value. If they are not, the client // MUST abort the handshake. // // RFC 5746 4.2: (!secure_renegotiation) // When the ServerHello is received, the client MUST // verify that it does not contain the // "renegotiation_info" extension. If it does, the client // MUST abort the handshake. (Because the server has // already indicated it does not support secure // renegotiation, the only way that this can happen is if // the server is broken or there is an attack.)
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "Invalid renegotiation data.\n"));
87740f2011-01-10Henrik Grubbström (Grubba)  return -1; } secure_renegotiation = 1; missing_secure_renegotiation = 0; break;
7de33b2013-12-30Henrik Grubbström (Grubba)  case EXTENSION_ec_point_formats: array(int) ecc_point_formats = extension_data->get_var_uint_array(1, 1); // NB: We only support the uncompressed point format for now. if (has_value(ecc_point_formats, POINT_uncompressed)) {
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->ecc_point_format = POINT_uncompressed;
7de33b2013-12-30Henrik Grubbström (Grubba)  } else { // Not a supported point format.
4d1bb22014-02-02Henrik Grubbström (Grubba)  session->ecc_point_format = -1;
7de33b2013-12-30Henrik Grubbström (Grubba)  } break;
8fb9ba2012-08-31Bill Welliver  case EXTENSION_server_name: break;
1d54432014-03-30Henrik Grubbström (Grubba)  case EXTENSION_heartbeat: { int hb_mode; if (extension_data->is_empty() || !(hb_mode = extension_data->get_uint(1)) || !extension_data->is_empty() || ((hb_mode != HEARTBEAT_MODE_peer_allowed_to_send) && (hb_mode != HEARTBEAT_MODE_peer_not_allowed_to_send))) { // RFC 6520 2: // Upon reception of an unknown mode, an error Alert // message using illegal_parameter as its // AlertDescription MUST be sent in response. send_packet(Alert(ALERT_fatal, ALERT_illegal_parameter,
5c12d72014-04-12Martin Nilsson  "Invalid heartbeat extension.\n"));
1d54432014-03-30Henrik Grubbström (Grubba)  } SSL3_DEBUG_MSG("heartbeat extension: %s\n",
cc52a32014-04-11Henrik Grubbström (Grubba)  fmt_constant(hb_mode, "HEARTBEAT_MODE"));
f3fcf42014-04-01Martin Nilsson  session->heartbeat_mode = [int(0..1)]hb_mode;
1d54432014-03-30Henrik Grubbström (Grubba)  } break;
febdb42011-01-10Henrik Grubbström (Grubba)  default: // RFC 5246 7.4.1.4: // If a client receives an extension type in ServerHello // that it did not request in the associated ClientHello, it // MUST abort the handshake with an unsupported_extension // fatal alert. send_packet(Alert(ALERT_fatal, ALERT_unsupported_extension,
0ddaf82014-04-24Martin Nilsson  "Unrequested extension.\n"));
febdb42011-01-10Henrik Grubbström (Grubba)  return -1; } } }
87740f2011-01-10Henrik Grubbström (Grubba)  if (missing_secure_renegotiation) { // RFC 5746 3.5: // When a ServerHello is received, the client MUST verify that the // "renegotiation_info" extension is present; if it is not, the // client MUST abort the handshake.
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
0ddaf82014-04-24Martin Nilsson  "Missing secure renegotiation extension.\n"));
87740f2011-01-10Henrik Grubbström (Grubba)  return -1; }
febdb42011-01-10Henrik Grubbström (Grubba) 
813b392000-08-04Andreas Sigfridsson  handshake_state = STATE_client_wait_for_server; break; } break;
33ef431997-03-13Niels Möller  case STATE_client_wait_for_server:
813b392000-08-04Andreas Sigfridsson  handshake_messages += raw; switch(type) { default:
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Unexpected server message.\n"));
813b392000-08-04Andreas Sigfridsson  return -1; case HANDSHAKE_certificate: {
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CERTIFICATE\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
88cfa12005-10-28H. William Welliver III  // we're anonymous, so no certificate is requred.
1cc9c72013-11-23Henrik Grubbström (Grubba)  if(ke && ke->anonymous)
88cfa12005-10-28H. William Welliver III  break;
8970062003-03-12Marcus Agehall  SSL3_DEBUG_MSG("Handshake: Certificate message received\n");
9fcdca2008-01-05Henrik Grubbström (Grubba)  int certs_len = input->get_uint(3); certs_len;
4d4fd82014-02-03Henrik Grubbström (Grubba)  array(string(8bit)) certs = ({ });
813b392000-08-04Andreas Sigfridsson  while(!input->is_empty()) certs += ({ input->get_var_string(3) });
aa77d52001-04-18Pär Svensson 
526a402004-01-30H. William Welliver III  // we have the certificate chain in hand, now we must verify them. if(!verify_certificate_chain(certs)) {
88cfa12005-10-28H. William Welliver III  werror("Unable to verify peer certificate chain.\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_bad_certificate,
0ddaf82014-04-24Martin Nilsson  "Bad server certificate chain.\n"));
88cfa12005-10-28H. William Welliver III  return -1;
526a402004-01-30H. William Welliver III  } else { session->peer_certificate_chain = certs; }
5e1d732013-11-19Martin Nilsson 
c79dc12001-06-14Pär Svensson  mixed error=catch
813b392000-08-04Andreas Sigfridsson  {
cdb43a2014-01-19Henrik Grubbström (Grubba)  session->peer_public_key = Standards.X509.decode_certificate( session->peer_certificate_chain[0])->public_key->pkc;
a7170b2014-03-10Henrik Grubbström (Grubba) #if constant(Crypto.ECC.Curve) if (session->peer_public_key->curve) { session->curve = ([object(Crypto.ECC.SECP_521R1.ECDSA)]session->peer_public_key)-> curve(); } #endif
c79dc12001-06-14Pär Svensson  };
4f5e1d2003-01-27Martin Nilsson  if(error)
813b392000-08-04Andreas Sigfridsson  {
75b3d42014-03-08Henrik Grubbström (Grubba)  session->peer_certificate_chain = UNDEFINED;
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("Failed to decode certificate!\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Failed to decode server certificate.\n"));
813b392000-08-04Andreas Sigfridsson  return -1; }
c79dc12001-06-14Pär Svensson 
813b392000-08-04Andreas Sigfridsson  certificate_state = CERT_received; break; } case HANDSHAKE_server_key_exchange: {
1cc9c72013-11-23Henrik Grubbström (Grubba)  if (ke) error("KE!\n");
93034b2013-12-29Henrik Grubbström (Grubba)  ke = session->ke_factory(context, session, this, client_version);
5ed44a2013-11-24Henrik Grubbström (Grubba)  if (ke->server_key_exchange(input, client_random, server_random) < 0) {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Verification of ServerKeyExchange failed.\n"));
813b392000-08-04Andreas Sigfridsson  return -1; } break; } case HANDSHAKE_certificate_request:
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: CERTIFICATE_REQUEST\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
b06b5d2013-08-01Martin Nilsson  // it is a fatal handshake_failure alert for an anonymous server to
88cfa12005-10-28H. William Welliver III  // request client authentication.
1cc9c72013-11-23Henrik Grubbström (Grubba)  if(ke->anonymous)
88cfa12005-10-28H. William Welliver III  {
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_handshake_failure,
ccb5962014-04-12Henrik Grubbström (Grubba)  "Anonymous server requested authentication by "
0ddaf82014-04-24Martin Nilsson  "certificate.\n"));
88cfa12005-10-28H. William Welliver III  return -1; } client_cert_types = input->get_var_uint_array(1, 1); client_cert_distinguished_names = ({});
8ce1f72014-02-21Martin Nilsson 
8bbd8b2014-04-13Henrik Grubbström (Grubba)  if (version >= PROTOCOL_TLS_1_2) { // TLS 1.2 has var_uint_array of hash and sign pairs here. string bytes = input->get_var_string(2); // Pairs of <hash_alg, signature_alg>. session->signature_algorithms = ((array(int))bytes)/2; SSL3_DEBUG_MSG("New signature_algorithms:\n"+ fmt_signature_pairs(session->signature_algorithms)); }
8ce1f72014-02-21Martin Nilsson 
88cfa12005-10-28H. William Welliver III  int num_distinguished_names = input->get_uint(2); if(num_distinguished_names) {
28a6752014-04-13Henrik Grubbström (Grubba)  ADT.struct s = ADT.struct(input->get_fix_string(num_distinguished_names));
88cfa12005-10-28H. William Welliver III  while(!s->is_empty()) {
28a6752014-04-13Henrik Grubbström (Grubba)  string(8bit) der = s->get_var_string(2); Standards.ASN1.Types.Sequence seq = [object(Standards.ASN1.Types.Sequence)] Standards.ASN1.Decode.simple_der_decode(der); if(object_program(seq) != Standards.ASN1.Types.Sequence)
88cfa12005-10-28H. William Welliver III  {
28a6752014-04-13Henrik Grubbström (Grubba)  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Badly formed Certificate Request.\n"));
88cfa12005-10-28H. William Welliver III  }
28a6752014-04-13Henrik Grubbström (Grubba)  client_cert_distinguished_names += ({ der });
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("got an authorized issuer: %O\n",
28a6752014-04-13Henrik Grubbström (Grubba)  Standards.PKCS.Certificate.get_dn_string( seq )); }
88cfa12005-10-28H. William Welliver III  } certificate_state = CERT_requested;
813b392000-08-04Andreas Sigfridsson  break; case HANDSHAKE_server_hello_done:
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: SERVER_HELLO_DONE\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
813b392000-08-04Andreas Sigfridsson  /* Send Certificate, ClientKeyExchange, CertificateVerify and * ChangeCipherSpec as appropriate, and then Finished. */
88cfa12005-10-28H. William Welliver III  /* only send a certificate if it's been requested. */ if(certificate_state == CERT_requested) { // okay, we have a list of certificate types and dns that are // acceptable to the remote server. we should weed out the certs // we have so that we only send certificates that match what they // want.
2dbaf82014-04-05Henrik Grubbström (Grubba)  array(CertificatePair) certs = [array(CertificatePair)]
fb501a2014-04-10Henrik Grubbström (Grubba)  filter(context->find_cert(client_cert_distinguished_names, 1) || ({}),
2dbaf82014-04-05Henrik Grubbström (Grubba)  lambda(CertificatePair cp, array(int)) { return has_value(client_cert_types, cp->cert_type); }, client_cert_types); if (sizeof(certs)) {
fb501a2014-04-10Henrik Grubbström (Grubba)  session->private_key = certs[0]->key;
2dbaf82014-04-05Henrik Grubbström (Grubba)  session->certificate_chain = certs[0]->certs;
88cfa12005-10-28H. William Welliver III #ifdef SSL3_DEBUG
2dbaf82014-04-05Henrik Grubbström (Grubba)  foreach(session->certificate_chain, string c) { werror("sending certificate: " + Standards.PKCS.Certificate.get_dn_string(Standards.X509.decode_certificate(c)->subject) + "\n"); }
88cfa12005-10-28H. William Welliver III #endif
2dbaf82014-04-05Henrik Grubbström (Grubba)  send_packet(certificate_packet(session->certificate_chain));
88cfa12005-10-28H. William Welliver III  certificate_state = CERT_received; // we use this as a way of saying "the server received our certificate"
2dbaf82014-04-05Henrik Grubbström (Grubba)  } else { send_packet(certificate_packet(({}))); certificate_state = CERT_no_certificate; }
88cfa12005-10-28H. William Welliver III  }
bff0ed2013-11-11Martin Nilsson  if( !session->has_required_certificates() )
813b392000-08-04Andreas Sigfridsson  {
bff0ed2013-11-11Martin Nilsson  SSL3_DEBUG_MSG("Certificate message required from server.\n");
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Certificate message missing.\n"));
bff0ed2013-11-11Martin Nilsson  return -1; }
6ca49e2005-05-25Martin Stjernholm 
18c01f2004-01-25Martin Nilsson  Packet key_exchange = client_key_exchange_packet();
813b392000-08-04Andreas Sigfridsson  if (key_exchange) send_packet(key_exchange);
ecec692014-04-10Martin Nilsson  // FIXME: The certificate code has changed, so this no longer // works, if it every did. #if 0
ceff2c2007-11-15H. William Welliver III  // FIXME: Certificate verify; we should redo this so it makes more sense
75b3d42014-03-08Henrik Grubbström (Grubba)  if(certificate_state == CERT_received &&
ecec692014-04-10Martin Nilsson  sizeof(context->cert_pairs) &&
75b3d42014-03-08Henrik Grubbström (Grubba)  context->private_key)
ceff2c2007-11-15H. William Welliver III  // we sent a certificate, so we should send the verification.
88cfa12005-10-28H. William Welliver III  { send_packet(certificate_verify_packet()); }
ecec692014-04-10Martin Nilsson #endif
813b392000-08-04Andreas Sigfridsson  send_packet(change_cipher_packet());
170da92014-04-05Henrik Grubbström (Grubba)  if(version == PROTOCOL_SSL_3_0)
caf60e2011-12-15Henrik Grubbström (Grubba)  send_packet(finished_packet("CLNT"));
170da92014-04-05Henrik Grubbström (Grubba)  else if(version >= PROTOCOL_TLS_1_0)
caf60e2011-12-15Henrik Grubbström (Grubba)  send_packet(finished_packet("client finished"));
bff0ed2013-11-11Martin Nilsson 
72bffa2014-04-14Henrik Grubbström (Grubba)  if (session->heartbeat_mode == HEARTBEAT_MODE_peer_allowed_to_send) { // Probe for the Heartbleed vulnerability (CVE-2014-0160). send_packet(heartbleed_packet()); }
bff0ed2013-11-11Martin Nilsson  handshake_state = STATE_client_wait_for_finish; expect_change_cipher = 1; break;
813b392000-08-04Andreas Sigfridsson  } break;
33ef431997-03-13Niels Möller  case STATE_client_wait_for_finish:
813b392000-08-04Andreas Sigfridsson  { if((type) != HANDSHAKE_finished) { SSL3_DEBUG_MSG("Expected type HANDSHAKE_finished(%d), got %d\n", HANDSHAKE_finished, type);
5c12d72014-04-12Martin Nilsson  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Expected handshake finished.\n"));
813b392000-08-04Andreas Sigfridsson  return -1;
4a14c02010-12-22Henrik Grubbström (Grubba)  } else {
a423622014-03-18Martin Nilsson  SSL3_DEBUG_MSG("SSL.handshake: FINISHED\n");
4a14c02010-12-22Henrik Grubbström (Grubba) 
caf60e2011-12-15Henrik Grubbström (Grubba)  string my_digest;
170da92014-04-05Henrik Grubbström (Grubba)  if (version == PROTOCOL_SSL_3_0) {
6b11b32011-12-14Henrik Grubbström (Grubba)  server_verify_data = input->get_fix_string(36);
caf60e2011-12-15Henrik Grubbström (Grubba)  my_digest = hash_messages("SRVR");
170da92014-04-05Henrik Grubbström (Grubba)  } else if (version >= PROTOCOL_TLS_1_0) {
6b11b32011-12-14Henrik Grubbström (Grubba)  server_verify_data = input->get_fix_string(12);
caf60e2011-12-15Henrik Grubbström (Grubba)  my_digest = hash_messages("server finished");
6b11b32011-12-14Henrik Grubbström (Grubba)  }
87740f2011-01-10Henrik Grubbström (Grubba) 
1b8c862011-03-10Henrik Grubbström (Grubba)  if (my_digest != server_verify_data) {
5c12d72014-04-12Martin Nilsson  SSL3_DEBUG_MSG("Digests differ.\n"); send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
0ddaf82014-04-24Martin Nilsson  "Digests differ.\n"));
1b8c862011-03-10Henrik Grubbström (Grubba)  return -1; }
813b392000-08-04Andreas Sigfridsson  return 1; // We're done shaking hands }
4a14c02010-12-22Henrik Grubbström (Grubba)  }
33ef431997-03-13Niels Möller  }
b06b5d2013-08-01Martin Nilsson  // SSL3_DEBUG_MSG("SSL.handshake: messages = %O\n", handshake_messages);
33ef431997-03-13Niels Möller  return 0; }
6262d42011-12-15Henrik Grubbström (Grubba) //! @param is_server //! Whether this is the server end of the connection or not. //! @param ctx //! The context for the connection.
eb53bd2014-05-04Martin Nilsson protected void create(SSL.context ctx)
33ef431997-03-13Niels Möller {
eb53bd2014-05-04Martin Nilsson  current_read_state = SSL.state(this); current_write_state = SSL.state(this);
687f012014-04-04Henrik Grubbström (Grubba)  if ((ctx->max_version < PROTOCOL_SSL_3_0) || (ctx->max_version > PROTOCOL_TLS_MAX)) { ctx->max_version = PROTOCOL_TLS_MAX;
6262d42011-12-15Henrik Grubbström (Grubba)  }
687f012014-04-04Henrik Grubbström (Grubba)  if (ctx->min_version < PROTOCOL_SSL_3_0) { ctx->min_version = PROTOCOL_SSL_3_0; } else if (ctx->min_version > ctx->max_version) { ctx->min_version = ctx->max_version;
6262d42011-12-15Henrik Grubbström (Grubba)  }
170da92014-04-05Henrik Grubbström (Grubba)  version = ctx->max_version;
a300792003-10-24Martin Stjernholm  context = ctx;
eb53bd2014-05-04Martin Nilsson } // // --- Old connection.pike below // //! SSL packet layer. //! //! @[SSL.connection] inherits @[SSL.handshake], and in addition to the state in //! the handshake super class, it contains the current read and write //! states, packet queues. This object is responsible for receiving and //! sending packets, processing handshake packets, and providing clear //! text packets for some application. // SSL/TLS Protocol Specification documents: // // SSL 2 http://wp.netscape.com/eng/security/SSL_2.html // SSL 3.0 http://wp.netscape.com/eng/ssl3/draft302.txt // (aka draft-freier-ssl-version3-02.txt). // TLS 1.0 (SSL 3.1) RFC 2246 "The TLS Protocol Version 1.0". // TLS 1.1 (SSL 3.2) draft-ietf-tls-rfc2246-bis // Renegotiation RFC 5746 "Renegotiation Indication Extension". .state current_read_state; .state current_write_state; string left_over; Packet packet; int sent; int dying; int closing; // Bitfield: 1 if a close is sent, 2 of one is received. function(object,int|object,string:void) alert_callback; constant PRI_alert = 1; constant PRI_urgent = 2; constant PRI_application = 3; protected ADT.Queue alert = ADT.Queue(); protected ADT.Queue urgent = ADT.Queue(); protected ADT.Queue application = ADT.Queue(); //! Called with alert object, sequence number of bad packet, //! and raw data as arguments, if a bad packet is received. //! //! Can be used to support a fallback redirect https->http. void set_alert_callback(function(object,int|object,string:void) callback) { alert_callback = callback; } //! Low-level receive handler. Returns a packet, an alert, or zero if //! more data is needed to get a complete packet. protected Packet recv_packet(string data) { string|Packet res; // SSL3_DEBUG_MSG("SSL.connection->recv_packet(%O)\n", data); if (left_over || !packet) { packet = Packet(2048); res = packet->recv( (left_over || "") + data, version); } else res = packet->recv(data, version); if (stringp(res)) { /* Finished a packet */ left_over = [string]res; if (current_read_state) { SSL3_DEBUG_MSG("SSL.connection->recv_packet(): version=0x%x\n", version); return current_read_state->decrypt_packet(packet, version); } else { SSL3_DEBUG_MSG("SSL.connection->recv_packet(): current_read_state is zero!\n"); return 0; } } else /* Partial packet read, or error */ left_over = 0; return [object]res; } //! Queues a packet for write. Handshake and and change cipher //! must use the same priority, so must application data and //! close_notifies. void send_packet(object packet, int|void priority) { if (closing & 1) { SSL3_DEBUG_MSG("SSL.connection->send_packet: ignoring packet after close\n"); return; } if (packet->content_type == PACKET_alert && packet->description == ALERT_close_notify) closing |= 1; if (!priority) priority = ([ PACKET_alert : PRI_alert, PACKET_change_cipher_spec : PRI_urgent, PACKET_handshake : PRI_urgent, PACKET_heartbeat : PRI_urgent, PACKET_application_data : PRI_application ])[packet->content_type]; SSL3_DEBUG_MSG("SSL.connection->send_packet: type %d, desc %d, pri %d, %O\n", packet->content_type, packet->description, priority, packet->fragment[..5]); switch (priority) { default: error( "Internal error\n" ); case PRI_alert: alert->put(packet); break; case PRI_urgent: urgent->put(packet); break; case PRI_application: application->put(packet); break; } } //! Extracts data from the packet queues. Returns a string of data //! to be written, "" if there are no pending packets, 1 of the //! connection is being closed politely, and -1 if the connection //! died unexpectedly. //! //! This function is intended to be called from an i/o write callback. string|int to_write() { if (dying) return -1; Packet packet = [object(Packet)](alert->get() || urgent->get() || application->get()); if (!packet) { return closing ? 1 : ""; } SSL3_DEBUG_MSG("SSL.connection: writing packet of type %d, %O\n", packet->content_type, packet->fragment[..6]); if (packet->content_type == PACKET_alert) { if (packet->level == ALERT_fatal) { dying = 1; // SSL3 5.4: // Alert messages with a level of fatal result in the immediate // termination of the connection. In this case, other // connections corresponding to the session may continue, but // the session identifier must be invalidated, preventing the // failed session from being used to establish new connections. if (session) { context->purge_session(session); } } } string res = current_write_state->encrypt_packet(packet, version)->send(); if (packet->content_type == PACKET_change_cipher_spec) current_write_state = pending_write_state; return res; } //! Initiate close. void send_close() { send_packet(Alert(ALERT_warning, ALERT_close_notify, "Closing connection.\n"), PRI_application); } //! Send an application data packet. If the data block is too large //! then as much as possible of the beginning of it is sent. The size //! of the sent data is returned. int send_streaming_data (string(8bit) data) { if (!sizeof(data)) return 0; Packet packet = Packet(); packet->content_type = PACKET_application_data; int max_packet_size = session->max_packet_size; int size; if ((!sent) && (version < PROTOCOL_TLS_1_1) && (session->cipher_spec->cipher_type == CIPHER_block)) { // Workaround for the BEAST attack. // This method is known as the 1/(n-1) split: // Send just one byte of payload in the first packet // to improve the initialization vectors in TLS 1.0. size = sizeof((packet->fragment = data[..0])); if (sizeof(data) > 1) { // If we have more data, take the opportunity to queue some of it too. send_packet(packet); packet = Packet(); packet->content_type = PACKET_application_data; size += sizeof((packet->fragment = data[1..max_packet_size-1])); } } else { size = sizeof ((packet->fragment = data[..max_packet_size-1])); } send_packet (packet); sent += size; return size; } protected int handle_alert(string s) { // sizeof(s)==2, checked at caller. int level = s[0]; int description = s[1]; if (! (ALERT_levels[level] && ALERT_descriptions[description])) { send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, "invalid alert\n")); return -1; } if (level == ALERT_fatal) { SSL3_DEBUG_MSG("SSL.connection: Fatal alert %d\n", description); return -1; } if (description == ALERT_close_notify) { SSL3_DEBUG_MSG("SSL.connection: Close notify alert %d\n", description); closing |= 2; return 1; } if (description == ALERT_no_certificate) { SSL3_DEBUG_MSG("SSL.connection: No certificate alert %d\n", description); if ((certificate_state == CERT_requested) && (context->auth_level == AUTHLEVEL_ask)) { certificate_state = CERT_no_certificate; return 0; } else { send_packet(Alert(ALERT_fatal, ((certificate_state == CERT_requested) ? ALERT_handshake_failure : ALERT_unexpected_message), "Certificate required.\n")); return -1; } } #ifdef SSL3_DEBUG else werror("SSL.connection: Received warning alert %d\n", description); #endif return 0; }
da33812004-01-14H. William Welliver III 
eb53bd2014-05-04Martin Nilsson int handle_change_cipher(int c) { if (!expect_change_cipher || (c != 1)) { SSL3_DEBUG_MSG("SSL.connection: handle_change_cipher: Unexcepted message!"); send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, "Unexpected change cipher!\n")); return -1; }
33ef431997-03-13Niels Möller  else
813b392000-08-04Andreas Sigfridsson  {
eb53bd2014-05-04Martin Nilsson  current_read_state = pending_read_state; expect_change_cipher = 0; return 0; } } void send_heartbeat() { if (!handshake_finished || (session->heartbeat_mode != HEARTBEAT_MODE_peer_allowed_to_send)) { // We're not allowed to send heartbeats. return; } ADT.struct hb_msg = ADT.struct(); hb_msg->put_uint(HEARTBEAT_MESSAGE_request, 1); hb_msg->put_uint(16, 2); int now = gethrtime(); hb_msg->put_fix_string(heartbeat_encode->crypt(sprintf("%8c%8c", now, now))); // We pad to an even 64 bytes. hb_msg->put_fix_string(random_string(64 - sizeof(hb_msg))); send_packet(heartbeat_packet(hb_msg->pop_data())); } void handle_heartbeat(string(8bit) s) { if (sizeof(s) < 19) return; // Minimum size for valid heartbeats. ADT.struct hb_msg = ADT.struct(s); int hb_type = hb_msg->get_uint(1); int hb_len = hb_msg->get_uint(2); SSL3_DEBUG_MSG("SSL.connection: Heartbeat %s (%d bytes)", fmt_constant(hb_type, "HEARTBEAT_MESSAGE"), hb_len); string(8bit) payload; int pad_len = 16; // RFC 6520 4: // If the payload_length of a received HeartbeatMessage is too // large, the received HeartbeatMessage MUST be discarded silently. if ((hb_len < 0) || ((hb_len + 16) > sizeof(hb_msg))) { #ifdef SSL3_SIMULATE_HEARTBLEED payload = hb_msg->get_rest(); if (sizeof(payload) < hb_len) { payload = payload + random_string(hb_len - sizeof(payload)); } else { payload = payload[..hb_len-1]; } #else return; #endif } else { payload = hb_msg->get_fix_string(hb_len); pad_len = sizeof(hb_msg); } switch(hb_type) { case HEARTBEAT_MESSAGE_request: // RFC 6520 4: // When a HeartbeatRequest message is received and sending a // HeartbeatResponse is not prohibited as described elsewhere in // this document, the receiver MUST send a corresponding // HeartbeatResponse message carrying an exact copy of the payload // of the received HeartbeatRequest. hb_msg = ADT.struct(); hb_msg->put_uint(HEARTBEAT_MESSAGE_response, 1); hb_msg->put_uint(hb_len, 2); hb_msg->put_fix_string(payload); hb_msg->put_fix_string(random_string(pad_len)); send_packet(heartbeat_packet(hb_msg->pop_data())); break; case HEARTBEAT_MESSAGE_response: // RFC 6520 4: // If a received HeartbeatResponse message does not contain the // expected payload, the message MUST be discarded silently. if ((sizeof(payload) == 16) && heartbeat_decode) { hb_msg = ADT.struct(heartbeat_decode->crypt(payload)); int a = hb_msg->get_uint(8); int b = hb_msg->get_uint(8); if (a != b) { if (!b) { // Heartbleed probe response. send_packet(Alert(ALERT_fatal, ALERT_insufficient_security, "Peer suffers from a bleeding heart.\n")); } break; } #ifdef SSL3_DEBUG int delta = gethrtime() - a; SSL3_DEBUG_MSG("SSL.connection: Heartbeat roundtrip: %dus\n", delta); #endif } break; default: break; } } string(8bit) alert_buffer = ""; string(8bit) handshake_buffer = ""; //! Main receive handler. Returns a string of received application //! data, or 1 if a close was received, or -1 if an error occurred. //! //! This function is intended to be called from an i/o read callback. string|int got_data(string|int s) { if(!stringp(s)) { return s; } if (closing & 2) { return 1; } // If closing == 1 we continue to try to read a remote close // message. That enables the caller to check for a clean close, and // to get the leftovers after the SSL connection. /* If alert_callback is called, this data is passed as an argument */ string alert_context = (left_over || "") + s; string res = ""; Packet packet; while (packet = recv_packet([string]s)) { s = ""; if (packet->is_alert) { /* Reply alert */ SSL3_DEBUG_MSG("SSL.connection: Bad received packet\n"); send_packet(packet); if (alert_callback) alert_callback(packet, current_read_state->seq_num, alert_context); if ((!packet) || (!this) || (packet->level == ALERT_fatal)) return -1; if (alert_callback) break; } else { SSL3_DEBUG_MSG("SSL.connection: received packet of type %d\n", packet->content_type); switch (packet->content_type) { case PACKET_alert: { SSL3_DEBUG_MSG("SSL.connection: ALERT\n"); int i; int err = 0; alert_buffer += packet->fragment; for (i = 0; !err && ((sizeof(alert_buffer) - i) >= 2); i+= 2) err = handle_alert(alert_buffer[i..i+1]); alert_buffer = alert_buffer[i..]; if (err) if (err > 0 && sizeof (res)) // If we get a close then we return the data we got so far. return res; else return err; break; } case PACKET_change_cipher_spec: { SSL3_DEBUG_MSG("SSL.connection: CHANGE_CIPHER_SPEC\n"); int i; int err; for (i = 0; (i < sizeof(packet->fragment)); i++) { err = handle_change_cipher(packet->fragment[i]); SSL3_DEBUG_MSG("tried change_cipher: %d\n", err); if (err) return err; } break; } case PACKET_handshake: { SSL3_DEBUG_MSG("SSL.connection: HANDSHAKE\n"); if (handshake_finished && !secure_renegotiation) { // Don't allow renegotiation in unsecure mode, to address // http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3555. // For details see: http://www.g-sec.lu/practicaltls.pdf and // RFC 5746. send_packet(Alert(ALERT_warning, ALERT_no_renegotiation, "Renegotiation not supported in unsecure mode.\n")); return -1; } if (expect_change_cipher) { /* No change_cipher message was received */ // FIXME: There's a bug somewhere since expect_change_cipher often // remains set after the handshake is completed. The effect is that // renegotiation doesn't work all the time. // // A side effect is that we are partly invulnerable to the // renegotiation vulnerability mentioned above. It is however not // safe to assume that, since there might be routes past this, // maybe through the use of a version 2 hello message below. send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, "Expected change cipher.\n")); return -1; } int err, len; handshake_buffer += packet->fragment; while (sizeof(handshake_buffer) >= 4) { sscanf(handshake_buffer, "%*c%3c", len); if (sizeof(handshake_buffer) < (len + 4)) break; err = handle_handshake(handshake_buffer[0], handshake_buffer[4..len + 3], handshake_buffer[.. len + 3]); handshake_buffer = handshake_buffer[len + 4..]; if (err < 0) return err; if (err > 0) { handshake_finished = 1; } } break; } case PACKET_application_data: SSL3_DEBUG_MSG("SSL.connection: APPLICATION_DATA\n"); if (!handshake_finished) { send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, "Handshake not finished yet!\n")); return -1; } res += packet->fragment; break; case PACKET_heartbeat: { // RFC 6520. SSL3_DEBUG_MSG("SSL.connection: Heartbeat.\n"); if (!handshake_finished) { // RFC 6520 3: // The receiving peer SHOULD discard the message silently, // if it arrives during the handshake. break; } if (!session->heartbeat_mode) { // RFC 6520 2: // If an endpoint that has indicated peer_not_allowed_to_send // receives a HeartbeatRequest message, the endpoint SHOULD // drop the message silently and MAY send an unexpected_message // Alert message. send_packet(Alert(ALERT_warning, ALERT_unexpected_message, "Heart beat mode not enabled.\n")); break; } handle_heartbeat(packet->fragment); } break; default: if (!handshake_finished) { send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, "Unexpected message during handshake!\n")); return -1; } // RFC 4346 6: // If a TLS implementation receives a record type it does not // understand, it SHOULD just ignore it. SSL3_DEBUG_MSG("SSL.connection: Ignoring packet of type %s\n", fmt_constant(packet->content_type, "PACKET")); break; } }
813b392000-08-04Andreas Sigfridsson  }
eb53bd2014-05-04Martin Nilsson  return closing & 2 ? 1 : res;
33ef431997-03-13Niels Möller }