Exemplo n.º 1
1
int test_builtin(BIO *out)
{
    EC_builtin_curve *curves = NULL;
    size_t crv_len = 0, n = 0;
    EC_KEY *eckey = NULL, *wrong_eckey = NULL;
    EC_GROUP *group;
    ECDSA_SIG *ecdsa_sig = NULL;
    unsigned char digest[20], wrong_digest[20];
    unsigned char *signature = NULL;
    const unsigned char *sig_ptr;
    unsigned char *sig_ptr2;
    unsigned char *raw_buf = NULL;
    unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
    int nid, ret = 0;

    /* fill digest values with some random data */
    if (!RAND_pseudo_bytes(digest, 20) ||
            !RAND_pseudo_bytes(wrong_digest, 20)) {
        BIO_printf(out, "ERROR: unable to get random data\n");
        goto builtin_err;
    }

    /*
     * create and verify a ecdsa signature with every availble curve (with )
     */
    BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
               "with some internal curves:\n");

    /* get a list of all internal curves */
    crv_len = EC_get_builtin_curves(NULL, 0);

    curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);

    if (curves == NULL) {
        BIO_printf(out, "malloc error\n");
        goto builtin_err;
    }

    if (!EC_get_builtin_curves(curves, crv_len)) {
        BIO_printf(out, "unable to get internal curves\n");
        goto builtin_err;
    }

    /* now create and verify a signature for every curve */
    for (n = 0; n < crv_len; n++) {
        unsigned char dirt, offset;

        nid = curves[n].nid;
        if (nid == NID_ipsec4)
            continue;
        /* create new ecdsa key (== EC_KEY) */
        if ((eckey = EC_KEY_new()) == NULL)
            goto builtin_err;
        group = EC_GROUP_new_by_curve_name(nid);
        if (group == NULL)
            goto builtin_err;
        if (EC_KEY_set_group(eckey, group) == 0)
            goto builtin_err;
        EC_GROUP_free(group);
        degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
        if (degree < 160)
            /* drop the curve */
        {
            EC_KEY_free(eckey);
            eckey = NULL;
            continue;
        }
        BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
        /* create key */
        if (!EC_KEY_generate_key(eckey)) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        /* create second key */
        if ((wrong_eckey = EC_KEY_new()) == NULL)
            goto builtin_err;
        group = EC_GROUP_new_by_curve_name(nid);
        if (group == NULL)
            goto builtin_err;
        if (EC_KEY_set_group(wrong_eckey, group) == 0)
            goto builtin_err;
        EC_GROUP_free(group);
        if (!EC_KEY_generate_key(wrong_eckey)) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }

        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* check key */
        if (!EC_KEY_check_key(eckey)) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* create signature */
        sig_len = ECDSA_size(eckey);
        if ((signature = OPENSSL_malloc(sig_len)) == NULL)
            goto builtin_err;
        if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* verify signature */
        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* verify signature with the wrong key */
        if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* wrong digest */
        if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);
        /* wrong length */
        if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);

        /*
         * Modify a single byte of the signature: to ensure we don't garble
         * the ASN1 structure, we read the raw signature and modify a byte in
         * one of the bignums directly.
         */
        sig_ptr = signature;
        if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }

        /* Store the two BIGNUMs in raw_buf. */
        r_len = BN_num_bytes(ecdsa_sig->r);
        s_len = BN_num_bytes(ecdsa_sig->s);
        bn_len = (degree + 7) / 8;
        if ((r_len > bn_len) || (s_len > bn_len)) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        buf_len = 2 * bn_len;
        if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
            goto builtin_err;
        /* Pad the bignums with leading zeroes. */
        memset(raw_buf, 0, buf_len);
        BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
        BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);

        /* Modify a single byte in the buffer. */
        offset = raw_buf[10] % buf_len;
        dirt = raw_buf[11] ? raw_buf[11] : 1;
        raw_buf[offset] ^= dirt;
        /* Now read the BIGNUMs back in from raw_buf. */
        if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
                (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
            goto builtin_err;

        sig_ptr2 = signature;
        sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        /*
         * Sanity check: undo the modification and verify signature.
         */
        raw_buf[offset] ^= dirt;
        if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
                (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
            goto builtin_err;

        sig_ptr2 = signature;
        sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
            BIO_printf(out, " failed\n");
            goto builtin_err;
        }
        BIO_printf(out, ".");
        (void)BIO_flush(out);

        BIO_printf(out, " ok\n");
        /* cleanup */
        /* clean bogus errors */
        ERR_clear_error();
        OPENSSL_free(signature);
        signature = NULL;
        EC_KEY_free(eckey);
        eckey = NULL;
        EC_KEY_free(wrong_eckey);
        wrong_eckey = NULL;
        ECDSA_SIG_free(ecdsa_sig);
        ecdsa_sig = NULL;
        OPENSSL_free(raw_buf);
        raw_buf = NULL;
    }

    ret = 1;
builtin_err:
    if (eckey)
        EC_KEY_free(eckey);
    if (wrong_eckey)
        EC_KEY_free(wrong_eckey);
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    if (signature)
        OPENSSL_free(signature);
    if (raw_buf)
        OPENSSL_free(raw_buf);
    if (curves)
        OPENSSL_free(curves);

    return ret;
}
Exemplo n.º 2
0
static isc_result_t
opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
	isc_result_t ret;
	EVP_PKEY *pkey;
	EC_KEY *eckey = NULL;
	int group_nid;

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);
	UNUSED(unused);
	UNUSED(callback);

	if (key->key_alg == DST_ALG_ECDSA256)
		group_nid = NID_X9_62_prime256v1;
	else
		group_nid = NID_secp384r1;

	eckey = EC_KEY_new_by_curve_name(group_nid);
	if (eckey == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));

	if (EC_KEY_generate_key(eckey) != 1)
		DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));

	pkey = EVP_PKEY_new();
	if (pkey == NULL)
		DST_RET (ISC_R_NOMEMORY);
	if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
		EVP_PKEY_free(pkey);
		DST_RET (ISC_R_FAILURE);
	}
	key->keydata.pkey = pkey;
	ret = ISC_R_SUCCESS;

 err:
	if (eckey != NULL)
		EC_KEY_free(eckey);
	return (ret);
}
Exemplo n.º 3
0
static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
    EC_KEY *ec = NULL;
    EC_PKEY_CTX *dctx = ctx->data;
    if (ctx->pkey == NULL && dctx->gen_group == NULL) {
        ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
        return 0;
    }
    ec = EC_KEY_new();
    if (!ec)
        return 0;
    EVP_PKEY_assign_EC_KEY(pkey, ec);
    if (ctx->pkey) {
        /* Note: if error return, pkey is freed by parent routine */
        if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
            return 0;
    } else {
        if (!EC_KEY_set_group(ec, dctx->gen_group))
            return 0;
    }
    return EC_KEY_generate_key(pkey->pkey.ec);
}
Exemplo n.º 4
0
soter_status_t soter_ec_gen_key(EVP_PKEY_CTX *pkey_ctx)
{
  EVP_PKEY *pkey;
  EC_KEY *ec;
  if (!pkey_ctx){
    return SOTER_INVALID_PARAMETER;
  }
  pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx);
  if (!pkey){
    return SOTER_INVALID_PARAMETER;
  }
  if (EVP_PKEY_EC != EVP_PKEY_id(pkey)){
    return SOTER_INVALID_PARAMETER;
  }
  ec = EVP_PKEY_get0(pkey);
  if (NULL == ec){
    return SOTER_INVALID_PARAMETER;
  }
  if (1 == EC_KEY_generate_key(ec)){
    return SOTER_SUCCESS;
  }
  return SOTER_FAIL;
}
Exemplo n.º 5
0
soter_status_t soter_asym_ka_gen_key(soter_asym_ka_t* asym_ka_ctx)
{
	EVP_PKEY *pkey;
	EC_KEY *ec;

	if (!asym_ka_ctx)
	{
		return SOTER_INVALID_PARAMETER;
	}

	pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx);

	if (!pkey)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_EC != EVP_PKEY_id(pkey))
	{
		return SOTER_INVALID_PARAMETER;
	}

	ec = EVP_PKEY_get0_EC_KEY(pkey);
	if (NULL == ec)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (1 == EC_KEY_generate_key(ec))
	{
		return SOTER_SUCCESS;
	}
	else
	{
		return SOTER_FAIL;
	}
}
Exemplo n.º 6
0
static void test_ecdsa_sign(void)
{
    EVP_PKEY *pkey;

    { /* create pkey */
        EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
        EC_KEY_generate_key(eckey);
        pkey = EVP_PKEY_new();
        EVP_PKEY_set1_EC_KEY(pkey, eckey);
        EC_KEY_free(eckey);
    }

    const char *message = "hello world";
    ptls_buffer_t sigbuf;
    uint8_t sigbuf_small[1024];

    ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small));
    ok(do_sign(pkey, &sigbuf, ptls_iovec_init(message, strlen(message)), EVP_sha256()) == 0);
    EVP_PKEY_up_ref(pkey);
    ok(verify_sign(pkey, ptls_iovec_init(message, strlen(message)), ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0);

    ptls_buffer_dispose(&sigbuf);
    EVP_PKEY_free(pkey);
}
Exemplo n.º 7
0
static EP_STAT
generate_ec_key(EP_CRYPTO_KEY *key, const char *curve)
{
	if (curve == NULL)
		curve = ep_adm_getstrparam("libep.crypto.key.ec.curve",
				"sect283r1");
	int nid = OBJ_txt2nid(curve);
	if (nid == NID_undef)
	{
		_ep_crypto_error("unknown EC curve name %s", curve);
		goto fail0;
	}
	EC_KEY *eckey = EC_KEY_new_by_curve_name(nid);
	if (eckey == NULL)
	{
		_ep_crypto_error("cannot create EC key");
		goto fail0;
	}
	if (!EC_KEY_generate_key(eckey))
	{
		_ep_crypto_error("cannot generate EC key");
		goto fail1;
	}
	if (EVP_PKEY_assign_EC_KEY(key, eckey) != 1)
	{
		_ep_crypto_error("cannot assign EC key");
		goto fail1;
	}
	return EP_STAT_OK;

fail1:
	EC_KEY_free(eckey);

fail0:
	return EP_STAT_CRYPTO_KEYCREATE;
}
Exemplo n.º 8
0
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
{
    EC_KEY *a = NULL;
    EC_KEY *b = NULL;
    BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
    char buf[12];
    unsigned char *abuf = NULL, *bbuf = NULL;
    int i, alen, blen, aout, bout, ret = 0;
    const EC_GROUP *group;

    a = EC_KEY_new_by_curve_name(nid);
    b = EC_KEY_new_by_curve_name(nid);
    if (a == NULL || b == NULL)
        goto err;

    group = EC_KEY_get0_group(a);

    if ((x_a = BN_new()) == NULL)
        goto err;
    if ((y_a = BN_new()) == NULL)
        goto err;
    if ((x_b = BN_new()) == NULL)
        goto err;
    if ((y_b = BN_new()) == NULL)
        goto err;

    BIO_puts(out, "Testing key generation with ");
    BIO_puts(out, text);
# ifdef NOISY
    BIO_puts(out, "\n");
# else
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(a))
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
        NID_X9_62_prime_field) {
        if (!EC_POINT_get_affine_coordinates_GFp
            (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(a),
                                                  x_a, y_a, ctx))
            goto err;
    }
# endif
# ifdef NOISY
    BIO_puts(out, "  pri 1=");
    BN_print(out, a->priv_key);
    BIO_puts(out, "\n  pub 1=");
    BN_print(out, x_a);
    BIO_puts(out, ",");
    BN_print(out, y_a);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, " .");
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(b))
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
        NID_X9_62_prime_field) {
        if (!EC_POINT_get_affine_coordinates_GFp
            (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(b),
                                                  x_b, y_b, ctx))
            goto err;
    }
# endif

# ifdef NOISY
    BIO_puts(out, "  pri 2=");
    BN_print(out, b->priv_key);
    BIO_puts(out, "\n  pub 2=");
    BN_print(out, x_b);
    BIO_puts(out, ",");
    BN_print(out, y_b);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    alen = KDF1_SHA1_len;
    abuf = (unsigned char *)OPENSSL_malloc(alen);
    aout =
        ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key1 =");
    for (i = 0; i < aout; i++) {
        sprintf(buf, "%02X", abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    blen = KDF1_SHA1_len;
    bbuf = (unsigned char *)OPENSSL_malloc(blen);
    bout =
        ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key2 =");
    for (i = 0; i < bout; i++) {
        sprintf(buf, "%02X", bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
# ifndef NOISY
        BIO_printf(out, " failed\n\n");
        BIO_printf(out, "key a:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(a));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_a);
        BIO_printf(out, ",");
        BN_print(out, y_a);
        BIO_printf(out, "\nkey b:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(b));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_b);
        BIO_printf(out, ",");
        BN_print(out, y_b);
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key a: ");
        for (i = 0; i < bout; i++) {
            sprintf(buf, "%02X", bbuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key b: ");
        for (i = 0; i < aout; i++) {
            sprintf(buf, "%02X", abuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
# endif
        fprintf(stderr, "Error in ECDH routines\n");
        ret = 0;
    } else {
# ifndef NOISY
        BIO_printf(out, " ok\n");
# endif
        ret = 1;
    }
 err:
    ERR_print_errors_fp(stderr);

    if (abuf != NULL)
        OPENSSL_free(abuf);
    if (bbuf != NULL)
        OPENSSL_free(bbuf);
    if (x_a)
        BN_free(x_a);
    if (y_a)
        BN_free(y_a);
    if (x_b)
        BN_free(x_b);
    if (y_b)
        BN_free(y_b);
    if (b)
        EC_KEY_free(b);
    if (a)
        EC_KEY_free(a);
    return (ret);
}
Exemplo n.º 9
0
static int
input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	EC_POINT *client_public;
	EC_KEY *server_key = NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	BIGNUM *shared_secret = NULL;
	struct sshkey *server_host_private, *server_host_public;
	u_char *server_host_key_blob = NULL, *signature = NULL;
	u_char *kbuf = NULL;
	u_char hash[SSH_DIGEST_MAX_LENGTH];
	size_t slen, sbloblen;
	size_t klen = 0, hashlen;
	int r;

	if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (EC_KEY_generate_key(server_key) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	group = EC_KEY_get0_group(server_key);

#ifdef DEBUG_KEXECDH
	fputs("server private key:\n", stderr);
	sshkey_dump_ec_key(server_key);
#endif

	if (kex->load_host_public_key == NULL ||
	    kex->load_host_private_key == NULL) {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	server_host_public = kex->load_host_public_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	server_host_private = kex->load_host_private_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	if (server_host_public == NULL) {
		r = SSH_ERR_NO_HOSTKEY_LOADED;
		goto out;
	}
	if ((client_public = EC_POINT_new(group)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;

#ifdef DEBUG_KEXECDH
	fputs("client public key:\n", stderr);
	sshkey_dump_ec_point(group, client_public);
#endif
	if (sshkey_ec_validate_public(group, client_public) != 0) {
		sshpkt_disconnect(ssh, "invalid client public key");
		r = SSH_ERR_MESSAGE_INCOMPLETE;
		goto out;
	}

	/* Calculate shared_secret */
	klen = (EC_GROUP_get_degree(group) + 7) / 8;
	if ((kbuf = malloc(klen)) == NULL ||
	    (shared_secret = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (ECDH_compute_key(kbuf, klen, client_public,
	    server_key, NULL) != (int)klen ||
	    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

#ifdef DEBUG_KEXECDH
	dump_digest("shared secret", kbuf, klen);
#endif
	/* calc H */
	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
	    &sbloblen)) != 0)
		goto out;
	hashlen = sizeof(hash);
	if ((r = kex_ecdh_hash(
	    kex->hash_alg,
	    group,
	    kex->client_version_string,
	    kex->server_version_string,
	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
	    server_host_key_blob, sbloblen,
	    client_public,
	    EC_KEY_get0_public_key(server_key),
	    shared_secret,
	    hash, &hashlen)) != 0)
		goto out;

	/* save session id := H */
	if (kex->session_id == NULL) {
		kex->session_id_len = hashlen;
		kex->session_id = malloc(kex->session_id_len);
		if (kex->session_id == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		memcpy(kex->session_id, hash, kex->session_id_len);
	}

	/* sign H */
	if ((r = kex->sign(server_host_private, server_host_public, &signature,
	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
		goto out;

	/* destroy_sensitive_data(); */

	public_key = EC_KEY_get0_public_key(server_key);
	/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
	    (r = sshpkt_put_ec(ssh, public_key, group)) != 0 ||
	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;

	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
		r = kex_send_newkeys(ssh);
 out:
	explicit_bzero(hash, sizeof(hash));
	if (kex->ec_client_key) {
		EC_KEY_free(kex->ec_client_key);
		kex->ec_client_key = NULL;
	}
	if (server_key)
		EC_KEY_free(server_key);
	if (kbuf) {
		explicit_bzero(kbuf, klen);
		free(kbuf);
	}
	if (shared_secret)
		BN_clear_free(shared_secret);
	free(server_host_key_blob);
	free(signature);
	return r;
}
Exemplo n.º 10
0
static krb5_error_code
generate_dh_keyblock(krb5_context context,
		     pk_client_params *client_params,
                     krb5_enctype enctype)
{
    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 (client_params->keyex == USE_DH) {

	if (client_params->u.dh.public_key == NULL) {
	    ret = KRB5KRB_ERR_GENERIC;
	    krb5_set_error_message(context, ret, "public_key");
	    goto out;
	}

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

	dh_gen_keylen = DH_size(client_params->u.dh.key);
	size = BN_num_bytes(client_params->u.dh.key->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->u.dh.public_key,
				       client_params->u.dh.key);
	if (dh_gen_keylen == -1) {
	    ret = KRB5KRB_ERR_GENERIC;
	    krb5_set_error_message(context, ret,
				   "Can't compute Diffie-Hellman key");
	    goto out;
	}
	ret = 0;
#ifdef HAVE_OPENSSL
    } else if (client_params->keyex == USE_ECDH) {

	if (client_params->u.ecdh.public_key == NULL) {
	    ret = KRB5KRB_ERR_GENERIC;
	    krb5_set_error_message(context, ret, "public_key");
	    goto out;
	}

	client_params->u.ecdh.key = EC_KEY_new();
	if (client_params->u.ecdh.key == NULL) {
	    ret = ENOMEM;
	    goto out;
	}
	EC_KEY_set_group(client_params->u.ecdh.key,
			 EC_KEY_get0_group(client_params->u.ecdh.public_key));

	if (EC_KEY_generate_key(client_params->u.ecdh.key) != 1) {
	    ret = ENOMEM;
	    goto out;
	}

	size = (EC_GROUP_get_degree(EC_KEY_get0_group(client_params->u.ecdh.key)) + 7) / 8;
	dh_gen_key = malloc(size);
	if (dh_gen_key == NULL) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret,
				   N_("malloc: out of memory", ""));
	    goto out;
	}

	dh_gen_keylen = ECDH_compute_key(dh_gen_key, size, 
					 EC_KEY_get0_public_key(client_params->u.ecdh.public_key),
					 client_params->u.ecdh.key, NULL);

#endif /* HAVE_OPENSSL */
    } else {
	ret = KRB5KRB_ERR_GENERIC;
	krb5_set_error_message(context, ret, 
			       "Diffie-Hellman not selected keys");
	goto out;
    }

    ret = _krb5_pk_octetstring2key(context,
				   enctype,
				   dh_gen_key, dh_gen_keylen,
				   NULL, NULL,
				   &client_params->reply_key);

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

    return ret;
}
Exemplo n.º 11
0
static int test_builtin(void)
{
    EC_builtin_curve *curves = NULL;
    size_t crv_len = 0, n = 0;
    EC_KEY *eckey = NULL, *wrong_eckey = NULL;
    EC_GROUP *group;
    ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL;
    unsigned char digest[20], wrong_digest[20];
    unsigned char *signature = NULL;
    const unsigned char *sig_ptr;
    unsigned char *sig_ptr2;
    unsigned char *raw_buf = NULL;
    const BIGNUM *sig_r, *sig_s;
    BIGNUM *modified_r = NULL, *modified_s = NULL;
    BIGNUM *unmodified_r = NULL, *unmodified_s = NULL;
    unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
    int nid, ret = 0;

    /* fill digest values with some random data */
    if (!TEST_true(RAND_bytes(digest, 20))
            || !TEST_true(RAND_bytes(wrong_digest, 20)))
        goto builtin_err;

    /* create and verify a ecdsa signature with every available curve */
    /* get a list of all internal curves */
    crv_len = EC_get_builtin_curves(NULL, 0);
    if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
            || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
        goto builtin_err;

    /* now create and verify a signature for every curve */
    for (n = 0; n < crv_len; n++) {
        unsigned char dirt, offset;

        nid = curves[n].nid;
        if (nid == NID_ipsec4 || nid == NID_X25519)
            continue;
        /* create new ecdsa key (== EC_KEY) */
        if (!TEST_ptr(eckey = EC_KEY_new())
                || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
                || !TEST_true(EC_KEY_set_group(eckey, group)))
            goto builtin_err;
        EC_GROUP_free(group);
        degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
        if (degree < 160) {
            /* drop the curve */
            EC_KEY_free(eckey);
            eckey = NULL;
            continue;
        }
        TEST_info("testing %s", OBJ_nid2sn(nid));

        /* create key */
        if (!TEST_true(EC_KEY_generate_key(eckey)))
            goto builtin_err;
        /* create second key */
        if (!TEST_ptr(wrong_eckey = EC_KEY_new())
                || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
                || !TEST_true(EC_KEY_set_group(wrong_eckey, group)))
            goto builtin_err;
        EC_GROUP_free(group);
        if (!TEST_true(EC_KEY_generate_key(wrong_eckey)))
            goto builtin_err;

        /* check key */
        if (!TEST_true(EC_KEY_check_key(eckey)))
            goto builtin_err;

        /* create signature */
        sig_len = ECDSA_size(eckey);
        if (!TEST_ptr(signature = OPENSSL_malloc(sig_len))
                || !TEST_true(ECDSA_sign(0, digest, 20, signature, &sig_len,
                                         eckey)))
            goto builtin_err;

        /* verify signature */
        if (!TEST_int_eq(ECDSA_verify(0, digest, 20, signature, sig_len,
                                      eckey), 1))
            goto builtin_err;

        /* verify signature with the wrong key */
        if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len,
                                      wrong_eckey), 1))
            goto builtin_err;

        /* wrong digest */
        if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, 20, signature,
                                      sig_len, eckey), 1))
            goto builtin_err;

        /* wrong length */
        if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature,
                                      sig_len - 1, eckey), 1))
            goto builtin_err;

        /*
         * Modify a single byte of the signature: to ensure we don't garble
         * the ASN1 structure, we read the raw signature and modify a byte in
         * one of the bignums directly.
         */
        sig_ptr = signature;
        if (!TEST_ptr(ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)))
            goto builtin_err;

        ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);

        /* Store the two BIGNUMs in raw_buf. */
        r_len = BN_num_bytes(sig_r);
        s_len = BN_num_bytes(sig_s);
        bn_len = (degree + 7) / 8;
        if (!TEST_false(r_len > bn_len)
                || !TEST_false(s_len > bn_len))
            goto builtin_err;
        buf_len = 2 * bn_len;
        if (!TEST_ptr(raw_buf = OPENSSL_zalloc(buf_len)))
            goto builtin_err;
        BN_bn2bin(sig_r, raw_buf + bn_len - r_len);
        BN_bn2bin(sig_s, raw_buf + buf_len - s_len);

        /* Modify a single byte in the buffer. */
        offset = raw_buf[10] % buf_len;
        dirt = raw_buf[11] ? raw_buf[11] : 1;
        raw_buf[offset] ^= dirt;

        /* Now read the BIGNUMs back in from raw_buf. */
        if (!TEST_ptr(modified_sig = ECDSA_SIG_new()))
            goto builtin_err;
        if (!TEST_ptr(modified_r = BN_bin2bn(raw_buf, bn_len, NULL))
                || !TEST_ptr(modified_s = BN_bin2bn(raw_buf + bn_len,
                                                    bn_len, NULL))
                || !TEST_true(ECDSA_SIG_set0(modified_sig,
                                             modified_r, modified_s))) {
            BN_free(modified_r);
            BN_free(modified_s);
            goto builtin_err;
        }
        sig_ptr2 = signature;
        sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
        if (!TEST_false(ECDSA_verify(0, digest, 20, signature, sig_len, eckey)))
            goto builtin_err;

        /* Sanity check: undo the modification and verify signature. */
        raw_buf[offset] ^= dirt;
        if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL))
                || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len,
                                                       bn_len, NULL))
                || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r,
                                             unmodified_s))) {
            BN_free(unmodified_r);
            BN_free(unmodified_s);
            goto builtin_err;
        }

        sig_ptr2 = signature;
        sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
        if (!TEST_true(ECDSA_verify(0, digest, 20, signature, sig_len, eckey)))
            goto builtin_err;

        /* cleanup */
        ERR_clear_error();
        OPENSSL_free(signature);
        signature = NULL;
        EC_KEY_free(eckey);
        eckey = NULL;
        EC_KEY_free(wrong_eckey);
        wrong_eckey = NULL;
        ECDSA_SIG_free(ecdsa_sig);
        ecdsa_sig = NULL;
        ECDSA_SIG_free(modified_sig);
        modified_sig = NULL;
        OPENSSL_free(raw_buf);
        raw_buf = NULL;
    }

    ret = 1;
 builtin_err:
    EC_KEY_free(eckey);
    EC_KEY_free(wrong_eckey);
    ECDSA_SIG_free(ecdsa_sig);
    ECDSA_SIG_free(modified_sig);
    OPENSSL_free(signature);
    OPENSSL_free(raw_buf);
    OPENSSL_free(curves);

    return ret;
}
Exemplo n.º 12
0
void
kexecdh_client(Kex *kex)
{
	EC_KEY *client_key;
	EC_POINT *server_public;
	const EC_GROUP *group;
	BIGNUM *shared_secret;
	Key *server_host_key;
	u_char *server_host_key_blob = NULL, *signature = NULL;
	u_char *kbuf, *hash;
	u_int klen, slen, sbloblen, hashlen;

	if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL)
		fatal("%s: EC_KEY_new_by_curve_name failed", __func__);
	if (EC_KEY_generate_key(client_key) != 1)
		fatal("%s: EC_KEY_generate_key failed", __func__);
	group = EC_KEY_get0_group(client_key);

	packet_start(SSH2_MSG_KEX_ECDH_INIT);
	packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key));
	packet_send();
	debug("sending SSH2_MSG_KEX_ECDH_INIT");

#ifdef DEBUG_KEXECDH
	fputs("client private key:\n", stderr);
	key_dump_ec_key(client_key);
#endif

	debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
	packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY);

	/* hostkey */
	server_host_key_blob = packet_get_string(&sbloblen);
	server_host_key = key_from_blob(server_host_key_blob, sbloblen);
	if (server_host_key == NULL)
		fatal("cannot decode server_host_key_blob");
	if (server_host_key->type != kex->hostkey_type)
		fatal("type mismatch for decoded server_host_key_blob");
	if (kex->verify_host_key == NULL)
		fatal("cannot verify server_host_key");
	if (kex->verify_host_key(server_host_key) == -1)
		fatal("server_host_key verification failed");

	/* Q_S, server public key */
	if ((server_public = EC_POINT_new(group)) == NULL)
		fatal("%s: EC_POINT_new failed", __func__);
	packet_get_ecpoint(group, server_public);

	if (key_ec_validate_public(group, server_public) != 0)
		fatal("%s: invalid server public key", __func__);

#ifdef DEBUG_KEXECDH
	fputs("server public key:\n", stderr);
	key_dump_ec_point(group, server_public);
#endif

	/* signed H */
	signature = packet_get_string(&slen);
	packet_check_eom();

	klen = (EC_GROUP_get_degree(group) + 7) / 8;
	kbuf = xmalloc(klen);
	if (ECDH_compute_key(kbuf, klen, server_public,
	    client_key, NULL) != (int)klen)
		fatal("%s: ECDH_compute_key failed", __func__);

#ifdef DEBUG_KEXECDH
	dump_digest("shared secret", kbuf, klen);
#endif
	if ((shared_secret = BN_new()) == NULL)
		fatal("%s: BN_new failed", __func__);
	if (BN_bin2bn(kbuf, klen, shared_secret) == NULL)
		fatal("%s: BN_bin2bn failed", __func__);
	memset(kbuf, 0, klen);
	free(kbuf);

	/* calc and verify H */
	kex_ecdh_hash(
	    kex->evp_md,
	    group,
	    kex->client_version_string,
	    kex->server_version_string,
	    buffer_ptr(&kex->my), buffer_len(&kex->my),
	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
	    server_host_key_blob, sbloblen,
	    EC_KEY_get0_public_key(client_key),
	    server_public,
	    shared_secret,
	    &hash, &hashlen
	);
	free(server_host_key_blob);
	EC_POINT_clear_free(server_public);
	EC_KEY_free(client_key);

	if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
		fatal("key_verify failed for server_host_key");
	key_free(server_host_key);
	free(signature);

	/* save session id */
	if (kex->session_id == NULL) {
		kex->session_id_len = hashlen;
		kex->session_id = xmalloc(kex->session_id_len);
		memcpy(kex->session_id, hash, kex->session_id_len);
	}

	kex_derive_keys(kex, hash, hashlen, shared_secret);
	BN_clear_free(shared_secret);
	kex_finish(kex);
}
Exemplo n.º 13
0
extern "C" int32_t CryptoNative_EcKeyGenerateKey(EC_KEY* eckey)
{
    return EC_KEY_generate_key(eckey);
}
Exemplo n.º 14
0
/* some tests from the X9.62 draft */
int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    BIGNUM *sig_r, *sig_s;

    if (md_ctx == NULL)
        goto x962_int_err;

    /* get the message digest */
    if (!EVP_DigestInit(md_ctx, EVP_sha1())
        || !EVP_DigestUpdate(md_ctx, (const void *)message, 3)
        || !EVP_DigestFinal(md_ctx, digest, &dgst_len))
        goto x962_int_err;

    BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
    /* create the key */
    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        goto x962_int_err;
    use_fake = 1;
    if (!EC_KEY_generate_key(key))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create the signature */
    use_fake = 1;
    /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
    if (!ECDSA_sign_setup(key, NULL, &kinv, &rp))
        goto x962_int_err;
    signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key);
    if (signature == NULL)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* compare the created signature with the expected signature */
    if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        goto x962_int_err;
    if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
        goto x962_int_err;
    ECDSA_SIG_get0(&sig_r, &sig_s, signature);
    if (BN_cmp(sig_r, r) || BN_cmp(sig_s, s))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify the signature */
    if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    ret = 1;
 x962_int_err:
    if (!ret)
        BIO_printf(out, " failed\n");
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(md_ctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}
Exemplo n.º 15
0
void
FilePrivateKeyStorage::generateKeyPair
  (const Name& keyName, const KeyParams& params)
{
  if (doesKeyExist(keyName, KEY_CLASS_PUBLIC))
    throw SecurityException("Public Key already exists");
  if (doesKeyExist(keyName, KEY_CLASS_PRIVATE))
    throw SecurityException("Private Key already exists");

  Blob publicKeyDer;
  Blob privateKeyDer;

  if (params.getKeyType() == KEY_TYPE_RSA) {
    const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);

    BIGNUM* exponent = 0;
    RSA* rsa = 0;

    exponent = BN_new();
    if (BN_set_word(exponent, RSA_F4) == 1) {
      rsa = RSA_new();
      if (RSA_generate_key_ex(rsa, rsaParams.getKeySize(), exponent, NULL) == 1) {
        // Encode the public key.
        int length = i2d_RSA_PUBKEY(rsa, NULL);
        publicKeyDer = Blob(ptr_lib::make_shared<vector<uint8_t> >(length), false);
        uint8_t* derPointer = const_cast<uint8_t*>(publicKeyDer.buf());
        i2d_RSA_PUBKEY(rsa, &derPointer);

        // Encode the private key.
        length = i2d_RSAPrivateKey(rsa, NULL);
        vector<uint8_t> pkcs1PrivateKeyDer(length);
        derPointer = &pkcs1PrivateKeyDer[0];
        i2d_RSAPrivateKey(rsa, &derPointer);
        privateKeyDer = encodePkcs8PrivateKey
          (pkcs1PrivateKeyDer, OID(RSA_ENCRYPTION_OID),
           ptr_lib::make_shared<DerNode::DerNull>());
      }
    }

    BN_free(exponent);
    RSA_free(rsa);
  }
  else if (params.getKeyType() == KEY_TYPE_ECDSA) {
    const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);

    OID parametersOid;
    int curveId = -1;

    // Find the entry in EC_KEY_INFO.
    for (size_t i = 0 ; i < sizeof(EC_KEY_INFO) / sizeof(EC_KEY_INFO[0]); ++i) {
      if (EC_KEY_INFO[i].keySize == ecdsaParams.getKeySize()) {
        curveId = EC_KEY_INFO[i].curveId;
        parametersOid.setIntegerList
          (EC_KEY_INFO[i].oidIntegerList, EC_KEY_INFO[i].oidIntegerListLength);

        break;
      }
    }
    if (curveId == -1)
      throw SecurityException("Unsupported keySize for KEY_TYPE_ECDSA");

    EC_KEY* ecKey = EC_KEY_new_by_curve_name(curveId);
    if (ecKey != NULL) {
      if (EC_KEY_generate_key(ecKey) == 1) {
        // Encode the public key.
        int length = i2d_EC_PUBKEY(ecKey, NULL);
        vector<uint8_t> opensslPublicKeyDer(length);
        uint8_t* derPointer = &opensslPublicKeyDer[0];
        i2d_EC_PUBKEY(ecKey, &derPointer);
        // Convert the openssl style to ndn-cxx which has the simple AlgorithmIdentifier.
        // Find the bit string which is the second child.
        ptr_lib::shared_ptr<DerNode> parsedNode = DerNode::parse
          (&opensslPublicKeyDer[0], 0);
        const std::vector<ptr_lib::shared_ptr<DerNode> >& children =
          parsedNode->getChildren();
        publicKeyDer = encodeSubjectPublicKeyInfo
          (OID(EC_ENCRYPTION_OID),
           ptr_lib::make_shared<DerNode::DerOid>(parametersOid), children[1]);

        // Encode the private key.
        EC_KEY_set_enc_flags(ecKey, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY);
        length = i2d_ECPrivateKey(ecKey, NULL);
        vector<uint8_t> pkcs1PrivateKeyDer(length);
        derPointer = &pkcs1PrivateKeyDer[0];
        i2d_ECPrivateKey(ecKey, &derPointer);
        privateKeyDer = encodePkcs8PrivateKey
          (pkcs1PrivateKeyDer, OID(EC_ENCRYPTION_OID),
           ptr_lib::make_shared<DerNode::DerOid>(parametersOid));
      }
    }

    EC_KEY_free(ecKey);
  }
  else
    throw SecurityException("Unsupported key type");

  string keyUri = keyName.toUri();
  string publicKeyFilePath = nameTransform(keyUri, ".pub");
  string privateKeyFilePath = nameTransform(keyUri, ".pri");

  ofstream publicKeyFile(publicKeyFilePath.c_str());
  publicKeyFile << toBase64(publicKeyDer.buf(), publicKeyDer.size(), true);
  ofstream privateKeyFile(privateKeyFilePath.c_str());
  privateKeyFile << toBase64(privateKeyDer.buf(), privateKeyDer.size(), true);

  ::chmod(publicKeyFilePath.c_str(),  S_IRUSR | S_IRGRP | S_IROTH);
  ::chmod(privateKeyFilePath.c_str(), S_IRUSR);
}
Exemplo n.º 16
0
int main(int argc, char *argv[]) {
	void *bb;
	BN_CTX *ctx = NULL;
	int nid;
	BIO *out;
	CRYPTO_malloc_debug_init();
	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
	const char *text = "NIST Prime-Curve P-192";

#ifdef OPENSSL_SYS_WIN32
	CRYPTO_malloc_init();
#endif

	RAND_seed(rnd_seed, sizeof rnd_seed);
	out = BIO_new(BIO_s_file());
	if (out == NULL)
		EXIT(1);
	BIO_set_fp(out, stdout, BIO_NOCLOSE);

	if ((ctx = BN_CTX_new()) == NULL)
		goto err;
	nid = NID_X9_62_prime192v1;

	//EC_POINT *bb;
	EC_KEY *a = NULL;    //EC_KEY is a structure
	BIGNUM *x_a = NULL, *y_a = NULL;

	char buf[12];
	//unsigned char *abuf=NULL,*bbuf=NULL;
	int i, alen, blen, aout, bout;
	const EC_GROUP *group;

	a = EC_KEY_new_by_curve_name(nid);
	if (a == NULL)
		goto err;

	group = EC_KEY_get0_group(a);

	if ((x_a = BN_new()) == NULL)
		goto err;
	//BN_new returns a pointer to the bignum
	if ((y_a = BN_new()) == NULL)
		goto err;

	BIO_puts(out, "Testing key generation with ");
	BIO_puts(out, text);

	if (!EC_KEY_generate_key(a))
		goto err;
	printf("\n1 ) generating keys\n");

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
			== NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}
	//returns the public key
	else {
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
				EC_KEY_get0_public_key(a), x_a, y_a, ctx))
			goto err;
	}

	BIO_puts(out, "  pri 1=");
	BN_print(out, EC_KEY_get0_private_key(a));
	BIO_puts(out, "\n  pub 1=");
	BN_print(out, x_a);
	BIO_puts(out, ",");
	BN_print(out, y_a);
	BIO_puts(out, "\n");

	func(EC_KEY_get0_public_key(a));

	err: ERR_print_errors_fp(stderr);

	if (x_a)
		BN_free(x_a);
	if (y_a)
		BN_free(y_a);
	if (a)
		EC_KEY_free(a);
	if (ctx)
		BN_CTX_free(ctx);
	BIO_free(out);
	CRYPTO_cleanup_all_ex_data();
	ERR_remove_state(0);
	CRYPTO_mem_leaks_fp(stderr);
	return 0;

}
Exemplo n.º 17
0
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
    /* ECDH keys */
    ssh_string q_c_string;
    ssh_string q_s_string;
    EC_KEY *ecdh_key;
    const EC_GROUP *group;
    const EC_POINT *ecdh_pubkey;
    bignum_CTX ctx;
    /* SSH host keys (rsa,dsa,ecdsa) */
    ssh_key privkey;
    ssh_string sig_blob = NULL;
    int len;
    int rc;

    /* Extract the client pubkey from the init packet */
    q_c_string = ssh_buffer_get_ssh_string(packet);
    if (q_c_string == NULL) {
        ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
        return SSH_ERROR;
    }
    session->next_crypto->ecdh_client_pubkey = q_c_string;

    /* Build server's keypair */

    ctx = BN_CTX_new();
    ecdh_key = EC_KEY_new_by_curve_name(NISTP256);
    if (ecdh_key == NULL) {
        ssh_set_error_oom(session);
        BN_CTX_free(ctx);
        return SSH_ERROR;
    }

    group = EC_KEY_get0_group(ecdh_key);
    EC_KEY_generate_key(ecdh_key);

    ecdh_pubkey = EC_KEY_get0_public_key(ecdh_key);
    len = EC_POINT_point2oct(group,
                             ecdh_pubkey,
                             POINT_CONVERSION_UNCOMPRESSED,
                             NULL,
                             0,
                             ctx);

    q_s_string = ssh_string_new(len);
    if (q_s_string == NULL) {
        EC_KEY_free(ecdh_key);
        BN_CTX_free(ctx);
        return SSH_ERROR;
    }

    EC_POINT_point2oct(group,
                       ecdh_pubkey,
                       POINT_CONVERSION_UNCOMPRESSED,
                       ssh_string_data(q_s_string),
                       len,
                       ctx);
    BN_CTX_free(ctx);

    session->next_crypto->ecdh_privkey = ecdh_key;
    session->next_crypto->ecdh_server_pubkey = q_s_string;

    /* build k and session_id */
    rc = ecdh_build_k(session);
    if (rc < 0) {
        ssh_set_error(session, SSH_FATAL, "Cannot build k number");
        return SSH_ERROR;
    }

    /* privkey is not allocated */
    rc = ssh_get_key_params(session, &privkey);
    if (rc == SSH_ERROR) {
        return SSH_ERROR;
    }

    rc = ssh_make_sessionid(session);
    if (rc != SSH_OK) {
        ssh_set_error(session, SSH_FATAL, "Could not create a session id");
        return SSH_ERROR;
    }

    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
    if (sig_blob == NULL) {
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
        return SSH_ERROR;
    }

    rc = ssh_buffer_pack(session->out_buffer,
                         "bSSS",
                         SSH2_MSG_KEXDH_REPLY,
                         session->next_crypto->server_pubkey, /* host's pubkey */
                         q_s_string, /* ecdh public key */
                         sig_blob); /* signature blob */

    ssh_string_free(sig_blob);

    if (rc != SSH_OK) {
        ssh_set_error_oom(session);
        return SSH_ERROR;
    }

    SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
    rc = ssh_packet_send(session);
    if (rc == SSH_ERROR) {
        return SSH_ERROR;
    }

    /* Send the MSG_NEWKEYS */
    rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
    if (rc < 0) {
        return SSH_ERROR;;
    }

    session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
    rc = ssh_packet_send(session);
    SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");

    return rc;
}
Exemplo n.º 18
0
char * getRealBitcoinAddress() {

	printf("OpenSSL version: %s\n", OPENSSL_VERSION_TEXT);
	/*printf("Enter the number of keys: ");
	fflush(stdout);
	*/
	char stringMatch[31];
	/*getLine1(stringMatch);
	unsigned long int i = strtol(stringMatch, NULL, 0);*/
	printf("Please enter a string of text for the key (30 max): ");
	fflush(stdout);
	getLine1(stringMatch);
	printf("Waiting for entropy... Move the cursor around...\n");
	fflush(stdout);
	char entropy[32];
	FILE * f = fopen("/dev/random", "r");

	if (fread(entropy, 32, 1, f) != 1) {

		printf("FAILURING GETTING ENTROPY!");
		return 1;
	}

	RAND_add(entropy, 32, 32);
	fclose(f);
	printf("Making your addresses for \"%s\"\n\n", stringMatch);
	EC_KEY * key = EC_KEY_new_by_curve_name(NID_secp256k1);
	uint8_t * pubKey = NULL;
	int pubSize = 0;
	uint8_t * privKey = NULL;
	int privSize = 0;
	uint8_t * shaHash = malloc(32);
	uint8_t * ripemdHash = malloc(20);
	unsigned int x;

	if (!EC_KEY_generate_key(key)) {

		printf("GENERATE KEY FAIL\n");
		exit(1);
	}

	int pubSizeNew = i2o_ECPublicKey(key, NULL);

	if (!pubSizeNew) {

		printf("PUB KEY TO DATA ZERO\n");
		exit(1);
	}

	if (pubSizeNew != pubSize) {

		pubSize = pubSizeNew;
		pubKey = realloc(pubKey, pubSize);
	}
	uint8_t * pubKey2 = pubKey;

	if (i2o_ECPublicKey(key, &pubKey2) != pubSize) {

		printf("PUB KEY TO DATA FAIL\n");
		exit(1);
	}

	SHA256(pubKey, pubSize, shaHash);
	RIPEMD160(shaHash, 32, ripemdHash);
	Address * address = createNewAddressFromRIPEMD160Hash(ripemdHash, 0, 0,
			err8);
	ByteArray * string = getStringForVersionChecksumBytes(
			getVersionChecksumBytes(address));
	decrementReferenceCount(address);
	uint8_t offset = 1;
	size_t matchSize = strlen(stringMatch);
	uint8_t y;
	/* Get private key*/
	const BIGNUM * privKeyNum = EC_KEY_get0_private_key(key);

	if (!privKeyNum) {
		printf("PRIV KEY TO BN FAIL\n");
	}

	int privSizeNew = BN_num_bytes(privKeyNum);

	if (privSizeNew != privSize) {
		privSize = privSizeNew;
		privKey = realloc(privKey, privSize);
	}

	int res = BN_bn2bin(privKeyNum, privKey);

	if (res != privSize) {
		printf("PRIV KEY TO DATA FAIL\n");
	}

	/* Print data to stdout*/
	printf("Private key (hex): ");
	int i;

	for (i = 0; i < privSize; i++) {
		printf(" %.2X", privKey[i]);
	}

	printf("\nPublic key (hex): ");
	int j;

	for (j = 0; j < pubSize; j++) {
		printf(" %.2X", pubKey[j]);
	}
	printf("\n");

	char *realBitcoinAddress = getByteArrayData(string);

	/*printf("\nAddress (base-58): %s\n\n", realBitcoinAddress);*/
	x++; /*Move to next*/

	decrementReferenceCount(string);


	free(shaHash);
	free(ripemdHash);
	EC_KEY_free(key);
	return realBitcoinAddress;
}
Exemplo n.º 19
0
/* some tests from the X9.62 draft */
int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX md_ctx;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;

    EVP_MD_CTX_init(&md_ctx);
    /* get the message digest */
    EVP_DigestInit(&md_ctx, EVP_ecdsa());
    EVP_DigestUpdate(&md_ctx, (const void *)message, 3);
    EVP_DigestFinal(&md_ctx, digest, &dgst_len);

    BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
    /* create the key */
    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        goto x962_int_err;
    if (!EC_KEY_generate_key(key))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create the signature */
    signature = ECDSA_do_sign(digest, 20, key);
    if (signature == NULL)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* compare the created signature with the expected signature */
    if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        goto x962_int_err;
    if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
        goto x962_int_err;
    if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify the signature */
    if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    ret = 1;
x962_int_err:
    if (!ret)
        BIO_printf(out, " failed\n");
    if (key)
        EC_KEY_free(key);
    if (signature)
        ECDSA_SIG_free(signature);
    if (r)
        BN_free(r);
    if (s)
        BN_free(s);
    EVP_MD_CTX_cleanup(&md_ctx);
    return ret;
}
Exemplo n.º 20
0
int main(int argc, char **argv)
{
	int r, i;
	KDF_FUNC kdf = NULL;
	EC_GROUP *ec_group = NULL;
	EC_KEY *ec_key = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_PKEY *pub_key = NULL;
	EVP_PKEY *priv_key = NULL;
	X509_ALGOR *map = NULL;
	CPK_MASTER_SECRET *master = NULL;
	CPK_PUBLIC_PARAMS *params = NULL;
	BIO *bio_out = NULL;
	unsigned char *buf = NULL;
	unsigned char *p;
	const unsigned char *cp;
	int len;

	/* init openssl global functions */
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	/* prepare cpk setup parameters */
	ec_key = EC_KEY_new_by_curve_name(OBJ_sn2nid("prime192v1"));
	assert(ec_key != NULL);

	EC_GROUP_set_asn1_flag((EC_GROUP *)EC_KEY_get0_group(ec_key), OPENSSL_EC_NAMED_CURVE);
	r = EC_KEY_generate_key(ec_key);
	assert(r == 1);

	pkey = EVP_PKEY_new();
	assert(pkey != NULL);
	r = EVP_PKEY_set1_EC_KEY(pkey, ec_key);
	assert(r == 1);
	map = CPK_MAP_new_default();
	assert(map != NULL);


	//EVP_PKEY_print_fp(pkey, stdout);

	/* generate master_secret and public_params */
	master = CPK_MASTER_SECRET_create("domainid", pkey, map);
	OPENSSL_assert(master);

	bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
	OPENSSL_assert(bio_out);

	r = CPK_MASTER_SECRET_print(bio_out, master, 0, 0);
	assert(r == 1);

	EVP_PKEY_free(pkey);
	pkey = NULL;
	pkey = CPK_MASTER_SECRET_extract_private_key(master, "id");
	assert(pkey != NULL);
	EVP_PKEY_free(pkey);
	//pkey = CPK_MASTER_SECRET_extract_private_key(master, NULL);
	//assert(pkey == NULL);
	pkey = CPK_MASTER_SECRET_extract_private_key(master, id_long);
	assert(pkey != NULL);
	printf("EVP_PKEY of '%s':\n", id_long);
	EVP_PKEY_print_fp(pkey, stdout);
	printf("\n");
	
	params = CPK_MASTER_SECRET_extract_public_params(master);
	assert(params);
	r = CPK_PUBLIC_PARAMS_print(bio_out, params, 0, 0);
	assert(r == 1);
	printf("\n");

	printf("test CPK_PUBLIC_PARAMS_extract_public_key()\n");
	pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_short);
	assert(pub_key != NULL);
	EVP_PKEY_free(pub_key);

	pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_long);
	assert(pub_key != NULL);
	printf("Public Key of '%s':\n", id_long);
	EVP_PKEY_print_fp(pkey, stdout);
	printf("\n");

	
	r = CPK_MASTER_SECRET_validate_public_params(master, params);
	assert(r == 1);
	if (priv_key) EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "identity");
	assert(priv_key);
	r = CPK_PUBLIC_PARAMS_validate_private_key(params, "identity", priv_key);
	assert(r == 1);
	r = CPK_PUBLIC_PARAMS_validate_private_key(params, "id", priv_key);
	assert(r == 0);

	/* der encoding and decoding */
	len = i2d_CPK_MASTER_SECRET(master, NULL);
	assert(len > 0);
	if (buf != NULL) OPENSSL_free(buf);
	buf = OPENSSL_malloc(len);
	assert(buf != NULL);
	p = buf;
	len = i2d_CPK_MASTER_SECRET(master, &p);
	assert(len > 0);
	assert(p - buf == len);

	cp = buf;
	if (master) CPK_MASTER_SECRET_free(master);
	master = NULL;
	master = d2i_CPK_MASTER_SECRET(NULL, &cp, len);
	assert(master != NULL);
	r = CPK_MASTER_SECRET_validate_public_params(master, params);
	assert(r == 1);

	kdf = KDF_get_x9_63(EVP_sha1());
	assert(kdf != NULL);


	if (priv_key != NULL) EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Alice");
	assert(priv_key != NULL);

	if (buf != NULL) OPENSSL_free(buf);
	buf = OPENSSL_malloc(1024);
	assert(buf != NULL);
	r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Bob", priv_key, kdf);
	for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n");

	if (priv_key != NULL)
		EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Bob");
	assert(priv_key != NULL);
	r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Alice", priv_key, kdf);
	for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n");


	printf("ok\n");
	
	return 0;
}
Exemplo n.º 21
0
/* some tests from the X9.62 draft */
static int x9_62_test_internal(int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX *md_ctx;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    const BIGNUM *sig_r, *sig_s;

    if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()))
        goto x962_int_err;

    /* get the message digest */
    if (!TEST_true(EVP_DigestInit(md_ctx, EVP_sha1()))
        || !TEST_true(EVP_DigestUpdate(md_ctx, (const void *)message, 3))
        || !TEST_true(EVP_DigestFinal(md_ctx, digest, &dgst_len)))
        goto x962_int_err;

    TEST_info("testing %s", OBJ_nid2sn(nid));

    /* create the key */
    if (!TEST_ptr(key = EC_KEY_new_by_curve_name(nid)))
        goto x962_int_err;
    use_fake = 1;
    if (!TEST_true(EC_KEY_generate_key(key)))
        goto x962_int_err;

    /* create the signature */
    use_fake = 1;
    /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
    if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)))
        goto x962_int_err;
    if (!TEST_ptr(signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key)))
        goto x962_int_err;

    /* compare the created signature with the expected signature */
    if (!TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()))
        goto x962_int_err;
    if (!TEST_true(BN_dec2bn(&r, r_in)) || !TEST_true(BN_dec2bn(&s, s_in)))
        goto x962_int_err;
    ECDSA_SIG_get0(signature, &sig_r, &sig_s);
    if (!TEST_BN_eq(sig_r, r)
            || !TEST_BN_eq(sig_s, s))
        goto x962_int_err;

    /* verify the signature */
    if (!TEST_int_eq(ECDSA_do_verify(digest, 20, signature, key), 1))
        goto x962_int_err;

    ret = 1;

 x962_int_err:
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(md_ctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}
Exemplo n.º 22
0
int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
    /* ECDH keys */
    ssh_string q_c_string = NULL;
    ssh_string q_s_string = NULL;
    EC_KEY *ecdh_key=NULL;
    const EC_GROUP *group;
    const EC_POINT *ecdh_pubkey;
    bignum_CTX ctx;
    /* SSH host keys (rsa,dsa,ecdsa) */
    ssh_key privkey;
    ssh_string sig_blob = NULL;
    int len;
    int rc;

    enter_function();

    /* Extract the client pubkey from the init packet */

    q_c_string = buffer_get_ssh_string(packet);
    if (q_c_string == NULL) {
      ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
      goto error;
    }
    session->next_crypto->ecdh_client_pubkey = q_c_string;

    /* Build server's keypair */

    ctx = BN_CTX_new();
    ecdh_key = EC_KEY_new_by_curve_name(NISTP256);
    group = EC_KEY_get0_group(ecdh_key);
    EC_KEY_generate_key(ecdh_key);
    ecdh_pubkey=EC_KEY_get0_public_key(ecdh_key);
    len = EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
        NULL,0,ctx);
    q_s_string=ssh_string_new(len);

    EC_POINT_point2oct(group,ecdh_pubkey,POINT_CONVERSION_UNCOMPRESSED,
        ssh_string_data(q_s_string),len,ctx);

    BN_CTX_free(ctx);
    session->next_crypto->ecdh_privkey = ecdh_key;
    session->next_crypto->ecdh_server_pubkey = q_s_string;

    buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
    /* build k and session_id */
    if (ecdh_build_k(session) < 0) {
      ssh_set_error(session, SSH_FATAL, "Cannot build k number");
      goto error;
    }
    if (ssh_get_key_params(session, &privkey) == SSH_ERROR)
        goto error;
    if (make_sessionid(session) != SSH_OK) {
      ssh_set_error(session, SSH_FATAL, "Could not create a session id");
      goto error;
    }

    /* add host's public key */
    buffer_add_ssh_string(session->out_buffer, session->next_crypto->server_pubkey);
    /* add ecdh public key */
    buffer_add_ssh_string(session->out_buffer,q_s_string);
    /* add signature blob */
    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
    if (sig_blob == NULL) {
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
        goto error;
    }
    buffer_add_ssh_string(session->out_buffer, sig_blob);
    ssh_string_free(sig_blob);
    /* Free private keys as they should not be readable after this point */
    if (session->srv.rsa_key) {
        ssh_key_free(session->srv.rsa_key);
        session->srv.rsa_key = NULL;
    }
    if (session->srv.dsa_key) {
        ssh_key_free(session->srv.dsa_key);
        session->srv.dsa_key = NULL;
    }

    ssh_log(session,SSH_LOG_PROTOCOL, "SSH_MSG_KEXDH_REPLY sent");
    rc = packet_send(session);
    if (rc == SSH_ERROR)
        goto error;

    /* Send the MSG_NEWKEYS */
    if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
      goto error;
    }
    session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
    rc=packet_send(session);
    ssh_log(session, SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
    return rc;
  error:
    return SSH_ERROR;
}
Exemplo n.º 23
0
int test_builtin(BIO *out) {
  size_t n = 0;
  EC_KEY *eckey = NULL, *wrong_eckey = NULL;
  EC_GROUP *group;
  BIGNUM *order = NULL;
  ECDSA_SIG *ecdsa_sig = NULL;
  unsigned char digest[20], wrong_digest[20];
  unsigned char *signature = NULL;
  const unsigned char *sig_ptr;
  unsigned char *sig_ptr2;
  unsigned char *raw_buf = NULL;
  unsigned int sig_len, r_len, s_len, bn_len, buf_len;
  int nid, ret = 0;

  /* fill digest values with some random data */
  if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) {
    BIO_printf(out, "ERROR: unable to get random data\n");
    goto builtin_err;
  }

  order = BN_new();
  if (order == NULL) {
    goto builtin_err;
  }

  /* create and verify a ecdsa signature with every availble curve
   * (with ) */
  BIO_printf(out,
             "\ntesting ECDSA_sign() and ECDSA_verify() "
             "with some internal curves:\n");

  static const int kCurveNIDs[] = {NID_secp224r1, NID_X9_62_prime256v1,
                                   NID_secp384r1, NID_secp521r1, NID_undef};

  /* now create and verify a signature for every curve */
  for (n = 0; kCurveNIDs[n] != NID_undef; n++) {
    unsigned char dirt, offset;

    nid = kCurveNIDs[n];
    /* create new ecdsa key (== EC_KEY) */
    eckey = EC_KEY_new();
    if (eckey == NULL) {
      goto builtin_err;
    }
    group = EC_GROUP_new_by_curve_name(nid);
    if (group == NULL) {
      goto builtin_err;
    }
    if (!EC_KEY_set_group(eckey, group)) {
      goto builtin_err;
    }
    EC_GROUP_free(group);
    if (!EC_GROUP_get_order(EC_KEY_get0_group(eckey), order, NULL)) {
      goto builtin_err;
    }
    if (BN_num_bits(order) < 160) {
      /* Too small to test. */
      EC_KEY_free(eckey);
      eckey = NULL;
      continue;
    }

    BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
    /* create key */
    if (!EC_KEY_generate_key(eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    /* create second key */
    wrong_eckey = EC_KEY_new();
    if (wrong_eckey == NULL) {
      goto builtin_err;
    }
    group = EC_GROUP_new_by_curve_name(nid);
    if (group == NULL) {
      goto builtin_err;
    }
    if (EC_KEY_set_group(wrong_eckey, group) == 0) {
      goto builtin_err;
    }
    EC_GROUP_free(group);
    if (!EC_KEY_generate_key(wrong_eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }

    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* check key */
    if (!EC_KEY_check_key(eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create signature */
    sig_len = ECDSA_size(eckey);
    signature = OPENSSL_malloc(sig_len);
    if (signature == NULL) {
      goto builtin_err;
    }
    if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify signature */
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify signature with the wrong key */
    if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* wrong digest */
    if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* wrong length */
    if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    /* Modify a single byte of the signature: to ensure we don't
     * garble the ASN1 structure, we read the raw signature and
     * modify a byte in one of the bignums directly. */
    sig_ptr = signature;
    ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len);
    if (ecdsa_sig == NULL) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }

    /* Store the two BIGNUMs in raw_buf. */
    r_len = BN_num_bytes(ecdsa_sig->r);
    s_len = BN_num_bytes(ecdsa_sig->s);
    bn_len = BN_num_bytes(order);
    if (r_len > bn_len || s_len > bn_len) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    buf_len = 2 * bn_len;
    raw_buf = OPENSSL_malloc(2 * bn_len);
    if (raw_buf == NULL) {
      goto builtin_err;
    }
    /* Pad the bignums with leading zeroes. */
    if (!BN_bn2bin_padded(raw_buf, bn_len, ecdsa_sig->r) ||
        !BN_bn2bin_padded(raw_buf + bn_len, bn_len, ecdsa_sig->s)) {
      goto builtin_err;
    }

    /* Modify a single byte in the buffer. */
    offset = raw_buf[10] % buf_len;
    dirt = raw_buf[11] ? raw_buf[11] : 1;
    raw_buf[offset] ^= dirt;
    /* Now read the BIGNUMs back in from raw_buf. */
    if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL ||
        BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) {
      goto builtin_err;
    }

    sig_ptr2 = signature;
    sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    /* Sanity check: undo the modification and verify signature. */
    raw_buf[offset] ^= dirt;
    if (BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL ||
        BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL) {
      goto builtin_err;
    }

    sig_ptr2 = signature;
    sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
    if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
      BIO_printf(out, " failed\n");
      goto builtin_err;
    }
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    /* cleanup */
    /* clean bogus errors */
    ERR_clear_error();
    OPENSSL_free(signature);
    signature = NULL;
    EC_KEY_free(eckey);
    eckey = NULL;
    EC_KEY_free(wrong_eckey);
    wrong_eckey = NULL;
    ECDSA_SIG_free(ecdsa_sig);
    ecdsa_sig = NULL;
    OPENSSL_free(raw_buf);
    raw_buf = NULL;
  }

  ret = 1;
builtin_err:
  if (eckey) {
    EC_KEY_free(eckey);
  }
  if (order) {
    BN_free(order);
  }
  if (wrong_eckey) {
    EC_KEY_free(wrong_eckey);
  }
  if (ecdsa_sig) {
    ECDSA_SIG_free(ecdsa_sig);
  }
  if (signature) {
    OPENSSL_free(signature);
  }
  if (raw_buf) {
    OPENSSL_free(raw_buf);
  }

  return ret;
}
Exemplo n.º 24
0
int test_builtin(BIO *out)
	{
	EC_builtin_curve *curves = NULL;
	size_t		crv_len = 0, n = 0;
	EC_KEY		*eckey = NULL, *wrong_eckey = NULL;
	EC_GROUP	*group;
	unsigned char	digest[20], wrong_digest[20];
	unsigned char	*signature = NULL; 
	unsigned int	sig_len;
	int		nid, ret =  0;
	
	/* fill digest values with some random data */
	if (!RAND_pseudo_bytes(digest, 20) ||
	    !RAND_pseudo_bytes(wrong_digest, 20))
		{
		BIO_printf(out, "ERROR: unable to get random data\n");
		goto builtin_err;
		}

	/* create and verify a ecdsa signature with every availble curve
	 * (with ) */
	BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
		"with some internal curves:\n");

	/* get a list of all internal curves */
	crv_len = EC_get_builtin_curves(NULL, 0);

	curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);

	if (curves == NULL)
		{
		BIO_printf(out, "malloc error\n");
		goto builtin_err;
		}
	
	if (!EC_get_builtin_curves(curves, crv_len))
		{
		BIO_printf(out, "unable to get internal curves\n");
		goto builtin_err;
		}

	/* now create and verify a signature for every curve */
	for (n = 0; n < crv_len; n++)
		{
		unsigned char dirt, offset;

		nid = curves[n].nid;
		if (nid == NID_ipsec4)
			continue;
		/* create new ecdsa key (== EC_KEY) */
		if ((eckey = EC_KEY_new()) == NULL)
			goto builtin_err;
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL)
			goto builtin_err;
		if (EC_KEY_set_group(eckey, group) == 0)
			goto builtin_err;
		EC_GROUP_free(group);
		if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160)
			/* drop the curve */ 
			{
			EC_KEY_free(eckey);
			eckey = NULL;
			continue;
			}
		BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
		/* create key */
		if (!EC_KEY_generate_key(eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		/* create second key */
		if ((wrong_eckey = EC_KEY_new()) == NULL)
			goto builtin_err;
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL)
			goto builtin_err;
		if (EC_KEY_set_group(wrong_eckey, group) == 0)
			goto builtin_err;
		EC_GROUP_free(group);
		if (!EC_KEY_generate_key(wrong_eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}

		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* check key */
		if (!EC_KEY_check_key(eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* create signature */
		sig_len = ECDSA_size(eckey);
		if ((signature = OPENSSL_malloc(sig_len)) == NULL)
			goto builtin_err;
                if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* verify signature */
		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* verify signature with the wrong key */
		if (ECDSA_verify(0, digest, 20, signature, sig_len, 
			wrong_eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* wrong digest */
		if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len,
			eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		/* modify a single byte of the signature */
		offset = signature[10] % sig_len;
		dirt   = signature[11];
		signature[offset] ^= dirt ? dirt : 1; 
		if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
			{
			BIO_printf(out, " failed\n");
			goto builtin_err;
			}
		BIO_printf(out, ".");
		(void)BIO_flush(out);
		
		BIO_printf(out, " ok\n");
		/* cleanup */
		OPENSSL_free(signature);
		signature = NULL;
		EC_KEY_free(eckey);
		eckey = NULL;
		EC_KEY_free(wrong_eckey);
		wrong_eckey = NULL;
		}

	ret = 1;	
builtin_err:
	if (eckey)
		EC_KEY_free(eckey);
	if (wrong_eckey)
		EC_KEY_free(wrong_eckey);
	if (signature)
		OPENSSL_free(signature);
	if (curves)
		OPENSSL_free(curves);

	return ret;
	}
Exemplo n.º 25
0
void *
vg_thread_loop(void *arg)
{
	unsigned char hash_buf[128];
	unsigned char *eckey_buf;
	unsigned char hash1[32];

	int i, c, len, output_interval;
	int hash_len;

	const BN_ULONG rekey_max = 10000000;
	BN_ULONG npoints, rekey_at, nbatch;

	vg_context_t *vcp = (vg_context_t *) arg;
	EC_KEY *pkey = NULL;
	const EC_GROUP *pgroup;
	const EC_POINT *pgen;
	const int ptarraysize = 256;
	EC_POINT *ppnt[ptarraysize];
	EC_POINT *pbatchinc;

	vg_test_func_t test_func = vcp->vc_test;
	vg_exec_context_t ctx;
	vg_exec_context_t *vxcp;

	struct timeval tvstart;


	memset(&ctx, 0, sizeof(ctx));
	vxcp = &ctx;

	vg_exec_context_init(vcp, &ctx);

	pkey = vxcp->vxc_key;
	pgroup = EC_KEY_get0_group(pkey);
	pgen = EC_GROUP_get0_generator(pgroup);

	for (i = 0; i < ptarraysize; i++) {
		ppnt[i] = EC_POINT_new(pgroup);
		if (!ppnt[i]) {
			fprintf(stderr, "ERROR: out of memory?\n");
			exit(1);
		}
	}
	pbatchinc = EC_POINT_new(pgroup);
	if (!pbatchinc) {
		fprintf(stderr, "ERROR: out of memory?\n");
		exit(1);
	}

	BN_set_word(&vxcp->vxc_bntmp, ptarraysize);
	EC_POINT_mul(pgroup, pbatchinc, &vxcp->vxc_bntmp, NULL, NULL,
		     vxcp->vxc_bnctx);
	EC_POINT_make_affine(pgroup, pbatchinc, vxcp->vxc_bnctx);

	npoints = 0;
	rekey_at = 0;
	nbatch = 0;
	vxcp->vxc_key = pkey;
	vxcp->vxc_binres[0] = vcp->vc_addrtype;
	c = 0;
	output_interval = 1000;
	gettimeofday(&tvstart, NULL);

	if (vcp->vc_format == VCF_SCRIPT) {
		hash_buf[ 0] = 0x51;  // OP_1
		hash_buf[ 1] = 0x41;  // pubkey length
		// gap for pubkey
		hash_buf[67] = 0x51;  // OP_1
		hash_buf[68] = 0xae;  // OP_CHECKMULTISIG
		eckey_buf = hash_buf + 2;
		hash_len = 69;

	} else {
		eckey_buf = hash_buf;
		hash_len = 65;
	}

	while (!vcp->vc_halt) {
		if (++npoints >= rekey_at) {
			vg_exec_context_upgrade_lock(vxcp);
			/* Generate a new random private key */
			EC_KEY_generate_key(pkey);
			npoints = 0;

			/* Determine rekey interval */
			EC_GROUP_get_order(pgroup, &vxcp->vxc_bntmp,
					   vxcp->vxc_bnctx);
			BN_sub(&vxcp->vxc_bntmp2,
			       &vxcp->vxc_bntmp,
			       EC_KEY_get0_private_key(pkey));
			rekey_at = BN_get_word(&vxcp->vxc_bntmp2);
			if ((rekey_at == BN_MASK2) || (rekey_at > rekey_max))
				rekey_at = rekey_max;
			assert(rekey_at > 0);

			EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey));
			vg_exec_context_downgrade_lock(vxcp);

			npoints++;
			vxcp->vxc_delta = 0;

			if (vcp->vc_pubkey_base)
				EC_POINT_add(pgroup,
					     ppnt[0],
					     ppnt[0],
					     vcp->vc_pubkey_base,
					     vxcp->vxc_bnctx);

			for (nbatch = 1;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch-1],
					     pgen, vxcp->vxc_bnctx);
			}

		} else {
			/*
			 * Common case
			 *
			 * EC_POINT_add() can skip a few multiplies if
			 * one or both inputs are affine (Z_is_one).
			 * This is the case for every point in ppnt, as
			 * well as pbatchinc.
			 */
			assert(nbatch == ptarraysize);
			for (nbatch = 0;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch],
					     pbatchinc,
					     vxcp->vxc_bnctx);
			}
		}

		/*
		 * The single most expensive operation performed in this
		 * loop is modular inversion of ppnt->Z.  There is an
		 * algorithm implemented in OpenSSL to do batched inversion
		 * that only does one actual BN_mod_inverse(), and saves
		 * a _lot_ of time.
		 *
		 * To take advantage of this, we batch up a few points,
		 * and feed them to EC_POINTs_make_affine() below.
		 */

		EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx);

		for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) {
			/* Hash the public key */
			len = EC_POINT_point2oct(pgroup, ppnt[i],
						 POINT_CONVERSION_UNCOMPRESSED,
						 eckey_buf,
						 65,
						 vxcp->vxc_bnctx);
			assert(len == 65);

			SHA256(hash_buf, hash_len, hash1);
			RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);

			switch (test_func(vxcp)) {
			case 1:
				npoints = 0;
				rekey_at = 0;
				i = nbatch;
				break;
			case 2:
				goto out;
			default:
				break;
			}
		}

		c += i;
		if (c >= output_interval) {
			output_interval = vg_output_timing(vcp, c, &tvstart);
			if (output_interval > 250000)
				output_interval = 250000;
			c = 0;
		}

		vg_exec_context_yield(vxcp);
	}

out:
	vg_exec_context_del(&ctx);
	vg_context_thread_exit(vcp);

	for (i = 0; i < ptarraysize; i++)
		if (ppnt[i])
			EC_POINT_free(ppnt[i]);
	if (pbatchinc)
		EC_POINT_free(pbatchinc);
	return NULL;
}
Exemplo n.º 26
0
std::string
CertificateManager::generateECDSACertificate ()
{
  EC_KEY *ec_key;
  std::shared_ptr <EC_GROUP> group;
  std::shared_ptr <EVP_PKEY> private_key;
  std::string pem;
  std::string ecdsaParameters, ecdsaKey;
  std::string certificateECDSA;

  ec_key = EC_KEY_new ();

  if (ec_key == nullptr) {
    GST_ERROR ("EC key not created");
    return certificateECDSA;
  }

  group = std::shared_ptr <EC_GROUP> (EC_GROUP_new_by_curve_name (
                                        NID_X9_62_prime256v1),
  [] (EC_GROUP * obj) {
    EC_GROUP_free (obj);
  });
  EC_GROUP_set_asn1_flag (group.get(), OPENSSL_EC_NAMED_CURVE);

  if (group == nullptr) {
    EC_KEY_free (ec_key);
    GST_ERROR ("EC group not created");
    return certificateECDSA;
  }

  if (EC_KEY_set_group (ec_key, group.get() ) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Group not set to key");
    return certificateECDSA;
  }

  if (EC_KEY_generate_key (ec_key) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("EC key not generated");
    return certificateECDSA;
  }

  private_key = std::shared_ptr<EVP_PKEY> (EVP_PKEY_new (),
  [] (EVP_PKEY * obj) {
    EVP_PKEY_free (obj);
  });

  if (private_key == nullptr) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Private key not created");
    return certificateECDSA;
  }

  if (EVP_PKEY_assign_EC_KEY (private_key.get(), ec_key) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Private key not assigned");
    return certificateECDSA;
  }

  pem = generateCertificate (private_key.get() );

  if (pem.empty () ) {
    GST_WARNING ("Certificate not generated");
    return certificateECDSA;
  }

  ecdsaKey = ECDSAKeyToPEMString (ec_key);
  ec_key = nullptr;
  ecdsaParameters = parametersToPEMString (group.get() );

  certificateECDSA = ecdsaParameters + ecdsaKey + pem;

  return certificateECDSA;
}
Exemplo n.º 27
0
static krb5_error_code
generate_ecdh_keyblock(krb5_context context,
                       EC_KEY *ec_key_pk,    /* the client's public key */
                       EC_KEY **ec_key_key,  /* the KDC's ephemeral private */
                       unsigned char **dh_gen_key, /* shared secret */
                       size_t *dh_gen_keylen)
{
    const EC_GROUP *group;
    EC_KEY *ephemeral;
    krb5_keyblock key;
    krb5_error_code ret;
    unsigned char *p;
    size_t size;
    int len;

    *dh_gen_key = NULL;
    *dh_gen_keylen = 0;
    *ec_key_key = NULL;

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

    if (ec_key_pk == NULL) {
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret, "public_key");
        return ret;
    }

    group = EC_KEY_get0_group(ec_key_pk);
    if (group == NULL) {
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret, "failed to get the group of "
                               "the client's public key");
        return ret;
    }

    ephemeral = EC_KEY_new();
    if (ephemeral == NULL)
        return krb5_enomem(context);

    EC_KEY_set_group(ephemeral, group);

    if (EC_KEY_generate_key(ephemeral) != 1) {
	EC_KEY_free(ephemeral);
        return krb5_enomem(context);
    }

    size = (EC_GROUP_get_degree(group) + 7) / 8;
    p = malloc(size);
    if (p == NULL) {
        EC_KEY_free(ephemeral);
        return krb5_enomem(context);
    }

    len = ECDH_compute_key(p, size,
                           EC_KEY_get0_public_key(ec_key_pk),
                           ephemeral, NULL);
    if (len <= 0) {
        free(p);
        EC_KEY_free(ephemeral);
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret, "Failed to compute ECDH "
                               "public shared secret");
        return ret;
    }

    *ec_key_key = ephemeral;
    *dh_gen_key = p;
    *dh_gen_keylen = len;

    return 0;
}
Exemplo n.º 28
0
static LUA_FUNCTION(openssl_pkey_new)
{
  EVP_PKEY *pkey = NULL;
  const char* alg = "rsa";

  if (lua_isnoneornil(L, 1) || lua_isstring(L, 1))
  {
    alg = luaL_optstring(L, 1, alg);

    if (strcasecmp(alg, "rsa") == 0)
    {
      int bits = luaL_optint(L, 2, 1024);
      int e = luaL_optint(L, 3, 65537);
      RSA* rsa = RSA_new();

      BIGNUM *E = BN_new();
      BN_set_word(E, e);
      if (RSA_generate_key_ex(rsa, bits, E, NULL))
      {
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
      }
      else
        RSA_free(rsa);
      BN_free(E);
    }
    else if (strcasecmp(alg, "dsa") == 0)
    {
      int bits = luaL_optint(L, 2, 1024);
      size_t seed_len = 0;
      const char* seed = luaL_optlstring(L, 3, NULL, &seed_len);

      DSA *dsa = DSA_new();
      if (DSA_generate_parameters_ex(dsa, bits, (byte*)seed, seed_len, NULL, NULL, NULL)
          && DSA_generate_key(dsa))
      {
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey, dsa);
      }
      else
        DSA_free(dsa);
    }
    else if (strcasecmp(alg, "dh") == 0)
    {
      int bits = luaL_optint(L, 2, 512);
      int generator = luaL_optint(L, 3, 2);

      DH* dh = DH_new();
      if (DH_generate_parameters_ex(dh, bits, generator, NULL))
      {
        if (DH_generate_key(dh))
        {
          pkey = EVP_PKEY_new();
          EVP_PKEY_assign_DH(pkey, dh);
        }
        else
          DH_free(dh);
      }
      else
        DH_free(dh);
    }
#ifndef OPENSSL_NO_EC
    else if (strcasecmp(alg, "ec") == 0)
    {
      EC_KEY *ec = NULL;
      EC_GROUP *group = openssl_get_ec_group(L, 2, 3, 4);
      if (!group)
        luaL_error(L, "failed to get ec_group object");
      ec = EC_KEY_new();
      if (ec)
      {
        EC_KEY_set_group(ec, group);
        EC_GROUP_free(group);
        if (EC_KEY_generate_key(ec))
        {
          pkey = EVP_PKEY_new();
          EVP_PKEY_assign_EC_KEY(pkey, ec);
        }
        else
          EC_KEY_free(ec);
      }
      else
        EC_GROUP_free(group);

    }
#endif
    else
    {
      luaL_error(L, "not support %s!!!!", alg);
    }
  }
  else if (lua_istable(L, 1))
  {
    lua_getfield(L, 1, "alg");
    alg = luaL_optstring(L, -1, alg);
    lua_pop(L, 1);
    if (strcasecmp(alg, "rsa") == 0)
    {
      pkey = EVP_PKEY_new();
      if (pkey)
      {
        RSA *rsa = RSA_new();
        if (rsa)
        {
          OPENSSL_PKEY_SET_BN(1, rsa, n);
          OPENSSL_PKEY_SET_BN(1, rsa, e);
          OPENSSL_PKEY_SET_BN(1, rsa, d);
          OPENSSL_PKEY_SET_BN(1, rsa, p);
          OPENSSL_PKEY_SET_BN(1, rsa, q);
          OPENSSL_PKEY_SET_BN(1, rsa, dmp1);
          OPENSSL_PKEY_SET_BN(1, rsa, dmq1);
          OPENSSL_PKEY_SET_BN(1, rsa, iqmp);
          if (rsa->n)
          {
            if (!EVP_PKEY_assign_RSA(pkey, rsa))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "dsa") == 0)
    {
      pkey = EVP_PKEY_new();
      if (pkey)
      {
        DSA *dsa = DSA_new();
        if (dsa)
        {
          OPENSSL_PKEY_SET_BN(-1, dsa, p);
          OPENSSL_PKEY_SET_BN(-1, dsa, q);
          OPENSSL_PKEY_SET_BN(-1, dsa, g);
          OPENSSL_PKEY_SET_BN(-1, dsa, priv_key);
          OPENSSL_PKEY_SET_BN(-1, dsa, pub_key);
          if (dsa->p && dsa->q && dsa->g)
          {
            if (!dsa->priv_key && !dsa->pub_key)
            {
              DSA_generate_key(dsa);
            }
            if (!EVP_PKEY_assign_DSA(pkey, dsa))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "dh") == 0)
    {

      pkey = EVP_PKEY_new();
      if (pkey)
      {
        DH *dh = DH_new();
        if (dh)
        {
          OPENSSL_PKEY_SET_BN(-1, dh, p);
          OPENSSL_PKEY_SET_BN(-1, dh, g);
          OPENSSL_PKEY_SET_BN(-1, dh, priv_key);
          OPENSSL_PKEY_SET_BN(-1, dh, pub_key);
          if (dh->p && dh->g)
          {
            if (!dh->pub_key)
            {
              DH_generate_key(dh);
            }
            if (!EVP_PKEY_assign_DH(pkey, dh))
            {
              EVP_PKEY_free(pkey);
              pkey = NULL;
            }
          }
        }
      }
    }
    else if (strcasecmp(alg, "ec") == 0)
    {
      BIGNUM *d = NULL;
      BIGNUM *x = NULL;
      BIGNUM *y = NULL;
      BIGNUM *z = NULL;
      EC_GROUP *group = NULL;

      lua_getfield(L, -1, "ec_name");
      lua_getfield(L, -2, "param_enc");
      lua_getfield(L, -3, "conv_form");
      group = openssl_get_ec_group(L, -3, -2, -1);
      lua_pop(L, 3);
      if (!group)
      {
        luaL_error(L, "get openssl.ec_group fail");
      }

      EC_GET_FIELD(d);
      EC_GET_FIELD(x);
      EC_GET_FIELD(y);
      EC_GET_FIELD(z);


      pkey = EVP_PKEY_new();
      if (pkey)
      {
        EC_KEY *ec = EC_KEY_new();
        if (ec)
        {
          EC_KEY_set_group(ec, group);
          if (d)
            EC_KEY_set_private_key(ec, d);
          if (x != NULL && y != NULL)
          {
            EC_POINT *pnt = EC_POINT_new(group);
            if (z == NULL)
              EC_POINT_set_affine_coordinates_GFp(group, pnt, x, y, NULL);
            else
              EC_POINT_set_Jprojective_coordinates_GFp(group, pnt, x, y, z, NULL);

            EC_KEY_set_public_key(ec, pnt);
          }

          if (!EVP_PKEY_assign_EC_KEY(pkey, ec))
          {
            EC_KEY_free(ec);
            EVP_PKEY_free(pkey);
            pkey = NULL;
          }
          if (d && !EC_KEY_check_key(ec))
          {
            EC_KEY_generate_key_part(ec);
          }
        }
      }
    }
  }

  if (pkey)
  {
    PUSH_OBJECT(pkey, "openssl.evp_pkey");
    return 1;
  }
  return 0;

}
Exemplo n.º 29
0
int 
ecparam_main(int argc, char **argv)
{
	EC_GROUP *group = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
	int new_form = 0;
	int asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int new_asn1_flag = 0;
	char *curve_name = NULL, *inrand = NULL;
	int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0,
	 i, genkey = 0;
	char *infile = NULL, *outfile = NULL, *prog;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *engine = NULL;

	BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL,
	*ec_order = NULL, *ec_cofactor = NULL;
	unsigned char *buffer = NULL;

	if (!load_config(bio_err, NULL))
		goto end;

	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-check") == 0)
			check = 1;
		else if (strcmp(*argv, "-name") == 0) {
			if (--argc < 1)
				goto bad;
			curve_name = *(++argv);
		} else if (strcmp(*argv, "-list_curves") == 0)
			list_curves = 1;
		else if (strcmp(*argv, "-conv_form") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (strcmp(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (strcmp(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (strcmp(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
		} else if (strcmp(*argv, "-param_enc") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (strcmp(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (strcmp(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
		} else if (strcmp(*argv, "-no_seed") == 0)
			no_seed = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-rand") == 0) {
			if (--argc < 1)
				goto bad;
			inrand = *(++argv);
		} else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg       input format - "
		    "default PEM (DER or PEM)\n");
		BIO_printf(bio_err, " -outform arg      output format - "
		    "default PEM\n");
		BIO_printf(bio_err, " -in  arg          input file  - "
		    "default stdin\n");
		BIO_printf(bio_err, " -out arg          output file - "
		    "default stdout\n");
		BIO_printf(bio_err, " -noout            do not print the "
		    "ec parameter\n");
		BIO_printf(bio_err, " -text             print the ec "
		    "parameters in text form\n");
		BIO_printf(bio_err, " -check            validate the ec "
		    "parameters\n");
		BIO_printf(bio_err, " -C                print a 'C' "
		    "function creating the parameters\n");
		BIO_printf(bio_err, " -name arg         use the "
		    "ec parameters with 'short name' name\n");
		BIO_printf(bio_err, " -list_curves      prints a list of "
		    "all currently available curve 'short names'\n");
		BIO_printf(bio_err, " -conv_form arg    specifies the "
		    "point conversion form \n");
		BIO_printf(bio_err, "                   possible values:"
		    " compressed\n");
		BIO_printf(bio_err, "                                   "
		    " uncompressed (default)\n");
		BIO_printf(bio_err, "                                   "
		    " hybrid\n");
		BIO_printf(bio_err, " -param_enc arg    specifies the way"
		    " the ec parameters are encoded\n");
		BIO_printf(bio_err, "                   in the asn1 der "
		    "encoding\n");
		BIO_printf(bio_err, "                   possible values:"
		    " named_curve (default)\n");
		BIO_printf(bio_err, "                                   "
		    " explicit\n");
		BIO_printf(bio_err, " -no_seed          if 'explicit'"
		    " parameters are chosen do not"
		    " use the seed\n");
		BIO_printf(bio_err, " -genkey           generate ec"
		    " key\n");
		BIO_printf(bio_err, " -rand file        files to use for"
		    " random number input\n");
		BIO_printf(bio_err, " -engine e         use engine e, "
		    "possibly a hardware device\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (list_curves) {
		EC_builtin_curve *curves = NULL;
		size_t crv_len = 0;
		size_t n = 0;

		crv_len = EC_get_builtin_curves(NULL, 0);

		curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));

		if (curves == NULL)
			goto end;

		if (!EC_get_builtin_curves(curves, crv_len)) {
			free(curves);
			goto end;
		}
		for (n = 0; n < crv_len; n++) {
			const char *comment;
			const char *sname;
			comment = curves[n].comment;
			sname = OBJ_nid2sn(curves[n].nid);
			if (comment == NULL)
				comment = "CURVE DESCRIPTION NOT AVAILABLE";
			if (sname == NULL)
				sname = "";

			BIO_printf(out, "  %-10s: ", sname);
			BIO_printf(out, "%s\n", comment);
		}

		free(curves);
		ret = 0;
		goto end;
	}
	if (curve_name != NULL) {
		int nid;

		/*
		 * workaround for the SECG curve names secp192r1 and
		 * secp256r1 (which are the same as the curves prime192v1 and
		 * prime256v1 defined in X9.62)
		 */
		if (!strcmp(curve_name, "secp192r1")) {
			BIO_printf(bio_err, "using curve name prime192v1 "
			    "instead of secp192r1\n");
			nid = NID_X9_62_prime192v1;
		} else if (!strcmp(curve_name, "secp256r1")) {
			BIO_printf(bio_err, "using curve name prime256v1 "
			    "instead of secp256r1\n");
			nid = NID_X9_62_prime256v1;
		} else
			nid = OBJ_sn2nid(curve_name);

		if (nid == 0) {
			BIO_printf(bio_err, "unknown curve name (%s)\n",
			    curve_name);
			goto end;
		}
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL) {
			BIO_printf(bio_err, "unable to create curve (%s)\n",
			    curve_name);
			goto end;
		}
		EC_GROUP_set_asn1_flag(group, asn1_flag);
		EC_GROUP_set_point_conversion_form(group, form);
	} else if (informat == FORMAT_ASN1) {
		group = d2i_ECPKParameters_bio(in, NULL);
	} else if (informat == FORMAT_PEM) {
		group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
	} else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}

	if (group == NULL) {
		BIO_printf(bio_err,
		    "unable to load elliptic curve parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (new_form)
		EC_GROUP_set_point_conversion_form(group, form);

	if (new_asn1_flag)
		EC_GROUP_set_asn1_flag(group, asn1_flag);

	if (no_seed) {
		EC_GROUP_set_seed(group, NULL, 0);
	}
	if (text) {
		if (!ECPKParameters_print(out, group, 0))
			goto end;
	}
	if (check) {
		if (group == NULL)
			BIO_printf(bio_err, "no elliptic curve parameters\n");
		BIO_printf(bio_err, "checking elliptic curve parameters: ");
		if (!EC_GROUP_check(group, NULL)) {
			BIO_printf(bio_err, "failed\n");
			ERR_print_errors(bio_err);
		} else
			BIO_printf(bio_err, "ok\n");

	}
	if (C) {
		size_t buf_len = 0, tmp_len = 0;
		const EC_POINT *point;
		int is_prime, len = 0;
		const EC_METHOD *meth = EC_GROUP_method_of(group);

		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
		    (ec_order = BN_new()) == NULL ||
		    (ec_cofactor = BN_new()) == NULL) {
			perror("malloc");
			goto end;
		}
		is_prime = (EC_METHOD_get_field_type(meth) ==
		    NID_X9_62_prime_field);

		if (is_prime) {
			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
				ec_b, NULL))
				goto end;
		} else {
			/* TODO */
			goto end;
		}

		if ((point = EC_GROUP_get0_generator(group)) == NULL)
			goto end;
		if (!EC_POINT_point2bn(group, point,
			EC_GROUP_get_point_conversion_form(group), ec_gen,
			NULL))
			goto end;
		if (!EC_GROUP_get_order(group, ec_order, NULL))
			goto end;
		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
			goto end;

		if (!ec_p || !ec_a || !ec_b || !ec_gen ||
		    !ec_order || !ec_cofactor)
			goto end;

		len = BN_num_bits(ec_order);

		if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
			buf_len = tmp_len;

		buffer = (unsigned char *) malloc(buf_len);

		if (buffer == NULL) {
			perror("malloc");
			goto end;
		}
		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
		    buffer);

		BIO_printf(out, "\n\n");

		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
		BIO_printf(out, "\tint ok=0;\n");
		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
		    "*tmp_3 = NULL;\n\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
		    "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
		    "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
		    "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		if (is_prime) {
			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
			    "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
			    "\n\t\tgoto err;\n\n");
		} else {
			/* TODO */
			goto end;
		}
		BIO_printf(out, "\t/* build generator */\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
		    "sizeof(ec_gen_%d), tmp_1)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
		    "NULL, NULL);\n");
		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
		    "sizeof(ec_order_%d), tmp_2)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
		    "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
		    " tmp_2, tmp_3))\n\t\tgoto err;\n");
		BIO_printf(out, "\n\tok=1;\n");
		BIO_printf(out, "err:\n");
		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
		BIO_printf(out, "\tif (!ok)\n");
		BIO_printf(out, "\t\t{\n");
		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
		BIO_printf(out, "\t\tgroup = NULL;\n");
		BIO_printf(out, "\t\t}\n");
		BIO_printf(out, "\treturn(group);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPKParameters_bio(out, group);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPKParameters(out, group);
		else {
			BIO_printf(bio_err, "bad output format specified for"
			    " outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write elliptic "
			    "curve parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		EC_KEY *eckey = EC_KEY_new();

		if (eckey == NULL)
			goto end;

		if (EC_KEY_set_group(eckey, group) == 0)
			goto end;

		if (!EC_KEY_generate_key(eckey)) {
			EC_KEY_free(eckey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPrivateKey_bio(out, eckey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
			    NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified "
			    "for outfile\n");
			EC_KEY_free(eckey);
			goto end;
		}
		EC_KEY_free(eckey);
	}
	ret = 0;
end:
	if (ec_p)
		BN_free(ec_p);
	if (ec_a)
		BN_free(ec_a);
	if (ec_b)
		BN_free(ec_b);
	if (ec_gen)
		BN_free(ec_gen);
	if (ec_order)
		BN_free(ec_order);
	if (ec_cofactor)
		BN_free(ec_cofactor);
	free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	
	return (ret);
}
Exemplo n.º 30
0
int main() {
	srand((unsigned)time(NULL));
	int i;
	EC_KEY* key;
	//key = EC_KEY_new_by_curve_name(415);
	key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
	const EC_GROUP *group = EC_KEY_get0_group(key);
	if (EC_KEY_generate_key(key)==0) {
		printf("Error generate key\n");
		return -1;
	}
	unsigned char pk_b[33];
	const EC_POINT *pub = EC_KEY_get0_public_key(key);
	if (EC_POINT_point2oct(group, pub, POINT_CONVERSION_COMPRESSED, pk_b, 33, 0)!=33) {
		printf("Error 2\n");
		return -1;
	}
	unsigned char h1[16],h2[16];

	printf("\x02");
	for (i=0;i<16;i++) {
		h1[i]=rand()%256;
		printf("%c",h1[i]);
	}
	for (i=0;i<33;i++)
		printf("%c",pk_b[i]);
	fflush(stdout);
	//get h2
	for (i=0;i<16;i++) 
		h2[i]=rand()%256;
	for (i=0;i<16;i++)
		scanf("%c",&h2[i]);
		
	//get peerpk_b
	unsigned char peerpk_b[33]={2 , 30 , 25 , 50 , 17 , 242 , 232 , 55 , 157 , 18 , 106 , 115 , 214 , 193 , 192 , 39 , 207 , 226 , 184 , 216 , 244 , 147 , 111 , 188 , 125 , 230 , 38 , 125 , 231 , 50 , 56 , 152 , 148 };
	for (i=0;i<33;i++)
		scanf("%c",&peerpk_b[i]);
	
	EC_POINT *peerpk = EC_POINT_new(group);
	if (EC_POINT_oct2point(group, peerpk, peerpk_b, 33, 0)==0) {
		printf("Error 3\n");
		return -1;
	}
	unsigned char skey[33];
	if (ECDH_compute_key(skey, 32,  peerpk, key, NULL)==0) {
		printf("Error 4\n");
		return -1;
	}


	SHA512_CTX shactx;	
	unsigned char hash[SHA512_DIGEST_LENGTH];
	SHA512_Init(&shactx);
	SHA512_Update(&shactx, h2, 16);
	SHA512_Update(&shactx, skey, 32);
	SHA512_Update(&shactx, h1, 16);
	SHA512_Final(hash, &shactx);

	for (i=0;i<64;i++)
		printf("%02x",hash[i]);	
	fflush(stdout);

	struct cipher c;
	c.recvfd=0;
	c.sendfd=1;
	for (i=0;i<16;i++)
		c.sendkey[i]=hash[i];
	for (i=0;i<4;i++)
		c.sendiv[i]=hash[32+i];
	for (i=0;i<16;i++)
		c.recvkey[i]=hash[16+i];
	for (i=0;i<4;i++)
		c.recviv[i]=hash[36+i];
	c.sendcnt=0;
	c.recvcnt=0;

	unsigned char d[1000];
	unsigned char oiv[8];
	int op;
	char dlen;

	while (true) {
		scanf("%d",&op);
		scanf("%c",&dlen);
		scanf("%c",&dlen);
		for (i=0;i<dlen;i++)
			scanf("%c",&d[i]);
		if (op==1) {
			for (i=0;i<8;i++)
				oiv[i]=rand()%256;
			encrypt(c,d,dlen,oiv);
			c.recvcnt+=1;
		} else if (op==2) {
			for (i=0;i<8;i++)
				scanf("%c",&oiv[i]);
			decrypt(c,d,dlen,oiv, NULL);
			c.sendcnt+=1;
		}
		fflush(stdout);
	}
	
	return 0;
}