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 + -
显示快捷键?