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 | |
|
3c859d | 2015-02-25 | Martin Nilsson | | #include "tls.h"
|
4f5e1d | 2003-01-27 | Martin Nilsson | | import .Constants;
|
3f2ef0 | 2015-01-05 | Henrik Grubbström (Grubba) | |
private constant State = .State;
private constant Session = .Session;
private constant Context = .Context;
private constant Buffer = .Buffer;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
c65c58 | 2014-05-15 | Martin Nilsson | | Session session;
|
dc90a5 | 2014-05-15 | Martin Nilsson | | Context context;
|
33ef43 | 1997-03-13 | Niels Möller | |
|
1604ca | 2015-01-10 | Henrik Grubbström (Grubba) | | array(State) pending_read_state = ({});
array(State) pending_write_state = ({});
|
33ef43 | 1997-03-13 | Niels Möller | |
|
5e3a14 | 2014-04-30 | Martin Nilsson | | int handshake_state;
|
b9909a | 2015-01-06 | Henrik Grubbström (Grubba) | | int previous_handshake;
|
fab1c6 | 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 | |
|
3f2ef0 | 2015-01-05 | Henrik Grubbström (Grubba) | | private constant Packet = .Packet;
private constant Alert = .Alert;
|
47f84c | 2014-04-12 | Henrik Grubbström (Grubba) | |
|
bf53f3 | 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) | | }
|
9eb76c | 2014-11-24 | Martin Nilsson | | Buffer get_signature_algorithms()
|
47c33a | 2014-04-13 | Henrik Grubbström (Grubba) | | {
|
7d5500 | 2014-11-24 | Martin Nilsson | | Buffer sign_algs = Buffer();
|
cec12e | 2014-07-07 | Henrik Grubbström (Grubba) | | foreach(context->get_signature_algorithms(), [int hash, int sign])
|
ef87a8 | 2014-05-20 | Martin Nilsson | | {
|
16d2f1 | 2014-11-21 | Martin Nilsson | | sign_algs->add_int(hash, 1);
sign_algs->add_int(sign, 1);
|
47c33a | 2014-04-13 | Henrik Grubbström (Grubba) | | }
|
9eb76c | 2014-11-24 | Martin Nilsson | | return sign_algs;
|
47c33a | 2014-04-13 | Henrik Grubbström (Grubba) | | }
|
c79dc1 | 2001-06-14 | Pär Svensson | | #ifdef SSL3_PROFILING
|
bc15c2 | 2014-05-02 | Martin Nilsson | | System.Timer timer = System.Timer();
|
e52ddd | 2015-03-31 | Martin Nilsson | | float last_time = 0.0;
|
c79dc1 | 2001-06-14 | Pär Svensson | | void addRecord(int t,int s) {
|
e52ddd | 2015-03-31 | Martin Nilsson | | addRecord(sprintf("sender: %d type: %s", s, fmt_constant(t, "HANDSHAKE")));
}
variant void addRecord(string label) {
float stamp = timer->peek();
Stdio.stdout.write("time: %.6f (%.6f) %s\n", stamp, stamp-last_time, label);
last_time = stamp;
|
c79dc1 | 2001-06-14 | Pär Svensson | | }
#endif
|
a23931 | 2015-04-15 | Martin Nilsson | | Buffer handshake_messages = Buffer();
protected void add_handshake_message(Buffer|Stdio.Buffer|string(8bit) data)
{
handshake_messages->add(data);
}
|
33ef43 | 1997-03-13 | Niels Möller | |
|
3f2ef0 | 2015-01-05 | Henrik Grubbström (Grubba) | | Packet handshake_packet(int(8bit) type,
string(8bit)|Buffer|object(Stdio.Buffer) data)
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
c79dc1 | 2001-06-14 | Pär Svensson | | #ifdef SSL3_PROFILING
addRecord(type,1);
#endif
|
f404dd | 2015-04-15 | Martin Nilsson | | string(8bit) str = sprintf("%1c%3H", type, (string(8bit))data);
|
a23931 | 2015-04-15 | Martin Nilsson | | add_handshake_message(str);
|
09f63c | 2014-11-25 | Martin Nilsson | |
|
f404dd | 2015-04-15 | Martin Nilsson | |
return Packet(version, PACKET_handshake, str);
|
33ef43 | 1997-03-13 | Niels Möller | | }
|
b6345f | 2004-01-23 | Martin Nilsson | | Packet change_cipher_packet()
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
1604ca | 2015-01-10 | Henrik Grubbström (Grubba) | | expect_change_cipher++;
|
4d1537 | 2014-11-25 | Martin Nilsson | | return Packet(version, PACKET_change_cipher_spec, "\001");
|
33ef43 | 1997-03-13 | Niels Möller | | }
|
33aabf | 2015-01-11 | Henrik Grubbström (Grubba) | | string(8bit) hash_messages(string(8bit) sender, int|void len)
|
33ef43 | 1997-03-13 | Niels Möller | | {
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | if(version == PROTOCOL_SSL_3_0) {
|
a23931 | 2015-04-15 | Martin Nilsson | | string(8bit) data = (string(8bit))handshake_messages + sender;
|
e52ddd | 2015-03-31 | Martin Nilsson | | return .Cipher.MACmd5(session->master_secret)->hash(data) +
|
2a87c8 | 2014-11-26 | Martin Nilsson | | .Cipher.MACsha(session->master_secret)->hash(data);
|
aa77d5 | 2001-04-18 | Pär Svensson | | }
|
68b67e | 2014-04-05 | Henrik Grubbström (Grubba) | | else if(version <= PROTOCOL_TLS_1_1) {
|
e52ddd | 2015-03-31 | Martin Nilsson | | return session->cipher_spec->prf(session->master_secret, sender,
|
0791b1 | 2013-11-24 | Henrik Grubbström (Grubba) | | Crypto.MD5.hash(handshake_messages)+
Crypto.SHA1.hash(handshake_messages), 12);
|
aa77d5 | 2001-04-18 | Pär Svensson | | }
|
e52ddd | 2015-03-31 | Martin Nilsson | | return session->cipher_spec->prf(session->master_secret, sender,
session->cipher_spec->hash
|
00ec6a | 2015-07-31 | Martin Nilsson | | ->hash(handshake_messages),
|
e52ddd | 2015-03-31 | Martin Nilsson | | len || 12);
|
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 | | {
|
09f63c | 2014-11-25 | Martin Nilsson | | return handshake_packet(HANDSHAKE_certificate,
Buffer()->add_string_array(certificates, 3, 3));
|
88cfa1 | 2005-10-28 | H. William Welliver III | | }
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | Packet certificate_verify_packet(string(8bit)|void signature_context)
|
2e19a4 | 2014-12-30 | Henrik Grubbström (Grubba) | | {
SSL3_DEBUG_MSG("SSL.Connection: CERTIFICATE_VERIFY\n"
"%O: handshake_messages: %d bytes.\n",
|
f960bd | 2015-07-31 | Martin Nilsson | | this, sizeof(handshake_messages));
|
2e19a4 | 2014-12-30 | Henrik Grubbström (Grubba) | | Buffer struct = Buffer();
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | if (signature_context) {
session->cipher_spec->sign(session,
signature_context +
session->cipher_spec->hash
|
00ec6a | 2015-07-31 | Martin Nilsson | | ->hash(handshake_messages),
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | struct);
} else {
|
a23931 | 2015-04-15 | Martin Nilsson | | session->cipher_spec->sign(session, (string(8bit))handshake_messages, struct);
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | }
|
2e19a4 | 2014-12-30 | Henrik Grubbström (Grubba) | |
return handshake_packet(HANDSHAKE_certificate_verify, struct);
}
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | int(-1..0) validate_certificate_verify(Buffer input,
string(8bit) signature_context)
{
int(0..1) verification_ok;
|
a23931 | 2015-04-15 | Martin Nilsson | | string(8bit) signed = (string(8bit))handshake_messages;
|
82a77e | 2015-04-04 | Martin Nilsson | | if (version >= PROTOCOL_TLS_1_3)
signed = signature_context + session->cipher_spec->hash->hash(signed);
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | mixed err = catch {
verification_ok = session->cipher_spec->verify(
|
82a77e | 2015-04-04 | Martin Nilsson | | session, signed, input);
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | };
#ifdef SSL3_DEBUG
if (err) {
master()->handle_error(err);
}
#endif
err = UNDEFINED;
|
1e3a13 | 2015-02-25 | Martin Nilsson | | COND_FATAL(!verification_ok, ALERT_unexpected_message,
"Validation of CertificateVerify failed.\n");
|
5321c2 | 2015-01-18 | Henrik Grubbström (Grubba) | | return 0;
}
|
09f63c | 2014-11-25 | Martin Nilsson | | Packet heartbeat_packet(Buffer s)
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | {
|
09f63c | 2014-11-25 | Martin Nilsson | | return Packet(version, PACKET_heartbeat, s->read());
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | }
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);
}
|
7d5500 | 2014-11-24 | Martin Nilsson | | Buffer hb_msg = Buffer();
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add_int(HEARTBEAT_MESSAGE_request, 1);
hb_msg->add_int(16, 2);
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | int now = gethrtime();
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add(heartbeat_encode->crypt(sprintf("%8c%8c", now, 0)));
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | |
|
09f63c | 2014-11-25 | Martin Nilsson | | return heartbeat_packet(hb_msg);
|
978f57 | 2014-04-14 | Henrik Grubbström (Grubba) | | }
|
0f48d7 | 2014-12-21 | Martin Nilsson | |
|
0a6d7b | 2015-01-26 | Martin Nilsson | | private array(Standards.X509.TBSCertificate)
verify_certificate_chain(array(string) certs)
|
7e7821 | 2004-01-23 | H. William Welliver III | | {
|
0f48d7 | 2014-12-21 | Martin Nilsson | |
|
d67d3e | 2015-02-27 | Martin Nilsson | |
|
88cfa1 | 2005-10-28 | H. William Welliver III | | if((context->auth_level < AUTHLEVEL_require) && !sizeof(certs))
|
0a6d7b | 2015-01-26 | Martin Nilsson | | return ({});
|
88cfa1 | 2005-10-28 | H. William Welliver III | |
|
0f48d7 | 2014-12-21 | Martin Nilsson | |
|
868f71 | 2012-05-20 | Martin Nilsson | |
|
0f48d7 | 2014-12-21 | Martin Nilsson | | if(!sizeof(certs))
|
88cfa1 | 2005-10-28 | H. William Welliver III | | return 0;
|
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 | | }
|
d67d3e | 2015-02-27 | Martin Nilsson | |
|
765567 | 2004-01-27 | H. William Welliver III | |
|
d67d3e | 2015-02-27 | Martin Nilsson | |
|
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,
|
d13f3f | 2013-11-24 | Henrik Grubbström (Grubba) | | context->require_trust);
|
765567 | 2004-01-27 | H. William Welliver III | | if(result->verified)
|
f591dd | 2004-01-29 | H. William Welliver III | | {
|
81bef2 | 2013-12-04 | Martin Nilsson | |
|
f591dd | 2004-01-29 | H. William Welliver III | | session->cert_data = result;
|
0a6d7b | 2015-01-26 | Martin Nilsson | | return [array(Standards.X509.TBSCertificate)]result->certificates;
|
f591dd | 2004-01-29 | H. William Welliver III | | }
|
7e7821 | 2004-01-23 | H. William Welliver III | |
|
0f1158 | 2015-01-19 | Martin Nilsson | | return 0;
|
7e7821 | 2004-01-23 | H. William Welliver III | | }
|
aa77d5 | 2001-04-18 | Pär Svensson | |
|
d7ffcb | 2015-01-26 | Martin Nilsson | |
|
0a6d7b | 2015-01-26 | Martin Nilsson | | int(0..1) handle_certificates(Buffer packet)
|
d7ffcb | 2015-01-26 | Martin Nilsson | | {
|
0a6d7b | 2015-01-26 | Martin Nilsson | | Stdio.Buffer input = packet->read_hbuffer(3);
|
d7ffcb | 2015-01-26 | Martin Nilsson | | array(string(8bit)) certs = ({ });
while(sizeof(input))
certs += ({ input->read_hstring(3) });
|
0a6d7b | 2015-01-26 | Martin Nilsson | | if(sizeof(packet))
{
send_packet(alert(ALERT_fatal, ALERT_unexpected_message,
"Unknown additional data in packet.\n"));
return 0;
}
array(Standards.X509.TBSCertificate) decoded =
verify_certificate_chain(certs);
if( !decoded )
|
d7ffcb | 2015-01-26 | Martin Nilsson | | {
send_packet(alert(ALERT_fatal, ALERT_bad_certificate,
|
5e4739 | 2015-01-27 | Martin Nilsson | | "Bad certificate chain.\n"));
|
d7ffcb | 2015-01-26 | Martin Nilsson | | return 0;
}
if( !sizeof(certs) )
return 1;
|
9ad63b | 2015-01-26 | Martin Nilsson | |
|
d7ffcb | 2015-01-26 | Martin Nilsson | | session->peer_certificate_chain = certs;
|
0a6d7b | 2015-01-26 | Martin Nilsson | | session->peer_public_key = decoded[-1]->public_key->pkc;
|
d7ffcb | 2015-01-26 | Martin Nilsson | | #if constant(Crypto.ECC.Curve)
|
0a6d7b | 2015-01-26 | Martin Nilsson | | if (session->peer_public_key->get_curve) {
session->curve =
([object(Crypto.ECC.Curve.ECDSA)]session->peer_public_key)->
get_curve();
|
d7ffcb | 2015-01-26 | Martin Nilsson | | }
|
0a6d7b | 2015-01-26 | Martin Nilsson | | #endif
|
d7ffcb | 2015-01-26 | Martin Nilsson | |
return 1;
}
|
72a2d0 | 2015-01-06 | Henrik Grubbström (Grubba) | |
void new_cipher_states();
void derive_master_secret(string(8bit) premaster_secret)
{
SSL3_DEBUG_MSG("%O: derive_master_secret: %s (%s)\n",
|
76cd91 | 2015-01-11 | Henrik Grubbström (Grubba) | | this, fmt_constant(handshake_state, "STATE"),
|
72a2d0 | 2015-01-06 | Henrik Grubbström (Grubba) | | fmt_version(version));
|
76cd91 | 2015-01-11 | Henrik Grubbström (Grubba) | | if (version >= PROTOCOL_TLS_1_3) {
switch(handshake_state) {
case STATE_wait_for_hello:
case STATE_wait_for_key_share:
session->master_secret = premaster_secret;
session->master_secret = hash_messages("handshake master secret", 48);
break;
case STATE_wait_for_finish:
session->master_secret = premaster_secret;
session->master_secret = hash_messages("extended master secret", 48);
break;
default:
error("Unexpected handshake state: %s\n",
fmt_constant(handshake_state, "STATE"));
break;
}
|
19a2f1 | 2015-01-24 | Henrik Grubbström (Grubba) | | } else if (!sizeof(premaster_secret)) {
session->master_secret = "";
|
1b04c7 | 2015-02-22 | Henrik Grubbström (Grubba) | | } else if (session->extended_master_secret) {
session->master_secret = premaster_secret;
session->master_secret = hash_messages("extended master secret", 48);
|
76cd91 | 2015-01-11 | Henrik Grubbström (Grubba) | | } else {
session->master_secret =
session->cipher_spec->prf(premaster_secret, "master secret",
client_random + server_random, 48);
}
|
72a2d0 | 2015-01-06 | Henrik Grubbström (Grubba) | |
new_cipher_states();
|
76cd91 | 2015-01-11 | Henrik Grubbström (Grubba) | |
if ((version >= PROTOCOL_TLS_1_3) &&
(handshake_state == STATE_wait_for_finish)) {
session->master_secret = premaster_secret;
session->master_secret = hash_messages("resumption premaster secret", 48);
}
|
72a2d0 | 2015-01-06 | Henrik Grubbström (Grubba) | | }
|
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 | |
|
af9ae2 | 2015-03-30 | Martin Nilsson | | int(-1..1) handle_handshake(int type, Buffer input, Stdio.Buffer 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 | | }
|
00e5f2 | 2015-08-05 | Henrik Grubbström (Grubba) | |
void shutdown()
{
current_read_state = current_write_state = UNDEFINED;
pending_read_state = pending_write_state = ({});
ke = UNDEFINED;
alert_callback = UNDEFINED;
}
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
91f9c7 | 2014-05-15 | Martin Nilsson | | State current_read_state;
State current_write_state;
|
1396b1 | 2015-03-31 | Martin Nilsson | | Stdio.Buffer read_buffer = Stdio.Buffer();
|
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 = ({});
if (state & CONNECTION_handshaking) res += ({ "handshaking" });
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;
}
|
59a60b | 2015-04-13 | Martin Nilsson | | protected Packet recv_packet()
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
1396b1 | 2015-03-31 | Martin Nilsson | | if (!packet)
|
6dfd42 | 2014-08-07 | Martin Nilsson | | packet = Packet(version, 2048);
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
6a935b | 2015-04-13 | Martin Nilsson | | int res = packet->recv(read_buffer);
|
1396b1 | 2015-03-31 | Martin Nilsson | |
|
6a935b | 2015-04-13 | Martin Nilsson | | switch(res)
{
case 1:
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);
|
6a935b | 2015-04-13 | Martin Nilsson | | return current_read_state->decrypt_packet(packet);
case 0:
SSL3_DEBUG_MSG("SSL.Connection->recv_packet(): current_read_state is zero!\n");
return 0;
case -1:
return alert(ALERT_fatal, ALERT_unexpected_message);
default:
error("Internal error.\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
1396b1 | 2015-03-31 | Martin Nilsson | | return 0;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
31e650 | 2014-05-16 | Martin Nilsson | | void send_packet(Packet packet, int|void priority)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
b7459d | 2015-04-05 | Henrik Grubbström (Grubba) | | if (state & (CONNECTION_local_closed | CONNECTION_local_failing)) {
SSL3_DEBUG_MSG("send_packet: Ignoring packet after close/fail.\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | return;
}
|
7197b0 | 2015-04-22 | Martin Nilsson | | session->last_activity = time(1);
|
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,
|
b492c8 | 2014-11-25 | Martin Nilsson | | 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;
|
b9909a | 2015-01-06 | Henrik Grubbström (Grubba) | | previous_handshake = 0;
|
5c4191 | 2014-08-24 | Henrik Grubbström (Grubba) | | }
|
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);
}
|
3f605c | 2015-03-31 | Martin Nilsson | |
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
02bb9d | 2014-07-13 | Henrik Grubbström (Grubba) | |
|
3f605c | 2015-03-31 | Martin Nilsson | | int(-1..2) to_write(Stdio.Buffer output)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
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());
|
e28e03 | 2015-03-31 | Martin Nilsson | | if (!packet)
return !!(state & CONNECTION_local_closing);
|
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) {
|
6fda6f | 2014-10-14 | Henrik Grubbström (Grubba) | | state = [int(0..0)|ConnectionState](state | CONNECTION_local_fatal |
CONNECTION_peer_closed);
|
00e5f2 | 2015-08-05 | Henrik Grubbström (Grubba) | | current_read_state = UNDEFINED;
pending_read_state = ({});
|
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 | | }
}
|
504fc6 | 2015-03-31 | Martin Nilsson | | packet = current_write_state->encrypt_packet(packet, context);
|
520815 | 2015-01-09 | Henrik Grubbström (Grubba) | | if (packet->content_type == PACKET_change_cipher_spec) {
|
1604ca | 2015-01-10 | Henrik Grubbström (Grubba) | | if (sizeof(pending_write_state)) {
current_write_state = pending_write_state[0];
pending_write_state = pending_write_state[1..];
} else {
error("Invalid Change Cipher Spec.\n");
}
|
520815 | 2015-01-09 | Henrik Grubbström (Grubba) | | if (version >= PROTOCOL_TLS_1_3) {
|
3f605c | 2015-03-31 | Martin Nilsson | | return 2;
|
520815 | 2015-01-09 | Henrik Grubbström (Grubba) | | }
}
|
504fc6 | 2015-03-31 | Martin Nilsson | |
|
3f605c | 2015-03-31 | Martin Nilsson | | packet->send(output);
return 2;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
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)
{
|
b5c591 | 2014-11-25 | Martin Nilsson | | int size = sizeof(data);
if (!size) return 0;
|
84b90d | 2014-05-04 | Martin Nilsson | | if ((!sent) && (version < PROTOCOL_TLS_1_1) &&
|
b5c591 | 2014-11-25 | Martin Nilsson | | (session->cipher_spec->cipher_type == CIPHER_block) &&
(size>1))
{
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
b5c591 | 2014-11-25 | Martin Nilsson | | send_packet(Packet(version, PACKET_application_data, data[..0]));
data = data[1..];
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
b5c591 | 2014-11-25 | Martin Nilsson | |
send_packet(Packet(version, PACKET_application_data,
data[..session->max_packet_size-1]));;
|
84b90d | 2014-05-04 | Martin Nilsson | | sent += size;
return size;
}
|
0bf845 | 2015-03-31 | Martin Nilsson | |
protected int(-1..1) handle_alert(string s)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
int level = s[0];
int description = s[1];
|
1e3a13 | 2015-02-25 | Martin Nilsson | | COND_FATAL(!(ALERT_levels[level] && ALERT_descriptions[description]),
ALERT_unexpected_message, "Invalid alert\n");
|
b3fa86 | 2015-04-05 | Martin Nilsson | |
COND_FATAL((ALERT_deprecated[description] &&
ALERT_deprecated[description] < version),
ALERT_unexpected_message, "Deprecated alert\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | if (level == ALERT_fatal)
{
|
a03254 | 2014-05-19 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Fatal alert %O\n",
ALERT_descriptions[description]);
|
6fda6f | 2014-10-14 | Henrik Grubbström (Grubba) | | state = [int(0..0)|ConnectionState](state | CONNECTION_peer_fatal |
CONNECTION_peer_closed);
|
9e98b9 | 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 | |
|
b492c8 | 2014-11-25 | Martin Nilsson | | if ( (certificate_state == CERT_requested) &&
(context->auth_level == AUTHLEVEL_ask) )
|
84b90d | 2014-05-04 | Martin Nilsson | | {
certificate_state = CERT_no_certificate;
return 0;
} else {
|
1e3a13 | 2015-02-25 | Martin Nilsson | | COND_FATAL(1, ((certificate_state == CERT_requested)
? ALERT_handshake_failure
: ALERT_unexpected_message),
"Certificate required.\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | }
}
#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 | |
|
c3e941 | 2015-07-31 | Martin Nilsson | | int(-1..0) handle_change_cipher(int c)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
1e3a13 | 2015-02-25 | Martin Nilsson | | COND_FATAL(!expect_change_cipher || (c != 1),
ALERT_unexpected_message, "Unexpected change cipher!\n");
if (sizeof(pending_read_state)) {
SSL3_DEBUG_MSG("%O: Changing read state.\n", this);
current_read_state = pending_read_state[0];
pending_read_state = pending_read_state[1..];
} else {
error("No new read state pending!\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
1e3a13 | 2015-02-25 | Martin Nilsson | | expect_change_cipher--;
return 0;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
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;
}
|
7d5500 | 2014-11-24 | Martin Nilsson | | Buffer hb_msg = Buffer();
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add_int(HEARTBEAT_MESSAGE_request, 1);
hb_msg->add_int(16, 2);
|
84b90d | 2014-05-04 | Martin Nilsson | | int now = gethrtime();
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add(heartbeat_encode->crypt(sprintf("%8c%8c", now, now)));
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add(random_string(64 - sizeof(hb_msg)));
|
09f63c | 2014-11-25 | Martin Nilsson | | send_packet(heartbeat_packet(hb_msg));
|
84b90d | 2014-05-04 | Martin Nilsson | | }
void handle_heartbeat(string(8bit) s)
{
if (sizeof(s) < 19) return;
|
7d5500 | 2014-11-24 | Martin Nilsson | | Buffer hb_msg = Buffer(s);
|
16d2f1 | 2014-11-21 | Martin Nilsson | | int hb_type = hb_msg->read_int(1);
int hb_len = hb_msg->read_int(2);
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
dfad6e | 2015-03-11 | Henrik Grubbström (Grubba) | | SSL3_DEBUG_MSG("SSL.Connection: Heartbeat %s (%d bytes)\n",
|
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
|
16d2f1 | 2014-11-21 | Martin Nilsson | | payload = hb_msg->read();
|
84b90d | 2014-05-04 | Martin Nilsson | | if (sizeof(payload) < hb_len) {
payload = payload + random_string(hb_len - sizeof(payload));
} else {
payload = payload[..hb_len-1];
}
#else
return;
#endif
} else {
|
16d2f1 | 2014-11-21 | Martin Nilsson | | payload = hb_msg->read(hb_len);
|
84b90d | 2014-05-04 | Martin Nilsson | | pad_len = sizeof(hb_msg);
}
switch(hb_type) {
case HEARTBEAT_MESSAGE_request:
|
7d5500 | 2014-11-24 | Martin Nilsson | | hb_msg = Buffer();
|
16d2f1 | 2014-11-21 | Martin Nilsson | | hb_msg->add_int(HEARTBEAT_MESSAGE_response, 1);
hb_msg->add_int(hb_len, 2);
hb_msg->add(payload);
hb_msg->add(random_string(pad_len));
|
09f63c | 2014-11-25 | Martin Nilsson | | send_packet(heartbeat_packet(hb_msg));
|
84b90d | 2014-05-04 | Martin Nilsson | | break;
case HEARTBEAT_MESSAGE_response:
if ((sizeof(payload) == 16) && heartbeat_decode) {
|
7d5500 | 2014-11-24 | Martin Nilsson | | hb_msg = Buffer(heartbeat_decode->crypt(payload));
|
16d2f1 | 2014-11-21 | Martin Nilsson | | int a = hb_msg->read_int(8);
int b = hb_msg->read_int(8);
|
84b90d | 2014-05-04 | Martin Nilsson | | 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;
}
}
|
af9ae2 | 2015-03-30 | Martin Nilsson | | Stdio.Buffer handshake_buffer = Stdio.Buffer();
|
0bf845 | 2015-03-31 | Martin Nilsson | | Stdio.Buffer alert_buffer = Stdio.Buffer();
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
c3e941 | 2015-07-31 | Martin Nilsson | | string(8bit)|int(-1..1) got_data(string(8bit) data)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | | if (state & CONNECTION_peer_closed) {
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | | return 1;
}
|
2ed01a | 2014-05-23 | Henrik Grubbström (Grubba) | |
|
84b90d | 2014-05-04 | Martin Nilsson | |
|
7197b0 | 2015-04-22 | Martin Nilsson | | session->last_activity = time(1);
|
59a60b | 2015-04-13 | Martin Nilsson | | read_buffer->add(data);
|
ce5ffa | 2015-04-13 | Martin Nilsson | | Stdio.Buffer.RewindKey read_buffer_key = read_buffer->rewind_key();
|
59a60b | 2015-04-13 | Martin Nilsson | |
|
4eacaa | 2014-05-18 | Henrik Grubbström (Grubba) | | string(8bit) res = "";
|
84b90d | 2014-05-04 | Martin Nilsson | | Packet packet;
|
59a60b | 2015-04-13 | Martin Nilsson | | while (packet = recv_packet())
|
84b90d | 2014-05-04 | Martin Nilsson | | {
if (packet->is_alert)
|
4d3b39 | 2015-04-13 | Martin Nilsson | | {
|
938d51 | 2014-05-16 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: Bad received packet\n");
|
84b90d | 2014-05-04 | Martin Nilsson | | if (alert_callback)
|
ce5ffa | 2015-04-13 | Martin Nilsson | | {
Stdio.Buffer.RewindKey here = read_buffer->rewind_key();
read_buffer_key->rewind();
alert_callback(packet, current_read_state->seq_num,
(string)read_buffer);
here->rewind();
}
|
4d3b39 | 2015-04-13 | Martin Nilsson | |
|
68ac5e | 2014-11-13 | Henrik Grubbström (Grubba) | | if (this && packet)
send_packet(packet);
|
4d3b39 | 2015-04-13 | Martin Nilsson | |
return -1;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
4d3b39 | 2015-04-13 | Martin Nilsson | |
SSL3_DEBUG_MSG("SSL.Connection: received packet of type %d\n",
packet->content_type);
switch (packet->content_type)
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
4d3b39 | 2015-04-13 | Martin Nilsson | | case PACKET_alert:
|
84b90d | 2014-05-04 | Martin Nilsson | | {
|
4d3b39 | 2015-04-13 | Martin Nilsson | | SSL3_DEBUG_MSG("SSL.Connection: ALERT\n");
COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message,
"Zero length Alert fragments not allowed.\n");
|
c3e941 | 2015-07-31 | Martin Nilsson | | int(-1..1) err = 0;
|
4d3b39 | 2015-04-13 | Martin Nilsson | | alert_buffer->add( packet->fragment );
while(!err && sizeof(alert_buffer)>1)
err = handle_alert(alert_buffer->read(2));
if (err)
|
c3e941 | 2015-07-31 | Martin Nilsson | | {
|
4d3b39 | 2015-04-13 | Martin Nilsson | | if (err > 0 && sizeof (res))
|
c3e941 | 2015-07-31 | Martin Nilsson | | {
|
4d3b39 | 2015-04-13 | Martin Nilsson | | return res;
|
c3e941 | 2015-07-31 | Martin Nilsson | | }
return err;
}
|
4d3b39 | 2015-04-13 | Martin Nilsson | | break;
}
case PACKET_change_cipher_spec:
{
SSL3_DEBUG_MSG("SSL.Connection: CHANGE_CIPHER_SPEC\n");
COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message,
"Zero length ChangeCipherSpec fragments not allowed.\n");
COND_FATAL(version >= PROTOCOL_TLS_1_3, ALERT_unexpected_message,
"ChangeCipherSpec not allowed in TLS 1.3 and later.\n");
foreach(packet->fragment;; int c)
{
|
c3e941 | 2015-07-31 | Martin Nilsson | | int(-1..0) err = handle_change_cipher(c);
|
4d3b39 | 2015-04-13 | Martin Nilsson | | SSL3_DEBUG_MSG("tried change_cipher: %d\n", err);
if (err)
return err;
}
break;
}
case PACKET_handshake:
{
SSL3_DEBUG_MSG("SSL.Connection: HANDSHAKE\n");
COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message,
"Zero length Handshake fragments not allowed.\n");
COND_FATAL(!(state & CONNECTION_handshaking) &&
!secure_renegotiation, ALERT_no_renegotiation,
"Renegotiation not supported in unsecure mode.\n");
COND_FATAL(expect_change_cipher && (version < PROTOCOL_TLS_1_3),
ALERT_unexpected_message, "Expected change cipher.\n");
|
c3e941 | 2015-07-31 | Martin Nilsson | | int(-1..1) err;
|
4d3b39 | 2015-04-13 | Martin Nilsson | | handshake_buffer->add( packet->fragment );
while (sizeof(handshake_buffer) >= 4)
{
Stdio.Buffer.RewindKey key = handshake_buffer->rewind_key();
int type = handshake_buffer->read_int8();
Buffer input = Buffer(handshake_buffer->read_hbuffer(3));
if(!input)
{
key->rewind();
break;
}
int len = 1+3+sizeof(input);
key->rewind();
Stdio.Buffer raw = handshake_buffer->read_buffer(len);
|
6f35e9 | 2014-05-05 | Martin Nilsson | |
mixed exception = catch {
|
4d3b39 | 2015-04-13 | Martin Nilsson | | err = handle_handshake(type, input, raw);
COND_FATAL(err>=0 && sizeof(input), ALERT_record_overflow,
sprintf("Extraneous handshake packet data (%O).\n",
type));
|
6f35e9 | 2014-05-05 | Martin Nilsson | | };
if( exception )
{
|
7d5500 | 2014-11-24 | Martin Nilsson | | if( objectp(exception) && ([object]exception)->buffer_error )
|
6f35e9 | 2014-05-05 | Martin Nilsson | | {
Error.Generic e = [object(Error.Generic)]exception;
|
1e3a13 | 2015-02-25 | Martin Nilsson | | COND_FATAL(1, ALERT_decode_error, e->message());
|
6f35e9 | 2014-05-05 | Martin Nilsson | | }
throw(exception);
}
|
4d3b39 | 2015-04-13 | Martin Nilsson | | if (err < 0)
return err;
if (err > 0) {
state &= ~CONNECTION_handshaking;
if ((version >= PROTOCOL_TLS_1_3) || expect_change_cipher) {
COND_FATAL(sizeof(handshake_buffer), ALERT_unexpected_message,
"Extraneous handshake packets.\n");
}
COND_FATAL(sizeof(handshake_buffer) && !secure_renegotiation,
ALERT_no_renegotiation,
"Renegotiation not supported in unsecure mode.\n");
}
}
break;
}
case PACKET_application_data:
SSL3_DEBUG_MSG("SSL.Connection: APPLICATION_DATA\n");
COND_FATAL(state & CONNECTION_handshaking,
ALERT_unexpected_message,
"Handshake not finished yet!\n");
res += packet->fragment;
break;
case PACKET_heartbeat:
{
SSL3_DEBUG_MSG("SSL.Connection: Heartbeat.\n");
if (state != CONNECTION_ready) {
break;
}
if (!session->heartbeat_mode) {
send_packet(alert(ALERT_warning, ALERT_unexpected_message,
"Heart beat mode not enabled.\n"));
break;
}
mixed exception = catch {
handle_heartbeat(packet->fragment);
};
if( exception )
{
if( objectp(exception) && ([object]exception)->buffer_error )
{
Error.Generic e = [object(Error.Generic)]exception;
COND_FATAL(1, ALERT_decode_error, e->message());
}
throw(exception);
}
|
6f35e9 | 2014-05-05 | Martin Nilsson | |
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
4d3b39 | 2015-04-13 | Martin Nilsson | | break;
default:
COND_FATAL(state & CONNECTION_handshaking,
ALERT_unexpected_message,
"Unexpected message during handshake!\n");
SSL3_DEBUG_MSG("SSL.Connection: Ignoring packet of type %s\n",
fmt_constant(packet->content_type, "PACKET"));
break;
|
84b90d | 2014-05-04 | Martin Nilsson | | }
|
813b39 | 2000-08-04 | Andreas Sigfridsson | | }
|
59a60b | 2015-04-13 | Martin Nilsson | |
|
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 | | }
|