示例#1
0
void ssl3_free(SSL *ssl) {
  if (ssl == NULL || ssl->s3 == NULL) {
    return;
  }

  ssl3_cleanup_key_block(ssl);
  ssl_read_buffer_clear(ssl);
  ssl_write_buffer_clear(ssl);
  SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
  OPENSSL_free(ssl->s3->tmp.peer_key);

  sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
  OPENSSL_free(ssl->s3->tmp.certificate_types);
  OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
  OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
  ssl3_free_handshake_buffer(ssl);
  ssl3_free_handshake_hash(ssl);
  OPENSSL_free(ssl->s3->next_proto_negotiated);
  OPENSSL_free(ssl->s3->alpn_selected);
  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);

  OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
  OPENSSL_free(ssl->s3);
  ssl->s3 = NULL;
}
示例#2
0
文件: s3_lib.c 项目: gfxcc/iShareOC
void ssl3_free(SSL *ssl) {
  if (ssl == NULL || ssl->s3 == NULL) {
    return;
  }

  ssl3_cleanup_key_block(ssl);
  ssl_read_buffer_clear(ssl);
  ssl_write_buffer_clear(ssl);
  SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
  OPENSSL_free(ssl->s3->tmp.peer_key);
  OPENSSL_free(ssl->s3->tmp.server_params);

  sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
  OPENSSL_free(ssl->s3->tmp.certificate_types);
  OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
  OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
  SSL_SESSION_free(ssl->s3->new_session);
  SSL_SESSION_free(ssl->s3->established_session);
  ssl3_free_handshake_buffer(ssl);
  ssl3_free_handshake_hash(ssl);
  ssl_handshake_free(ssl->s3->hs);
  OPENSSL_free(ssl->s3->next_proto_negotiated);
  OPENSSL_free(ssl->s3->alpn_selected);
  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
  OPENSSL_free(ssl->s3->pending_message);

  OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
  OPENSSL_free(ssl->s3);
  ssl->s3 = NULL;
}
示例#3
0
static int ssl3_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
  if (ssl->s3->rrec.length != 0) {
    /* There may not be unprocessed record data at a cipher change. */
    OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    SSL_AEAD_CTX_free(aead_ctx);
    return 0;
  }

  memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));

  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
  ssl->s3->aead_read_ctx = aead_ctx;
  return 1;
}
示例#4
0
static int ssl3_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
  memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));

  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
  ssl->s3->aead_write_ctx = aead_ctx;
  return 1;
}
示例#5
0
文件: s3_lib.c 项目: caiolima/webkit
void ssl3_free(SSL *ssl) {
  if (ssl == NULL || ssl->s3 == NULL) {
    return;
  }

  ssl3_cleanup_key_block(ssl);
  ssl_read_buffer_clear(ssl);
  ssl_write_buffer_clear(ssl);

  SSL_SESSION_free(ssl->s3->new_session);
  SSL_SESSION_free(ssl->s3->established_session);
  ssl3_free_handshake_buffer(ssl);
  ssl3_free_handshake_hash(ssl);
  ssl_handshake_free(ssl->s3->hs);
  OPENSSL_free(ssl->s3->next_proto_negotiated);
  OPENSSL_free(ssl->s3->alpn_selected);
  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
  OPENSSL_free(ssl->s3->pending_message);

  OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
  OPENSSL_free(ssl->s3);
  ssl->s3 = NULL;
}
示例#6
0
int tls1_change_cipher_state(SSL *s, int which) {
  /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
   * need to update the read cipherspec. Otherwise we have just written one. */
  const char is_read = (which & SSL3_CC_READ) != 0;
  /* use_client_keys is true if we wish to use the keys for the "client write"
   * direction. This is the case if we're a client sending a ChangeCipherSpec,
   * or a server reading a client's ChangeCipherSpec. */
  const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
                               which == SSL3_CHANGE_CIPHER_SERVER_READ;
  const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
  const uint8_t *client_write_key, *server_write_key, *key;
  const uint8_t *client_write_iv, *server_write_iv, *iv;
  const EVP_AEAD *aead = s->s3->tmp.new_aead;
  size_t key_len, iv_len, mac_secret_len;
  const uint8_t *key_data;

  /* Reset sequence number to zero. */
  if (!SSL_IS_DTLS(s)) {
    memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
  }

  mac_secret_len = s->s3->tmp.new_mac_secret_len;
  iv_len = s->s3->tmp.new_fixed_iv_len;

  if (aead == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  key_len = EVP_AEAD_key_length(aead);
  if (mac_secret_len > 0) {
    /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher
     * suites) the key length reported by |EVP_AEAD_key_length| will
     * include the MAC and IV key bytes. */
    if (key_len < mac_secret_len + iv_len) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    key_len -= mac_secret_len + iv_len;
  }

  key_data = s->s3->tmp.key_block;
  client_write_mac_secret = key_data;
  key_data += mac_secret_len;
  server_write_mac_secret = key_data;
  key_data += mac_secret_len;
  client_write_key = key_data;
  key_data += key_len;
  server_write_key = key_data;
  key_data += key_len;
  client_write_iv = key_data;
  key_data += iv_len;
  server_write_iv = key_data;
  key_data += iv_len;

  if (use_client_keys) {
    mac_secret = client_write_mac_secret;
    key = client_write_key;
    iv = client_write_iv;
  } else {
    mac_secret = server_write_mac_secret;
    key = server_write_key;
    iv = server_write_iv;
  }

  if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (is_read) {
    SSL_AEAD_CTX_free(s->aead_read_ctx);
    s->aead_read_ctx = SSL_AEAD_CTX_new(
        evp_aead_open, ssl3_version_from_wire(s, s->version),
        s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
        iv_len);
    return s->aead_read_ctx != NULL;
  }

  SSL_AEAD_CTX_free(s->aead_write_ctx);
  s->aead_write_ctx = SSL_AEAD_CTX_new(
      evp_aead_seal, ssl3_version_from_wire(s, s->version),
      s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
      iv_len);
  if (s->aead_write_ctx == NULL) {
    return 0;
  }

  s->s3->need_record_splitting = 0;
  if (!SSL_USE_EXPLICIT_IV(s) &&
      (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
      SSL_CIPHER_is_block_cipher(s->s3->tmp.new_cipher)) {
    /* Enable 1/n-1 record-splitting to randomize the IV. See
     * https://www.openssl.org/~bodo/tls-cbc.txt and the BEAST attack. */
    s->s3->need_record_splitting = 1;
  }
  return 1;
}
示例#7
0
SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
                               uint16_t version, const SSL_CIPHER *cipher,
                               const uint8_t *enc_key, size_t enc_key_len,
                               const uint8_t *mac_key, size_t mac_key_len,
                               const uint8_t *fixed_iv, size_t fixed_iv_len) {
  const EVP_AEAD *aead;
  size_t discard;
  if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, cipher, version)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
  if (mac_key_len > 0) {
    /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
     * suites). */
    if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    memcpy(merged_key, mac_key, mac_key_len);
    memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
    memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv, fixed_iv_len);
    enc_key = merged_key;
    enc_key_len += mac_key_len;
    enc_key_len += fixed_iv_len;
  }

  SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
  if (aead_ctx == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
  aead_ctx->cipher = cipher;

  if (!EVP_AEAD_CTX_init_with_direction(
          &aead_ctx->ctx, aead, enc_key, enc_key_len,
          EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
    OPENSSL_free(aead_ctx);
    return NULL;
  }

  assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
  aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
  if (mac_key_len == 0) {
    /* For a real AEAD, the IV is the fixed part of the nonce. */
    if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) ||
        fixed_iv_len > aead_ctx->variable_nonce_len) {
      SSL_AEAD_CTX_free(aead_ctx);
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    aead_ctx->variable_nonce_len -= fixed_iv_len;

    memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
    aead_ctx->fixed_nonce_len = fixed_iv_len;
    /* AES-GCM uses an explicit nonce. */
    if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) {
      aead_ctx->variable_nonce_included_in_record = 1;
    }
  } else {
    aead_ctx->variable_nonce_included_in_record = 1;
    aead_ctx->random_variable_nonce = 1;
    aead_ctx->omit_length_in_ad = 1;
    aead_ctx->omit_version_in_ad = (version == SSL3_VERSION);
  }

  return aead_ctx;
}