wtls_pdu.c

来自「mms client」· C语言 代码 · 共 998 行 · 第 1/3 页

C
998
字号
           Set the offset as the data length, which will indicate we've gone as far           as we can */        if ((*offset + guessedPayloadLength) > dataLength) {                *offset = dataLength;                return NULL;        }                /* If we pass that test, set offset to the correct return value */        *offset += guessedPayloadLength;                /* Copy the octstr again, so that we end up with an octstr containing           just the PDU we want */        dataFromOffsetToLength = octstr_copy(dataFromOffset, 0, guessedPayloadLength);                /* Submit that octstr to the wtls_message_unpack function */        returnPayload = wtls_payload_unpack(dataFromOffsetToLength);                /* Test to make sure the returned PDU is good */        if (returnPayload != NULL) {                        /* And return the PDU to our caller */                return returnPayload;        }                /* Otherwise return NULL */        return NULL;}        wtls_Payload *wtls_payload_unpack(Octstr *data) {        wtls_Payload *payload = NULL;		Octstr *buffer;        long bitpos = 0, charpos = 0;        int msg_length;                gw_assert(data != NULL);        payload = gw_malloc(sizeof(wtls_Payload));        /* the record field length flag */        payload->rlen = octstr_get_bits(data, bitpos, 1);        bitpos += 1;        /* the sequence number flag */        payload->seqnum = octstr_get_bits(data, bitpos, 1);        bitpos += 1;        /* the cipher usage flag */        payload->cipher = octstr_get_bits(data, bitpos, 1);        bitpos += 1;        /* the reserved bit */        payload->reserved = octstr_get_bits(data, bitpos, 1);        bitpos += 1;        /* the message type */        payload->type = octstr_get_bits(data, bitpos, 4);        bitpos += 4;        charpos += 1;                /* get the sequence number if present */        if(payload->seqnum) {                seqnum = unpack_int16(data, &charpos);        }                /* get the WTLS plaintext length if present */        if(payload->rlen) {                msg_length = unpack_int16(data, &charpos);        }		/* the part of data that has just been processed is not		   needed anymore. We delete it. What is left of data is		   the payload. */		octstr_delete(data, 0, charpos);		payload->data = data;				return payload;}void *wtls_payloadlist_destroy(List* payloadList) {		wtls_Payload* currentPayload;		int listLen, i;				listLen = list_len(payloadList);		for( i=0; i<listLen; i++) {			currentPayload = (wtls_Payload *)list_get(payloadList, i);			wtls_payload_destroy(currentPayload);		}				/* delete the list itself */		gw_free(payloadList);}wtls_PDU *wtls_pdu_unpack(wtls_Payload *payload, WTLSMachine* wtls_machine) {        wtls_PDU *pdu = NULL;        Octstr *buffer;        long bitpos = 0, charpos = 0;        int msg_length;                gw_assert(payload->data != NULL);        pdu = gw_malloc(sizeof(*pdu));		pdu->type = payload->type;		pdu->reserved = payload->reserved;		pdu->cipher = payload->cipher;		pdu->seqnum = payload->seqnum;		pdu->rlen = payload->rlen;						/* is the PDU encrypted ? */			/*		if(pdu->cipher) {				buffer = wtls_decrypt(payload->data, wtls_machine);		}		else {		*/				buffer = payload->data;		/*		}		*/		        switch (pdu->type) {        case ChangeCipher_PDU:                pdu->u.cc.change = octstr_get_char(buffer, charpos);                charpos += 1;                break;        case Alert_PDU:                pdu->u.alert.level = octstr_get_char(buffer, charpos);                charpos += 1;                pdu->u.alert.desc = octstr_get_char(buffer, charpos);                charpos += 1;                pdu->u.alert.chksum = unpack_octstr_fixed(buffer, &charpos, 4);                break;          case Handshake_PDU:                pdu->u.handshake.msg_type = octstr_get_char(buffer, charpos);                charpos += 1;                pdu->u.handshake.length = unpack_int16(buffer, &charpos);                switch (pdu->u.handshake.msg_type) {                case hello_request:                        break;                case client_hello:                        pdu->u.handshake.client_hello = (ClientHello *)gw_malloc(sizeof(ClientHello));                        pdu->u.handshake.client_hello->clientversion = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.client_hello->random = unpack_random(buffer, &charpos);                        pdu->u.handshake.client_hello->session_id = unpack_octstr(buffer, &charpos);                        /* pack the list of keys */                        pdu->u.handshake.client_hello->client_key_ids = unpack_key_list(buffer, &charpos);                        pdu->u.handshake.client_hello->trusted_key_ids = unpack_key_list(buffer, &charpos);                        /* pack the list of CipherSuites */                        pdu->u.handshake.client_hello->ciphersuites = unpack_ciphersuite_list(buffer, &charpos);                        /* CompressionMethods */                        pdu->u.handshake.client_hello->comp_methods = unpack_compression_method_list(buffer, &charpos);                        pdu->u.handshake.client_hello->snmode = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.client_hello->krefresh = octstr_get_char(buffer, charpos);                        charpos += 1;                        break;                case server_hello:                        pdu->u.handshake.server_hello = (ServerHello *)gw_malloc(sizeof(ServerHello));                        pdu->u.handshake.server_hello->serverversion = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.server_hello->random = unpack_random(buffer, &charpos);                        pdu->u.handshake.server_hello->session_id = unpack_octstr(buffer, &charpos);                        charpos += 1;                        pdu->u.handshake.server_hello->client_key_id                                = octstr_get_char(buffer, charpos);                        charpos += 1;                        /* CypherSuite */                        pdu->u.handshake.server_hello->ciphersuite->bulk_cipher_algo                                = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.server_hello->ciphersuite->mac_algo                                = octstr_get_char(buffer, charpos);                        charpos += 1;                        /* CompressionMethod */                        pdu->u.handshake.server_hello->comp_method = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.server_hello->snmode = octstr_get_char(buffer, charpos);                        charpos += 1;                        pdu->u.handshake.server_hello->krefresh = octstr_get_char(buffer, charpos);                        charpos += 1;                        break;                case certificate:                        pdu->u.handshake.certificate = (Certificate *)gw_malloc(sizeof(Certificate));                        pdu->u.handshake.certificate->certificateformat = octstr_get_char(buffer, charpos);                        charpos += 1;                        switch (pdu->u.handshake.certificate->certificateformat) {                        case WTLSCert:                                pdu->u.handshake.certificate->wtls_certificate = unpack_wtls_certificate(buffer, &charpos);                                break;                        case X509Cert:                                pdu->u.handshake.certificate->x509_certificate = unpack_octstr16(buffer, &charpos);                                break;                        case X968Cert:                                pdu->u.handshake.certificate->x968_certificate = unpack_octstr16(buffer, &charpos);                                break;                        }                        break;                case server_key_exchange:                        pdu->u.handshake.server_key_exchange = (ServerKeyExchange *)gw_malloc(sizeof(ServerKeyExchange));                        /* unpack the ParameterSpecifier  and ParameterSet*/                        pdu->u.handshake.server_key_exchange->param_spec                                = unpack_param_spec(buffer, &charpos);                        switch (client_key_exchange_algo) {                        case rsa_anon:                                pdu->u.handshake.server_key_exchange->rsa_params                                        = unpack_rsa_pubkey(buffer, &charpos);                                break;                        case dh_anon:                                pdu->u.handshake.server_key_exchange->dh_params                                        = unpack_dh_pubkey(buffer, &charpos);                                break;                        case ecdh_anon:                                pdu->u.handshake.server_key_exchange->ecdh_params                                        = unpack_ec_pubkey(buffer, &charpos);                                break;                        }                        break;                case client_key_exchange:                        pdu->u.handshake.client_key_exchange = (ClientKeyExchange *)gw_malloc(sizeof(ClientKeyExchange));                        switch (client_key_exchange_algo) {                        case rsa:                        case rsa_anon:                                pdu->u.handshake.client_key_exchange->rsa_params                                        = unpack_rsa_encrypted_secret(buffer, &charpos);                                break;                        case dh_anon:                                pdu->u.handshake.client_key_exchange->dh_anon_params                                        = unpack_dh_pubkey(buffer, &charpos);                                break;                        case ecdh_anon:                        case ecdh_ecdsa:                                pdu->u.handshake.client_key_exchange->ecdh_params                                        = unpack_ec_pubkey(buffer, &charpos);                                break;                        }                        break;                case server_hello_done:                        /* empty */                        break;                case finished:                        pdu->u.handshake.finished = (Finished *)gw_malloc(sizeof(Finished));                        pdu->u.handshake.finished->verify_data                                        = unpack_octstr_fixed(buffer, &charpos, 12);						octstr_dump(pdu->u.handshake.finished->verify_data, 0);                        break;                }                break;        case Application_PDU:                /* application message */                pdu->u.application.data = octstr_duplicate(buffer);                break;        default:                debug("wap.wtls", 0, "%*sPDU: ", 0, "");                octstr_dump(buffer, 0);                panic(0, "Unpacking unknown WTLS PDU type %ld", (long) pdu->type);        }		        return pdu;}Octstr *wtls_payload_pack(wtls_Payload *payload) {        Octstr *data;        long bitpos, charpos;        long messageSizePos, sizepos;        /* Used for length calculations */        int size;                /* We rely on octstr_set_bits to lengthen our octstr as needed. */        data = octstr_create("");        bitpos = 0;        charpos = 0;        sizepos = 0;                /* the record field length flag - always present*/        octstr_set_bits(data, bitpos, 1, 1);        bitpos += 1;        /* the sequence number flag */        octstr_set_bits(data, bitpos, 1, payload->seqnum);        bitpos += 1;        /* the cipher usage flag */        octstr_set_bits(data, bitpos, 1, payload->cipher);        bitpos += 1;        /* the reserved bit */        octstr_set_bits(data, bitpos, 1, payload->reserved);        bitpos += 1;        /* set the message type */        octstr_set_bits(data, bitpos, 4, payload->type);        bitpos += 4;        charpos += 1;        /* set the sequence number if present */        if(payload->seqnum) {                charpos = pack_int16(data, charpos, payload->seqnum);        }        /* set the WTLS length  */        charpos = pack_int16(data, charpos, payload->rlen);                /* append the data from the wtls_PDU */        octstr_insert(data, payload->data, octstr_len(data));                 return data;}wtls_Payload *wtls_pdu_pack(wtls_PDU *pdu, WTLSMachine* wtls_machine) {        Octstr *data, *buffer, *encryptedbuffer;        wtls_Payload *payload;        long bitpos, charpos;        long messageSizePos, sizepos;        /* Used for length calculations */        int size, recordType;        		/* create the wtls_PDU */		payload = (wtls_Payload *)gw_malloc(sizeof(wtls_Payload));				payload->type = pdu->type;		payload->reserved = pdu->reserved;		payload->cipher = pdu->cipher;		payload->seqnum = pdu->seqnum;		        /* We rely on octstr_set_bits to lengthen our octstr as needed. */        data = octstr_create("");        buffer = octstr_create("");        bitpos = 0;        charpos = 0;        sizepos = 0;                switch (pdu->type) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?