Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wtls_state-decl.h

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * Macro calls to generate rows of the state table. See the documentation for
00059  * guidance how to use and update these. 
00060  *
00061  * by Nick Clarey <nclarey@3glab.com>
00062  */
00063 
00064 STATE_NAME(NULL_STATE)
00065 STATE_NAME(CREATING)
00066 STATE_NAME(CREATED)
00067 STATE_NAME(EXCHANGE)
00068 STATE_NAME(COMMIT)
00069 STATE_NAME(OPENING)
00070 STATE_NAME(OPEN)
00071 
00072 /* If the packet is a ClientHello */
00073 /* We only include this case in state NULL; the others are handled by the
00074    wtls_find_or_create function */
00075 
00076 ROW(NULL_STATE,
00077     T_Unitdata_Ind,
00078     1,
00079     {
00080         /* The Wap event we have to dispatch */
00081         WAPEvent *res;
00082         wtls_Payload* tempPayload;
00083         wtls_PDU* clientHelloPDU;
00084         CipherSuite* ciphersuite;
00085         int randomCounter;
00086             
00087         tempPayload = (wtls_Payload*) gwlist_search (event->u.T_Unitdata_Ind.pdu_list,
00088                                                    (void*) client_hello,
00089                                                    match_handshake_type);
00090 
00091         clientHelloPDU = wtls_pdu_unpack(tempPayload,wtls_machine);
00092             
00093         /* Store the client's random value - use pack for simplicity */
00094         wtls_machine->client_random = octstr_create("");
00095         randomCounter = pack_int32(wtls_machine->client_random,0,
00096                                    clientHelloPDU->u.handshake.client_hello->random->gmt_unix_time);
00097         octstr_insert(wtls_machine->client_random,
00098                       clientHelloPDU->u.handshake.client_hello->random->random_bytes,
00099                       randomCounter);
00100             
00101         /* Generate a SEC_Create_Res event, and pass it back into the queue */
00102         res = wap_event_create(SEC_Create_Res);
00103         res->u.SEC_Create_Res.addr_tuple =
00104                 wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple);
00105 
00106         /* Select the ciphersuite from the supplied list */
00107         ciphersuite = wtls_choose_ciphersuite(clientHelloPDU->u.handshake.client_hello->ciphersuites);
00108 
00109         /* Set the relevant values in the wtls_machine and PDU structure */
00110         wtls_machine->bulk_cipher_algorithm = ciphersuite->bulk_cipher_algo;
00111         wtls_machine->mac_algorithm = ciphersuite->mac_algo;
00112         res->u.SEC_Create_Res.bulk_cipher_algo = ciphersuite->bulk_cipher_algo;
00113         res->u.SEC_Create_Res.mac_algo = ciphersuite->mac_algo;
00114         res->u.SEC_Create_Res.client_key_id =
00115                 wtls_choose_clientkeyid(clientHelloPDU->u.handshake.client_hello->client_key_ids);
00116 
00117         /* Set the sequence number mode in both the machine and the outgoing packet */
00118         res->u.SEC_Create_Res.snmode = wtls_choose_snmode(clientHelloPDU->u.handshake.client_hello->snmode);
00119         wtls_machine->sequence_number_mode = res->u.SEC_Create_Res.snmode;
00120 
00121         /* Set the key refresh mode in both the machine and the outgoing packet */
00122         res->u.SEC_Create_Res.krefresh = wtls_choose_krefresh(clientHelloPDU->u.handshake.client_hello->krefresh);
00123         wtls_machine->key_refresh = res->u.SEC_Create_Res.krefresh;
00124             
00125         /* Keep the data so we can send it back in EXCHANGE */
00126         // temporary - needs to delete old one if exists !
00127         //wtls_machine->handshake_data = octstr_create("");
00128         octstr_append(wtls_machine->handshake_data, tempPayload->data);
00129             
00130         debug("wtls:handle_event", 0,"Dispatching SEC_Create_Res event");
00131         wtls_dispatch_event(res);
00132 
00133 },
00134     CREATING)
00135 
00136 /* Creating State */
00137 /* Termination */
00138 ROW(CREATING,
00139     SEC_Terminate_Req,
00140     1,
00141     {
00142 /* Send off a T_Unitdata_Req containing an alert as specified */
00143             send_alert(event->u.SEC_Terminate_Req.alert_level,
00144                        event->u.SEC_Terminate_Req.alert_desc,
00145                        wtls_machine);
00146     },
00147     NULL_STATE)
00148 
00149 /* Exception */
00150 ROW(CREATING,
00151     SEC_Exception_Req,
00152     1,
00153     {
00154             /* Send off a T_Unitdata_Req containing an exception as specified */
00155             send_alert(event->u.SEC_Exception_Req.alert_level,
00156                        event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00157     },
00158     CREATING)
00159 
00160 /* Create Response - create a buffer with a "ServerHello" and possibly a Certificate or something else */
00161 ROW(CREATING,
00162     SEC_Create_Res,
00163     1,
00164     {
00165             WAPEvent *req;
00166             wtls_PDU* serverHelloPDU;
00167             Random* tempRandom;
00168             int randomCounter = 0;
00169             
00170             /* Our serverHello */
00171             serverHelloPDU = wtls_pdu_create(Handshake_PDU);
00172             serverHelloPDU->u.handshake.msg_type = server_hello;
00173             serverHelloPDU->u.handshake.server_hello = (ServerHello*) gw_malloc(sizeof(ServerHello));
00174             
00175             /* Set our server version */
00176             serverHelloPDU->u.handshake.server_hello->serverversion = 1;
00177             
00178             /* Get a suitably random number - store it in both the machine structure and outgoing PDU */
00179             tempRandom = wtls_get_random();
00180             wtls_machine->server_random = octstr_create("");
00181             randomCounter = pack_int32(wtls_machine->server_random,0,tempRandom->gmt_unix_time);
00182             octstr_insert(wtls_machine->server_random,tempRandom->random_bytes,octstr_len(wtls_machine->server_random));
00183             
00184             serverHelloPDU->u.handshake.server_hello->random = tempRandom;
00185             
00186             /* At the moment, we don't support session caching, so tell them to forget about caching us */
00187             serverHelloPDU->u.handshake.server_hello->session_id = octstr_create("");
00188             
00189             /* We need to select an appropriate mechanism here from the ones listed */
00190             serverHelloPDU->u.handshake.server_hello->client_key_id = event->u.SEC_Create_Res.client_key_id;
00191             
00192             /* Get our ciphersuite details */
00193             serverHelloPDU->u.handshake.server_hello->ciphersuite = (CipherSuite*) gw_malloc(sizeof(CipherSuite));
00194             serverHelloPDU->u.handshake.server_hello->ciphersuite->bulk_cipher_algo = event->u.SEC_Create_Res.bulk_cipher_algo;
00195             serverHelloPDU->u.handshake.server_hello->ciphersuite->mac_algo = event->u.SEC_Create_Res.mac_algo;            
00196             serverHelloPDU->u.handshake.server_hello->comp_method = null_comp;
00197             
00198             /* We need to confirm the client's choice, or if they haven't specified one, select
00199                one ourselves */
00200             serverHelloPDU->u.handshake.server_hello->snmode = event->u.SEC_Create_Res.snmode;
00201             
00202             /* We need to either confirm the client's choice of key refresh rate, or choose a lower rate */
00203             serverHelloPDU->u.handshake.server_hello->krefresh = event->u.SEC_Create_Res.krefresh;
00204             
00205             /* Add the PDUsto the server's outgoing list  */
00206             add_pdu(wtls_machine, serverHelloPDU);            
00207             
00208             /* Generate and dispatch a SEC_Exchange_Req or maybe a SEC_Commit_Req */
00209             req = wap_event_create(SEC_Exchange_Req);
00210             req->u.SEC_Exchange_Req.addr_tuple =
00211                     wap_addr_tuple_duplicate(event->u.T_Unitdata_Ind.addr_tuple);
00212             wtls_dispatch_event(req);
00213             debug("wtls: handle_event", 0,"Dispatching SEC_Exchange_Req event");
00214             
00215     },
00216     CREATED)
00217 
00218 /* Created State */
00219 /* Exchange Request - Full Handshake will be performed */
00220 ROW(CREATED,
00221     SEC_Exchange_Req,
00222     1,
00223     {
00224             wtls_PDU* serverKeyXchgPDU;
00225             wtls_PDU* serverHelloDonePDU;
00226             
00227             /* Assert that the PDU list is valid */
00228             gw_assert(wtls_machine->packet_to_send != NULL);
00229             
00230             /* We'll also need a Server Key Exchange message */
00231             serverKeyXchgPDU = wtls_pdu_create(Handshake_PDU);
00232             serverKeyXchgPDU->u.handshake.msg_type = server_key_exchange;
00233             serverKeyXchgPDU->u.handshake.server_key_exchange = (ServerKeyExchange*) gw_malloc(sizeof(ServerKeyExchange));
00234             serverKeyXchgPDU->u.handshake.server_key_exchange->param_spec = NULL;
00235             
00236             /* Allocate memory for the RSA component */
00237             debug("wtls: ", 0,"Going to get the RSA public key...");
00238             serverKeyXchgPDU->u.handshake.server_key_exchange->rsa_params = wtls_get_rsapublickey();
00239             debug("wtls: ", 0,"...got it.");
00240             add_pdu(wtls_machine, serverKeyXchgPDU);            
00241             debug("wtls: ", 0,"in CREATED - just added pdu...");
00242 
00243             /* Add some more PDUs to the List - potentially a ServerKeyExchange,
00244                a CertificateRequest and a ServerHelloDone */
00245             /* Just a ServerHelloDone for now */
00246             serverHelloDonePDU = wtls_pdu_create(Handshake_PDU);
00247             serverHelloDonePDU->u.handshake.msg_type = server_hello_done;
00248             add_pdu(wtls_machine, serverHelloDonePDU);
00249             
00250             /* Translate the buffer and address details into a T_Unitdata_Req
00251              * and send it winging it's way across the network */
00252             send_queuedpdus(wtls_machine);
00253     },
00254     EXCHANGE)
00255 
00256 /* Commit Request - Abbreviated Handshake will be performed */
00257 ROW(CREATED,
00258     SEC_Commit_Req,
00259     1,
00260 {
00261         /* Assert that the PDU list is valid */
00262         /* Add some more PDUs to the List - a ChangeCipherSpec and a Finished */
00263         /* Translate the buffer and address details into a T_Unitdata_Req */
00264         /* And send it winging it's way across the network */
00265 },
00266         COMMIT)
00267 
00268 /* Terminate Request */
00269 ROW(CREATED,
00270     SEC_Terminate_Req,
00271     1,
00272     {
00273             /* Send off a T_Unitdata_Req containing an alert as specified */
00274             send_alert(event->u.SEC_Terminate_Req.alert_level,
00275                        event->u.SEC_Terminate_Req.alert_desc, wtls_machine);
00276     },
00277     NULL_STATE)
00278 
00279 /* Exception Request */
00280 ROW(CREATED,
00281     SEC_Exception_Req,
00282     1,
00283     {
00284             /* Send off a T_Unitdata_Req containing an exception as specified */
00285             send_alert(event->u.SEC_Exception_Req.alert_level,
00286                        event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00287     },
00288     CREATED)
00289 
00290 /* Exchange State */
00291 /* Unitdata arrival - identical ClientHello record */
00292 ROW(EXCHANGE,
00293     T_Unitdata_Ind,
00294     clienthellos_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1,
00295         {
00296                 /* It appears as though someone has sent us an identical ClientHello to the last one */
00297                 /* Make ourselves a T_Unitdata_Req with the last_transmitted_packet */
00298                 /* And send it on it's merry  */
00299         },
00300     EXCHANGE)
00301 
00302 /* Unitdata arrival - non-identical ClientHello record */
00303 //ROW(EXCHANGE,
00304 //    T_Unitdata_Ind,
00305 //    clienthellos_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) != 1,
00306 //    {
00307 /* So, this one's different. They must have changed their mind about something, so try a CREATING again */
00308 /* Do the necessary SEC_Create_Ind stuff */
00309 //    },
00310 //    CREATING)
00311 
00312 /* Unitdata arrival - good packet */
00313 ROW(EXCHANGE,
00314     T_Unitdata_Ind,
00315     1,
00316     {
00317             RSAPublicKey *public_key = NULL;
00318             Octstr* key_block;
00319             Octstr* final_client_write_enc_key = NULL;
00320             Octstr* final_server_write_enc_key = NULL;
00321             Octstr* final_client_write_IV = NULL;
00322             Octstr* final_server_write_IV = NULL;
00323             Octstr* emptySecret = NULL;
00324             Octstr* checking_data = NULL;
00325                         
00326             // packet_contains_changecipherspec (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00327             // packet_contains_finished (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00328             // packet_contains_optional_stuff (event->u.T_Unitdata_Ind.pdu_list) == 1,
00329 
00330             /* The Wap PDUs we have to dispatch */
00331             wtls_PDU* changeCipherSpecPDU;
00332             wtls_PDU* finishedPDU;
00333             
00334             /* The PDUs we have to process */
00335             wtls_Payload* tempPayload;
00336             wtls_PDU* clientKeyXchgPDU;
00337             wtls_PDU* changeCipherSpec_incoming_PDU;
00338             wtls_PDU* finished_incoming_PDU;
00339 
00340             /* For decrypting/encrypting data */
00341             Octstr* concatenatedRandoms=0;
00342             Octstr* encryptedData=0;
00343             Octstr* decryptedData=0;
00344             Octstr* labelVerify=0;
00345             Octstr* labelMaster=0;
00346             
00347             /* Process the incoming event : ClientKeyExchange*/            
00348             tempPayload = (wtls_Payload*) gwlist_search (event->u.T_Unitdata_Ind.pdu_list,
00349                                                       (void*) client_key_exchange,
00350                                                       match_handshake_type);
00351 
00352             /* Keep the data so we can send it back */
00353             octstr_insert(wtls_machine->handshake_data, tempPayload->data,
00354                           octstr_len(wtls_machine->handshake_data));
00355                                      
00356             clientKeyXchgPDU = wtls_pdu_unpack(tempPayload,wtls_machine);
00357             wtls_pdu_dump(clientKeyXchgPDU,0);
00358                         
00359             /* Decrypt the client key exchange PDU */
00360             encryptedData = clientKeyXchgPDU->u.handshake.client_key_exchange->rsa_params->encrypted_secret;
00361             decryptedData = wtls_decrypt_rsa(encryptedData);
00362             
00363             public_key = wtls_get_rsapublickey();
00364             pack_int16(decryptedData, octstr_len(decryptedData), octstr_len(public_key->rsa_exponent));
00365             octstr_insert(decryptedData, public_key->rsa_exponent, octstr_len(decryptedData));
00366             pack_int16(decryptedData, octstr_len(decryptedData), octstr_len(public_key->rsa_modulus));
00367             octstr_insert(decryptedData, public_key->rsa_modulus, octstr_len(decryptedData));
00368 
00369             /* Concatenate our random data */
00370             concatenatedRandoms = octstr_cat(wtls_machine->client_random,
00371                                              wtls_machine->server_random);
00372          
00373             /* Generate our master secret */
00374             labelMaster = octstr_create("master secret");
00375             wtls_machine->master_secret = wtls_calculate_prf(decryptedData, labelMaster,
00376                                               concatenatedRandoms,20, wtls_machine );
00377             octstr_destroy(labelMaster);
00378             labelMaster = NULL;
00379 
00380             /* calculate the key blocks */
00381             calculate_server_key_block(wtls_machine);
00382             calculate_client_key_block(wtls_machine);
00383                         
00384             /* Process the incoming event : ChangeCipherSpec*/            
00385             tempPayload = (wtls_Payload*) gwlist_search (event->u.T_Unitdata_Ind.pdu_list,
00386                                                       (void*) ChangeCipher_PDU,
00387                                                       match_pdu_type);
00388 
00389             changeCipherSpec_incoming_PDU = wtls_pdu_unpack(tempPayload, wtls_machine);
00390             if(changeCipherSpec_incoming_PDU->u.cc.change == 1) {
00391                 debug("wtls", 0,"Need to decrypt the PDUs from now on...");
00392                 wtls_machine->encrypted = 1;
00393                 wtls_decrypt_pdu_list(wtls_machine, event->u.T_Unitdata_Ind.pdu_list);
00394             }
00395 
00396             octstr_dump(wtls_machine->client_write_MAC_secret,0);
00397             
00398             wtls_pdu_dump(changeCipherSpec_incoming_PDU,0);
00399 
00400             /* Process the incoming event : Finished*/            
00401             tempPayload = (wtls_Payload*) gwlist_search (event->u.T_Unitdata_Ind.pdu_list,
00402                                                       (void*) finished,
00403                                                       match_handshake_type);
00404             if(tempPayload == NULL)
00405                 debug("wtls", 0, "null finished !!!");
00406             
00407             finished_incoming_PDU = wtls_pdu_unpack(tempPayload,wtls_machine);
00408             debug("wtls", 0, "Client Finished PDU:");
00409             wtls_pdu_dump(finished_incoming_PDU,0);
00410 
00411             /* Check the verify_data */
00412             labelVerify = octstr_create("client finished");
00413             checking_data = wtls_calculate_prf(wtls_machine->master_secret, labelVerify,
00414                               (Octstr *)wtls_hash(wtls_machine->handshake_data, wtls_machine),
00415                               12, wtls_machine);
00416             octstr_destroy(labelVerify);
00417             labelVerify = NULL;
00418             
00419             if(octstr_compare(finished_incoming_PDU->u.handshake.finished->verify_data, checking_data)==0) {
00420                 debug("wtls", 0, "DATA VERIFICATION OK");
00421             }
00422             
00423             /* Keep the data so we can send it back in the next message */
00424             /*octstr_insert(wtls_machine->handshake_data, tempPayload->data,
00425                           octstr_len(wtls_machine->handshake_data));
00426             */
00427             // temporary fix
00428             octstr_truncate(tempPayload->data, 15);
00429             octstr_insert(wtls_machine->handshake_data, tempPayload->data,
00430                           octstr_len(wtls_machine->handshake_data));
00431                                      
00432             /* Create a new PDU List containing a ChangeCipherSpec and a Finished */
00433             changeCipherSpecPDU = wtls_pdu_create(ChangeCipher_PDU);
00434             changeCipherSpecPDU->u.cc.change = 1;
00435             
00436             /* Generate our verify data */
00437             finishedPDU = wtls_pdu_create(Handshake_PDU);
00438             finishedPDU->u.handshake.msg_type = finished;
00439             finishedPDU->cipher = 1;
00440             finishedPDU->u.handshake.finished = gw_malloc(sizeof(Finished));
00441             
00442             labelVerify = octstr_create("server finished");
00443 
00444             finishedPDU->u.handshake.finished->verify_data = wtls_calculate_prf(wtls_machine->master_secret,
00445                                             labelVerify,(Octstr *)wtls_hash(wtls_machine->handshake_data, wtls_machine),
00446                                             12,wtls_machine);
00447                        
00448             /* Reset the accumulated Handshake data */
00449             octstr_destroy(wtls_machine->handshake_data);
00450             wtls_machine->handshake_data = octstr_create("");
00451                         
00452             octstr_destroy(labelVerify);
00453             labelVerify = NULL;
00454             
00455             /* Add the pdus to our list */
00456             add_pdu(wtls_machine, changeCipherSpecPDU);            
00457             add_pdu(wtls_machine, finishedPDU);
00458             
00459             /* Send it off */
00460             send_queuedpdus(wtls_machine);
00461                         
00462             /* reset the seq_num */
00463             wtls_machine->server_seq_num = 0;
00464     },
00465     OPENING)
00466 
00467 /* Unitdata arrival - critical/fatal alert */
00468 ROW(EXCHANGE,
00469         T_Unitdata_Ind,
00470         is_critical_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00471         {
00472 /* Do the necessary SEC_Terminate_Ind stuff */
00473 /* And we're dead :-< */
00474 },
00475         NULL_STATE)
00476 
00477 /* Unitdata arrival - warning alert */
00478 ROW(EXCHANGE,
00479         T_Unitdata_Ind,
00480         is_warning_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00481         {
00482 /* Do the necessary SEC_Exception_Ind stuff */
00483 },
00484         EXCHANGE)
00485 
00486 /* Terminate */
00487 ROW(EXCHANGE,
00488         SEC_Terminate_Req,
00489         1,
00490         {
00491 /* Send off a T_Unitdata_Req containing an alert as specified */
00492 send_alert(event->u.SEC_Terminate_Req.alert_level,
00493         event->u.SEC_Terminate_Req.alert_desc, wtls_machine);
00494 },
00495         NULL_STATE)
00496 
00497 /* Exception */
00498 ROW(EXCHANGE,
00499         SEC_Exception_Req,
00500         1,
00501         {
00502 /* Send off a T_Unitdata_Req containing an exception as specified */
00503 send_alert(event->u.SEC_Exception_Req.alert_level,
00504         event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00505 },
00506         EXCHANGE)
00507 
00508 /* Commit State */
00509 /* Unitdata arrival - identical ClientHello record */
00510 ROW(COMMIT,
00511         T_Unitdata_Ind,
00512         clienthellos_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1,
00513         {
00514 /* It appears as though someone has sent us an identical ClientHello to the last one */
00515 /* Make ourselves a T_Unitdata_Req with the last_transmitted_packet */
00516 /* And send it on it's merry way */
00517 },
00518         COMMIT)
00519 
00520 /* Unitdata arrival - non-identical ClientHello record */
00521 ROW(COMMIT,
00522         T_Unitdata_Ind,
00523         clienthellos_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) != 1,
00524         {
00525 /* So, this one's different. They must have changed their mind about something, so try a CREATING again */
00526 /* Do the necessary SEC_Create_Ind stuff */
00527 },
00528         CREATING)
00529 
00530 /* Unitdata arrival - good packet with ChangeCipherSpec and Finished */
00531 ROW(COMMIT,
00532         T_Unitdata_Ind,
00533         packet_contains_changecipherspec (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00534 packet_contains_finished (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00535 packet_contains_userdata (event->u.T_Unitdata_Ind.pdu_list) != 1,
00536         {
00537 /* Create ourselves a SEC_Commit_Cnf packet to send off */
00538 /* Send it off */
00539 },
00540         OPEN)
00541 
00542 /* Unitdata arrival - good packet with ChangeCipherSpec, Finished and UD */
00543 ROW(COMMIT,
00544         T_Unitdata_Ind,
00545         packet_contains_changecipherspec (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00546 packet_contains_finished (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00547 packet_contains_userdata (event->u.T_Unitdata_Ind.pdu_list) == 1,
00548         {
00549 /* Create a SEC_Commit_Cnf packet to send off */
00550 /* Send it off */
00551 /* Relay the contents of the packets up to the WTP or WSP layers,
00552    depending on the destination port */
00553 },
00554         OPEN)
00555 
00556 /* Unitdata arrival - critical/fatal alert */
00557 ROW(COMMIT,
00558         T_Unitdata_Ind,
00559         is_critical_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00560         {
00561 /* Do the necessary SEC_Terminate_Ind stuff */
00562 /* And we're dead :-< */
00563 },
00564         NULL_STATE)
00565 
00566 /* Unitdata arrival - warning alert */
00567 ROW(COMMIT,
00568         T_Unitdata_Ind,
00569         is_warning_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00570         {
00571 /* Do the necessary SEC_Exception_Ind stuff */
00572 },
00573         COMMIT)
00574 
00575 /* Terminate */
00576 ROW(COMMIT,
00577         SEC_Terminate_Req,
00578         1,
00579         {
00580 /* Send off a T_Unitdata_Req containing an alert as specified */
00581 send_alert(event->u.SEC_Terminate_Req.alert_level,
00582         event->u.SEC_Terminate_Req.alert_desc, wtls_machine);
00583 },
00584         NULL_STATE)
00585 
00586 /* Exception */
00587 ROW(COMMIT,
00588         SEC_Exception_Req,
00589         1,
00590         {
00591 /* Send off a T_Unitdata_Req containing an exception as specified */
00592 send_alert(event->u.SEC_Exception_Req.alert_level,
00593         event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00594 },
00595         COMMIT)
00596 
00597 /* Opening State */
00598 /* Create Request */
00599 ROW(OPENING,
00600         SEC_Create_Request_Req,
00601         1,
00602         {
00603 /* Send off a T_Unitdata_Req containing a HelloRequest */
00604 },
00605         OPENING)
00606 
00607 /* Send out UnitData */
00608 ROW(OPENING,
00609         SEC_Unitdata_Req,
00610         1,
00611         {
00612 /* Apply the negotiated security "stuff" to the received packet */
00613 /* Send out the packet to the destination port/address requested */
00614 },
00615         OPENING)
00616 
00617 /* Unitdata received - ClientHello */
00618 //ROW(OPENING,
00619 //        T_Unitdata_Ind,
00620 //        packet_contains_clienthello (event->u.T_Unitdata_Ind.pdu_list) == 0,
00621 //        {
00624 //},
00625 //        CREATING)
00626 
00627 /* Unitdata received */
00628 ROW(OPENING,
00629         T_Unitdata_Ind,
00630         packet_contains_userdata(event->u.T_Unitdata_Ind.pdu_list) == 1,
00631         {
00632             wtls_Payload* tempPayload;
00633             wtls_PDU* ApplicationPDU;
00634             
00635             tempPayload = (wtls_Payload*) gwlist_search (event->u.T_Unitdata_Ind.pdu_list,
00636                                                       (void*) Application_PDU,
00637                                                       match_pdu_type);
00638 
00639             if(tempPayload == NULL)
00640                 debug("wtls", 0, "no App PDU found in list !!!");
00641             
00642             debug("wtls",0, "PDU type: %d", tempPayload->type);
00643             octstr_dump(tempPayload->data,0);
00644 
00645             ApplicationPDU = wtls_pdu_unpack(tempPayload, wtls_machine);
00646             
00647             wtls_pdu_dump(ApplicationPDU,0);
00648             
00649             /* Apply the negotiated decryption/decoding/MAC check to the received data */
00650             /* Take the userdata and pass it on up to the WTP/WSP, depending on the destination port */
00651             
00652             /* calculate the padding length */
00653             /*
00654             contentLength = octstr_len(bufferCopy);
00655             macSize = hash_table[wtls_machine->mac_algorithm].mac_size;
00656             blockLength = bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;
00657             paddingLength = (contentLength + macSize + 1) % (blockLength);
00658             */
00659             /* get the MAC */
00660 },
00661         OPEN)
00662 
00663 /* Unitdata arrival - Certificate, ClientKeyExchange ... Finished */
00664 ROW(OPENING,
00665         T_Unitdata_Ind,
00666         certificates_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1 &&
00667 clientkeyexchanges_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1 && 
00668 certifcateverifys_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1 &&
00669 changecipherspecs_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1 &&
00670 finisheds_are_indentical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1,
00671         {
00672 /* It appears as though someone has sent us an identical ClientHello to the last one */
00673 /* Make ourselves a T_Unitdata_Req with the last_transmitted_packet */
00674 /* And send it on it's merry way */
00675 },
00676         OPENING)
00677 
00678 /* Unitdata arrival - critical/fatal alert */
00679 ROW(OPENING,
00680         T_Unitdata_Ind,
00681         is_critical_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00682         {
00683 /* Do the necessary SEC_Terminate_Ind stuff */
00684 /* And we're dead :-< */
00685 },
00686         NULL_STATE)
00687 
00688 /* Unitdata arrival - warning alert */
00689 ROW(OPENING,
00690         T_Unitdata_Ind,
00691         is_warning_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00692         {
00693 /* Do the necessary SEC_Exception_Ind stuff */
00694 },
00695         OPENING)
00696 
00697 /* Terminate */
00698 ROW(OPENING,
00699         SEC_Terminate_Req,
00700         1,
00701         {
00702 /* Send off a T_Unitdata_Req containing an alert as specified */
00703 send_alert(event->u.SEC_Terminate_Req.alert_level,
00704         event->u.SEC_Terminate_Req.alert_desc, wtls_machine);
00705 },
00706         NULL_STATE)
00707 
00708 /* Exception */
00709 ROW(OPENING,
00710         SEC_Exception_Req,
00711         1,
00712         {
00713 /* Send off a T_Unitdata_Req containing an exception as specified */
00714 send_alert(event->u.SEC_Exception_Req.alert_level,
00715         event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00716 },
00717         OPENING)
00718 
00719 /* Open State */
00720 /* Create Request */
00721 ROW(OPEN,
00722         SEC_Create_Request_Req,
00723         1,
00724         {
00725 /* Send off a T_Unitdata_Req with a HelloRequest */
00726 },
00727         OPEN)
00728 
00729 /* Send out UnitData */
00730 ROW(OPEN,
00731         SEC_Unitdata_Req,
00732         1,
00733         { 
00734 /* Apply the negotiated security "stuff" to the received packet */
00735 /* Send out the packet to the destination port/address requested */
00736 },
00737         OPEN)
00738 
00739 /* Unitdata received - ClientHello */
00740 ROW(OPEN,
00741         T_Unitdata_Ind,
00742         packet_contains_clienthello (event->u.T_Unitdata_Ind.pdu_list) == 1,
00743         {
00744 /* Hmm, they're obviously not happy with something we discussed, so let's head back to creating */
00745 /* Do the necessary SEC_Create_Ind stuff */
00746 },
00747         CREATING)
00748 
00749 /* Unitdata received */
00750 ROW(OPEN,
00751         T_Unitdata_Ind,
00752         packet_contains_userdata(event->u.T_Unitdata_Ind.pdu_list) == 1,
00753         {
00754 /* Apply the negotiated decryption/decoding/MAC check to the received data */
00755 /* Take the userdata and pass it on up to the WTP/WSP, depending on the destination port */
00756 },
00757         OPEN)
00758 
00759 /* Unitdata arrival - ChangeCipherSpec, Finished */
00760 ROW(OPEN,
00761         T_Unitdata_Ind,
00762         packet_contains_changecipherspec (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00763 packet_contains_finished (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00764 packet_contains_userdata(event->u.T_Unitdata_Ind.pdu_list) != 1 &&
00765 finisheds_are_indentical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1,
00766         {
00767 /* Just send out a T_Unitdata_Req with an Alert(duplicate_finished_received) */
00768 },
00769         OPEN)
00770 
00771 /* Unitdata arrival - ChangeCipherSpec, Finished and UD */
00772 ROW(OPEN,
00773         T_Unitdata_Ind,
00774         packet_contains_changecipherspec (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00775 packet_contains_finished (event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00776 packet_contains_userdata(event->u.T_Unitdata_Ind.pdu_list) == 1 &&
00777 finisheds_are_indentical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet) == 1,
00778         {
00779 /* Apply the negotiated decryption/decoding/MAC check to the received data */
00780 /* Take the userdata and pass it on up to the WTP/WSP, depending on the destination port */
00781 /* Send out a T_Unitdata_Req with an Alert(duplicate_finished_received) */
00782 },
00783         OPEN)
00784 
00785 /* Unitdata arrival - critical/fatal alert */
00786 ROW(OPEN,
00787         T_Unitdata_Ind,
00788         is_critical_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00789         {
00790 /* Do the necessary SEC_Terminate_Ind stuff */
00791 /* And we're dead :-< */
00792 },
00793         NULL_STATE)
00794 
00795 /* Unitdata arrival - warning alert */
00796 ROW(OPEN,
00797         T_Unitdata_Ind,
00798         is_warning_alert(event->u.T_Unitdata_Ind.pdu_list) == 1,
00799         {
00800 /* Do the necessary SEC_Terminate_Ind stuff */
00801 },
00802         OPEN)
00803 
00804 /* Terminate */
00805 ROW(OPEN,
00806         SEC_Terminate_Req,
00807         1,
00808         {
00809 /* Send off a T_Unitdata_Req containing an alert as specified */
00810 send_alert(event->u.SEC_Terminate_Req.alert_level,
00811         event->u.SEC_Terminate_Req.alert_desc, wtls_machine);
00812 },
00813         NULL_STATE)
00814 
00815 /* Exception */
00816 ROW(OPEN,
00817         SEC_Exception_Req,
00818         1,
00819     {
00820 /* Send off a T_Unitdata_Req containing an exception as specified */
00821 send_alert(event->u.SEC_Exception_Req.alert_level,
00822         event->u.SEC_Exception_Req.alert_desc, wtls_machine);
00823 },
00824         OPEN)
00825 
00826 #undef ROW
00827 #undef STATE_NAME
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.