📄 connmgr.c
字号:
wtls_cm_push_buffer (wtls_connection_t *conn, BYTE *buf, UINT16 buflen)
{
wtls_handshake_state *hs = conn->h_state;
hs->hm[hs->num_handshake_msgs].buf = buf;
hs->hm[hs->num_handshake_msgs].buflen = buflen;
hs->num_handshake_msgs++;
}
static void
wtls_cm_copy_buffer (wtls_connection_t *conn, BYTE *buf, UINT16 buflen)
{
wtls_handshake_state *hs = conn->h_state;
BYTE *cbuf;
cbuf = NEWARRAY (BYTE, buflen);
B_COPYSTRINGN (cbuf, buf, buflen);
hs->hm[hs->num_handshake_msgs].buf = cbuf;
hs->hm[hs->num_handshake_msgs].buflen = buflen;
hs->num_handshake_msgs++;
}
SDL_Integer
wtls_cm_create_client_hello (void *connptr)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_handshake_state *hs = conn->h_state;
wtls_client_hello *ch = &(hs->client_hello);
ch->client_version = WTLS_PROTOCOL_VERSION;
B_COPYSTRINGN (ch->random, hs->pending.client_hello_random, 16);
ch->session_id = hs->pending.session_id;
/* Finally, sequence number and key refresh */
ch->seqnum_mode = SEQNUMMODE_EXPLICIT;
ch->key_refresh_rate = hs->pending.key_refresh_rate;
/* The following values are fetched from Cryptcfg.h */
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_getMethods, "WTLS: calling CRYPTa_getMethods");
#endif
CRYPTa_getMethods ((UINT16)conn->cm_proc);
return RET_OK;
}
SDL_Integer
wtls_cm_continue_create_client_hello (void *connptr, SDL_Integer result,
void *cmptr, SDL_Natural cmlen,
void *kxptr, SDL_Natural kxlen,
void *tkptr, SDL_Natural tklen,
void **pbufptr, SDL_Natural *pbuflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_handshake_state *hs = conn->h_state;
wtls_client_hello *ch = &(hs->client_hello);
wap_cvt_t cvt_obj;
BYTE *buf;
UINT16 buflen;
if (result != CRV_OK) {
wtls_err_set (ERR_CRYPTLIB, ERR_GET_METHODS,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
DEALLOC (&cmptr);
DEALLOC (&kxptr);
DEALLOC (&tkptr);
return -1;
}
wtls_cm_make_cipher_suites (conn->server_addr.Bearer,
(BYTE *)cmptr, (UINT16)cmlen,
&(ch->cipher_suites), &(ch->cipher_suites_len));
DEALLOC (&cmptr);
ch->client_key_ids = (BYTE *)kxptr;
ch->client_key_id_len = (UINT16)kxlen;
ch->trusted_key_ids = (BYTE *)tkptr;
ch->trusted_key_id_len = (UINT16)tklen;
ch->compression_methods = NEWARRAY (BYTE, 1);
ch->compression_methods[0] = COMPRESS_NULL;
ch->num_compression_methods = 1;
/* Convert to external format */
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
wtls_cvt_client_hello (&cvt_obj, ch);
buflen = (UINT16)cvt_obj.pos;
ch->msg_type = HANDSHK_CLIENT_HELLO;
ch->length = (UINT16)(buflen - 3);
buf = NEWARRAY (BYTE, buflen);
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
wtls_cvt_client_hello (&cvt_obj, ch);
conn->h_state->msgs |= BIT_CLIENT_HELLO;
wtls_cm_copy_buffer (conn, buf, buflen);
*pbufptr = buf;
*pbuflen = buflen;
return RET_OK;
}
/*
* Check the contents of the Server Hello message,
* and copy parameters to the pending state.
*/
SDL_Integer
wtls_cm_process_server_hello (void *connptr, void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_server_hello *sh;
wtls_client_hello *ch;
INT16 i;
INT16 resuming = FALSE;
wap_cvt_t cvt_obj;
ch = &(conn->h_state->client_hello);
sh = &(conn->h_state->server_hello);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_server_hello (&cvt_obj, sh)) {
wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
DEALLOC (&buf);
return -1;
}
/* Protocol version */
if (ch->client_version != sh->server_version) {
DEALLOC (&buf);
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_MESSAGE_PARAMETERS,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
return -1;
}
/* Random value */
B_COPYSTRINGN (conn->h_state->pending.server_hello_random, sh->random, 16);
/* Session Id */
if ((ch->session_id.length > 0) &&
(ch->session_id.length == sh->session_id.length) &&
(memcmp (ch->session_id.id, sh->session_id.id,
ch->session_id.length) == 0)) {
resuming = TRUE;
}
else {
conn->h_state->pending.session_id = sh->session_id;
}
/* Client key ID */
if (!resuming) {
if (wtls_cm_check_client_key_id_index (conn, ch, sh) != RET_OK) {
DEALLOC (&buf);
return -1;
}
}
else {
conn->h_state->key_exch.key_exchange_suite = 0;
}
/* Check selected cipher suite */
if (!resuming) {
if (wtls_cm_check_cipher_suite (conn, ch, sh) != RET_OK) {
DEALLOC (&buf);
return -1;
}
}
else {
if ((conn->h_state->pending.bulk_cipher_alg !=
sh->cipher_suite.bulk_cipher_alg) ||
(conn->h_state->pending.mac_alg != sh->cipher_suite.mac_alg)) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_CIPHER_SUITE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
DEALLOC (&buf);
return -1;
}
}
/* Check selected compression method */
if (!resuming) {
for (i = 0; i < ch->num_compression_methods; i++) {
if (ch->compression_methods[i] == sh->compression_method)
break;
}
if (i == ch->num_compression_methods) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_COMPRESSION_ALG,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
DEALLOC (&buf);
return -1;
}
conn->h_state->pending.compression_alg = sh->compression_method;
}
else {
if (conn->h_state->pending.compression_alg != sh->compression_method) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_COMPRESSION_ALG,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
DEALLOC (&buf);
return -1;
}
}
/* Check sequence number mode */
if (sh->seqnum_mode != SEQNUMMODE_EXPLICIT) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_SEQNUM_MODE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
DEALLOC (&buf);
return -1;
}
conn->h_state->pending.seqnum_mode = sh->seqnum_mode;
/* Check key refresh rate */
if (sh->key_refresh_rate > ch->key_refresh_rate) {
wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_KEY_REFRESH,
1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
DEALLOC (&buf);
return -1;
}
conn->h_state->pending.key_refresh_rate = sh->key_refresh_rate;
conn->h_state->msgs |= BIT_SERVER_HELLO;
wtls_cm_push_buffer (conn, buf, (UINT16)buflen);
if (resuming) {
return RET_ABBR;
}
else if ((conn->h_state->key_exch.key_exchange_suite ==
KEY_EXCH_SHARED_SECRET) ||
(conn->h_state->key_exch.key_exchange_suite ==
KEY_EXCH_NULL)) {
return RET_SHARED_SECRET;
}
else {
return RET_FULL;
}
}
SDL_Integer
wtls_cm_process_server_certificate (void *connptr,
void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_server_certificate *sc;
wap_cvt_t cvt_obj;
sc = &(conn->h_state->server_certificate);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_server_certificate (&cvt_obj, sc)) {
wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
DEALLOC (&buf);
return -1;
}
conn->h_state->msgs |= BIT_SERVER_CERTIFICATE;
wtls_cm_push_buffer (conn, buf, (UINT16)buflen);
return RET_OK;
}
SDL_Integer
wtls_cm_process_server_key_exchange (void *connptr,
void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_server_key_exchange *ske;
wap_cvt_t cvt_obj;
ske = &(conn->h_state->server_key_exchange);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_server_key_exchange (&cvt_obj,
conn->h_state->key_exch.key_exchange_suite, ske)) {
wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
DEALLOC (&buf);
return -1;
}
conn->h_state->msgs |= BIT_SERVER_KEY_EXCHANGE;
wtls_cm_push_buffer (conn, buf, (UINT16)buflen);
return RET_OK;
}
SDL_Integer
wtls_cm_process_certificate_request (void *connptr,
void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_certificate_request *cr;
wap_cvt_t cvt_obj;
cr = &(conn->h_state->certificate_request);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_certificate_request (&cvt_obj, cr)) {
wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
DEALLOC (&buf);
return -1;
}
conn->h_state->msgs |= BIT_SERVER_CERTIFICATE_REQUEST;
wtls_cm_push_buffer (conn, buf,(UINT16) buflen);
return RET_OK;
}
INT16
wtls_cm_process_server_hello_done (void *connptr,
void *bufptr, SDL_Natural buflen)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
BYTE *buf = (BYTE *)bufptr;
wtls_server_hello_done *shd;
wap_cvt_t cvt_obj;
shd = &(conn->h_state->server_hello_done);
wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
if (!wtls_cvt_server_hello_done (&cvt_obj, shd)) {
wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
DEALLOC (&buf);
return -1;
}
conn->h_state->msgs |= BIT_SERVER_HELLO_DONE;
wtls_cm_push_buffer (conn, buf, (UINT16)buflen);
return RET_OK;
}
SDL_Integer
wtls_cm_create_client_certificate_msg (void *connptr)
{
wtls_connection_t *conn = (wtls_connection_t *)connptr;
wtls_certificate_request *cr = &(conn->h_state->certificate_request);
/* If the server has requested a client certificate, then we
* must send a Certificate message. */
if (conn->h_state->msgs & BIT_SERVER_CERTIFICATE_REQUEST) {
if (conn->h_state->key_exch.identifier.identifier_type != IDENTIFIER_NULL) {
return RET_SEND_MSG;
}
#ifdef LOG_EXTERNAL
CLNTa_log (0, log_wtls_CRYPTa_getClientCertificate,
"WTLS: calling CRYPTa_getClientCertificate");
#endif
CRYPTa_getClientCertificate ((UINT16)conn->cm_proc,
cr->buf, cr->buflen);
return RET_GET_CERT;
}
return RET_OK;
}
SDL_Integer
wtls_cm_continue_create_client_certificate_msg (void *connptr)
{
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;
cc->msg_type = HANDSHK_CERTIFICATE;
cc->buflen = 0;
cc->buf = NULL;
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;
wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
wtls_cvt_identifier (&cvt_obj, &(conn->h_state->key_exch.identifier));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -