http://code.google.com/p/selene-tls/source/detail?r=9187551f396e
Modified:
/lib/core/init.c
/lib/parser/handshake_callbacks.c
/lib/parser/handshake_messages.h
/lib/parser/handshake_messages/client_key_exchange.c
/lib/parser/parser.h
=======================================
--- /lib/core/init.c Sat Jul 23 13:51:31 2011
+++ /lib/core/init.c Sun Aug 14 00:05:56 2011
@@ -119,6 +119,10 @@
sln_cert_chain_destroy(s->conf, s->peer_certs);
s->peer_certs = NULL;
}
+
+ if (s->peer_pubkey != NULL) {
+ sln_free(s, s->peer_pubkey);
+ }
sln_free(s, s);
=======================================
--- /lib/parser/handshake_callbacks.c Sat Jul 30 10:44:44 2011
+++ /lib/parser/handshake_callbacks.c Sun Aug 14 00:05:56 2011
@@ -20,6 +20,7 @@
#include "handshake_messages.h"
#include "sln_tok.h"
#include "sln_arrays.h"
+#include "sln_rsa.h"
#include <string.h>
static selene_error_t*
@@ -151,6 +152,17 @@
{
return s->peer_certs;
}
+
+sln_pubkey_t*
+sln_peer_pubkey(selene_t *s)
+{
+ if (!s->peer_pubkey) {
+ selene_cert_t* cert = selene_cert_chain_entry(s->peer_certs, 0);
+ s->peer_pubkey = sln_alloc(s, sizeof(sln_pubkey_t));
+ s->peer_pubkey->key = X509_get_pubkey(cert->cert);
+ }
+ return s->peer_pubkey;
+}
void
selene_complete_validate_certificate(selene_t *s, int valid)
@@ -184,12 +196,47 @@
certs->chain = NULL;
return selene_publish(s, SELENE_EVENT_VALIDATE_CERTIFICATE);
}
+
+static selene_error_t*
+handle_server_done(selene_t *s, selene_event_e event, void *x)
+{
+ sln_parser_baton_t *baton = s->backend_baton;
+ sln_msg_tls_t tls;
+ sln_msg_client_key_exchange_t cke;
+ sln_pubkey_t *pubkey;
+ sln_bucket_t *btls = NULL;
+ sln_bucket_t *bcke = NULL;
+
+ sln_parser_tls_set_current_version(s, (uint8_t
*)&baton->pre_master_secret[0], (uint8_t *)&baton->pre_master_secret[1]);
+
+ sln_parser_rand_bytes_secure(baton->pre_master_secret + 2,
SLN_SECRET_LENGTH - 2);
+
+ pubkey = sln_peer_pubkey(s);
+
+ /* TODO: out */
+ SELENE_ERR(sln_rsa_public_encrypt(s, pubkey, baton->pre_master_secret,
SLN_SECRET_LENGTH, NULL));
+ /* cke.pre_master_secret_length = len(out); */
+ /* cke.pre_master_key = out; */
+
+ SELENE_ERR(sln_handshake_serialize_client_key_exchange(s, &cke, &bcke));
+ tls.content_type = SLN_CONTENT_TYPE_HANDSHAKE;
+ sln_parser_tls_set_current_version(s, &tls.version_major,
&tls.version_minor);
+ tls.length = bcke->size;
+
+ SELENE_ERR(sln_tls_serialize_header(s, &tls, &btls));
+
+ SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, btls);
+ SLN_BRIGADE_INSERT_TAIL(s->bb.out_enc, bcke);
+
+ return SELENE_SUCCESS;
+}
void
sln_handshake_register_callbacks(selene_t *s)
{
if (s->mode == SLN_MODE_CLIENT) {
selene_handler_set(s, SELENE__EVENT_HS_GOT_CERTIFICATE,
handle_server_certificate, NULL);
+ selene_handler_set(s, SELENE__EVENT_HS_GOT_SERVER_HELLO_DONE,
handle_server_done, NULL);
selene_handler_set(s, SELENE_EVENT_VALIDATE_CERTIFICATE,
validate_certificate, NULL);
}
else {
=======================================
--- /lib/parser/handshake_messages.h Mon Jul 18 15:02:12 2011
+++ /lib/parser/handshake_messages.h Sun Aug 14 00:05:56 2011
@@ -204,8 +204,8 @@
} sln_handshake_client_key_exchange_state_e;
typedef struct sln_msg_client_key_exchange_t {
- uint32_t pre_master_key_length;
- char *pre_master_key;
+ uint32_t pre_master_secret_length;
+ char *pre_master_secret;
} sln_msg_client_key_exchange_t;
selene_error_t*
=======================================
--- /lib/parser/handshake_messages/client_key_exchange.c Sun Jul 31
09:51:31 2011
+++ /lib/parser/handshake_messages/client_key_exchange.c Sun Aug 14
00:05:56 2011
@@ -33,18 +33,18 @@
len += 3;
/* pre master key size */
- len += cke->pre_master_key_length;
+ len += cke->pre_master_secret_length;
sln_bucket_create_empty(s->alloc, &b, len);
b->data[0] = SLN_HS_MT_CLIENT_KEY_EXCHANGE;
- b->data[1] = cke->pre_master_key_length >> 16;
- b->data[2] = cke->pre_master_key_length >> 8;
- b->data[3] = cke->pre_master_key_length;
+ b->data[1] = cke->pre_master_secret_length >> 16;
+ b->data[2] = cke->pre_master_secret_length >> 8;
+ b->data[3] = cke->pre_master_secret_length;
off = 4;
- memcpy(b->data + off, cke->pre_master_key, cke->pre_master_key_length);
- off += cke->pre_master_key_length;
+ memcpy(b->data + off, cke->pre_master_secret,
cke->pre_master_secret_length);
+ off += cke->pre_master_secret_length;
SLN_ASSERT(off == len);
@@ -52,7 +52,6 @@
return SELENE_SUCCESS;
}
-
typedef struct cke_baton_t {
sln_handshake_client_key_exchange_state_e state;
@@ -67,18 +66,18 @@
switch (ckb->state) {
case SLN_HS_CLIENT_KEY_EXCHANGE_LENGTH:
{
- ckb->cke.pre_master_key_length = v->v.uint24;
+ ckb->cke.pre_master_secret_length = v->v.uint24;
ckb->state = SLN_HS_CLIENT_KEY_EXCHANGE_DATA;
v->next = TOK_COPY_BRIGADE;
- v->wantlen = ckb->cke.pre_master_key_length;
+ v->wantlen = ckb->cke.pre_master_secret_length;
break;
}
case SLN_HS_CLIENT_KEY_EXCHANGE_DATA:
{
- size_t len = ckb->cke.pre_master_key_length;
- ckb->cke.pre_master_key = sln_alloc(hs->s,
sln_brigade_size(v->v.bb));
- sln_brigade_flatten(v->v.bb, ckb->cke.pre_master_key, &len);
- SLN_ASSERT(ckb->cke.pre_master_key_length == len);
+ size_t len = ckb->cke.pre_master_secret_length;
+ ckb->cke.pre_master_secret = sln_alloc(hs->s,
sln_brigade_size(v->v.bb));
+ sln_brigade_flatten(v->v.bb, ckb->cke.pre_master_secret, &len);
+ SLN_ASSERT(ckb->cke.pre_master_secret_length == len);
v->next = TOK_DONE;
v->wantlen = 0;
break;
=======================================
--- /lib/parser/parser.h Sun Jul 10 15:49:18 2011
+++ /lib/parser/parser.h Sun Aug 14 00:05:56 2011
@@ -72,6 +72,16 @@
SLN_CONNSTATE_ALERT_FATAL
} sln_connstate_e;
+typedef struct sln_params_t {
+ char *mac_secret;
+ char *key;
+ char *iv;
+ selene_cipher_suite_e suite;
+ unsigned long seq_num;
+} sln_params_t;
+
+#define SLN_SECRET_LENGTH (48)
+
struct sln_parser_baton_t {
sln_connstate_e connstate;
sln_handshake_e handshake;
@@ -85,6 +95,22 @@
uint8_t peer_version_major;
uint8_t peer_version_minor;
+ char pre_master_secret[SLN_SECRET_LENGTH];
+ char master_secret[SLN_SECRET_LENGTH];
+
+ /* The order in the struct is important here, we abuse this layout
+ * when computing the master secret
+ */
+ uint32_t client_utc_unix_time;
+ char client_random_bytes[28];
+ uint32_t server_utc_unix_time;
+ char server_random_bytes[28];
+
+ sln_params_t pending_send_parameters;
+ sln_params_t pending_recv_parameters;
+ sln_params_t active_send_parameters;
+ sln_params_t active_recv_parameters;
+
union {
sln_msg_client_hello_t *client_hello;
sln_msg_server_hello_t *server_hello;