Example #1
0
static WTPInitMachine *init_machine_create(WAPAddrTuple *tuple, unsigned short
                                           tid, int tidnew)
{
     WTPInitMachine *init_machine;
	
     init_machine = gw_malloc(sizeof(WTPInitMachine)); 
        
     #define ENUM(name) init_machine->name = INITIATOR_NULL_STATE;
     #define INTEGER(name) init_machine->name = 0; 
     #define EVENT(name) init_machine->name = NULL;
     #define TIMER(name) init_machine->name = gwtimer_create(queue); 
     #define ADDRTUPLE(name) init_machine->name = NULL; 
     #define MACHINE(field) field
     #include "wtp_init_machine.def"

     gwlist_append(init_machines, init_machine);

     init_machine->mid = counter_increase(init_machine_id_counter);
     init_machine->addr_tuple = wap_addr_tuple_duplicate(tuple);
     init_machine->tid = tid;
     init_machine->tidnew = tidnew;
	
     debug("wap.wtp", 0, "WTP: Created WTPInitMachine %p (%ld)", 
	   (void *) init_machine, init_machine->mid);

     return init_machine;
}
Example #2
0
static WTLSMachine *wtls_machine_create(WAPAddrTuple * tuple)
{

        WTLSMachine *wtls_machine;
        wtls_machine = gw_malloc(sizeof(WTLSMachine)); 
        
#define MACHINE(field) field
#define ENUM(name) wtls_machine->name = NULL_STATE;
#define ADDRTUPLE(name) wtls_machine->name = NULL;
#define INTEGER(name) wtls_machine->name = 0;
#define OCTSTR(name) wtls_machine->name = NULL;
#define PDULIST(name) wtls_machine->name = NULL;
#include "wtls_machine-decl.h"
        
        gwlist_append(wtls_machines, wtls_machine);
        wtls_machine->mid = counter_increase(wtls_machine_id_counter);
        wtls_machine->addr_tuple = wap_addr_tuple_duplicate(tuple);
   wtls_machine->server_seq_num = wtls_machine->client_seq_num = -1;
   wtls_machine->last_refresh = -1;

		wtls_machine->handshake_data = octstr_create("");
		
   debug("wap.wtls", 0, "WTLS: Created WTLSMachine %ld (0x%p)",
         wtls_machine->mid, (void *)wtls_machine);
        return wtls_machine;
}
Example #3
0
static WAPEvent *unpack_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;
    WTP_TPI *tpi;
    int	i, num_tpis;

    event = wap_event_create(RcvAck);
    event->u.RcvAck.tid = pdu->u.Ack.tid;
    event->u.RcvAck.tid_ok = pdu->u.Ack.tidverify;
    event->u.RcvAck.rid = pdu->u.Ack.rid;
    event->u.RcvAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

    /* Set default to 0 because Ack on 1 piece message has no tpi */
    event->u.RcvAck.psn = 0;
    num_tpis = gwlist_len(pdu->options);

    for (i = 0; i < num_tpis; i++) {
        tpi = gwlist_get(pdu->options, i);
        if (tpi->type == TPI_PSN) {
            event->u.RcvAck.psn = octstr_get_bits(tpi->data,0,8);
            break;
        }
    }

    return event;
}
Example #4
0
/*
 * Adds an item to the tid cache, one item per every initiator. Initiator is 
 * identified by the address four-tuple, fetched from a wtp responder machine.
 */ 
static void add_tid(WTPRespMachine *resp_machine, long tid)
{
    WTPCached_tid *new_item = NULL;
       
    new_item = cache_item_create_empty(); 
    new_item->addr_tuple = wap_addr_tuple_duplicate(resp_machine->addr_tuple);
    new_item->tid = tid; 

    list_append(tid_cache, new_item);
}
Example #5
0
static void fatalAlert(WAPEvent * event, int description)
{
   WAPEvent *abort;

   abort = wap_event_create(SEC_Terminate_Req);
   abort->u.SEC_Terminate_Req.addr_tuple = wap_addr_tuple_duplicate
       (event->u.T_Unitdata_Ind.addr_tuple);
   abort->u.SEC_Terminate_Req.alert_level = fatal_alert;
   abort->u.SEC_Terminate_Req.alert_desc = description;
   wtls_dispatch_event(abort);
}
Example #6
0
int wtls_get_address_tuple(long mid, WAPAddrTuple ** tuple)
{
	WTLSMachine *sm;
	
	sm = find_wtls_machine_using_mid(mid);
	if (sm == NULL)
		return -1;

	*tuple = wap_addr_tuple_duplicate(sm->addr_tuple);
	return 0;
}
Example #7
0
static WAPEvent *unpack_abort(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
     WAPEvent *event;

     event = wap_event_create(RcvAbort);
     event->u.RcvAbort.tid = pdu->u.Abort.tid;
     event->u.RcvAbort.abort_type = pdu->u.Abort.abort_type;
     event->u.RcvAbort.abort_reason = pdu->u.Abort.abort_reason;
     event->u.RcvAbort.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

     return event;
}
Example #8
0
/*
 * Creates TR-Invoke.cnf event
 */
static WAPEvent *create_tr_invoke_cnf(WTPInitMachine *init_machine)
{
    WAPEvent *event;

    gw_assert(init_machine != NULL);
    event = wap_event_create(TR_Invoke_Cnf);
    event->u.TR_Invoke_Cnf.handle = init_machine->mid;
    event->u.TR_Invoke_Cnf.addr_tuple = 
        wap_addr_tuple_duplicate(init_machine->addr_tuple);

    return event;
}
Example #9
0
static void make_unit_push_request(WAPEvent *e)
{
    WAPEvent *wsp_event;
    List *push_headers;
    Octstr *smsc_id;
    Octstr *dlr_url;
    Octstr *smsbox_id;
    Octstr *push_body;
    Octstr *service_name;

    gw_assert(e->type == Po_Unit_Push_Req);
    gw_assert(e->u.Po_Unit_Push_Req.addr_tuple);
    gw_assert(e->u.Po_Unit_Push_Req.service_name);

    smsc_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsc_id); 
    dlr_url = octstr_duplicate(e->u.Po_Unit_Push_Req.dlr_url);
    smsbox_id = octstr_duplicate(e->u.Po_Unit_Push_Req.smsbox_id);
    push_body = octstr_duplicate(e->u.Po_Unit_Push_Req.push_body);
    service_name = octstr_duplicate(e->u.Po_Unit_Push_Req.service_name); 
    push_headers = add_push_flag(e);

    wsp_event = wap_event_create(S_Unit_Push_Req);
    wsp_event->u.S_Unit_Push_Req.addr_tuple = 
        wap_addr_tuple_duplicate(e->u.Po_Unit_Push_Req.addr_tuple);
    wsp_event->u.S_Unit_Push_Req.push_id = e->u.Po_Unit_Push_Req.push_id;
    wsp_event->u.S_Unit_Push_Req.push_headers = push_headers;

    wsp_event->u.S_Unit_Push_Req.address_type = 
        e->u.Po_Unit_Push_Req.address_type;
    if (smsc_id != NULL)
        wsp_event->u.S_Unit_Push_Req.smsc_id = smsc_id;
    else
        wsp_event->u.S_Unit_Push_Req.smsc_id = NULL;  
    if (dlr_url != NULL)      
        wsp_event->u.S_Unit_Push_Req.dlr_url = dlr_url;        
    else  
        wsp_event->u.S_Unit_Push_Req.dlr_url = NULL;      
    wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Po_Unit_Push_Req.dlr_mask;            
    if (smsbox_id != NULL)
        wsp_event->u.S_Unit_Push_Req.smsbox_id = smsbox_id;
    else
        wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL;
    wsp_event->u.S_Unit_Push_Req.service_name = service_name;
    if (push_body != NULL)
        wsp_event->u.S_Unit_Push_Req.push_body = push_body;
    else
        wsp_event->u.S_Unit_Push_Req.push_body = NULL;

    dispatch_to_wsp_unit(wsp_event);
    debug("wap.push.ota", 0, "OTA: made connectionless session service"
          " request");
}
Example #10
0
static WAPEvent *unpack_negative_ack(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;

    event = wap_event_create(RcvNegativeAck);
    event->u.RcvNegativeAck.tid = pdu->u.Negative_ack.tid;
    event->u.RcvNegativeAck.rid = pdu->u.Negative_ack.rid;
    event->u.RcvNegativeAck.nmissing = pdu->u.Negative_ack.nmissing;
    event->u.RcvNegativeAck.missing = octstr_duplicate(pdu->u.Negative_ack.missing);
    event->u.RcvNegativeAck.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);
    
    return event;
}
Example #11
0
static WAPEvent *pack_error(WAPEvent *datagram)
{
    WAPEvent *event;

    gw_assert(datagram->type == T_DUnitdata_Ind);

    event = wap_event_create(RcvErrorPDU);
    event->u.RcvErrorPDU.tid = deduce_tid(datagram->u.T_DUnitdata_Ind.user_data);
    event->u.RcvErrorPDU.addr_tuple = 
	wap_addr_tuple_duplicate(datagram->u.T_DUnitdata_Ind.addr_tuple);

    return event;
}
Example #12
0
/*
 * Creates TR-Abort.ind event from an initiator state machine. In addtion, set
 * the ir_flag on.
 */
static WAPEvent *create_tr_abort_ind(WTPInitMachine *sm, long abort_reason) 
{
    WAPEvent *event;
	
    event = wap_event_create(TR_Abort_Ind);

    event->u.TR_Abort_Ind.abort_code = abort_reason;
    event->u.TR_Abort_Ind.addr_tuple = 
	wap_addr_tuple_duplicate(sm->addr_tuple);
    event->u.TR_Abort_Ind.handle = sm->mid;
    event->u.TR_Abort_Ind.ir_flag = INITIATOR_INDICATION;

    return event;
}
Example #13
0
static WAPEvent *unpack_result(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;

    event = wap_event_create(RcvResult);
    event->u.RcvResult.user_data = 
        octstr_duplicate(pdu->u.Result.user_data);
    event->u.RcvResult.tid = pdu->u.Result.tid;
    event->u.RcvResult.rid = pdu->u.Result.rid;
    event->u.RcvResult.gtr = pdu->u.Result.gtr;
    event->u.RcvResult.ttr = pdu->u.Result.ttr;
    event->u.RcvResult.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

    return event;
}
Example #14
0
static void make_session_request(WAPEvent *e)
{
    WAPEvent *wsp_event;
    List *appid_headers, *push_headers;

    gw_assert(e->type == Pom_SessionRequest_Req);
    push_headers = e->u.Pom_SessionRequest_Req.push_headers;

    check_session_request_headers(push_headers);

    wsp_event = wap_event_create(S_Unit_Push_Req);
    wsp_event->u.S_Unit_Push_Req.address_type =
        e->u.Pom_SessionRequest_Req.address_type;
    if (e->u.Pom_SessionRequest_Req.smsc_id != NULL)
        wsp_event->u.S_Unit_Push_Req.smsc_id =
            octstr_duplicate(e->u.Pom_SessionRequest_Req.smsc_id);
    else
        wsp_event->u.S_Unit_Push_Req.smsc_id = NULL;
    if (e->u.Pom_SessionRequest_Req.dlr_url != NULL)
        wsp_event->u.S_Unit_Push_Req.dlr_url =
            octstr_duplicate(e->u.Pom_SessionRequest_Req.dlr_url);
    else
        wsp_event->u.S_Unit_Push_Req.dlr_url = NULL;
    wsp_event->u.S_Unit_Push_Req.dlr_mask = e->u.Pom_SessionRequest_Req.dlr_mask;
    if (e->u.Pom_SessionRequest_Req.smsbox_id != NULL)
        wsp_event->u.S_Unit_Push_Req.smsbox_id =
            octstr_duplicate(e->u.Pom_SessionRequest_Req.smsbox_id);
    else
        wsp_event->u.S_Unit_Push_Req.smsbox_id = NULL;    
    wsp_event->u.S_Unit_Push_Req.service_name = 
        octstr_duplicate(e->u.Pom_SessionRequest_Req.service_name);

    wsp_event->u.S_Unit_Push_Req.push_id = 
        e->u.Pom_SessionRequest_Req.push_id;
    wsp_event->u.S_Unit_Push_Req.addr_tuple = 
        wap_addr_tuple_duplicate(e->u.Pom_SessionRequest_Req.addr_tuple);
    wsp_event->u.S_Unit_Push_Req.push_headers = 
        http_header_duplicate(push_headers);

    appid_headers = http_header_find_all(push_headers, "X-WAP-Application-Id");
    wsp_event->u.S_Unit_Push_Req.push_body = pack_sia(appid_headers);
    
    debug("wap.push.ota", 0, "OTA: making a connectionless session request for"
          " creating a session");

    dispatch_to_wsp_unit(wsp_event);
}
Example #15
0
static WAPEvent *unpack_segmented_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;

    event = wap_event_create(RcvSegInvoke);
    event->u.RcvSegInvoke.user_data = 
        octstr_duplicate(pdu->u.Segmented_invoke.user_data);
    event->u.RcvSegInvoke.tid = pdu->u.Segmented_invoke.tid;
    event->u.RcvSegInvoke.rid = pdu->u.Segmented_invoke.rid;
    event->u.RcvSegInvoke.no_cache_supported = 0;
    event->u.RcvSegInvoke.gtr = pdu->u.Segmented_invoke.gtr;
    event->u.RcvSegInvoke.ttr = pdu->u.Segmented_invoke.ttr;
    event->u.RcvSegInvoke.psn = pdu->u.Segmented_invoke.psn;
    event->u.RcvSegInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

    return event;
}
Example #16
0
static WAPEvent *unpack_invoke(WTP_PDU *pdu, WAPAddrTuple *addr_tuple)
{
    WAPEvent *event;

    event = wap_event_create(RcvInvoke);
    event->u.RcvInvoke.user_data = 
        octstr_duplicate(pdu->u.Invoke.user_data);
    event->u.RcvInvoke.tcl = pdu->u.Invoke.class;
    event->u.RcvInvoke.tid = pdu->u.Invoke.tid;
    event->u.RcvInvoke.tid_new = pdu->u.Invoke.tidnew;
    event->u.RcvInvoke.rid = pdu->u.Invoke.rid;
    event->u.RcvInvoke.up_flag = pdu->u.Invoke.uack;
    event->u.RcvInvoke.no_cache_supported = 0;
    event->u.RcvInvoke.version = pdu->u.Invoke.version;
    event->u.RcvInvoke.gtr = pdu->u.Invoke.gtr;
    event->u.RcvInvoke.ttr = pdu->u.Invoke.ttr;
    event->u.RcvInvoke.addr_tuple = wap_addr_tuple_duplicate(addr_tuple);

    return event;
}
Example #17
0
static WSPMethodMachine *method_machine_create(WSPMachine *sm,
			long wtp_handle) {
	WSPMethodMachine *msm;
	
	msm = gw_malloc(sizeof(*msm));
	
	#define INTEGER(name) msm->name = 0;
	#define ADDRTUPLE(name) msm->name = NULL;
	#define EVENT(name) msm->name = NULL;
	#define MACHINE(fields) fields
	#include "wsp_server_method_machine.def"
	
	msm->transaction_id = wtp_handle;
	msm->state = NULL_METHOD;
	msm->addr_tuple = wap_addr_tuple_duplicate(sm->addr_tuple);
	msm->session_id = sm->session_id;

	gwlist_append(sm->methodmachines, msm);

	return msm;
}
Example #18
0
static WSPPushMachine *push_machine_create(WSPMachine *sm, 
        long pid)
{
        WSPPushMachine *m;

        m = gw_malloc(sizeof(WSPPushMachine));

        #define INTEGER(name) m->name = 0;
        #define ADDRTUPLE(name) m->name = NULL;
        #define HTTPHEADER(name) m->name = http_create_empty_headers();
        #define MACHINE(fields) fields
        #include "wsp_server_push_machine.def"

        m->server_push_id = pid;
        m->transaction_id = pid;
	m->state = SERVER_PUSH_NULL_STATE;
	m->addr_tuple = wap_addr_tuple_duplicate(sm->addr_tuple);
	m->session_id = sm->session_id;

	gwlist_append(sm->pushmachines, m);

	return m;      
}
Example #19
0
static WSPMachine *find_session_machine(WAPEvent *event, WSP_PDU *pdu) {
	WSPMachine *sm;
	long session_id;
	WAPAddrTuple *tuple;
	
	tuple = NULL;
	session_id = -1;
	
	switch (event->type) {
	case TR_Invoke_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Ind.addr_tuple);
		break;

        case TR_Invoke_Cnf:
                tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Cnf.addr_tuple);
	        break;

	case TR_Result_Cnf:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Result_Cnf.addr_tuple);
		break;

	case TR_Abort_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Abort_Ind.addr_tuple);
		break;

	case S_Connect_Res:
		session_id = event->u.S_Connect_Res.session_id;
		break;

	case S_Resume_Res:
		session_id = event->u.S_Resume_Res.session_id;
		break;

	case Disconnect_Event:
		session_id = event->u.Disconnect_Event.session_handle;
		break;

	case Suspend_Event:
		session_id = event->u.Suspend_Event.session_handle;
		break;

	case S_MethodInvoke_Res:
		session_id = event->u.S_MethodInvoke_Res.session_id;
		break;

	case S_MethodResult_Req:
		session_id = event->u.S_MethodResult_Req.session_id;
		break;

	case S_ConfirmedPush_Req:
                session_id = event->u.S_ConfirmedPush_Req.session_id;
	        break;

        case S_Push_Req:
                session_id = event->u.S_Push_Req.session_id;
	        break;

	default:
		error(0, "WSP: Cannot find machine for %s event",
			wap_event_name(event->type));
	}
	
	gw_assert(tuple != NULL || session_id != -1);

	/* Pre-state-machine tests, according to 7.1.5.  After the tests,
	 * caller will pass the event to sm if sm is not NULL. */
	sm = NULL;
	/* First test is for MRUEXCEEDED, and we don't have a MRU */

	/* Second test is for class 2 TR-Invoke.ind with Connect PDU */
	if (event->type == TR_Invoke_Ind &&
	    event->u.TR_Invoke_Ind.tcl == 2 &&
	    pdu->type == Connect) {
			/* Create a new session, even if there is already
			 * a session open for this address.  The new session
			 * will take care of killing the old ones. */
			sm = machine_create();
			gw_assert(tuple != NULL);
			sm->addr_tuple = wap_addr_tuple_duplicate(tuple);
			sm->connect_handle = event->u.TR_Invoke_Ind.handle;
	/* Third test is for class 2 TR-Invoke.ind with Resume PDU */
	} else if (event->type == TR_Invoke_Ind &&
		   event->u.TR_Invoke_Ind.tcl == 2 &&
	  	   pdu->type == Resume) {
		/* Pass to session identified by session id, not
		 * the address tuple. */
		session_id = pdu->u.Resume.sessionid;
		sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		if (sm == NULL) {
			/* No session; TR-Abort.req(DISCONNECT) */
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Fourth test is for a class 1 or 2 TR-Invoke.Ind with no
	 * session for that address tuple.  We also handle class 0
	 * TR-Invoke.ind here by ignoring them; this seems to be
	 * an omission in the spec table. */
	} else if (event->type == TR_Invoke_Ind) {
		sm = gwlist_search(session_machines, tuple,
				 transaction_belongs_to_session);
		if (sm == NULL && (event->u.TR_Invoke_Ind.tcl == 1 ||
				event->u.TR_Invoke_Ind.tcl == 2)) {
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Other tests are for events not handled by the state tables;
	 * do those later, after we've tried to handle them. */
	} else {
		if (session_id != -1) {
			sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		} else {
			sm = gwlist_search(session_machines, tuple,
				transaction_belongs_to_session);
		}
		/* The table doesn't really say what we should do with
		 * non-Invoke events for which there is no session.  But
		 * such a situation means there is an error _somewhere_
		 * in the gateway. */
		if (sm == NULL) {
			error(0, "WSP: Cannot find session machine for event.");
			wap_event_dump(event);
		}
	}

	wap_addr_tuple_destroy(tuple);
	return sm;
}
Example #20
0
       wtp_event = make_abort(reason, handle);
       dispatch_to_wtp_init(wtp_event);
}

/*
 * The server sends invoke (to be exact, makes TR-Invoke.req) only when it is 
 * pushing. (Only the client disconnects sessions.)
 */ 
static void send_invoke(WSPMachine *m, WSP_PDU *pdu, WAPEvent *e, long class)
{
        WAPEvent *wtp_event;

        wtp_event = wap_event_create(TR_Invoke_Req);
        wtp_event->u.TR_Invoke_Req.addr_tuple = 
	    wap_addr_tuple_duplicate(m->addr_tuple);
/*
 * There is no mention of acknowledgement type in the specs.�But because 
 * confirmed push is confirmed after response from OTA, provider acknowledge-
 * ments seem redundant.
 */
	wtp_event->u.TR_Invoke_Req.up_flag = USER_ACKNOWLEDGEMENT;
        wtp_event->u.TR_Invoke_Req.tcl = class;
        if (e->type == S_ConfirmedPush_Req)
           wtp_event->u.TR_Invoke_Req.handle = 
               e->u.S_ConfirmedPush_Req.server_push_id;
	wtp_event->u.TR_Invoke_Req.user_data = wsp_pdu_pack(pdu);

        wsp_pdu_destroy(pdu);
        dispatch_to_wtp_init(wtp_event);
}
Example #21
0
static void clientHello(WAPEvent * event, WTLSMachine * wtls_machine)
{
   /* The Wap event we have to dispatch */
   WAPEvent *res;
   wtls_Payload *tempPayload;
   wtls_PDU *clientHelloPDU;
   CipherSuite *ciphersuite;
   int randomCounter, algo;

   tempPayload =
       (wtls_Payload *) gwlist_search(event->u.T_Unitdata_Ind.pdu_list,
                  (void *)client_hello,
                  match_handshake_type);
   if (!tempPayload) {
      error(0, "Illegal PDU while waiting for a ClientHello");
      fatalAlert(event, unexpected_message);
      return;
   }
   clientHelloPDU = wtls_pdu_unpack(tempPayload, wtls_machine);

   /* Store the client's random value - use pack for simplicity */
   wtls_machine->client_random = octstr_create("");
   randomCounter = pack_int32(wtls_machine->client_random, 0,
               clientHelloPDU->u.handshake.client_hello->
               random->gmt_unix_time);
   octstr_insert(wtls_machine->client_random,
            clientHelloPDU->u.handshake.client_hello->random->
            random_bytes, randomCounter);

   /* Select the ciphersuite from the supplied list */
   ciphersuite =
       wtls_choose_ciphersuite(clientHelloPDU->u.handshake.client_hello->
                ciphersuites);
   if (!ciphersuite) {
      error(0, "Couldn't agree on encryption cipher. Aborting");
      wtls_pdu_destroy(clientHelloPDU);
      fatalAlert(event, handshake_failure);
      return;
   }
   /* Set the relevant values in the wtls_machine and PDU structure */
   wtls_machine->bulk_cipher_algorithm = ciphersuite->bulk_cipher_algo;
   wtls_machine->mac_algorithm = ciphersuite->mac_algo;

   /* Generate a SEC_Create_Res event, and pass it back into the queue */
   res = wap_event_create(SEC_Create_Res);
   res->u.SEC_Create_Res.addr_tuple =
       wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple);
   res->u.SEC_Create_Res.bulk_cipher_algo = ciphersuite->bulk_cipher_algo;
   res->u.SEC_Create_Res.mac_algo = ciphersuite->mac_algo;
   res->u.SEC_Create_Res.client_key_id = wtls_choose_clientkeyid
       (clientHelloPDU->u.handshake.client_hello->client_key_ids, &algo);
   if (!res->u.SEC_Create_Res.client_key_id) {
      error(0, "Couldn't agree on key exchange protocol. Aborting");
      wtls_pdu_destroy(clientHelloPDU);
      wap_event_destroy(res);
      fatalAlert(event, unknown_key_id);
      return;
   }
   wtls_machine->key_algorithm = algo;

   /* Set the sequence number mode in both the machine and the outgoing packet */
   res->u.SEC_Create_Res.snmode =
       wtls_choose_snmode(clientHelloPDU->u.handshake.client_hello->
                snmode);
   wtls_machine->sequence_number_mode = res->u.SEC_Create_Res.snmode;

   /* Set the key refresh mode in both the machine and the outgoing packet */
   res->u.SEC_Create_Res.krefresh =
       clientHelloPDU->u.handshake.client_hello->krefresh;
   wtls_machine->key_refresh = res->u.SEC_Create_Res.krefresh;
   /* Global refresh variable */
   debug("wtls", 0, "clientHello ~> Accepted refresh = %d, refresh_rate = "
         "%d", wtls_machine->key_refresh, 1 << wtls_machine->key_refresh);

   /* Keep the data so we can send it back in EXCHANGE
    * temporary - needs to delete old one if exists !
    * wtls_machine->handshake_data = octstr_create("");
    */
   if (wtls_machine->handshake_data)
      octstr_destroy(wtls_machine->handshake_data);
   wtls_machine->handshake_data = octstr_create("");
   octstr_append(wtls_machine->handshake_data, tempPayload->data);

   debug("wtls", 0, "clientHello ~> Dispatching SEC_Create_Res event");
   wtls_pdu_destroy(clientHelloPDU);
   wtls_dispatch_event(res);
}
Example #22
0
static void serverHello(WAPEvent * event, WTLSMachine * wtls_machine)
{
   WAPEvent *req;
   wtls_PDU *serverHelloPDU;
//   wtls_PDU* certificatePDU;
   Random *tempRandom;
/*   List *certList;
   Certificate *cert;
*/ int randomCounter = 0;

   /* Our serverHello */
   serverHelloPDU = wtls_pdu_create(Handshake_PDU);
   serverHelloPDU->rlen = 1;
   serverHelloPDU->snMode = wtls_machine->sequence_number_mode ? 1 : 0;
   serverHelloPDU->u.handshake.msg_type = server_hello;
   serverHelloPDU->u.handshake.server_hello =
       (ServerHello *) gw_malloc(sizeof(ServerHello));

   /* Set our server version */
   serverHelloPDU->u.handshake.server_hello->serverversion = 1;

   /* Get a suitably random number - store it in both the machine structure and outgoing PDU */
   tempRandom = wtls_get_random();
   wtls_machine->server_random = octstr_create("");
   randomCounter =
       pack_int32(wtls_machine->server_random, 0,
             tempRandom->gmt_unix_time);
   octstr_insert(wtls_machine->server_random, tempRandom->random_bytes,
            octstr_len(wtls_machine->server_random));

   serverHelloPDU->u.handshake.server_hello->random = tempRandom;

   /* At the moment, we don't support session caching, so tell them to forget about caching us */
   serverHelloPDU->u.handshake.server_hello->session_id =
       octstr_format("%llu", wtls_machine->mid);

   /* We need to select an appropriate mechanism here from the ones listed */
   serverHelloPDU->u.handshake.server_hello->client_key_id =
       event->u.SEC_Create_Res.client_key_id;

   /* Get our ciphersuite details */
   serverHelloPDU->u.handshake.server_hello->ciphersuite = (CipherSuite *)
       gw_malloc(sizeof(CipherSuite));
   serverHelloPDU->u.handshake.server_hello->ciphersuite->bulk_cipher_algo
       = event->u.SEC_Create_Res.bulk_cipher_algo;
   serverHelloPDU->u.handshake.server_hello->ciphersuite->mac_algo =
       event->u.SEC_Create_Res.mac_algo;
   serverHelloPDU->u.handshake.server_hello->comp_method = null_comp;

   /* We need to confirm the client's choice, or if they haven't 
    * specified one, select one ourselves 
    */
   serverHelloPDU->u.handshake.server_hello->snmode =
       event->u.SEC_Create_Res.snmode;

   /* We need to either confirm the client's choice of key refresh rate, or choose a lower rate */
   serverHelloPDU->u.handshake.server_hello->krefresh =
       event->u.SEC_Create_Res.krefresh;

   /* Add the PDUsto the server's outgoing list  */
   add_pdu(wtls_machine, serverHelloPDU);
   wtls_pdu_destroy(serverHelloPDU);

   /* Generate and dispatch a SEC_Exchange_Req or maybe a SEC_Commit_Req */
   req = wap_event_create(SEC_Exchange_Req);
   req->u.SEC_Exchange_Req.addr_tuple =
       wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple);
   wtls_dispatch_event(req);
   debug("wtls", 0, "serverHello ~> Dispatching SEC_Exchange_Req event");
}