67 #ifdef HAVE_WTLS_OPENSSL 80 #define WTLS_CONNECTIONLESS_PORT 9202 86 static List *wtls_machines = NULL;
91 static Counter *wtls_machine_id_counter = NULL;
104 static List *wtls_queue = NULL;
118 static void wtls_machine_destroy(
void *p);
149 static WTLSMachine *find_wtls_machine_using_mid(
long mid);
154 char *stateName(
int s);
157 static int match_handshake_type(
void *item,
void *pattern);
158 static int match_pdu_type(
void *item,
void *pattern);
161 extern Octstr *wtls_get_certificate(
void);
175 List *wtlsPayloadList;
182 info(0,
"Event created");
185 unitdataIndEvent->
u.T_Unitdata_Ind.addr_tuple =
187 msg->wdp_datagram.source_port,
188 msg->wdp_datagram.destination_address,
189 msg->wdp_datagram.destination_port);
190 info(0,
"Set address and stuff");
194 info(0,
"Datagram unpacked!");
197 unitdataIndEvent->
u.T_Unitdata_Ind.pdu_list = wtlsPayloadList;
200 return unitdataIndEvent;
211 dispatch_resp_to_bb = responder_dispatch;
229 debug(
"wap.wtls", 0,
"wtls_shutdown: %ld wtls machines left",
249 tuple = dgram->
u.T_DUnitdata_Req.addr_tuple;
250 if ((wtls_machine = wtls_machine_find(tuple, -1))) {
254 "wtls_dispatch_resp ~> Dispatching datagram to bearerbox");
257 respPDU->
snMode = wtls_machine->sequence_number_mode ? 1 : 0;
260 dgram->
u.T_DUnitdata_Req.user_data;
261 debug(
"wtls", 0,
"Sending Response PDU:");
263 add_pdu(wtls_machine, respPDU);
266 dgram->
u.T_DUnitdata_Req.user_data = NULL;
267 }
else error(0,
"wtls_dispatch_event: Unable to find state machine. " 268 "Dropping datagram.");
275 sm = find_wtls_machine_using_mid(mid);
289 alertPDU->
snMode = wtls_machine->sequence_number_mode ? 1 : 0;
290 alertPDU->
u.
alert.
level =
event->u.SEC_Terminate_Req.alert_level;
291 alertPDU->
u.
alert.
desc =
event->u.SEC_Terminate_Req.alert_desc;
296 add_pdu(wtls_machine, alertPDU);
308 wtls_machine->server_seq_num++;
311 if (!(payloadToAdd =
wtls_pdu_pack(pduToAdd, wtls_machine))) {
312 wtls_machine->server_seq_num--;
315 if (!payloadToAdd->
data) {
316 wtls_machine->server_seq_num--;
322 if (!wtls_machine->packet_to_send)
330 wtls_machine->server_seq_num = -1;
333 currentLength =
octstr_len(wtls_machine->packet_to_send);
334 octstr_insert(wtls_machine->packet_to_send, packedPDU, currentLength);
347 gw_assert(wtls_machine->packet_to_send != NULL);
348 if (!wtls_machine->packet_to_send)
353 add_wtls_address(
msg, wtls_machine);
354 msg->wdp_datagram.user_data =
358 dispatch_resp_to_bb(
msg);
362 wtls_machine->packet_to_send = NULL;
371 debug(
"wap.wtls", 0,
"adding address");
372 msg->wdp_datagram.source_address =
374 msg->wdp_datagram.source_port = wtls_machine->addr_tuple->local->port;
375 msg->wdp_datagram.destination_address =
377 msg->wdp_datagram.destination_port =
378 wtls_machine->addr_tuple->remote->port;
393 sm = wtls_machine_find_or_create(e);
397 wtls_event_handle(sm, e);
404 char *stateName(
int s)
407 #define STATE_NAME(state) case state: return #state; 408 #define ROW(state, event, condition, action, new_state) 411 return "unknown state";
421 (event->
u.T_Unitdata_Ind.addr_tuple);
434 int randomCounter, algo;
439 match_handshake_type);
441 error(0,
"Illegal PDU while waiting for a ClientHello");
449 randomCounter =
pack_int32(wtls_machine->client_random, 0,
454 random_bytes, randomCounter);
461 error(0,
"Couldn't agree on encryption cipher. Aborting");
468 wtls_machine->mac_algorithm = ciphersuite->
mac_algo;
472 res->
u.SEC_Create_Res.addr_tuple =
475 res->
u.SEC_Create_Res.mac_algo = ciphersuite->
mac_algo;
478 if (!res->
u.SEC_Create_Res.client_key_id) {
479 error(0,
"Couldn't agree on key exchange protocol. Aborting");
485 wtls_machine->key_algorithm = algo;
488 res->
u.SEC_Create_Res.snmode =
491 wtls_machine->sequence_number_mode = res->
u.SEC_Create_Res.snmode;
494 res->
u.SEC_Create_Res.krefresh =
496 wtls_machine->key_refresh = res->
u.SEC_Create_Res.krefresh;
498 debug(
"wtls", 0,
"clientHello ~> Accepted refresh = %d, refresh_rate = " 499 "%d", wtls_machine->key_refresh, 1 << wtls_machine->key_refresh);
505 if (wtls_machine->handshake_data)
510 debug(
"wtls", 0,
"clientHello ~> Dispatching SEC_Create_Res event");
523 int randomCounter = 0;
527 serverHelloPDU->
rlen = 1;
528 serverHelloPDU->
snMode = wtls_machine->sequence_number_mode ? 1 : 0;
553 event->u.SEC_Create_Res.client_key_id;
559 =
event->u.SEC_Create_Res.bulk_cipher_algo;
561 event->u.SEC_Create_Res.mac_algo;
568 event->u.SEC_Create_Res.snmode;
572 event->u.SEC_Create_Res.krefresh;
575 add_pdu(wtls_machine, serverHelloPDU);
580 req->
u.SEC_Exchange_Req.addr_tuple =
583 debug(
"wtls", 0,
"serverHello ~> Dispatching SEC_Exchange_Req event");
589 Octstr *checking_data = NULL;
598 wtls_PDU *changeCipherSpec_incoming_PDU;
602 Octstr *concatenatedRandoms = NULL;
603 Octstr *encryptedData = NULL;
604 Octstr *decryptedData = NULL;
605 Octstr *labelVerify = NULL;
606 Octstr *labelMaster = NULL;
612 match_handshake_type);
615 error(0,
"Missing client_key_exchange. Aborting...");
634 if (!decryptedData) {
636 "Key Exchange failed. Couldn't decrypt client's secret (%d)." 637 " Aborting...", wtls_machine->key_algorithm);
653 concatenatedRandoms =
octstr_cat(wtls_machine->client_random,
654 wtls_machine->server_random);
670 error(0,
"Missing change_cipher. Aborting...");
682 octstr_dump(wtls_machine->client_write_MAC_secret, 0);
686 if (changeCipherSpec_incoming_PDU->
u.
cc.
change == 1) {
687 debug(
"wtls", 0,
"Need to decrypt the PDUs from now on...");
689 event->
u.T_Unitdata_Ind.pdu_list);
696 match_handshake_type);
698 error(0,
"Failed to decrypt finished PDU. Aborting...");
709 debug(
"wtls", 0,
"Client Finished PDU:");
723 checking_data) == 0) {
724 wtls_machine->encrypted = 1;
725 debug(
"wtls", 0,
"DATA VERIFICATION OK");
740 changeCipherSpecPDU->
rlen = 1;
741 changeCipherSpecPDU->
snMode =
742 wtls_machine->sequence_number_mode ? 1 : 0;
748 finishedPDU->
rlen = 1;
749 finishedPDU->
snMode = wtls_machine->sequence_number_mode ? 1 : 0;;
757 (wtls_machine->handshake_data, wtls_machine), 12, wtls_machine);
764 add_pdu(wtls_machine, changeCipherSpecPDU);
765 add_pdu(wtls_machine, finishedPDU);
795 listLen =
gwlist_len(event->
u.T_Unitdata_Ind.pdu_list);
796 for (; i < listLen; i++) {
799 dgram->
u.T_DUnitdata_Ind.addr_tuple =
802 event->
u.T_Unitdata_Ind.addr_tuple->
804 event->
u.T_Unitdata_Ind.addr_tuple->
806 event->
u.T_Unitdata_Ind.addr_tuple->
808 dgram->
u.T_DUnitdata_Ind.user_data = payLoad->
data;
810 payLoad->
data = NULL;
822 debug(
"wap.wtls", 0,
"WTLS: wtls_machine %ld, state %s, event %s.",
823 wtls_machine->
mid, stateName(wtls_machine->state),
829 if (wtls_machine->encrypted)
831 event->
u.T_Unitdata_Ind.pdu_list);
835 #define STATE_NAME(state) 836 #define ROW(wtls_state, event_type, condition, action, next_state) \ 837 if (wtls_machine->state == wtls_state && \ 838 event->type == event_type && \ 841 wtls_machine->state = next_state; \ 842 debug("wap.wtls", 0, "WTLS %ld: New state %s", wtls_machine->mid, #next_state); \ 846 error(0,
"WTLS: handle_event: unhandled event!");
848 "WTLS: handle_event: Unhandled event was:");
856 if (wtls_machine->state == NULL_STATE) {
857 wtls_machine_destroy(wtls_machine);
878 debug(
"wap.wtls", 0,
"event->type = %d", event->
type);
881 switch (event->
type) {
883 case T_DUnitdata_Ind:
884 tuple =
event->u.T_Unitdata_Ind.addr_tuple;
892 case SEC_Unitdata_Req:
893 tuple =
event->u.T_Unitdata_Ind.addr_tuple;
896 debug(
"wap.wtls", 0,
"WTLS: wtls_machine_find_or_create:" 897 "unhandled event (1)");
906 wtls_machine = wtls_machine_find(tuple, mid);
910 if (wtls_machine == NULL) {
911 switch (event->
type) {
915 "WTLS: received a SEC_Create_Request_Req, and don't know what to do with it...");
920 case T_DUnitdata_Ind:
930 wtls_machine = wtls_machine_create(tuple);
936 error(0,
"WTLS: wtls_machine_find_or_create:" 937 " unhandled event (2)");
945 static int is_wanted_wtls_machine(
void *a,
void *b)
970 m =
gwlist_search(wtls_machines, &pat, is_wanted_wtls_machine);
980 #define MACHINE(field) field 981 #define ENUM(name) wtls_machine->name = NULL_STATE; 982 #define ADDRTUPLE(name) wtls_machine->name = NULL; 983 #define INTEGER(name) wtls_machine->name = 0; 984 #define OCTSTR(name) wtls_machine->name = NULL; 985 #define PDULIST(name) wtls_machine->name = NULL; 991 wtls_machine->server_seq_num = wtls_machine->client_seq_num = -1;
992 wtls_machine->last_refresh = -1;
996 debug(
"wap.wtls", 0,
"WTLS: Created WTLSMachine %ld (0x%p)",
997 wtls_machine->
mid, (
void *)wtls_machine);
1005 static void wtls_machine_destroy(
void *p)
1010 debug(
"wap.wtls", 0,
"WTLS: Destroying WTLSMachine %ld (0x%p)",
1011 wtls_machine->
mid, (
void *)wtls_machine);
1014 #define MACHINE(field) field 1015 #define ENUM(name) wtls_machine->name = NULL_STATE; 1016 #define ADDRTUPLE(name) wap_addr_tuple_destroy(wtls_machine->name); 1017 #define INTEGER(name) wtls_machine->name = 0; 1018 #define OCTSTR(name) octstr_destroy(wtls_machine->name); 1019 #define PDULIST(name) wtls_machine->name = NULL; 1022 gw_free(wtls_machine);
1025 static int wtls_machine_has_mid(
void *a,
void *b)
1032 return sm->
mid == mid;
1035 static WTLSMachine *find_wtls_machine_using_mid(
long mid)
1037 return gwlist_search(wtls_machines, &mid, wtls_machine_has_mid);
1041 static int match_handshake_type(
void *item,
void *pattern)
1048 type = (long)pattern;
1050 if (!matchingPayload->
data)
1061 static int match_pdu_type(
void *item,
void *pattern)
1067 type = (long)pattern;
1069 if (matchingPayload->
type ==
type) {
void msg_dump(Msg *msg, int level)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
ServerHello * server_hello
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
wtls_Payload * wtls_pdu_pack(wtls_PDU *pdu, WTLSMachine *wtls_machine)
CipherSuite * wtls_choose_ciphersuite(List *ciphersuites)
wtls_PDU * wtls_pdu_create(int type)
EXCHANGE SEC_Terminate_Req
ClientKeyExchange * client_key_exchange
void wtls_payload_destroy(wtls_Payload *payload)
gw_assert(wtls_machine->packet_to_send !=NULL)
void counter_destroy(Counter *counter)
void gwlist_append(List *list, void *item)
static void main_thread(void *)
add_pdu(wtls_machine, serverKeyXchgPDU)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
int wtls_choose_clientkeyid(List *clientKeyIDs, int *algo)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
void wtls_dispatch_event(WAPEvent *event)
Octstr * wtls_payload_pack(wtls_Payload *payload, int seqnum)
Octstr * wtls_decrypt_key(int type, Octstr *encryptedData)
Octstr * wtls_hash(Octstr *inputData, WTLSMachine *wtls_machine)
int pack_int16(Octstr *data, long charpos, int i)
void wap_event_dump(WAPEvent *event)
void gwthread_join_every(gwthread_func_t *func)
unsigned long counter_increase(Counter *counter)
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
void wtls_pdu_dump(wtls_PDU *msg, int level)
void wtls_init(wtls_dispatch_func_t *responder_dispatch)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Counter * counter_create(void)
int wtls_choose_snmode(int snmode)
void wtls_dispatch_resp(WAPEvent *event)
void wtls_pdu_destroy(wtls_PDU *msg)
void gwlist_remove_producer(List *list)
void wap_event_destroy_item(void *event)
Random * wtls_get_random(void)
#define octstr_duplicate(ostr)
#define octstr_dump(ostr, level,...)
const char * wap_event_name(WAPEventName type)
long gwlist_delete_equal(List *list, void *item)
clientHello(event, wtls_machine)
#define wap_event_create(type)
RSAPublicKey * wtls_get_rsapublickey(void)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
CipherSuite * ciphersuite
void wap_dispatch_datagram(WAPEvent *dgram)
int wtls_get_address_tuple(long mid, WAPAddrTuple **tuple)
long octstr_len(const Octstr *ostr)
int wap_addr_tuple_same(WAPAddrTuple *a, WAPAddrTuple *b)
void write_to_bearerbox(Msg *pmsg)
OPEN NULL_STATE NULL_STATE SEC_Create_Request_Req
void * gwlist_consume(List *list)
CREATING CREATING SEC_Exchange_Req
void debug(const char *place, int err, const char *fmt,...)
void wtls_decrypt_pdu_list(WTLSMachine *wtls_machine, List *pdu_list)
void destroy_rsa_pubkey(RSAPublicKey *key)
WAPAddrTuple * wap_addr_tuple_create(Octstr *rmt_addr, long rmt_port, Octstr *lcl_addr, long lcl_port)
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
CompressionMethod comp_method
Octstr * wtls_calculate_prf(Octstr *secret, Octstr *label, Octstr *seed, int byteLength, WTLSMachine *wtls_machine)
int pack_int32(Octstr *data, long charpos, long i)
ClientHello * client_hello
CREATING SEC_Exception_Req
void octstr_truncate(Octstr *ostr, int new_len)
RSAEncryptedSecret * rsa_params
WAPEvent * wtls_unpack_wdp_datagram(Msg *msg)
List * wtls_unpack_payloadlist(Octstr *data)
void gwlist_add_producer(List *list)
int octstr_get_char(const Octstr *ostr, long pos)
send_queuedpdus(wtls_machine)
static XMLRPCDocument * msg
void wap_event_destroy(WAPEvent *event)
void wtls_dispatch_func_t(Msg *msg)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
wtls_PDU * wtls_pdu_unpack(wtls_Payload *payload, WTLSMachine *wtls_machine)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)