📄 connmgr.c
字号:
buflen = (UINT16)cvt_obj.pos;
buf = NEWARRAY (BYTE, buflen);
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
if (!wtls_cvt_identifier (&cvt_obj, &(conn->h_state->key_exch.identifier))) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
DEALLOC (&buf);
return -1;
}
conn->h_state->key_id = buf;
conn->h_state->key_idlen = buflen;
return RET_OK;
}
SDL_Integer
wtls_cm_process_client_certificate_response (void *connptr,
SDL_Natural result,
void *key_id,
SDL_Natural key_idlen,
void **pbufptr,
SDL_Natural *pbuflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_client_certificate *cc = &(conn->h_state->client_certificate);
wap_cvt_t cvt_obj;
BYTE *buf;
UINT16 buflen;
if (result == CRV_MISSING_CERTIFICATE) {
cc->buflen = 0;
cc->buf = NULL;
}
else if (result == CRV_OK) {
cc->buflen = (UINT16)*pbuflen;
cc->buf = (BYTE *)*pbufptr;
}
else {
wtls_err_set (ERR_CRYPTLIB, ERR_GET_CLIENT_CERTIFICATE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
cc->length = 0;
cc->msg_type = HANDSHK_CERTIFICATE;
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
if (!wtls_cvt_client_certificate (&cvt_obj, cc)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
buflen = (UINT16)cvt_obj.pos;
cc->length = buflen - 3;
buf = NEWARRAY (BYTE, buflen);
if (buf == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
}
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
if (!wtls_cvt_client_certificate (&cvt_obj, cc)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
DEALLOC (&buf);
return -1;
}
wtls_cm_copy_buffer (conn, buf, buflen);
conn->h_state->msgs |= BIT_CLIENT_CERTIFICATE;
conn->h_state->key_id = key_id;
conn->h_state->key_idlen = (UINT16)key_idlen;
*pbufptr = buf;
*pbuflen = buflen;
return RET_OK;
}
SDL_Integer
wtls_cm_create_client_key_exchange (void *connptr,
void **pbufptr, SDL_Natural *pbuflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wap_cvt_t cvt_obj;
/* In case we need to send a Client Key Exchange message */
if (conn->h_state->need_client_key_exchange) {
wtls_client_key_exchange *cke = &(conn->h_state->client_key_exchange);
BYTE *buf;
UINT16 buflen;
KeyExchangeSuite kes = conn->h_state->key_exch.key_exchange_suite;
cke->msg_type = HANDSHK_CLIENT_KEY_EXCHANGE;
cke->length = 0;
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
if (!wtls_cvt_client_key_exchange (&cvt_obj, kes, cke)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
buflen = (UINT16)cvt_obj.pos;
buf = NEWARRAY (BYTE, buflen);
if (buf == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
}
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
cke->length = buflen - 3;
if (!wtls_cvt_client_key_exchange (&cvt_obj, kes, cke)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
wtls_cm_copy_buffer (conn, buf, buflen);
conn->h_state->msgs |= BIT_CLIENT_KEY_EXCHANGE;
*pbufptr = buf;
*pbuflen = buflen;
return RET_SEND_MSG;
}
return RET_OK;
}
SDL_Integer
wtls_cm_create_certificate_verify_msg (void *connptr)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_crypto_t cobj;
BYTE md[MAX_HASH_MAC_SIZE];
INT16 i;
if ((conn->h_state->msgs & BIT_CLIENT_CERTIFICATE) &&
(conn->h_state->client_certificate.buflen != 0)) {
/* Apply the current hash function to all previous handshake
* messages. */
wtls_crypto_init (&cobj,
conn->h_state->pending.bulk_cipher_alg,
conn->h_state->pending.mac_alg,
conn->h_state->pending.compression_alg);
if (wtls_crypto_hash_init (&cobj) < 0) {
return -1;
}
for (i = 0; i < conn->h_state->num_handshake_msgs; i++) {
if (wtls_crypto_hash_update (&cobj,
conn->h_state->hm[i].buf,
conn->h_state->hm[i].buflen) < 0) {
return -1;
}
}
if (wtls_crypto_hash_final (&cobj, md) < 0) {
return -1;
}
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_computeSignature,
"WTLS: calling CRYPTa_computeSignature");
#endif
CRYPTa_computeSignature ((UINT16)conn->cm_proc,
conn->h_state->key_id, conn->h_state->key_idlen,
md, cobj.full_mac_size);
return RET_SEND_MSG;
}
return RET_OK;
}
SDL_Integer
wtls_cm_process_compute_signature_response (void *connptr,
SDL_Natural result,
void **pbufptr,
SDL_Natural *pbuflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_certificate_verify *cv = &(conn->h_state->certificate_verify);
wap_cvt_t cvt_obj;
BYTE *buf;
UINT16 buflen;
if (result != CRV_OK) {
wtls_err_set (ERR_CRYPTLIB, ERR_COMPUTE_SIGNATURE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
cv->msg_type = HANDSHK_CERTIFICATE_VERIFY;
cv->siglen = (UINT16)*pbuflen;
cv->signature = *pbufptr;
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
if (!wtls_cvt_certificate_verify (&cvt_obj, cv)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
buflen = (UINT16)cvt_obj.pos;
buf = NEWARRAY (BYTE, buflen);
if (buf == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
}
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
cv->length = buflen - 3;
if (!wtls_cvt_certificate_verify (&cvt_obj, cv)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
wtls_cm_copy_buffer (conn, buf, buflen);
conn->h_state->msgs |= BIT_CLIENT_CERTIFICATE_VERIFY;
*pbufptr = buf;
*pbuflen = buflen;
return RET_OK;
}
SDL_Integer
wtls_cm_verify_cert (void *connptr)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE addr[18];
/* If server sent a certificate, then verify it. */
if (conn->h_state->msgs & BIT_SERVER_CERTIFICATE) {
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_verifyCertificateChain,
"WTLS: calling CRYPTa_verifyCertificateChain");
#endif
wtls_cm_mkaddr (&(conn->server_addr), addr);
CRYPTa_verifyCertificateChain ((UINT16)conn->cm_proc,
conn->h_state->server_certificate.buf,
conn->h_state->server_certificate.buflen,
addr, (UINT16)(addr[1] + 2),
NULL, 0);
return RET_VERIFY_CERT;
}
return RET_OK;
}
SDL_Integer
wtls_cm_process_verify_cert_result (SDL_Integer res)
{
SDL_Integer retval = -1;
if (res == CRV_UNKNOWN_CERTIFICATE_TYPE) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_UNSUPPORTED_CERTIFICATE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_UNSUPPORTED_CERTIFICATE);
}
else if (res == CRV_NO_MATCHING_ROOT_CERTIFICATE) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_UNKNOWN_CA,
1, ALERT_LEVEL_FATAL, ALERT_DESC_UNKNOWN_CA);
}
else if (res == CRV_BAD_CERTIFICATE) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_BAD_CERTIFICATE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_BAD_CERTIFICATE);
}
else if (res == CRV_CERTIFICATE_EXPIRED) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_CERTIFICATE_EXPIRED,
1, ALERT_LEVEL_FATAL, ALERT_DESC_CERTIFICATE_EXPIRED);
}
else {
retval = RET_OK;
}
return retval;
}
/*
* Create a client Finished message to be sent to the server.
* This is defined in WTLS spec section 10.5.9.
*/
SDL_Integer
wtls_cm_create_verify_data (void *connptr)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE md[MAX_HASH_MAC_SIZE];
INT16 i;
wtls_crypto_t cobj;
/* Apply the current hash function to all previous handshake
* messages. */
wtls_crypto_init (&cobj,
conn->h_state->pending.bulk_cipher_alg,
conn->h_state->pending.mac_alg,
conn->h_state->pending.compression_alg);
if (wtls_crypto_hash_init (&cobj) < 0) {
return -1;
}
for (i = 0; i < conn->h_state->num_handshake_msgs; i++) {
if (wtls_crypto_hash_update (&cobj,
conn->h_state->hm[i].buf,
conn->h_state->hm[i].buflen) < 0) {
return -1;
}
}
if (wtls_crypto_hash_final (&cobj, md) < 0) {
return -1;
}
/* PRF (master_secret, finished_label, H(handshake_messages))[0..11]; */
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
CRYPTa_PRF ((UINT16)conn->cm_proc,
cobj.hash_alg,
conn->h_state->pending.master_secret_id, NULL, 0,
"client finished",
md, cobj.full_mac_size, 12);
return RET_OK;
}
SDL_Integer
wtls_cm_create_finished (void *connptr, void **pbufptr, SDL_Natural *pbuflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)*pbufptr;
wtls_finished *cf = &(conn->h_state->client_finished);
wap_cvt_t cvt_obj;
if (*pbuflen != 12) {
wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
cf->msg_type = HANDSHK_FINISHED;
cf->length = 12;
B_COPYSTRINGN (cf->verify_data, buf, 12);
DEALLOC (&buf);
buf = NEWARRAY (BYTE, 15);
if (buf == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
}
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, 15);
if (!wtls_cvt_finished (&cvt_obj, cf)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
DEALLOC (&buf);
return -1;
}
wtls_cm_copy_buffer (conn, buf, 15);
conn->h_state->msgs |= BIT_CLIENT_FINISHED;
*pbufptr = buf;
*pbuflen = 15;
return RET_OK;
}
SDL_Integer
wtls_cm_process_finished (void *connptr, void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_finished *sf;
wap_cvt_t cvt_obj;
wtls_crypto_t *cobj = &(conn->read.cobj);
BYTE md[MAX_HASH_MAC_SIZE];
INT16 i;
/* Apply the current hash function to all previous handshake
* messages. */
if (wtls_crypto_hash_init (cobj) < 0) {
DEALLOC (&buf);
return -1;
}
for (i = 0; i < conn->h_state->num_handshake_msgs; i++) {
if (wtls_crypto_hash_update (cobj,
conn->h_state->hm[i].buf,
conn->h_state->hm[i].buflen) < 0) {
DEALLOC (&buf);
return -1;
}
}
if (wtls_crypto_hash_final (cobj, md) < 0) {
DEALLOC (&buf);
return -1;
}
sf = &(conn->h_state->server_finished);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_finished (&cvt_obj, sf)) {
wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
DEALLOC (&buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -