Esempio n. 1
0
int
mono_btls_ssl_ctx_set_ciphers (MonoBtlsSslCtx *ctx, int count, const uint16_t *data,
				   int allow_unsupported)
{
	CBB cbb;
	int i, ret = 0;

	if (!CBB_init (&cbb, 64))
		goto err;

	/* Assemble a cipher string with the specified ciphers' names. */
	for (i = 0; i < count; i++) {
		const char *name;
		const SSL_CIPHER *cipher = SSL_get_cipher_by_value (data [i]);
		if (!cipher) {
			debug_printf (ctx, "mono_btls_ssl_ctx_set_ciphers(): unknown cipher %02x", data [i]);
			if (!allow_unsupported)
				goto err;
			continue;
		}
		name = SSL_CIPHER_get_name (cipher);
		if (i > 0 && !CBB_add_u8 (&cbb, ':'))
			goto err;
		if (!CBB_add_bytes (&cbb, (const uint8_t *)name, strlen(name)))
			goto err;
	}

	/* NUL-terminate the string. */
	if (!CBB_add_u8 (&cbb, 0))
		goto err;

	ret = SSL_CTX_set_cipher_list (ctx->ctx, (const char *)CBB_data (&cbb));

err:
	CBB_cleanup (&cbb);
	return ret;
}
Esempio n. 2
0
static int ssl_encrypt_ticket_with_cipher_ctx(SSL *ssl, CBB *out,
                                              const uint8_t *session_buf,
                                              size_t session_len) {
  int ret = 0;

  EVP_CIPHER_CTX ctx;
  EVP_CIPHER_CTX_init(&ctx);
  HMAC_CTX hctx;
  HMAC_CTX_init(&hctx);

  /* If the session is too long, emit a dummy value rather than abort the
   * connection. */
  static const size_t kMaxTicketOverhead =
      16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE;
  if (session_len > 0xffff - kMaxTicketOverhead) {
    static const char kTicketPlaceholder[] = "TICKET TOO LARGE";
    if (CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder,
                      strlen(kTicketPlaceholder))) {
      ret = 1;
    }
    goto err;
  }

  /* Initialize HMAC and cipher contexts. If callback present it does all the
   * work otherwise use generated values from parent ctx. */
  SSL_CTX *tctx = ssl->session_ctx;
  uint8_t iv[EVP_MAX_IV_LENGTH];
  uint8_t key_name[16];
  if (tctx->tlsext_ticket_key_cb != NULL) {
    if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx,
                                   1 /* encrypt */) < 0) {
      goto err;
    }
  } else {
    if (!RAND_bytes(iv, 16) ||
        !EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                            tctx->tlsext_tick_aes_key, iv) ||
        !HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
                      NULL)) {
      goto err;
    }
    OPENSSL_memcpy(key_name, tctx->tlsext_tick_key_name, 16);
  }

  uint8_t *ptr;
  if (!CBB_add_bytes(out, key_name, 16) ||
      !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(&ctx)) ||
      !CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) {
    goto err;
  }

  size_t total = 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  OPENSSL_memcpy(ptr, session_buf, session_len);
  total = session_len;
#else
  int len;
  if (!EVP_EncryptUpdate(&ctx, ptr + total, &len, session_buf, session_len)) {
    goto err;
  }
  total += len;
  if (!EVP_EncryptFinal_ex(&ctx, ptr + total, &len)) {
    goto err;
  }
  total += len;
#endif
  if (!CBB_did_write(out, total)) {
    goto err;
  }

  unsigned hlen;
  if (!HMAC_Update(&hctx, CBB_data(out), CBB_len(out)) ||
      !CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) ||
      !HMAC_Final(&hctx, ptr, &hlen) ||
      !CBB_did_write(out, hlen)) {
    goto err;
  }

  ret = 1;

err:
  EVP_CIPHER_CTX_cleanup(&ctx);
  HMAC_CTX_cleanup(&hctx);
  return ret;
}