📄 wtls_pdu.c
字号:
/* 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) { case ChangeCipher_PDU: octstr_append_char(buffer, pdu->u.cc.change); charpos += 1; break; case Alert_PDU: octstr_append_char(buffer, pdu->u.alert.level); charpos += 1; octstr_append_char(buffer, pdu->u.alert.desc); charpos += 1; charpos = pack_octstr_fixed(buffer, charpos, pdu->u.alert.chksum); charpos += 1; break; case Handshake_PDU: octstr_append_char(buffer, pdu->u.handshake.msg_type); charpos += 1; /* Save the location of the message size */ messageSizePos = charpos; charpos = pack_int16 (buffer, charpos, pdu->u.handshake.length); switch (pdu->u.handshake.msg_type) { case hello_request: break; case client_hello: octstr_append_char(buffer, pdu->u.handshake.client_hello->clientversion); charpos += 1; charpos = pack_random(buffer, charpos, pdu->u.handshake.client_hello->random); octstr_append_char(buffer, octstr_len( pdu->u.handshake.client_hello->session_id)); charpos += 1; charpos = pack_octstr(buffer, charpos, pdu->u.handshake.client_hello->session_id); /* pack the list of keys */ charpos = pack_key_list(buffer, charpos, pdu->u.handshake.client_hello->client_key_ids); charpos = pack_key_list(buffer, charpos, pdu->u.handshake.client_hello->trusted_key_ids); /* pack the list of CipherSuites */ charpos = pack_ciphersuite_list(buffer, charpos, pdu->u.handshake.client_hello->ciphersuites); /* CompressionMethods */ charpos = pack_compression_method_list(buffer, charpos, pdu->u.handshake.client_hello->comp_methods); octstr_append_char(buffer, pdu->u.handshake.client_hello->snmode); charpos += 1; octstr_append_char(buffer, pdu->u.handshake.client_hello->krefresh); charpos += 1; break; case server_hello: octstr_append_char(buffer, pdu->u.handshake.server_hello->serverversion); charpos += 1; charpos = pack_random(buffer, charpos, pdu->u.handshake.server_hello->random); charpos = pack_octstr(buffer, charpos, pdu->u.handshake.server_hello->session_id); charpos += 1; octstr_append_char(buffer, pdu->u.handshake.server_hello-> client_key_id); charpos += 1; /* CypherSuite */ octstr_append_char(buffer, pdu->u.handshake.server_hello-> ciphersuite->bulk_cipher_algo); charpos += 1; octstr_append_char(buffer, pdu->u.handshake.server_hello-> ciphersuite->mac_algo); charpos += 1; /* CompressionMethod */ octstr_append_char(buffer, pdu->u.handshake.server_hello->comp_method); charpos += 1; octstr_append_char(buffer, pdu->u.handshake.server_hello->snmode); charpos += 1; octstr_append_char(buffer, pdu->u.handshake.server_hello->krefresh); charpos += 1; break; case certificate: octstr_append_char(buffer, pdu->u.handshake.certificate->certificateformat); charpos += 1; switch (pdu->u.handshake.certificate->certificateformat) { case WTLSCert: charpos = pack_wtls_certificate(buffer, charpos, pdu->u.handshake.certificate->wtls_certificate); break; case X509Cert: charpos = pack_octstr16(buffer, charpos, pdu->u.handshake.certificate->x509_certificate); break; case X968Cert: charpos = pack_octstr16(buffer, charpos, pdu->u.handshake.certificate->x968_certificate); break; } break; case server_key_exchange: debug("wtls: ", 0,"Packing ServerKeyExchange"); /* pack the ParameterSpecifier */ charpos = pack_param_spec(buffer, charpos, pdu->u.handshake.server_key_exchange->param_spec); switch (client_key_exchange_algo) { case rsa_anon: charpos = pack_rsa_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->rsa_params); break; case dh_anon: charpos = pack_dh_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->dh_params); break; case ecdh_anon: charpos = pack_ec_pubkey(buffer, charpos, pdu->u.handshake.server_key_exchange->ecdh_params); break; } break; case client_key_exchange: switch (client_key_exchange_algo) { case rsa: case rsa_anon: charpos = pack_rsa_encrypted_secret(buffer, charpos, pdu->u.handshake.client_key_exchange->rsa_params); break; case dh_anon: charpos = pack_dh_pubkey(buffer, charpos, pdu->u.handshake.client_key_exchange->dh_anon_params); break; case ecdh_anon: case ecdh_ecdsa: charpos = pack_ec_pubkey(buffer, charpos, pdu->u.handshake.client_key_exchange->ecdh_params); break; } break; case server_hello_done: /* empty */ break; case finished: charpos = pack_octstr_fixed(buffer, charpos, pdu->u.handshake.finished->verify_data); debug("wtls", 0, "verify_data (in pack)"); octstr_dump(pdu->u.handshake.finished->verify_data,0 ); break; } /* Change the length */ size = octstr_len(buffer) - messageSizePos - 2; debug("wtls_msg.c:length",0,"Setting msg size to : %d",size); octstr_set_char(buffer, messageSizePos, (size & 0xFF00) >> 8); messageSizePos += 1; octstr_set_char(buffer, messageSizePos, (size & 0x00FF)); /* we keep the handshake data to create the Finished PDU */ octstr_append(wtls_machine->handshake_data, buffer); break; case Application_PDU: /* application message */ charpos += pack_octstr(data, charpos, pdu->u.application.data); break; default: panic(0, "Packing unknown WTLS PDU type %ld", (long) pdu->type); } /* encrypt the buffer if needed */ if(pdu->cipher) { /* the MAC is calculated with the record type so we need it now */ recordType = 1 << 7; /* length, always present */ recordType |= pdu->seqnum << 6; recordType |= pdu->cipher << 5; recordType |= pdu->reserved << 4; recordType |= pdu->type; encryptedbuffer = wtls_encrypt(buffer, wtls_machine, recordType); payload->data = encryptedbuffer; } else { payload->data = buffer; } payload->rlen = octstr_len(payload->data); debug("wtls", 0, "Packed PDU Length: %d", payload->rlen); return payload;}void wtls_pdu_dump(wtls_PDU *pdu, int level) { unsigned char *dbg = "wap.wtls"; /* the message type */ debug(dbg, 0, "%*sPDU type: %p", level, "", pdu->type); /* the reserved bit */ debug(dbg, 0, "%*sReserved bit: %p", level, "", pdu->reserved); /* cipher usage flag */ debug(dbg, 0, "%*sCipher in use: %p", level, "", pdu->cipher); /* the sequence number flag */ debug(dbg, 0, "%*sSequence number in use: %p", level, "", pdu->seqnum); /* the record field length flag */ debug(dbg, 0, "%*sRecord field length present: %p", level, "", pdu->rlen); switch (pdu->type) { case ChangeCipher_PDU: debug(dbg, 0, "%*sChangeCipher:", level, ""); debug(dbg, 0, "%*sChange: %d", level+1, "", pdu->u.cc.change); break; case Alert_PDU: debug(dbg, 0, "%*sAlert:", level, ""); debug(dbg, 0, "%*sLevel: %p", level+1, "", pdu->u.alert.level); debug(dbg, 0, "%*sDescription: %d", level+1, "", pdu->u.alert.desc); debug(dbg, 0, "%*sChecksum: %p", level+1, "", pdu->u.alert.chksum); break; case Handshake_PDU: debug(dbg, 0, "%*sHandshake:", level, ""); debug(dbg, 0, "%*sMessage Type: %d", level+1, "", pdu->u.handshake.msg_type); debug(dbg, 0, "%*sLength: %d", level+1, "", pdu->u.handshake.length); switch (pdu->u.handshake.msg_type) { case hello_request: debug(dbg, 0, "%*sHelloRequest.", level, ""); break; case client_hello: debug(dbg, 0, "%*sClientHello :", level, ""); debug(dbg, 0, "%*sClient version: %d", level+1, "", pdu->u.handshake.client_hello->clientversion); debug(dbg, 0, "%*sRandom:", level+1, ""); dump_random(dbg, level+2, pdu->u.handshake.client_hello->random); debug(dbg, 0, "%*sSessionId: ", level, ""); octstr_dump(pdu->u.handshake.client_hello->session_id, level + 2); /* pack the list of keys */ debug(dbg, 0, "%*sClient Key IDs: ", level+1, ""); dump_key_list(dbg, level+2, pdu->u.handshake.client_hello->client_key_ids); debug(dbg, 0, "%*sTrusted Key IDs: ", level+1, ""); dump_key_list(dbg, level+2, pdu->u.handshake.client_hello->trusted_key_ids); /* pack the list of CipherSuites */ debug(dbg, 0, "%*sCipherSuite List: ", level+1, ""); dump_ciphersuite_list(dbg, level+2, pdu->u.handshake.client_hello->ciphersuites); /* CompressionMethods */ debug(dbg, 0, "%*sCompression Method List: ", level+1, ""); dump_compression_method_list(dbg, level+2, pdu->u.handshake.client_hello->comp_methods); debug(dbg, 0, "%*sSeq Number Mode: %d", level+1, "", pdu->u.handshake.client_hello->snmode); debug(dbg, 0, "%*sKey Refresh: %p", level+1, "", pdu->u.handshake.client_hello->krefresh); break; case server_hello: debug(dbg, 0, "%*sServerHello :", level, ""); debug(dbg, 0, "%*sServer version: %d", level+1, "", pdu->u.handshake.server_hello->serverversion); debug(dbg, 0, "%*sRandom:", level+1, ""); dump_random(dbg, level+2, pdu->u.handshake.server_hello->random); debug(dbg, 0, "%*sSession ID: %d", level+1, "", pdu->u.handshake.server_hello->session_id); debug(dbg, 0, "%*sClient Key ID: %p", level+1, "", pdu->u.handshake.server_hello->client_key_id); /* CypherSuite */ debug(dbg, 0, "%*sBulk Cipher Algo: %p", level+1, "", pdu->u.handshake.server_hello->ciphersuite->bulk_cipher_algo); debug(dbg, 0, "%*sMAC Algo: %p", level+1, "", pdu->u.handshake.server_hello->ciphersuite->mac_algo); /* CompressionMethod */ debug(dbg, 0, "%*sCompression Method: %p", level+1, "", pdu->u.handshake.server_hello->comp_method); debug(dbg, 0, "%*sSeq Number Mode: %p", level+1, "", pdu->u.handshake.server_hello->snmode); debug(dbg, 0, "%*sKey Refresh: %p", level+1, "", pdu->u.handshake.server_hello->krefresh); break; case certificate: debug(dbg, 0, "%*sCertificate :", level, ""); debug(dbg, 0, "%*sCertificate Format: %p", level+1, "", pdu->u.handshake.certificate->certificateformat); switch (pdu->u.handshake.certificate->certificateformat) { case WTLSCert: debug(dbg, 0, "%*sWTLS Certificate: %p", level+1, ""); dump_wtls_certificate(dbg, level+2, pdu->u.handshake.certificate->wtls_certificate); break; case X509Cert: debug(dbg, 0, "%*sX509 Certificate: %p", level+1, ""); octstr_dump(pdu->u.handshake.certificate->x509_certificate, level+2); break; case X968Cert: debug(dbg, 0, "%*sX968 Certificate: %p", level+1, ""); octstr_dump(pdu->u.handshake.certificate->x968_certificate, level+2); break; } break; case server_key_exchange: debug(dbg, 0, "%*sServerKeyExchange :", level, ""); /* ParameterSpecifier */ debug(dbg, 0, "%*sParameter Index: %p", level+1, "", pdu->u.handshake.server_key_exchange->param_spec->param_index); if(pdu->u.handshake.server_key_exchange->param_spec->param_index == 255) { /* ParameterSet */ debug(dbg, 0, "%*sParameter Set: %p", level+1, "", pdu->u.handshake.server_key_exchange->param_spec->param_set); } switch (client_key_exchange_algo) { case rsa_anon: dump_rsa_pubkey(dbg, level+1, pdu->u.handshake.server_key_exchange->rsa_params); break; case dh_anon: dump_dh_pubkey(dbg, level+1, pdu->u.handshake.server_key_exchange->dh_params); break; case ecdh_anon: dump_ec_pubkey(dbg, level+1, pdu->u.handshake.server_key_exchange->ecdh_params); break; } break; case client_key_exchange: debug(dbg, 0, "%*sClientKeyExchange :", level, ""); switch (client_key_exchange_algo) { case rsa: case rsa_anon: dump_rsa_encrypted_secret(dbg, level+1, pdu->u.handshake.client_key_exchange->rsa_params); break; case dh_anon: dump_dh_pubkey(dbg, level+1, pdu->u.handshake.client_key_exchange->dh_anon_params); break; case ecdh_anon: case ecdh_ecdsa: dump_ec_pubkey(dbg, level+1, pdu->u.handshake.client_key_exchange->ecdh_params); break; } break; case server_hello_done: debug(dbg, 0, "%*sClientHelloDone.", level, ""); /* empty */ break; case finished: debug(dbg, 0, "%*sFinished :", level, ""); debug(dbg, 0, "%*sverify_data :", level+1, ""); octstr_dump(pdu->u.handshake.finished->verify_data, level+2); break; } break; case Application_PDU: debug(dbg, 0, "%*sApplication :", level, ""); /* application message */ octstr_dump(pdu->u.application.data, level+1); break; default: debug(dbg, 0, "%*sWTLS PDU at %p:", level, "", (void *)pdu); debug(dbg, 0, "%*s unknown type %u", level, "", pdu->type); } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -