⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtls_pdu.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 3 页
字号:
        }}/* This function will unpack an Octstr, starting at the specified offset, and   return the corresponding wtls_PDU* which was generated from that offset. Offset   is changed during the running of this function, and ends up as the octet at the start of the   next pdu */wtls_Payload* wtls_payload_unpack_from_offset (Octstr *data, int *offset) {        int guessedPayloadLength = 0;        int dataLength = 0;        Octstr* dataFromOffset = 0;        Octstr* dataFromOffsetToLength = 0;        wtls_Payload* returnPayload = 0;                /* This would be a sure sign of trouble */        gw_assert (offset != NULL);        gw_assert (data != NULL);        gw_assert (octstr_len(data) >= *offset);        dataLength = octstr_len(data);                /* First, we need to figure out how long a PDU starting from           the specified offset is going to be. We need to peek quickly into the           PDU to check this */        dataFromOffset = octstr_copy(data, *offset, dataLength);        guessedPayloadLength = wtls_payload_guess_length(dataFromOffset);        /* Ooops. Something's wrong. This requested PDU is screwed up. */        if (guessedPayloadLength == -1) {                *offset = dataLength;                return NULL;        }                /* Quit if we discover that the PDU length plus the requested offset is           larger than the length of the data supplied - this would mean that we           would overrun our data, and therefore something is corrupt in this PDU.           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;

⌨️ 快捷键说明

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