Пример #1
0
x4s_buf x4_dh_shared(const uint8 * g, size_t glen,
                     const uint8 * p, size_t plen,
                     const uint8 * x, size_t xlen,
                     const uint8 * gx, size_t gxlen,
                     const uint8 * gy, size_t gylen)
{
  DH     * dh;
  BIGNUM * bn;
  x4s_buf gxy = { 0 };

  /*  */
  x4_assert(gx && gxlen && gy && gylen);

  /*  */
  dh = _dh_init(g,glen, p,plen, x,xlen);
  x4_assert(dh);

  dh->pub_key = BN_bin2bn(gx, gxlen, 0);
  x4_assert(dh->pub_key);

  bn = BN_bin2bn(gy, gylen, 0);
  x4_assert(bn);

  x4_buf_resize(&gxy, DH_size(dh));
  DH_compute_key(gxy.data, bn, dh);

  DH_free(dh);
  return gxy;
}
Пример #2
0
bool
tr_dh_make_key (tr_dh_ctx_t   raw_handle,
                size_t        private_key_length,
                uint8_t     * public_key,
                size_t      * public_key_length)
{
  DH * handle = raw_handle;
  int dh_size, my_public_key_length;
  const BIGNUM * hand_pub_key;

  assert (handle != NULL);
  assert (public_key != NULL);


  DH_set_length(handle, private_key_length * 8);

  if (!check_result (DH_generate_key (handle)))
    return false;

  DH_get0_key (handle, &hand_pub_key, NULL);

  my_public_key_length = BN_bn2bin (hand_pub_key, public_key);
  dh_size = DH_size (handle);

  tr_dh_align_key (public_key, my_public_key_length, dh_size);

  if (public_key_length != NULL)
    *public_key_length = dh_size;

  return true;
}
Пример #3
0
void
tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
    const char *dh_file_inline
    )
{
  DH *dh;
  BIO *bio;

  ASSERT(NULL != ctx);

  if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline)
    {
      if (!(bio = BIO_new_mem_buf ((char *)dh_file_inline, -1)))
	msg (M_SSLDHERR, "Cannot open memory BIO for inline DH parameters");
    }
  else
    {
      /* Get Diffie Hellman Parameters */
      if (!(bio = BIO_new_file (dh_file, "r")))
	msg (M_SSLDHERR, "Cannot open %s for DH parameters", dh_file);
    }

  dh = PEM_read_bio_DHparams (bio, NULL, NULL, NULL);
  BIO_free (bio);

  if (!dh)
    msg (M_SSLDHERR, "Cannot load DH parameters from %s", dh_file);
  if (!SSL_CTX_set_tmp_dh (ctx->ctx, dh))
    msg (M_SSLDHERR, "SSL_CTX_set_tmp_dh");

  msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key",
       8 * DH_size (dh));

  DH_free (dh);
}
Пример #4
0
static isc_result_t
openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
                        isc_buffer_t *secret)
{
    DH *dhpub, *dhpriv;
    int ret;
    isc_region_t r;
    unsigned int len;

    REQUIRE(pub->keydata.dh != NULL);
    REQUIRE(priv->keydata.dh != NULL);

    dhpub = pub->keydata.dh;
    dhpriv = priv->keydata.dh;

    len = DH_size(dhpriv);
    isc_buffer_availableregion(secret, &r);
    if (r.length < len)
        return (ISC_R_NOSPACE);
    ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
    if (ret == 0)
        return (dst__openssl_toresult2("DH_compute_key",
                                       DST_R_COMPUTESECRETFAILURE));
    isc_buffer_add(secret, len);
    return (ISC_R_SUCCESS);
}
Пример #5
0
static int init_dh(SSL_CTX *ctx, const char *cert) {
    DH *dh;
    BIO *bio;

    assert(cert);

    bio = BIO_new_file(cert, "r");
    if (!bio) {
      ERR_print_errors_fp(stderr);
      return -1;
    }

    dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
    BIO_free(bio);
    if (!dh) {
        ERR("{core} Note: no DH parameters found in %s\n", cert);
        return -1;
    }

    LOG("{core} Using DH parameters from %s\n", cert);
    SSL_CTX_set_tmp_dh(ctx, dh);
    LOG("{core} DH initialized with %d bit key\n", 8*DH_size(dh));
    DH_free(dh);

    return 0;
}
Пример #6
0
Файл: dh.c Проект: KennethL/otp
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
    BIGNUM *other_pub_key = NULL,
        *dh_p = NULL,
        *dh_g = NULL;
    DH *dh_priv = DH_new();

    /* Check the arguments and get
          my private key (dh_priv),
          the peer's public key (other_pub_key),
          the parameters p & q
    */

    {
        BIGNUM *dummy_pub_key = NULL,
               *priv_key = NULL;
        ERL_NIF_TERM head, tail;

        if (!get_bn_from_bin(env, argv[0], &other_pub_key)
            || !get_bn_from_bin(env, argv[1], &priv_key)
            || !enif_get_list_cell(env, argv[2], &head, &tail)
            || !get_bn_from_bin(env, head, &dh_p)
            || !enif_get_list_cell(env, tail, &head, &tail)
            || !get_bn_from_bin(env, head, &dh_g)
            || !enif_is_empty_list(env, tail)

            /* Note: DH_set0_key() does not allow setting only the
             * private key, although DH_compute_key() does not use the
             * public key. Work around this limitation by setting
             * the public key to a copy of the private key.
             */
            || !(dummy_pub_key = BN_dup(priv_key))
            || !DH_set0_key(dh_priv, dummy_pub_key, priv_key)
            || !DH_set0_pqg(dh_priv, dh_p, NULL, dh_g)
            ) {
            if (dh_p) BN_free(dh_p);
            if (dh_g) BN_free(dh_g);
            if (other_pub_key) BN_free(other_pub_key);
            if (dummy_pub_key) BN_free(dummy_pub_key);
            if (priv_key) BN_free(priv_key);
            return enif_make_badarg(env);
        }
    }
    {
        ErlNifBinary ret_bin;
        int size;

        enif_alloc_binary(DH_size(dh_priv), &ret_bin);
        size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv);
        BN_free(other_pub_key);
        DH_free(dh_priv);
        if (size<=0) {
            enif_release_binary(&ret_bin);
            return atom_error;
        }

        if (size != ret_bin.size) enif_realloc_binary(&ret_bin, size);
        return enif_make_binary(env, &ret_bin);
    }
}
Пример #7
0
tr_dh_secret_t
tr_dh_agree (tr_dh_ctx_t     handle,
             const uint8_t * other_public_key,
             size_t          other_public_key_length)
{
  struct tr_dh_secret * ret;
  int dh_size, secret_key_length;
  BIGNUM * other_key;

  assert (handle != NULL);
  assert (other_public_key != NULL);

  if (!check_pointer (other_key = BN_bin2bn (other_public_key, other_public_key_length, NULL)))
    return NULL;

  dh_size = DH_size (handle);
  ret = tr_dh_secret_new (dh_size);

  secret_key_length = DH_compute_key (ret->key, other_key, handle);
  if (check_result_neq (secret_key_length, -1))
    {
      tr_dh_secret_align (ret, secret_key_length);
    }
  else
    {
      tr_dh_secret_free (ret);
      ret = NULL;
    }

  BN_free (other_key);
  return ret;
}
Пример #8
0
	// Set the prime P and the generator, generate local public key
	DH_key_exchange::DH_key_exchange ()
	{
		m_DH = DH_new ();

		m_DH->p = BN_bin2bn (m_dh_prime, sizeof(m_dh_prime), NULL);
		m_DH->g = BN_bin2bn (m_dh_generator, sizeof(m_dh_generator), NULL);

		assert (sizeof(m_dh_prime) == DH_size(m_DH));
		
		DH_generate_key (m_DH); // TODO Check != 0

		assert (m_DH->pub_key);

		// DH can generate key sizes that are smaller than the size of
		// P with exponentially decreasing probability, in which case
		// the msb's of m_dh_local_key need to be zeroed
		// appropriately.
		int key_size = get_local_key_size();
		int len_dh = sizeof(m_dh_prime); // must equal DH_size(m_DH)
		if (key_size != len_dh)
		{
			assert(key_size > 0 && key_size < len_dh);

			int pad_zero_size = len_dh - key_size;
			std::fill(m_dh_local_key, m_dh_local_key + pad_zero_size, 0);
			BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key + pad_zero_size);
		}
		else
			BN_bn2bin(m_DH->pub_key, (unsigned char*)m_dh_local_key); // TODO Check return value
	}
Пример #9
0
struct sec performDH(char *pubkeyRec,DH *privkey){
	
	struct sec s;
	int secret_size;
	/* Send the public key to the peer.
	* How this occurs will be specific to your situation (see main text below) */


	/* Receive the public key from the peer. In this example we're just hard coding a value */
	BIGNUM *pubkey = NULL;
	if(0 == (BN_dec2bn(&pubkey, pubkeyRec))) handleErrors();

	/* Compute the shared secret */
	unsigned char *secret;
	if(NULL == (secret = OPENSSL_malloc(sizeof(unsigned char) * (DH_size(privkey))))) handleErrors();

	if(0 > (secret_size = DH_compute_key(secret, pubkey, privkey))) handleErrors();

	/* Do something with the shared secret */
	/* Note secret_size may be less than DH_size(privkey) */
	printf("The shared secret is:\n");
	
	strcpy(s.value,secret);
	s.length=secret_size;
	/* Clean up */
	OPENSSL_free(secret);
	BN_free(pubkey);
	DH_free(privkey);

	return s;
}
Пример #10
0
void openssl_dh_crypt()
{
	BIO *b;
	DH *d1, *d2;
	int i, len1, len2;
	unsigned char skey1[COMM_LEN], skey2[COMM_LEN];

	d1 = DH_new();
	d2 = DH_new();
	DH_generate_parameters_ex(d1, 64, DH_GENERATOR_2, NULL);
	DH_check(d1, &i);
	printf("\nDH key size: %d\n", DH_size(d1));
	DH_generate_key(d1);

	d2->p = BN_dup(d1->p);
	d2->g = BN_dup(d1->g);
	DH_generate_key(d2);
	DH_check_pub_key(d1, d1->pub_key, &i);
	len1 = DH_compute_key(skey1, d2->pub_key, d1);
	len2 = DH_compute_key(skey2, d1->pub_key, d2);
	if ((len1 != len2) || (memcmp(skey1, skey2, len1) != 0)) {
		printf("DH_compute_key err!\n");
		DH_free(d1);
		DH_free(d2);
		return;
	}

	b = BIO_new(BIO_s_file());
	BIO_set_fp(b, stdout, BIO_NOCLOSE);
	DHparams_print(b, d1);

	BIO_free(b);
	DH_free(d1);
	DH_free(d2);
}
Пример #11
0
bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length) {
	if (_pDH == NULL) {
		FATAL("DHWrapper not initialized");
		return false;
	}

	if (_sharedKeyLength != 0 || _pSharedKey != NULL) {
		FATAL("Shared key already computed");
		return false;
	}

	_sharedKeyLength = DH_size(_pDH);
	if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024) {
		FATAL("Unable to get shared key size in bytes");
		return false;
	}
	_pSharedKey = new uint8_t[_sharedKeyLength];
	memset(_pSharedKey, 0, _sharedKeyLength);

	_peerPublickey = BN_bin2bn(pPeerPublicKey, length, 0);
	if (_peerPublickey == NULL) {
		FATAL("Unable to get the peer public key");
		return false;
	}

	if (DH_compute_key(_pSharedKey, _peerPublickey, _pDH) == -1) {
		FATAL("Unable to compute the shared key");
		return false;
	}

	return true;
}
Пример #12
0
const uint8_t*
tr_cryptoComputeSecret( tr_crypto *     crypto,
                        const uint8_t * peerPublicKey )
{
    int      len;
    uint8_t  secret[KEY_LEN];
    BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL );
    DH *     dh;

    ensureKeyExists( crypto );
    dh = crypto->dh;

    assert( DH_size( dh ) == KEY_LEN );

    len = DH_compute_key( secret, bn, dh );
    if( len == -1 )
        logErrorFromSSL( );
    else {
        int offset;
        assert( len <= KEY_LEN );
        offset = KEY_LEN - len;
        memset( crypto->mySecret, 0, offset );
        memcpy( crypto->mySecret + offset, secret, len );
        crypto->mySecretIsSet = 1;
    }

    BN_free( bn );
    return crypto->mySecret;
}
Пример #13
0
int tr_compute_dh_key(unsigned char **pbuf,
		      BIGNUM *pub_key,
		      DH *priv_dh) {
  size_t buflen;
  unsigned char *buf = NULL;;
  int rc = 0;

  if ((!pbuf) ||
      (!pub_key) ||
      (!priv_dh)) {
    tr_debug("tr_compute_dh_key: Invalid parameters.");
    return(-1);
  }
  *pbuf = NULL;
  buflen = DH_size(priv_dh);
  buf = malloc(buflen);
  if (buf == NULL) {
    tr_crit("tr_compute_dh_key: out of memory");
    return -1;
  }


  rc = DH_compute_key(buf, pub_key, priv_dh);
  if (0 <= rc) {
    *pbuf = buf;
  }else {
    free(buf);
  }
  return rc;
}
Пример #14
0
std::string avjackif::async_client_hello(boost::asio::yield_context yield_context)
{
	proto::client_hello client_hello;
	client_hello.set_client("avim");
	client_hello.set_version(0001);

	unsigned char to[512];

	auto dh = DH_new();
	DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL);
	DH_generate_key(dh);

	// 把 g,p, pubkey 传过去
	client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to));
	client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to));
	client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to));

	auto tobesend = av_router::encode(client_hello);

	boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context);

	// 解码
	std::unique_ptr<proto::server_hello> server_hello(
		(proto::server_hello*)async_read_protobuf_message(*m_sock, yield_context));

	m_remote_addr.reset(new proto::av_address(
		av_address_from_string(server_hello->server_av_address())));

	auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(),
		server_hello->random_pub_key().length(), NULL);

	m_shared_key.resize(DH_size(dh));
	// 密钥就算出来啦!
	DH_compute_key(&m_shared_key[0], server_pubkey, dh);
	BN_free(server_pubkey);

    std::printf("key = 0x");
    for (int i=0; i<DH_size(dh); ++i)
	{
        std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf);
    }
    std::printf("\n");
	DH_free(dh);

	return server_hello->random_pub_key();
}
Пример #15
0
static krb5_error_code
generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
                     krb5_enctype enctype, krb5_keyblock *reply_key)
{
    unsigned char *dh_gen_key = NULL;
    krb5_keyblock key;
    krb5_error_code ret;
    size_t dh_gen_keylen, size;

    memset(&key, 0, sizeof(key));

    if (!DH_generate_key(client_params->dh)) {
	ret = KRB5KRB_ERR_GENERIC;
	krb5_set_error_message(context, ret, "Can't generate Diffie-Hellman keys");
	goto out;
    }
    if (client_params->dh_public_key == NULL) {
	ret = KRB5KRB_ERR_GENERIC;
	krb5_set_error_message(context, ret, "dh_public_key");
	goto out;
    }

    dh_gen_keylen = DH_size(client_params->dh);
    size = BN_num_bytes(client_params->dh->p);
    if (size < dh_gen_keylen)
	size = dh_gen_keylen;

    dh_gen_key = malloc(size);
    if (dh_gen_key == NULL) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret, "malloc: out of memory");
	goto out;
    }
    memset(dh_gen_key, 0, size - dh_gen_keylen);

    dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
				   client_params->dh_public_key,
				   client_params->dh);
    if (dh_gen_keylen == -1) {
	ret = KRB5KRB_ERR_GENERIC;
	krb5_set_error_message(context, ret, "Can't compute Diffie-Hellman key");
	goto out;
    }

    ret = _krb5_pk_octetstring2key(context,
				   enctype,
				   dh_gen_key, dh_gen_keylen,
				   NULL, NULL,
				   reply_key);

 out:
    if (dh_gen_key)
	free(dh_gen_key);
    if (key.keyvalue.data)
	krb5_free_keyblock_contents(context, &key);

    return ret;
}
Пример #16
0
/*
 *	Generate an empheral DH key.  Because this can take a long
 *	time to compute, we can use precomputed parameters of the
 *	common key sizes.
 *
 *	Since few sites will bother to precompute these parameter
 *	files, we also provide a fallback to the parameters provided
 *	by the OpenSSL project.
 *
 *	These values can be static (once loaded or computed) since
 *	the OpenSSL library can efficiently generate random keys from
 *	the information provided.
 */
static DH  *
tmp_dh_cb(SSL *s, int is_export, int keylength)
{
	DH		   *r = NULL;
	static DH  *dh = NULL;
	static DH  *dh512 = NULL;
	static DH  *dh1024 = NULL;
	static DH  *dh2048 = NULL;
	static DH  *dh4096 = NULL;

	switch (keylength)
	{
		case 512:
			if (dh512 == NULL)
				dh512 = load_dh_file(keylength);
			if (dh512 == NULL)
				dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
			r = dh512;
			break;

		case 1024:
			if (dh1024 == NULL)
				dh1024 = load_dh_file(keylength);
			if (dh1024 == NULL)
				dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
			r = dh1024;
			break;

		case 2048:
			if (dh2048 == NULL)
				dh2048 = load_dh_file(keylength);
			if (dh2048 == NULL)
				dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
			r = dh2048;
			break;

		case 4096:
			if (dh4096 == NULL)
				dh4096 = load_dh_file(keylength);
			if (dh4096 == NULL)
				dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
			r = dh4096;
			break;

		default:
			if (dh == NULL)
				dh = load_dh_file(keylength);
			r = dh;
	}

	/* this may take a long time, but it may be necessary... */
	if (r == NULL || 8 * DH_size(r) < keylength)
		r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);

	return r;
}
Пример #17
0
ssize_t
tls_get_connection_info(struct tls *ctx, char *buf, size_t buflen)
{
	SSL *conn = ctx->ssl_conn;
	const char *ocsp_pfx = "", *ocsp_info = "";
	const char *proto = "-", *cipher = "-";
	char dh[64];
	int used_dh_bits = ctx->used_dh_bits, used_ecdh_nid = ctx->used_ecdh_nid;

	if (conn != NULL) {
		proto = SSL_get_version(conn);
		cipher = SSL_get_cipher(conn);

#ifdef SSL_get_server_tmp_key
		if (ctx->flags & TLS_CLIENT) {
			EVP_PKEY *pk = NULL;
			int ok = SSL_get_server_tmp_key(conn, &pk);
			int pk_type = EVP_PKEY_id(pk);
			if (ok && pk) {
				if (pk_type == EVP_PKEY_DH) {
					DH *dh = EVP_PKEY_get0(pk);
					used_dh_bits = DH_size(dh) * 8;
				} else if (pk_type == EVP_PKEY_EC) {
					EC_KEY *ecdh = EVP_PKEY_get0(pk);
					const EC_GROUP *eg = EC_KEY_get0_group(ecdh);
					used_ecdh_nid = EC_GROUP_get_curve_name(eg);
				}
				EVP_PKEY_free(pk);
			}
		}
#endif
	}

	if (used_dh_bits) {
		snprintf(dh, sizeof dh, "/DH=%d", used_dh_bits);
	} else if (used_ecdh_nid) {
		snprintf(dh, sizeof dh, "/ECDH=%s", OBJ_nid2sn(used_ecdh_nid));
	} else {
		dh[0] = 0;
	}

	if (ctx->ocsp_result) {
		ocsp_info = ctx->ocsp_result;
		ocsp_pfx = "/OCSP=";
	}

	return snprintf(buf, buflen, "%s/%s%s%s%s", proto, cipher, dh, ocsp_pfx, ocsp_info);
}
Пример #18
0
NOEXPORT int init_dh(SERVICE_OPTIONS *section) {
    DH *dh=NULL;

    s_log(LOG_DEBUG, "DH initialization");
#ifdef HAVE_OSSL_ENGINE_H
    if(!section->engine) /* cert is a file and not an identifier */
#endif
        dh=read_dh(section->cert);
    if(!dh)
        dh=get_dh2048();
    if(!dh) {
        s_log(LOG_NOTICE, "DH initialization failed");
        return 1; /* FAILED */
    }
    SSL_CTX_set_tmp_dh(section->ctx, dh);
    s_log(LOG_DEBUG, "DH initialized with %d-bit key", 8*DH_size(dh));
    DH_free(dh);
    return 0; /* OK */
}
Пример #19
0
int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key)
{
    struct s2n_dh_params client_params;
    uint8_t *client_pub_key;
    uint16_t client_pub_key_size;
    int shared_key_size;

    GUARD(s2n_dh_params_check(server_dh_params));
    GUARD(s2n_dh_params_copy(server_dh_params, &client_params));
    GUARD(s2n_dh_generate_ephemeral_key(&client_params));
    GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));

    const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params);
    client_pub_key_size = BN_num_bytes(client_pub_key_bn);
    GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size));
    client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size);
    if (client_pub_key == NULL) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY);
    }

    if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY);
    }

    /* server_dh_params already validated */
    const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params);
    shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh);
    if (shared_key_size < 0) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
    }

    shared_key->size = shared_key_size;

    GUARD(s2n_dh_params_free(&client_params));

    return 0;
}
Пример #20
0
static int
init_dh(SSL_CTX * ctx, unsigned char *dhparam)
{
	int             rc = TRUE;
	BIO            *bio = 0;
	DH             *dh = 0;

	if (dhparam == NULL)
		return TRUE;

	if ((bio = BIO_new_file((char *) dhparam, "r")) == NULL) {
		LOG(SPOCP_ERR)
		    traceLog(LOG_ERR,"DH: could not read %s: %s", dhparam,
			     strerror(errno));
		rc = FALSE;
	} else {

		if ((dh =
		     PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL) {
			LOG(SPOCP_ERR)
			    traceLog(LOG_ERR,"DH: could not load params from %s",
				     dhparam);
			rc = FALSE;
		} else {
			if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
				LOG(SPOCP_DEBUG)
					traceLog(LOG_ERR,
					    "Couldn't set Diffie-Hellman parameters");
				rc = FALSE;
			} else
				LOG(SPOCP_DEBUG)
				    traceLog(LOG_ERR,
					"Diffie-Hellman initialised from %s with %d-bit key",
				    	 dhparam, 8 * DH_size(dh));

			DH_free(dh);
		}

		BIO_free(bio);
	}

	return rc;
}
Пример #21
0
bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
{
	// Check parameters
	if ((ppSymmetricKey == NULL) ||
	    (publicKey == NULL) ||
	    (privateKey == NULL))
	{
		return false;
	}

	// Get keys
	DH *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey();
	DH *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey();
	if (pub == NULL || pub->pub_key == NULL || priv == NULL)
	{
		ERROR_MSG("Failed to get OpenSSL DH keys");

		return false;
	}

	// Derive the secret
	ByteString secret;
	secret.resize(DH_size(priv));;

	if (DH_compute_key(&secret[0], pub->pub_key, priv) <= 0)
	{
		ERROR_MSG("DH key derivation failed (0x%08X)", ERR_get_error());

		return false;
	}

	*ppSymmetricKey = new SymmetricKey;
	if (*ppSymmetricKey == NULL)
		return false;
	if (!(*ppSymmetricKey)->setKeyBits(secret))
	{
		delete *ppSymmetricKey;
		*ppSymmetricKey = NULL;
		return false;
	}

	return true;
}
Пример #22
0
int Condor_Diffie_Hellman :: compute_shared_secret(const char * pk)
{
    // the input pk is assumed to be an encoded string representing
    // the binary data for the remote party's public key -- y (or x)
    // the local DH knows about g and x, now, it will compute
    // (g^x)^y, or (g^y)^x

    BIGNUM * remote_pubKey = NULL;

    if (BN_hex2bn(&remote_pubKey, pk) == 0) {
        dprintf(D_ALWAYS, "Unable to obtain remote public key\n");
        goto error;
    }

    if ((dh_ != NULL) && (remote_pubKey != NULL)) {

        secret_ = (unsigned char *) malloc(DH_size(dh_));

        // Now compute
        keySize_ = DH_compute_key(secret_, remote_pubKey, dh_);
        BN_clear_free(remote_pubKey);

        if (keySize_ == -1) {
            dprintf(D_ALWAYS, "Unable to compute shared secret\n");
            goto error;
        }
    }   
    else {
        goto error;
    }
    return 1;

 error:
    if (remote_pubKey) {
        BN_clear_free(remote_pubKey);
    }
    if (secret_) {
        free(secret_);
        secret_ = NULL;
    }
    return 0;
}
Пример #23
0
static void
tls_info_callback(const SSL *ssl, int where, int rc)
{
	struct tls *ctx = SSL_get_app_data(ssl);

	/* steal info about used DH key */
	if (ssl->s3 && ssl->s3->tmp.dh && !ctx->used_dh_bits) {
		ctx->used_dh_bits = DH_size(ssl->s3->tmp.dh) * 8;
	} else if (ssl->s3 && ssl->s3->tmp.ecdh && !ctx->used_ecdh_nid) {
		ctx->used_ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ssl->s3->tmp.ecdh));
	}

	/* detect renegotation on established connection */
	if (where & SSL_CB_HANDSHAKE_START) {
		if (ctx->state & TLS_STATE_ESTABLISHED)
			ctx->state |= TLS_STATE_ABORT;
	} else if (where & SSL_CB_HANDSHAKE_DONE) {
		ctx->state |= TLS_STATE_ESTABLISHED;
	}
}
Пример #24
0
static int init_dh(void) {
#ifdef USE_DH
    FILE *fp;
    DH *dh;
    BIO *bio;

    fp=fopen(options.cert, "r");
    if(!fp) {
#ifdef USE_WIN32
        /* Win32 doesn't seem to set errno in fopen() */
        log(LOG_ERR, "Failed to open %s", options.cert);
#else
        ioerror(options.cert);
#endif
        return -1; /* FAILED */
    }
    bio=BIO_new_fp(fp, BIO_CLOSE|BIO_FP_TEXT);
    if(!bio) {
        log(LOG_ERR, "BIO_new_fp failed");
        return -1; /* FAILED */
    }
    if((dh=PEM_read_bio_DHparams(bio, NULL, NULL
#if SSLEAY_VERSION_NUMBER >= 0x00904000L
            , NULL
#endif
            ))) {
        BIO_free(bio);
        log(LOG_DEBUG, "Using Diffie-Hellman parameters from %s",
            options.cert);
    } else { /* Failed to load DH parameters from file */
        BIO_free(bio);
        log(LOG_NOTICE, "Could not load DH parameters from %s", options.cert);
        return -1; /* FAILED */
    }
    SSL_CTX_set_tmp_dh(ctx, dh);
    log(LOG_INFO, "Diffie-Hellman initialized with %d bit key",
        8*DH_size(dh));
    DH_free(dh);
#endif /* USE_DH */
    return 0; /* OK */
}
Пример #25
0
BUF_MEM *
dh_compute_key(EVP_PKEY *key, const BUF_MEM * in, BN_CTX *bn_ctx)
{
    BUF_MEM * out = NULL;
    BIGNUM * bn = NULL;
    DH *dh = NULL;

    check(key && in, "Invalid arguments");

    dh = EVP_PKEY_get1_DH(key);
    if (!dh)
        return NULL;

    /* decode public key */
    bn = BN_bin2bn((unsigned char *) in->data, in->length, bn);
    if (!bn)
        goto err;

    out = BUF_MEM_create(DH_size(dh));
    if (!out)
        goto err;

    out->length = DH_compute_key((unsigned char *) out->data, bn, dh);
    if ((int) out->length < 0)
        goto err;

    BN_clear_free(bn);
    DH_free(dh);

    return out;

err:
    if (out)
        BUF_MEM_free(out);
    if (bn)
        BN_clear_free(bn);
    if (dh)
        DH_free(dh);

    return NULL;
}
Пример #26
0
/*
 *	Load precomputed DH parameters.
 *
 *	To prevent "downgrade" attacks, we perform a number of checks
 *	to verify that the DBA-generated DH parameters file contains
 *	what we expect it to contain.
 */
static DH  *
load_dh_file(int keylength)
{
	char		homedir[MAXPGPATH];
	char		fnbuf[MAXPGPATH];
	FILE	   *fp;
	DH		   *dh;
	int			codes;

	if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
		return NULL;

	/* attempt to open file.  It's not an error if it doesn't exist. */
	snprintf(fnbuf, sizeof(fnbuf), DHFILEPATTERN, homedir, keylength);

	if ((fp = fopen(fnbuf, "r")) == NULL)
		return NULL;

/*	flock(fileno(fp), LOCK_SH); */
	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
/*	flock(fileno(fp), LOCK_UN); */
	fclose(fp);

	/* is the prime the correct size? */
	if (dh != NULL && 8 * DH_size(dh) < keylength)
		dh = NULL;

	/* make sure the DH parameters are usable */
	if (dh != NULL)
	{
		if (DH_check(dh, &codes))
			return NULL;
		if (codes & DH_CHECK_P_NOT_PRIME)
			return NULL;
		if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
			(codes & DH_CHECK_P_NOT_SAFE_PRIME))
			return NULL;
	}

	return dh;
}
Пример #27
0
/*
 *  call-seq:
 *     dh.compute_key(pub_bn) -> aString
 *
 * Returns a String containing a shared secret computed from the other party's public value.
 * See DH_compute_key() for further information.
 *
 * === Parameters
 * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
 * DH#public_key as that contains the DH parameters only.
 */
static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
    DH *dh;
    EVP_PKEY *pkey;
    BIGNUM *pub_key;
    VALUE str;
    int len;

    GetPKeyDH(self, pkey);
    dh = pkey->pkey.dh;
    pub_key = GetBNPtr(pub);
    len = DH_size(dh);
    str = rb_str_new(0, len);
    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
	ossl_raise(eDHError, NULL);
    }
    rb_str_set_len(str, len);

    return str;
}
Пример #28
0
/*
 *  call-seq:
 *     dh.compute_key(pub_bn) -> aString
 *
 * Returns a String containing a shared secret computed from the other party's public value.
 * See DH_compute_key() for further information.
 *
 * === Parameters
 * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
 * DH#public_key as that contains the DH parameters only.
 */
static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
    DH *dh;
    const BIGNUM *pub_key, *dh_p;
    VALUE str;
    int len;

    GetDH(self, dh);
    DH_get0_pqg(dh, &dh_p, NULL, NULL);
    if (!dh_p)
	ossl_raise(eDHError, "incomplete DH");
    pub_key = GetBNPtr(pub);
    len = DH_size(dh);
    str = rb_str_new(0, len);
    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
	ossl_raise(eDHError, NULL);
    }
    rb_str_set_len(str, len);

    return str;
}
Пример #29
0
static void
tls_info_callback(const SSL *ssl, int where, int rc)
{
	struct tls *ctx = SSL_get_app_data(ssl);

#ifdef USE_LIBSSL_INTERNALS
	if (!(ctx->state & TLS_HANDSHAKE_COMPLETE) && ssl->s3) {
		/* steal info about used DH key */
		if (ssl->s3->tmp.dh && !ctx->used_dh_bits) {
			ctx->used_dh_bits = DH_size(ssl->s3->tmp.dh) * 8;
		} else if (ssl->s3->tmp.ecdh && !ctx->used_ecdh_nid) {
			ctx->used_ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ssl->s3->tmp.ecdh));
		}
	}
#endif

	/* detect renegotation on established connection */
	if (where & SSL_CB_HANDSHAKE_START) {
		if (ctx->state & TLS_HANDSHAKE_COMPLETE)
			ctx->state |= TLS_DO_ABORT;
	}
}
Пример #30
0
int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3)
{
    uint8_t *original_ptr = pkcs3->data;
    dh_params->dh = d2i_DHparams(NULL, (const unsigned char **)(void *)&pkcs3->data, pkcs3->size);
    GUARD(s2n_check_p_g_dh_params(dh_params));
    if (pkcs3->data - original_ptr != pkcs3->size) {
        DH_free(dh_params->dh);
        S2N_ERROR(S2N_ERR_INVALID_PKCS3);
    }
    pkcs3->data = original_ptr;

    /* Require at least 2048 bits for the DH size */
    if (DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES) {
        DH_free(dh_params->dh);
        S2N_ERROR(S2N_ERR_DH_TOO_SMALL);
    }

    /* Check the generator and prime */
    GUARD(s2n_dh_params_check(dh_params));

    return 0;
}