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

📄 connmgr.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    return -1;
  }
  conn->h_state->msgs |= BIT_SERVER_FINISHED;
  wtls_cm_push_buffer (conn, buf, (UINT16)buflen);

  /* 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->read.master_secret_id, NULL, 0,
              "server finished",
              md, cobj->full_mac_size, 12);

  return RET_OK;
}

/*
 * Check a server Finished message that we received.
 * This is defined in WTLS spec section 10.5.9.
 */
SDL_Integer
wtls_cm_check_server_finished (void *connptr, SDL_Integer result,
                               void *bufptr, SDL_Natural buflen)
{
  wtls_connection_t *conn = (wtls_connection_t *)connptr;
  BYTE              *buf = (BYTE *)bufptr;
  wtls_finished     *sf = &(conn->h_state->server_finished);
  INT16             i;
  SDL_Integer       retval = RET_OK;

  if (result != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_SERVER_FINISHED,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_DECRYPT_ERROR);
    return -1;
  }

  if (buflen < 12) {
    wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_SERVER_FINISHED,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_DECRYPT_ERROR);
    DEALLOC (&buf);
    return -1;
  }

  /* Is it the same value as in the Finished message? */
#ifndef TEST_WTLS
  for (i = 0; i < 12; i++) {
    if (buf[i] != sf->verify_data[i]) {
      wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_SERVER_FINISHED,
                    1, ALERT_LEVEL_FATAL, ALERT_DESC_DECRYPT_ERROR);
      retval = -1;
      break;
    }
  }
#endif
  DEALLOC (&buf);

  return retval;
}

SDL_Integer
wtls_cm_process_data_msg (void *connptr,
                          void *bufptr, SDL_Natural buflen,
                          TDUnitdataIndType *data_ind)
{
  wtls_connection_t *conn = (wtls_connection_t *)connptr;

  yAssF_AddressType (data_ind->DestinationAddress, conn->client_addr, XASS);
  yAssF_AddressType (data_ind->SourceAddress, conn->server_addr, XASS);
  data_ind->UserData = pdubuf_newFromData ((UINT16)buflen, (BYTE *)bufptr);

  return RET_OK;
}

/*
 * Check incoming messages.
 * If we see a data message, then we have confirmation and go to
 * state OPEN. If we see an alert, then check what type of alert.
 */
SDL_Integer
wtls_cm_opening_msg_ind (void *connptr, SDL_Natural msg_type,
                         void *bufptr, SDL_Natural buflen,
                         TDUnitdataIndType *data_ind)
{
  wtls_connection_t *conn = (wtls_connection_t *)connptr;
  BYTE              *buf = (BYTE *)bufptr;
  wap_cvt_t          cvt_obj;
  wtls_alert_t       alert;

  switch (msg_type) {
  case CONTENT_TYPE_ALERT:
    wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, buf, (UINT16)buflen);
    if (!wtls_cvt_alert (&cvt_obj, &alert)) {
      wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
                    ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
      return -1;
    }

    if (alert.level == ALERT_LEVEL_WARNING) {
      if (alert.description == ALERT_DESC_DUPLICATE_FINISHED_RECEIVED) {
        return RET_DUPLICATE_FINISHED;
      }
    }
    wtls_err_set (ERR_RECEIVED_ALERT, ERR_RECEIVED_ALERT,
                  0, alert.level, alert.description);
    return -1;

  case CONTENT_TYPE_DATA:
    yAssF_AddressType (data_ind->DestinationAddress, conn->client_addr, XASS);
    yAssF_AddressType (data_ind->SourceAddress, conn->server_addr, XASS);
    data_ind->UserData = pdubuf_newFromData ((UINT16)buflen, buf);
    return RET_OK;

  case CONTENT_TYPE_HANDSHAKE:
    if (wtls_cm_get_handshake_type (buf, buflen) == HANDSHK_HELLO_REQUEST) {
      DEALLOC (&buf);
      return RET_HELLO_REQUEST;
    }
    DEALLOC (&buf);

    default:
      wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_UNEXPECTED_MESSAGE,
                    1, ALERT_LEVEL_CRITICAL, ALERT_DESC_UNEXPECTED_MESSAGE);
      return -1;
  }
}

SDL_Integer
wtls_cm_get_next_outbound_message (void *connptr,
                                   void **precptr)
{
  wtls_connection_t *conn = (wtls_connection_t *)connptr;
  
  *precptr = wtls_main_pop_outbound_message (conn->cm_proc);
  if (*precptr == NULL) {
    return RET_QUEUE_EMPTY;
  }

  return RET_OK;
}

void
wtls_cm_terminate (void *connptr, SDL_Boolean established)
{
  wtls_connection_t *conn = (wtls_connection_t *)connptr;

  if (established == SDL_True) {
    CRYPTa_connectionTerminated (conn->server_addr.ViewID,
                                 conn->server_addr.ChannelID);
    CRYPTa_sessionActive (conn->write.master_secret_id, 0);
  }

  wtls_connection_free (conn);
}

/************************************************************
 * Local functions
 ************************************************************/

static INT16
wtls_cm_check_client_key_id_index (wtls_connection_t *conn,
                                   wtls_client_hello *ch,
                                   wtls_server_hello *sh)
{
  INT16                 i;
  wtls_key_exchange_id *key_exchange_id = &(conn->h_state->key_exch);
  wap_cvt_t             cvt_obj;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC, ch->client_key_ids,
                ch->client_key_id_len);

  if (sh->client_key_id == 0) {
    wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_KEY_EXCHANGE_IDX,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
    return -1;
  }

  for (i = sh->client_key_id; i > 0; i--) {
    if (!wtls_cvt_key_exchange_id (&cvt_obj, key_exchange_id)) {
      wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_KEY_EXCHANGE_DECODE,
                    1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
      return -1;
    }
  }

  return RET_OK;
}

static INT16
wtls_cm_check_cipher_suite (wtls_connection_t *conn,
                            wtls_client_hello *ch,
                            wtls_server_hello *sh)
{
  INT16 i;

  for (i = 0; i < ch->cipher_suites_len; i += 2) {
    if ((ch->cipher_suites[i] == sh->cipher_suite.bulk_cipher_alg)
        && (ch->cipher_suites[i + 1] == sh->cipher_suite.mac_alg))
      break;
  }
  if (i >= ch->cipher_suites_len) {
    wtls_err_set (ERR_HANDSHAKE_FAILURE, ERR_CIPHER_SUITE,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_ILLEGAL_PARAMETER);
    return -1;
  }
  conn->h_state->pending.bulk_cipher_alg = sh->cipher_suite.bulk_cipher_alg;
  conn->h_state->pending.mac_alg = sh->cipher_suite.mac_alg;
    
  return RET_OK;
}


#define NUM_MAC_METHODS 3

static INT16
wtls_cm_make_cipher_suites (INT8 bearer,
                            BYTE *methods, UINT16 methodslen,
                            BYTE **cs, UINT8 *cslen)
{
  BYTE  *p;
  UINT8 SHA_methods[NUM_MAC_METHODS];
  UINT8 MD5_methods[NUM_MAC_METHODS];
  INT16 i, j;
  BYTE  *cipher_suites;

  /*
   * Our current policy: for each encryption algorithm make cipher
   * suites with MAC-algorithms in an order that depends on
   * the bearer. The faster the bearer, the longer the MAC.
   */
  cipher_suites = NEWARRAY (BYTE, methodslen * NUM_MAC_METHODS);
  if (cipher_suites == NULL) {
    return -1;
  }

  switch (bearer) {
  case BEARER_ANY_UDP:
  case BEARER_GSM_CSD:
  case BEARER_GSM_GPRS:
  case BEARER_BT:
    SHA_methods[0] = WTLS_MAC(SHA, UDP, 1);
    SHA_methods[1] = WTLS_MAC(SHA, UDP, 2);
    SHA_methods[2] = WTLS_MAC(SHA, UDP, 3);

    MD5_methods[0] = WTLS_MAC(MD5, UDP, 1);
    MD5_methods[1] = WTLS_MAC(MD5, UDP, 2);
    MD5_methods[2] = WTLS_MAC(MD5, UDP, 3);
    break;

  case BEARER_GSM_USSD:
    SHA_methods[0] = WTLS_MAC(SHA, USSD, 1);
    SHA_methods[1] = WTLS_MAC(SHA, USSD, 2);
    SHA_methods[2] = WTLS_MAC(SHA, USSD, 3);

    MD5_methods[0] = WTLS_MAC(MD5, USSD, 1);
    MD5_methods[1] = WTLS_MAC(MD5, USSD, 2);
    MD5_methods[2] = WTLS_MAC(MD5, USSD, 3);
    break;

  case BEARER_GSM_SMS:
  default:
    SHA_methods[0] = WTLS_MAC(SHA, SMS, 1);
    SHA_methods[1] = WTLS_MAC(SHA, SMS, 2);
    SHA_methods[2] = WTLS_MAC(SHA, SMS, 3);

    MD5_methods[0] = WTLS_MAC(MD5, SMS, 1);
    MD5_methods[1] = WTLS_MAC(MD5, SMS, 2);
    MD5_methods[2] = WTLS_MAC(MD5, SMS, 3);
    break;
  }

  p = cipher_suites;
  for (i = 0; i < methodslen; i += 2) {
    if (methods[i + 1] == HASH_SHA) {
      for (j = 0; j < NUM_MAC_METHODS; j++) {
        p[j * 2] = methods[i];
        p[j * 2 + 1] = SHA_methods[j];
      }
      p += (NUM_MAC_METHODS * 2);
    }
    else if (methods[i + 1] == HASH_MD5) {
      for (j = 0; j < NUM_MAC_METHODS; j++) {
        p[j * 2] = methods[i];
        p[j * 2 + 1] = MD5_methods[j];
      }
      p += (NUM_MAC_METHODS * 2);
    }
  }

  *cs = cipher_suites;
  *cslen = MIN ((p - cipher_suites), 254);;

  return RET_OK;
}

/*
 * Fetch values for connection parameters.
 *
 * When starting a new connection, certain parameters have to
 * be given values. These values may depend on what type
 * of bearer the connection uses. The different parameters are:
 *
 * Max number of retransmissions:
 * The maximum number of times we are willing to resend a handshake
 * message without getting an answer.
 *
 * Retry interval:
 * The maximum time to wait for an answer to a handshake message,
 * before sending it again. Time unit is 1/10 second.
 *
 * Timeout interval:
 * A connection is closed down if no messages are exchanged during
 * a time interval of this size. Time unit is 1/10 second.
 */
void
wtls_cm_get_connection_parameters (SDL_Octet bearer,
                                   SDL_Integer *maxRetransmissions,
                                   SDL_Integer *retryInterval)
{
  switch (bearer) {
  case BEARER_ANY_UDP:
  case BEARER_GSM_CSD:
  case BEARER_GSM_GPRS:
  case BEARER_BT:
    *maxRetransmissions = WTLS_MAX_RETRANSMISSIONS_UDP;
    *retryInterval = WTLS_RETRANSMISSION_INTERVAL_UDP;
    break;

  case BEARER_GSM_USSD:
    *maxRetransmissions = WTLS_MAX_RETRANSMISSIONS_USSD;
    *retryInterval = WTLS_RETRANSMISSION_INTERVAL_USSD;
    break;

  case BEARER_GSM_SMS:
    *maxRetransmissions = WTLS_MAX_RETRANSMISSIONS_SMS;
    *retryInterval = WTLS_RETRANSMISSION_INTERVAL_SMS;
    break;
  }
}

/*
 * Key refresh rate:
 * How often do we want to refresh the encryption keys?
 * A value n here means that we refresh the keys every 2^n messages.
 * For example, if n = 3, we refresh after 8, 16, 24, etc. messages.
 * The slower the bearer, the more often we do key refresh; the goal
 * being to have the same time interval between key refreshes for
 * all bearers.
 */
void
wtls_cm_set_key_refresh_rate (UINT8 bearer, UINT8 *key_refresh_rate)
{
  switch (bearer) {
  case BEARER_ANY_UDP:
  case BEARER_GSM_CSD:
  case BEARER_GSM_GPRS:
  case BEARER_BT:
    *key_refresh_rate = WTLS_KEY_REFRESH_RATE_UDP;
    break;

  case BEARER_GSM_USSD:
    *key_refresh_rate = WTLS_KEY_REFRESH_RATE_USSD;
    break;

  case BEARER_GSM_SMS:
    *key_refresh_rate = WTLS_KEY_REFRESH_RATE_SMS;
    break;
  }
}

static void
wtls_cm_mkaddr (AddressType *inaddr, BYTE *outaddr)
{
  switch (inaddr->Bearer) {
  case BEARER_ANY_UDP:
  case BEARER_GSM_CSD:
  case BEARER_GSM_GPRS:
  case BEARER_BT:
    outaddr[0] = BEARER_ANY_UDP;
    break;

  case BEARER_GSM_USSD:
    outaddr[0] = BEARER_GSM_USSD;
    break;

  case BEARER_GSM_SMS:
    outaddr[0] = BEARER_GSM_SMS;
    break;

  default:
    outaddr[0] = BEARER_ANY_UDP;
    break;
  }
  outaddr[1] = inaddr->Address.length;
  memcpy (outaddr + 2, inaddr->Address.data, inaddr->Address.length);
}

⌨️ 快捷键说明

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