370919 | 2002-03-20 | Martin Nilsson | | #pike __REAL_VERSION__
|
18c01f | 2004-01-25 | Martin Nilsson | | #pragma strict_types
|
e1fb09 | 2014-02-14 | Martin Nilsson | | #require constant(SSL.Cipher)
|
370919 | 2002-03-20 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
f5bb03 | 2001-09-17 | Martin Nilsson | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
f5bb03 | 2001-09-17 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
565b33 | 2014-05-17 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
fc7f09 | 2014-06-01 | Martin Nilsson | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
fc7f09 | 2014-06-01 | Martin Nilsson | |
|
c79dc1 | 2001-06-14 | Pär Svensson | |
|
4f5e1d | 2003-01-27 | Martin Nilsson | | import .Constants;
|
91f9c7 | 2014-05-15 | Martin Nilsson | | #define State .State
|
c65c58 | 2014-05-15 | Martin Nilsson | | #define Session .Session
|
dc90a5 | 2014-05-15 | Martin Nilsson | | #define Context .Context
|
33ef43 | 1997-03-13 | Niels Möller | |
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | #ifdef SSL3_DEBUG
|
624414 | 2003-01-27 | Martin Nilsson | | #define SSL3_DEBUG_MSG(X ...) werror(X)
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | #else /*! SSL3_DEBUG */
|
624414 | 2003-01-27 | Martin Nilsson | | #define SSL3_DEBUG_MSG(X ...)
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | #endif /* SSL3_DEBUG */
|
c65c58 | 2014-05-15 | Martin Nilsson | | Session session;
|
dc90a5 | 2014-05-15 | Martin Nilsson | | Context context;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
91f9c7 | 2014-05-15 | Martin Nilsson | | State pending_read_state;
State pending_write_state;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
5e3a14 | 2014-04-30 | Martin Nilsson | | int handshake_state;
|
77243d | 2014-11-22 | Henrik Grubbström (Grubba) | | int reuse;
|
33ef43 | 1997-03-13 | Niels Möller | |
constant CERT_none = 0;
constant CERT_requested = 1;
|
b1b57a | 1997-03-17 | Niels Möller | | constant CERT_received = 2;
|
33ef43 | 1997-03-13 | Niels Möller | | constant CERT_no_certificate = 3;
int certificate_state;
|
da1209 | 1998-08-26 | Niels Möller | | int expect_change_cipher;
|
87740f | 2011-01-10 | Henrik Grubbström (Grubba) | |
int secure_renegotiation;
|
2d4060 | 2014-05-16 | Martin Nilsson | | string(8bit) client_verify_data = "";
string(8bit) server_verify_data = "";
|
ca9498 | 2013-12-08 | Henrik Grubbström (Grubba) | |
|
87740f | 2011-01-10 | Henrik Grubbström (Grubba) | |
|
2f77da | 2013-11-23 | Henrik Grubbström (Grubba) | |
.Cipher.KeyExchange ke;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | ProtocolVersion version;
ProtocolVersion client_version;
|
88cfa1 | 2005-10-28 | H. William Welliver III | |
|
f5bb03 | 2001-09-17 | Martin Nilsson | |
|
2d4060 | 2014-05-16 | Martin Nilsson | | string(8bit) client_random;
string(8bit) server_random;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
08afc7 | 2014-05-01 | Martin Nilsson | | #define Packet .Packet
|
7f45cf | 2014-05-15 | Martin Nilsson | | #define Alert .Alert
|
47f84c | 2014-04-12 | Henrik Grubbström (Grubba) | |
|
231341 | 2020-02-01 | Tobias S. Josefowitz | | int(0..1) tickets_enabled = 0;
|
ad2363 | 2016-07-13 | Henrik Grubbström (Grubba) | |
|
aff04c | 2015-07-06 | Henrik Grubbström (Grubba) | |
string(8bit) application_protocol;
|
2d4060 | 2014-05-16 | Martin Nilsson | | Alert alert(int(1..2) level, int(8bit) description,
|
7f45cf | 2014-05-15 | Martin Nilsson | | string|void message)
|
47f84c | 2014-04-12 | Henrik Grubbström (Grubba) | | {
return context->alert_factory(this, level, description, version,
|
74b5eb | 2014-04-24 | Martin Nilsson | | message);
|
47f84c | 2014-04-12 | Henrik Grubbström (Grubba) | | }
|
47c33a | 2014-04-13 | Henrik Grubbström (Grubba) | | string(8bit) get_signature_algorithms()
{
ADT.struct sign_algs = ADT.struct();
|
cec12e | 2014-07-07 | Henrik Grubbström (Grubba) | | foreach(context->get_signature_algorithms(), [int hash, int sign])
|
ef87a8 | 2014-05-20 | Martin Nilsson | | {
sign_algs->put_uint(hash, 1);
sign_algs->put_uint(sign, 1);
|
47c33a | 2014-04-13 | Henrik Grubbström (Grubba) | | }
return sign_algs->pop_data();
}
|
c79dc1 | 2001-06-14 | Pär Svensson | | #ifdef SSL3_PROFILING
|
bc15c2 | 2014-05-02 | Martin Nilsson | | System.Timer timer = System.Timer();
|
c79dc1 | 2001-06-14 | Pär Svensson | | void addRecord(int t,int s) {
|
bc15c2 | 2014-05-02 | Martin Nilsson | | Stdio.stdout.write("time: %.6f sender: %d type: %s\n", timer->get(), s,
fmt_constant(t, "HANDSHAKE"));
|
c79dc1 | 2001-06-14 | Pär Svensson | | }
#endif
|
2d4060 | 2014-05-16 | Martin Nilsson | | string(8bit) handshake_messages;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
2d4060 | 2014-05-16 | Martin Nilsson | | Packet handshake_packet(int(8bit) type, string data)
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
c79dc1 | 2001-06-14 | Pär Svensson | | #ifdef SSL3_PROFILING
addRecord(type,1);
#endif
|
33ef43 | 1997-03-13 | Niels Möller | |
|
6dfd42 | 2014-08-07 | Martin Nilsson | | Packet packet = Packet(version);
|
33ef43 | 1997-03-13 | Niels Möller | | packet->content_type = PACKET_handshake;
|
2d4060 | 2014-05-16 | Martin Nilsson | | packet->fragment = sprintf("%1c%3H", type, [string(8bit)]data);
|
33ef43 | 1997-03-13 | Niels Möller | | handshake_messages += packet->fragment;
return packet;
}
|
b6345f | 2004-01-23 | Martin Nilsson | | Packet change_cipher_packet()
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
6dfd42 | 2014-08-07 | Martin Nilsson | | Packet packet = Packet(version);
|
33ef43 | 1997-03-13 | Niels Möller | | packet->content_type = PACKET_change_cipher_spec;
packet->fragment = "\001";
|
22d10b | 2016-07-15 | Henrik Grubbström (Grubba) | | expect_change_cipher++;
|
33ef43 | 1997-03-13 | Niels Möller | | return packet;
}
|
2d4060 | 2014-05-16 | Martin Nilsson | | string(8bit) hash_messages(string(8bit) sender)
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | if(version == PROTOCOL_SSL_3_0) {
|
1ff551 | 2014-03-29 | Martin Nilsson | | return .Cipher.MACmd5(session->master_secret)->hash(handshake_messages + sender) +
.Cipher.MACsha(session->master_secret)->hash(handshake_messages + sender);
|
aa77d5 | 2001-04-18 | Pär Svensson | | }
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | else if(version <= PROTOCOL_TLS_1_1) {
|
0791b1 | 2013-11-24 | Henrik Grubbström (Grubba) | | return session->cipher_spec->prf(session->master_secret, sender,
Crypto.MD5.hash(handshake_messages)+
Crypto.SHA1.hash(handshake_messages), 12);
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | } else if(version >= PROTOCOL_TLS_1_2) {
|
0791b1 | 2013-11-24 | Henrik Grubbström (Grubba) | | return session->cipher_spec->prf(session->master_secret, sender,
|
4b0f8e | 2013-12-04 | Henrik Grubbström (Grubba) | | session->cipher_spec->hash->hash(handshake_messages), 12);
|
aa77d5 | 2001-04-18 | Pär Svensson | | }
|
33ef43 | 1997-03-13 | Niels Möller | | }
|
2d4060 | 2014-05-16 | Martin Nilsson | | Packet certificate_packet(array(string(8bit)) certificates)
|
88cfa1 | 2005-10-28 | H. William Welliver III | | {
ADT.struct struct = ADT.struct();
|
dd722b | 2014-05-31 | Martin Nilsson | | struct->put_var_string_array(certificates, 3, 3);
|
88cfa1 | 2005-10-28 | H. William Welliver III | | return handshake_packet(HANDSHAKE_certificate, struct->pop_data());
}
|
ee3750 | 2014-05-04 | Martin Nilsson | | Packet heartbeat_packet(string(8bit) s)
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | {
|
6dfd42 | 2014-08-07 | Martin Nilsson | | Packet packet = Packet(version);
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | 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) {
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);
}
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)));
return heartbeat_packet(hb_msg->pop_data());
}
|
765567 | 2004-01-27 | H. William Welliver III | |
|
f591dd | 2004-01-29 | H. William Welliver III | |
|
b6345f | 2004-01-23 | Martin Nilsson | | int verify_certificate_chain(array(string) certs)
|
7e7821 | 2004-01-23 | H. William Welliver III | | {
|
526a40 | 2004-01-30 | H. William Welliver III | |
if(!context->verify_certificates)
return 1;
|
88cfa1 | 2005-10-28 | H. William Welliver III | |
if((context->auth_level < AUTHLEVEL_require) && !sizeof(certs))
return 1;
|
868f71 | 2012-05-20 | Martin Nilsson | |
|
88cfa1 | 2005-10-28 | H. William Welliver III | | if(!certs || !sizeof(certs))
return 0;
|
7e7821 | 2004-01-23 | H. William Welliver III | |
|
09aa4f | 2013-12-04 | Martin Nilsson | |
|
526a40 | 2004-01-30 | H. William Welliver III | | if(sizeof(context->authorities_cache))
|
7e7821 | 2004-01-23 | H. William Welliver III | | {
|
9cade8 | 2014-02-15 | Martin Nilsson | | string r=Standards.X509.decode_certificate(certs[-1])->issuer
|
09aa4f | 2013-12-04 | Martin Nilsson | | ->get_der();
int issuer_known = 0;
foreach(context->authorities_cache, string c)
|
7e7821 | 2004-01-23 | H. William Welliver III | | {
|
09aa4f | 2013-12-04 | Martin Nilsson | | if(r == c)
|
526a40 | 2004-01-30 | H. William Welliver III | | {
issuer_known = 1;
break;
}
|
7e7821 | 2004-01-23 | H. William Welliver III | | }
|
526a40 | 2004-01-30 | H. William Welliver III | | if(issuer_known==0)
{
return 0;
}
|
f591dd | 2004-01-29 | H. William Welliver III | | }
|
765567 | 2004-01-27 | H. William Welliver III | |
|
7e7821 | 2004-01-23 | H. William Welliver III | |
|
765567 | 2004-01-27 | H. William Welliver III | |
|
d13f3f | 2013-11-24 | Henrik Grubbström (Grubba) | | mapping result =
|
81bef2 | 2013-12-04 | Martin Nilsson | | Standards.X509.verify_certificate_chain(certs,
context->trusted_issuers_cache,
|
2883e0 | 2020-02-24 | Tobias S. Josefowitz | | context->require_trust,
([ "verifier_algorithms"
: context->verifier_algorithms]));
|
765567 | 2004-01-27 | H. William Welliver III | |
|
7194b8 | 2015-12-03 | Henrik Grubbström (Grubba) | |
session->cert_data = result;
|
05f3ec | 2015-12-04 | Henrik Grubbström (Grubba) | | if(result->verified && session->server_name &&
|
1adaf6 | 2015-12-04 | Henrik Grubbström (Grubba) | | sizeof([array](result->certificates || ({})))) {
|
05f3ec | 2015-12-04 | Henrik Grubbström (Grubba) | | array(Standards.X509.TBSCertificate) certs =
[array(Standards.X509.TBSCertificate)](result->certificates);
Standards.X509.TBSCertificate cert = certs[-1];
array(string) globs = Standards.PKCS.Certificate.
decode_distinguished_name(cert->subject)->commonName - ({ 0 });
if (cert->ext_subjectAltName_dNSName) {
globs += cert->ext_subjectAltName_dNSName;
|
78494b | 2015-12-03 | Henrik Grubbström (Grubba) | | }
|
f4d095 | 2020-01-21 | Tobias S. Josefowitz | |
array(string) split_server_name = lower_case(session->server_name) / ".";
result->verified = 0;
OUTER: foreach (map(globs, lower_case);; string the_glob) {
array(string) split_glob = the_glob / ".";
if (sizeof(split_glob) != sizeof(split_server_name))
continue;
foreach (split_glob; int i; string the_glob) {
if (!glob(the_glob, split_server_name[i]))
continue OUTER;
}
result->verified = 1;
break;
}
|
f591dd | 2004-01-29 | H. William Welliver III | | }
|
7e7821 | 2004-01-23 | H. William Welliver III | |
|
05f3ec | 2015-12-04 | Henrik Grubbström (Grubba) | | return [int(0..1)](result->verified);
|
7e7821 | 2004-01-23 | H. William Welliver III | | }
|
aa77d5 | 2001-04-18 | Pär Svensson | |
|
f5bb03 | 2001-09-17 | Martin Nilsson | |
|
4c0c47 | 2013-10-27 | Henrik Grubbström (Grubba) | |
|
3a5f8e | 2010-02-21 | Stephen R. van den Berg | |
|
5f883e | 2008-09-05 | Martin Stjernholm | |
|
2d4060 | 2014-05-16 | Martin Nilsson | | int(-1..1) handle_handshake(int type, string(8bit) data, string(8bit) raw);
|
33ef43 | 1997-03-13 | Niels Möller | |
|
4ceceb | 2014-05-05 | Henrik Grubbström (Grubba) | |
|
6262d4 | 2011-12-15 | Henrik Grubbström (Grubba) | |
|
dc90a5 | 2014-05-15 | Martin Nilsson | | protected void create(Context ctx)
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
91f9c7 | 2014-05-15 | Martin Nilsson | | current_read_state = State(this);
current_write_state = State(this);
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
f466b6 | 2014-04-04 | Henrik Grubbström (Grubba) | | if ((ctx->max_version < PROTOCOL_SSL_3_0) ||
(ctx->max_version > PROTOCOL_TLS_MAX)) {
ctx->max_version = PROTOCOL_TLS_MAX;
|
6262d4 | 2011-12-15 | Henrik Grubbström (Grubba) | | }
|
f466b6 | 2014-04-04 | Henrik 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;
|
6262d4 | 2011-12-15 | Henrik Grubbström (Grubba) | | }
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | version = ctx->max_version;
|
a30079 | 2003-10-24 | Martin Stjernholm | | context = ctx;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
91f9c7 | 2014-05-15 | Martin Nilsson | | State current_read_state;
State current_write_state;
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | string(8bit) left_over;
|
84b90d | 2014-05-04 | Martin Nilsson | | Packet packet;
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | | int sent;
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | |
ConnectionState state = CONNECTION_handshaking;
|
84b90d | 2014-05-04 | Martin Nilsson | |
function(object,int|object,string:void) alert_callback;
constant PRI_alert = 1;
constant PRI_urgent = 2;
constant PRI_application = 3;
|
7f45cf | 2014-05-15 | Martin Nilsson | | protected ADT.Queue alert_q = ADT.Queue();
protected ADT.Queue urgent_q = ADT.Queue();
protected ADT.Queue application_q = ADT.Queue();
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | |
string describe_state()
{
if (!state) return "ready";
array(string) res = ({});
|
d58c82 | 2019-10-11 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_handshaking) {
res += ({ "handshaking(" + fmt_constant(handshake_state, "STATE") + ")" });
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_local_failing) {
if (state & CONNECTION_local_fatal) {
res += ({ "local_fatal" });
} else {
res += ({ "local_failing" });
}
}
if (state & CONNECTION_local_closing) {
if (state & CONNECTION_local_closed) {
res += ({ "local_closed" });
} else {
res += ({ "local_closing" });
}
}
if (state & CONNECTION_peer_fatal) res += ({ "peer_fatal" });
if (state & CONNECTION_peer_closed) res += ({ "peer_closed" });
return res * "|";
}
|
423a55 | 2014-08-01 | Henrik Grubbström (Grubba) | | protected string _sprintf(int t)
{
if (t == 'O') return sprintf("SSL.Connection(%s)", describe_state());
}
|
84b90d | 2014-05-04 | Martin Nilsson | |
void set_alert_callback(function(object,int|object,string:void) callback)
{
alert_callback = callback;
}
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | protected Packet recv_packet(string(8bit) data)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | string(8bit)|Packet res;
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
938d51 | 2014-05-16 | Martin Nilsson | |
|
84b90d | 2014-05-04 | Martin Nilsson | | if (left_over || !packet)
{
|
6dfd42 | 2014-08-07 | Martin Nilsson | | packet = Packet(version, 2048);
res = packet->recv( (left_over || "") + data);
|
84b90d | 2014-05-04 | Martin Nilsson | | }
else
|
6dfd42 | 2014-08-07 | Martin Nilsson | | res = packet->recv(data);
|
84b90d | 2014-05-04 | Martin Nilsson | |
if (stringp(res))
{
left_over = [string]res;
if (current_read_state) {
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection->recv_packet(): version=0x%x\n",
|
84b90d | 2014-05-04 | Martin Nilsson | | version);
|
6dfd42 | 2014-08-07 | Martin Nilsson | | return current_read_state->decrypt_packet(packet);
|
84b90d | 2014-05-04 | Martin Nilsson | | } else {
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection->recv_packet(): current_read_state is zero!\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | return 0;
}
}
else
left_over = 0;
return [object]res;
}
|
31e650 | 2014-05-16 | Martin Nilsson | | void send_packet(Packet packet, int|void priority)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_local_closing) {
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection->send_packet: ignoring packet after close\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | return;
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (packet->content_type == PACKET_alert) {
if (packet->level == ALERT_fatal) {
state = [int(0..0)|ConnectionState](state | CONNECTION_local_failing);
} else if (packet->description == ALERT_close_notify) {
state = [int(0..0)|ConnectionState](state | CONNECTION_local_closing);
}
}
|
84b90d | 2014-05-04 | Martin Nilsson | |
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];
|
5c4191 | 2014-08-24 | Henrik Grubbström (Grubba) | |
if ((packet->content_type == PACKET_handshake) &&
(priority == PRI_application)) {
expect_change_cipher = 0;
certificate_state = 0;
state = [int(0..0)|ConnectionState](state | CONNECTION_handshaking);
handshake_state = STATE_wait_for_hello;
}
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection->send_packet: type %d, pri %d, %O\n",
|
31e650 | 2014-05-16 | Martin Nilsson | | packet->content_type, priority, packet->fragment[..5]);
|
84b90d | 2014-05-04 | Martin Nilsson | | switch (priority)
{
default:
error( "Internal error\n" );
case PRI_alert:
|
7f45cf | 2014-05-15 | Martin Nilsson | | alert_q->put(packet);
|
84b90d | 2014-05-04 | Martin Nilsson | | break;
case PRI_urgent:
|
7f45cf | 2014-05-15 | Martin Nilsson | | urgent_q->put(packet);
|
84b90d | 2014-05-04 | Martin Nilsson | | break;
case PRI_application:
|
7f45cf | 2014-05-15 | Martin Nilsson | | application_q->put(packet);
|
84b90d | 2014-05-04 | Martin Nilsson | | break;
}
}
|
02bb9d | 2014-07-13 | Henrik Grubbström (Grubba) | |
int query_write_queue_size()
{
return sizeof(alert_q) + sizeof(urgent_q) + sizeof(application_q);
}
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
02bb9d | 2014-07-13 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | | string|int to_write()
{
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_local_fatal)
|
84b90d | 2014-05-04 | Martin Nilsson | | return -1;
|
7f45cf | 2014-05-15 | Martin Nilsson | | Packet packet = [object(Packet)](alert_q->get() || urgent_q->get() ||
application_q->get());
|
84b90d | 2014-05-04 | Martin Nilsson | | if (!packet) {
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | return (state & CONNECTION_local_closing) ? 1 : "";
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: writing packet of type %d, %O\n",
|
84b90d | 2014-05-04 | Martin Nilsson | | packet->content_type, packet->fragment[..6]);
if (packet->content_type == PACKET_alert)
{
if (packet->level == ALERT_fatal) {
|
86fda2 | 2019-10-05 | Henrik Grubbström (Grubba) | | state = [int(0..0)|ConnectionState](state | CONNECTION_local_fatal);
|
84b90d | 2014-05-04 | Martin Nilsson | |
if (session) {
context->purge_session(session);
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | } else if (packet->description == ALERT_close_notify) {
state = [int(0..0)|ConnectionState](state | CONNECTION_local_closed);
|
84b90d | 2014-05-04 | Martin Nilsson | | }
}
|
6dfd42 | 2014-08-07 | Martin Nilsson | | string res = current_write_state->encrypt_packet(packet)->send();
|
84b90d | 2014-05-04 | Martin Nilsson | | if (packet->content_type == PACKET_change_cipher_spec)
current_write_state = pending_write_state;
return res;
}
void send_close()
{
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_warning, ALERT_close_notify,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Closing connection.\n"), PRI_application);
}
|
5c4191 | 2014-08-24 | Henrik Grubbström (Grubba) | |
void send_renegotiate();
|
84b90d | 2014-05-04 | Martin Nilsson | |
int send_streaming_data (string(8bit) data)
{
if (!sizeof(data)) return 0;
|
6dfd42 | 2014-08-07 | Martin Nilsson | | Packet packet = Packet(version);
|
84b90d | 2014-05-04 | Martin Nilsson | | 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)) {
size = sizeof((packet->fragment = data[..0]));
if (sizeof(data) > 1) {
send_packet(packet);
|
6dfd42 | 2014-08-07 | Martin Nilsson | | packet = Packet(version);
|
84b90d | 2014-05-04 | Martin Nilsson | | 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)
{
int level = s[0];
int description = s[1];
if (! (ALERT_levels[level] && ALERT_descriptions[description]))
{
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "invalid alert\n"));
return -1;
}
if (level == ALERT_fatal)
{
|
a03254 | 2014-05-19 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Fatal alert %O\n",
ALERT_descriptions[description]);
|
99a21b | 2014-10-14 | Henrik Grubbström (Grubba) | | state = [int(0..0)|ConnectionState](state | CONNECTION_peer_fatal |
CONNECTION_peer_closed);
|
d90b88 | 2014-12-05 | Henrik Grubbström (Grubba) | |
if (session) {
context->purge_session(session);
}
|
84b90d | 2014-05-04 | Martin Nilsson | | return -1;
}
if (description == ALERT_close_notify)
{
|
a03254 | 2014-05-19 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: %O\n", ALERT_descriptions[description]);
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | state = [int(0..0)|ConnectionState](state | CONNECTION_peer_closed);
|
84b90d | 2014-05-04 | Martin Nilsson | | return 1;
}
if (description == ALERT_no_certificate)
{
|
a03254 | 2014-05-19 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: %O\n", ALERT_descriptions[description]);
|
84b90d | 2014-05-04 | Martin Nilsson | |
if ((certificate_state == CERT_requested) && (context->auth_level == AUTHLEVEL_ask))
{
certificate_state = CERT_no_certificate;
return 0;
} else {
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal,
|
84b90d | 2014-05-04 | Martin Nilsson | | ((certificate_state == CERT_requested)
? ALERT_handshake_failure
: ALERT_unexpected_message),
"Certificate required.\n"));
return -1;
}
}
#ifdef SSL3_DEBUG
else
|
a03254 | 2014-05-19 | Martin Nilsson | | werror("SSL.Connection: Received warning alert %O\n",
ALERT_descriptions[description]);
|
84b90d | 2014-05-04 | Martin Nilsson | | #endif
return 0;
}
|
da3381 | 2004-01-14 | H. William Welliver III | |
|
84b90d | 2014-05-04 | Martin Nilsson | | int handle_change_cipher(int c)
{
if (!expect_change_cipher || (c != 1))
{
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Unexpected change cipher!\n"));
return -1;
}
|
33ef43 | 1997-03-13 | Niels Möller | | else
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | {
|
84b90d | 2014-05-04 | Martin Nilsson | | current_read_state = pending_read_state;
|
22d10b | 2016-07-15 | Henrik Grubbström (Grubba) | | expect_change_cipher--;
|
84b90d | 2014-05-04 | Martin Nilsson | | return 0;
}
}
void send_heartbeat()
{
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if ((state != CONNECTION_ready) ||
|
84b90d | 2014-05-04 | Martin Nilsson | | (session->heartbeat_mode != HEARTBEAT_MODE_peer_allowed_to_send)) {
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)));
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;
ADT.struct hb_msg = ADT.struct(s);
int hb_type = hb_msg->get_uint(1);
int hb_len = hb_msg->get_uint(2);
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Heartbeat %s (%d bytes)",
|
84b90d | 2014-05-04 | Martin Nilsson | | fmt_constant(hb_type, "HEARTBEAT_MESSAGE"), hb_len);
string(8bit) payload;
int pad_len = 16;
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:
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:
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) {
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_insufficient_security,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Peer suffers from a bleeding heart.\n"));
}
break;
}
#ifdef SSL3_DEBUG
int delta = gethrtime() - a;
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Heartbeat roundtrip: %dus\n", delta);
|
84b90d | 2014-05-04 | Martin Nilsson | | #endif
}
break;
default:
break;
}
}
string(8bit) alert_buffer = "";
string(8bit) handshake_buffer = "";
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | string(8bit)|int got_data(string(8bit) data)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
eca80f | 2020-02-01 | Tobias S. Josefowitz | | if (state & (CONNECTION_peer_closed|CONNECTION_local_fatal)) {
|
84b90d | 2014-05-04 | Martin Nilsson | | return 1;
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
3f200d | 2015-04-13 | Martin Nilsson | |
string(8bit) alert_context = (left_over || "") + data;
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | string(8bit) res = "";
|
84b90d | 2014-05-04 | Martin Nilsson | | Packet packet;
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | while (packet = recv_packet(data))
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | data = "";
|
84b90d | 2014-05-04 | Martin Nilsson | |
if (packet->is_alert)
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Bad received packet\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | if (alert_callback)
|
3f200d | 2015-04-13 | Martin Nilsson | | alert_callback(packet, current_read_state->seq_num, alert_context);
|
0b0048 | 2014-11-13 | Henrik Grubbström (Grubba) | | if (this && packet)
send_packet(packet);
|
84b90d | 2014-05-04 | Martin Nilsson | | if ((!packet) || (!this) || (packet->level == ALERT_fatal))
return -1;
if (alert_callback)
break;
}
else
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: received packet of type %d\n",
|
84b90d | 2014-05-04 | Martin Nilsson | | packet->content_type);
switch (packet->content_type)
{
case PACKET_alert:
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: ALERT\n");
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
0844c2 | 2014-08-05 | Martin Nilsson | | if( !sizeof(packet->fragment) )
{
send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
"Zero length Alert fragments not allowed.\n"));
return -1;
}
|
84b90d | 2014-05-04 | Martin Nilsson | | 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))
return res;
else
return err;
break;
}
case PACKET_change_cipher_spec:
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: CHANGE_CIPHER_SPEC\n");
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
0844c2 | 2014-08-05 | Martin Nilsson | | if( !sizeof(packet->fragment) )
{
send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
"Zero length ChangeCipherSpec fragments not allowed.\n"));
return -1;
}
|
5cbf61 | 2014-08-05 | Martin Nilsson | | foreach(packet->fragment;; int c)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
5cbf61 | 2014-08-05 | Martin Nilsson | | int err = handle_change_cipher(c);
|
84b90d | 2014-05-04 | Martin Nilsson | | SSL3_DEBUG_MSG("tried change_cipher: %d\n", err);
if (err)
return err;
}
break;
}
case PACKET_handshake:
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: HANDSHAKE\n");
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
0844c2 | 2014-08-05 | Martin Nilsson | | if( !sizeof(packet->fragment) )
{
send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
"Zero length Handshake fragments not allowed.\n"));
return -1;
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (!(state & CONNECTION_handshaking) &&
!secure_renegotiation) {
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_warning, ALERT_no_renegotiation,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Renegotiation not supported in unsecure mode.\n"));
return -1;
}
if (expect_change_cipher)
{
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "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;
|
6f35e9 | 2014-05-05 | Martin Nilsson | | mixed exception = catch {
err = handle_handshake(handshake_buffer[0],
handshake_buffer[4..len + 3],
handshake_buffer[.. len + 3]);
};
if( exception )
{
if( objectp(exception) && ([object]exception)->ADT_struct )
{
Error.Generic e = [object(Error.Generic)]exception;
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_decode_error,
|
6f35e9 | 2014-05-05 | Martin Nilsson | | e->message()));
return -1;
}
throw(exception);
}
|
84b90d | 2014-05-04 | Martin Nilsson | | handshake_buffer = handshake_buffer[len + 4..];
if (err < 0)
return err;
if (err > 0) {
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | state &= ~CONNECTION_handshaking;
|
fff7fa | 2015-03-31 | Martin Nilsson | | if( expect_change_cipher && sizeof(handshake_buffer) )
{
send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
"Extraneous handshake packets.\n"));
return -1;
}
if( !secure_renegotiation && sizeof(handshake_buffer) )
{
send_packet(alert(ALERT_fatal, ALERT_no_renegotiation,
"Renegotiation not supported in unsecure "
"mode.\n"));
return -1;
}
|
84b90d | 2014-05-04 | Martin Nilsson | | }
}
break;
}
case PACKET_application_data:
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: APPLICATION_DATA\n");
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_handshaking)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Handshake not finished yet!\n"));
return -1;
}
res += packet->fragment;
break;
case PACKET_heartbeat:
{
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Heartbeat.\n");
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state != CONNECTION_ready) {
|
84b90d | 2014-05-04 | Martin Nilsson | |
break;
}
if (!session->heartbeat_mode) {
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_warning, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Heart beat mode not enabled.\n"));
break;
}
|
6f35e9 | 2014-05-05 | Martin Nilsson | |
mixed exception = catch {
handle_heartbeat(packet->fragment);
};
if( exception )
{
if( objectp(exception) && ([object]exception)->ADT_struct )
{
Error.Generic e = [object(Error.Generic)]exception;
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_decode_error,
|
6f35e9 | 2014-05-05 | Martin Nilsson | | e->message()));
return -1;
}
throw(exception);
}
|
84b90d | 2014-05-04 | Martin Nilsson | | }
break;
default:
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_handshaking)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
7f45cf | 2014-05-15 | Martin Nilsson | | send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
|
84b90d | 2014-05-04 | Martin Nilsson | | "Unexpected message during handshake!\n"));
return -1;
}
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Ignoring packet of type %s\n",
|
84b90d | 2014-05-04 | Martin Nilsson | | fmt_constant(packet->content_type, "PACKET"));
break;
}
}
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | }
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | if (sizeof(res)) return res;
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_peer_closed) return 1;
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | return "";
|
33ef43 | 1997-03-13 | Niels Möller | | }
|