示例#1
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;
	}
示例#2
0
文件: ecdsatest.c 项目: GH-JY/openssl
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_bytes(digest, 20) <= 0 || RAND_bytes(wrong_digest, 20) <= 0) {
        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(*curves) * 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_zalloc(buf_len)) == NULL)
            goto builtin_err;
        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:
    EC_KEY_free(eckey);
    EC_KEY_free(wrong_eckey);
    ECDSA_SIG_free(ecdsa_sig);
    OPENSSL_free(signature);
    OPENSSL_free(raw_buf);
    OPENSSL_free(curves);

    return ret;
}
示例#3
0
/*  call-seq:
 *     OpenSSL::PKey::EC.new()
 *     OpenSSL::PKey::EC.new(ec_key)
 *     OpenSSL::PKey::EC.new(ec_group)
 *     OpenSSL::PKey::EC.new("secp112r1")
 *     OpenSSL::PKey::EC.new(pem_string)
 *     OpenSSL::PKey::EC.new(pem_string [, pwd])
 *     OpenSSL::PKey::EC.new(der_string)
 *
 *  See the OpenSSL documentation for:
 *     EC_KEY_*
 */
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    EC_KEY *ec = NULL;
    VALUE arg, pass;
    VALUE group = Qnil;
    char *passwd = NULL;

    GetPKey(self, pkey);
    if (pkey->pkey.ec)
        ossl_raise(eECError, "EC_KEY already initialized");

    rb_scan_args(argc, argv, "02", &arg, &pass);

    if (NIL_P(arg)) {
        ec = EC_KEY_new();
    } else {
        if (rb_obj_is_kind_of(arg, cEC)) {
            EC_KEY *other_ec = NULL;

            SafeRequire_EC_KEY(arg, other_ec);
            ec = EC_KEY_dup(other_ec);
        } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
        	ec = EC_KEY_new();
        	group = arg;
        } else {
            BIO *in = ossl_obj2bio(arg);

            if (!NIL_P(pass)) {
		passwd = StringValuePtr(pass);
	    }
	    ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
            if (!ec) {
		OSSL_BIO_reset(in);
		ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
            }
            if (!ec) {
		OSSL_BIO_reset(in);
                ec = d2i_ECPrivateKey_bio(in, NULL);
            }
            if (!ec) {
		OSSL_BIO_reset(in);
                ec = d2i_EC_PUBKEY_bio(in, NULL);
            }

            BIO_free(in);

            if (ec == NULL) {
                const char *name = StringValueCStr(arg);
                int nid = OBJ_sn2nid(name);

                (void)ERR_get_error();
                if (nid == NID_undef)
                    ossl_raise(eECError, "unknown curve name (%s)\n", name);

                if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)
                    ossl_raise(eECError, "unable to create curve (%s)\n", name);

                EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
                EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
            }
        }
    }

    if (ec == NULL)
        ossl_raise(eECError, NULL);

    if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
	EC_KEY_free(ec);
	ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
    }

    rb_iv_set(self, "@group", Qnil);

    if (!NIL_P(group))
        rb_funcall(self, rb_intern("group="), 1, arg);

    return self;
}
示例#4
0
文件: p11_ec.c 项目: bphinz/libp11
/*
 * Get EC key material and stash pointer in ex_data
 * Note we get called twice, once for private key, and once for public
 * We need to get the EC_PARAMS and EC_POINT into both,
 * as lib11 dates from RSA only where all the pub key components
 * were also part of the private key.  With EC the point
 * is not in the private key, and the params may or may not be.
 *
 */
static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key)
{
	EVP_PKEY *pk;
	EC_KEY * ec = NULL;
	CK_RV ckrv;
	size_t ec_paramslen = 0;
	CK_BYTE * ec_params = NULL;
	size_t ec_pointlen = 0;
	CK_BYTE * ec_point = NULL;
	PKCS11_KEY * pubkey;
	ASN1_OCTET_STRING *os=NULL;

	pk = EVP_PKEY_new();
	if (pk == NULL)
		return NULL;

	ec = EC_KEY_new();
	if (ec == NULL) {
		EVP_PKEY_free(pk);
		return NULL;
	}
	EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */

	/* For Openssl req we need at least the
	 * EC_KEY_get0_group(ec_key)) to return the group.
	 * Even if it fails will continue as a sign only does not need
	 * need this if the pkcs11 or card can figure this out.
	 */

	if (key_getattr_var(key, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK &&
			ec_paramslen > 0) {
		ec_params = OPENSSL_malloc(ec_paramslen);
		if (ec_params) {
			ckrv = key_getattr_var(key, CKA_EC_PARAMS, ec_params, &ec_paramslen);
			if (ckrv == CKR_OK) {
				const unsigned char * a = ec_params;
				/* convert to OpenSSL parmas */
				d2i_ECParameters(&ec, &a, (long) ec_paramslen);
			}
		}
	}

	/* Now get the ec_point */
	pubkey = key->isPrivate ? PKCS11_find_key_from_key(key) : key;
	if (pubkey) {
		ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen);
		if (ckrv == CKR_OK && ec_pointlen > 0) {
			ec_point = OPENSSL_malloc(ec_pointlen);
			if (ec_point) {
				ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen);
				if (ckrv == CKR_OK) {
					/* PKCS#11 returns ASN1 octstring*/
					const unsigned char * a;
					/* we have asn1 octet string, need to strip off 04 len */

					a = ec_point;
					os = d2i_ASN1_OCTET_STRING(NULL, &a, (long) ec_pointlen);
					if (os) {
						a = os->data;
						o2i_ECPublicKey(&ec, &a, os->length);
					}
/* EC_KEY_print_fp(stderr, ec, 5); */
				}
			}
		}
	}

	/* If the key is not extractable, create a key object
	 * that will use the card's functions to sign & decrypt
	 */
	if (os)
		ASN1_STRING_free(os);
	if (ec_point)
		OPENSSL_free(ec_point);
	if (ec_params)
		OPENSSL_free(ec_params);

	if (key->isPrivate) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		EC_KEY_set_method(ec, PKCS11_get_ec_key_method());
#else
		ECDSA_set_method(ec, PKCS11_get_ecdsa_method());
	/* TODO: Retrieve the ECDSA private key object attributes instead,
	 * unless the key has the "sensitive" attribute set */
#endif
	}
	/* TODO: Extract the ECDSA private key instead, if the key
	 * is marked as extractable (and not private?) */

#if OPENSSL_VERSION_NUMBER >= 0x10100002L
	EC_KEY_set_ex_data(ec,ec_key_ex_index, key);
#else
	ECDSA_set_ex_data(ec, ecdsa_ex_index, key);
#endif
	EC_KEY_free(ec); /* drops our reference to it */
	return pk;
}
示例#5
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;
	}

	size = DH_size(client_params->u.dh.key);

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

	dh_gen_keylen = DH_compute_key(dh_gen_key,client_params->u.dh.public_key, client_params->u.dh.key);
	if (dh_gen_keylen == (size_t)-1) {
	    ret = KRB5KRB_ERR_GENERIC;
	    krb5_set_error_message(context, ret,
				   "Can't compute Diffie-Hellman key");
	    goto out;
	}
	if (dh_gen_keylen < size) {
	    size -= dh_gen_keylen;
	    memmove(dh_gen_key + size, dh_gen_key, dh_gen_keylen);
	    memset(dh_gen_key, 0, size);
	}

	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;
}
示例#6
0
int generatePem(char **pem) {
    int returnError = NOERROR;
    char * errorMessage = "";
    char *pemholder = calloc(240, sizeof(char));
    EC_KEY *eckey = NULL;
    BIO *out = NULL;
    BUF_MEM *buf = NULL;
    EC_GROUP *group = NULL;
    
    if ((out = BIO_new(BIO_s_mem())) == NULL) {
        returnError = ERROR;
        errorMessage = "Error in BIO_new(BIO_s_mem())";
        goto clearVariables;
    }
    
    if ((group = EC_GROUP_new_by_curve_name(NID_secp256k1)) == NULL) {
        returnError = ERROR;
        errorMessage = "Error in EC_GROUP_new_by_curve_name(NID_secp256k1))";
        goto clearVariables;
    }

    if (((eckey = EC_KEY_new()) == NULL) ||
        ((buf = BUF_MEM_new()) == NULL)) {
        returnError = ERROR;
        errorMessage = "Error in EC_KEY_new())";
        goto clearVariables;
    };

    if (createNewKey(group, eckey) == ERROR) {
        returnError = ERROR;
        errorMessage = "Error in createNewKey(group, eckey)";
        goto clearVariables;
    }

    if (PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL) == 0) {
        returnError = ERROR;
        errorMessage = "Error in PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL)";
        goto clearVariables;
    }

    BIO_get_mem_ptr(out, &buf);

    memcpy(pemholder, buf->data, 224);
    if (buf->data[218] == '\n') {
        pemholder[219] = '\0';
        memcpy(*pem, pemholder, 220);
    } else if ( buf->data[219] == '\n') {
        pemholder[220] = '\0';       
        memcpy(*pem, pemholder, 221);
    } else if ( buf->data[221] == '\n') {
        pemholder[222] = '\0';       
        memcpy(*pem, pemholder, 223);
    } else if (buf->data[222] == '\n') {
        pemholder[223] = '\0';
        memcpy(*pem, pemholder, 224);
    } else {
        returnError = ERROR;
        errorMessage = "Invalid PEM generated";
        goto clearVariables;
    }

    goto clearVariables;

clearVariables:
    if (group != NULL)
        EC_GROUP_clear_free(group);
    if (pemholder != NULL) 
        free(pemholder);
    if (eckey != NULL)
        EC_KEY_free(eckey);
    if (out != NULL)
        BIO_free_all(out);
    if (errorMessage[0] != '\0')
        printf("Error: %s\n", errorMessage);

    return returnError;
};
示例#7
0
文件: evp_pkey.c 项目: LucidOne/Rovio
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
{
	EVP_PKEY *pkey = NULL;
#ifndef OPENSSL_NO_RSA
	RSA *rsa = NULL;
#endif
#ifndef OPENSSL_NO_DSA
	DSA *dsa = NULL;
	ASN1_TYPE *t1, *t2;
	ASN1_INTEGER *privkey;
	STACK_OF(ASN1_TYPE) *ndsa = NULL;
#endif
#ifndef OPENSSL_NO_EC
	EC_KEY *eckey = NULL;
	const unsigned char *p_tmp;
#endif
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
	ASN1_TYPE    *param = NULL;	
	BN_CTX *ctx = NULL;
	int plen;
#endif
	X509_ALGOR *a;
	const unsigned char *p;
	const unsigned char *cp;
	int pkeylen;
	int  nid;
	char obj_tmp[80];

	if(p8->pkey->type == V_ASN1_OCTET_STRING) {
		p8->broken = PKCS8_OK;
		p = p8->pkey->value.octet_string->data;
		pkeylen = p8->pkey->value.octet_string->length;
	} else {
		p8->broken = PKCS8_NO_OCTET;
		p = p8->pkey->value.sequence->data;
		pkeylen = p8->pkey->value.sequence->length;
	}
	if (!(pkey = EVP_PKEY_new())) {
		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	a = p8->pkeyalg;
	nid = OBJ_obj2nid(a->algorithm);
	switch(nid)
	{
#ifndef OPENSSL_NO_RSA
		case NID_rsaEncryption:
		cp = p;
		if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			return NULL;
		}
		EVP_PKEY_assign_RSA (pkey, rsa);
		break;
#endif
#ifndef OPENSSL_NO_DSA
		case NID_dsa:
		/* PKCS#8 DSA is weird: you just get a private key integer
	         * and parameters in the AlgorithmIdentifier the pubkey must
		 * be recalculated.
		 */
	
		/* Check for broken DSA PKCS#8, UGH! */
		if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
		    if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, 
							  d2i_ASN1_TYPE,
							  ASN1_TYPE_free))) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		    }
		    if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		    }
		    /* Handle Two broken types:
		     * SEQUENCE {parameters, priv_key}
		     * SEQUENCE {pub_key, priv_key}
		     */

		    t1 = sk_ASN1_TYPE_value(ndsa, 0);
		    t2 = sk_ASN1_TYPE_value(ndsa, 1);
		    if(t1->type == V_ASN1_SEQUENCE) {
			p8->broken = PKCS8_EMBEDDED_PARAM;
			param = t1;
		    } else if(a->parameter->type == V_ASN1_SEQUENCE) {
			p8->broken = PKCS8_NS_DB;
			param = a->parameter;
		    } else {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		    }

		    if(t2->type != V_ASN1_INTEGER) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		    }
		    privkey = t2->value.integer;
		} else {
			if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
				EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
				goto dsaerr;
			}
			param = p8->pkeyalg->parameter;
		}
		if (!param || (param->type != V_ASN1_SEQUENCE)) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		}
		cp = p = param->value.sequence->data;
		plen = param->value.sequence->length;
		if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto dsaerr;
		}
		/* We have parameters now set private key */
		if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
			goto dsaerr;
		}
		/* Calculate public key (ouch!) */
		if (!(dsa->pub_key = BN_new())) {
			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
			goto dsaerr;
		}
		if (!(ctx = BN_CTX_new())) {
			EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
			goto dsaerr;
		}
			
		if (!BN_mod_exp(dsa->pub_key, dsa->g,
						 dsa->priv_key, dsa->p, ctx)) {
			
			EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
			goto dsaerr;
		}

		EVP_PKEY_assign_DSA(pkey, dsa);
		BN_CTX_free (ctx);
		if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
		else ASN1_INTEGER_free(privkey);
		break;
		dsaerr:
		BN_CTX_free (ctx);
		sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
		DSA_free(dsa);
		EVP_PKEY_free(pkey);
		return NULL;
		break;
#endif
#ifndef OPENSSL_NO_EC
		case NID_X9_62_id_ecPublicKey:
		p_tmp = p;
		/* extract the ec parameters */
		param = p8->pkeyalg->parameter;

		if (!param || ((param->type != V_ASN1_SEQUENCE) &&
		    (param->type != V_ASN1_OBJECT)))
		{
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto ecerr;
		}

		if (param->type == V_ASN1_SEQUENCE)
		{
			cp = p = param->value.sequence->data;
			plen = param->value.sequence->length;

			if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
			{
				EVPerr(EVP_F_EVP_PKCS82PKEY,
					EVP_R_DECODE_ERROR);
				goto ecerr;
			}
		}
		else
		{
			EC_GROUP *group;
			cp = p = param->value.object->data;
			plen = param->value.object->length;

			/* type == V_ASN1_OBJECT => the parameters are given
			 * by an asn1 OID
			 */
			if ((eckey = EC_KEY_new()) == NULL)
			{
				EVPerr(EVP_F_EVP_PKCS82PKEY,
					ERR_R_MALLOC_FAILURE);
				goto ecerr;
			}
			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
			if (group == NULL)
				goto ecerr;
			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
			if (EC_KEY_set_group(eckey, group) == 0)
				goto ecerr;
			EC_GROUP_free(group);
		}

		/* We have parameters now set private key */
		if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
		{
			EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
			goto ecerr;
		}

		/* calculate public key (if necessary) */
		if (EC_KEY_get0_public_key(eckey) == NULL)
		{
			const BIGNUM *priv_key;
			const EC_GROUP *group;
			EC_POINT *pub_key;
			/* the public key was not included in the SEC1 private
			 * key => calculate the public key */
			group   = EC_KEY_get0_group(eckey);
			pub_key = EC_POINT_new(group);
			if (pub_key == NULL)
			{
				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
				goto ecerr;
			}
			if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
			{
				EC_POINT_free(pub_key);
				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
				goto ecerr;
			}
			priv_key = EC_KEY_get0_private_key(eckey);
			if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
			{
				EC_POINT_free(pub_key);
				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
				goto ecerr;
			}
			if (EC_KEY_set_public_key(eckey, pub_key) == 0)
			{
				EC_POINT_free(pub_key);
				EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
				goto ecerr;
			}
			EC_POINT_free(pub_key);
		}

		EVP_PKEY_assign_EC_KEY(pkey, eckey);
		if (ctx)
			BN_CTX_free(ctx);
		break;
ecerr:
		if (ctx)
			BN_CTX_free(ctx);
		if (eckey)
			EC_KEY_free(eckey);
		if (pkey)
			EVP_PKEY_free(pkey);
		return NULL;
#endif
		default:
		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
		if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
		else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
		ERR_add_error_data(2, "TYPE=", obj_tmp);
		EVP_PKEY_free (pkey);
		return NULL;
	}
	return pkey;
}
示例#8
0
文件: pkey.c 项目: witchu/lua-openssl
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)
    {
      int ec_name = NID_undef;
      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;

}
示例#9
0
int ecparam_main(int argc, char **argv)
{
    BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
    BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
    BIO *in = NULL, *out = NULL;
    EC_GROUP *group = NULL;
    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
    char *curve_name = NULL, *inrand = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    unsigned char *buffer = NULL;
    OPTION_CHOICE o;
    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret =
        1;
    int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
    int text = 0, i, need_rand = 0, genkey = 0;

    prog = opt_init(argc, argv, ecparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(ecparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_LIST_CURVES:
            list_curves = 1;
            break;
        case OPT_NO_SEED:
            no_seed = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_NAME:
            curve_name = opt_arg();
            break;
        case OPT_CONV_FORM:
            if (!opt_pair(opt_arg(), forms, &new_form))
                goto opthelp;
            form = new_form;
            new_form = 1;
            break;
        case OPT_PARAM_ENC:
            if (!opt_pair(opt_arg(), encodings, &asn1_flag))
                goto opthelp;
            new_asn1_flag = 1;
            break;
        case OPT_GENKEY:
            genkey = need_rand = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            need_rand = 1;
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    in = bio_open_default(infile, RB(informat));
    if (in == NULL)
        goto end;
    out = bio_open_default(outfile, WB(outformat));
    if (out == NULL)
        goto end;

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

        curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
        if (!EC_get_builtin_curves(curves, crv_len)) {
            OPENSSL_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);
        }

        OPENSSL_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") == 0) {
            BIO_printf(bio_err, "using curve name prime192v1 "
                       "instead of secp192r1\n");
            nid = NID_X9_62_prime192v1;
        } else if (strcmp(curve_name, "secp256r1") == 0) {
            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)
            nid = EC_curve_nist2nid(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
        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
    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("Can't allocate BN");
            goto end;
        }

        is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
        if (!is_prime) {
            BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
            goto end;
        }

        if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL))
            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 = app_malloc(buf_len, "BN buffer");

        BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len);
        print_bignum_var(out, ec_p, "ec_p", len, buffer);
        print_bignum_var(out, ec_a, "ec_a", len, buffer);
        print_bignum_var(out, ec_b, "ec_b", len, buffer);
        print_bignum_var(out, ec_gen, "ec_gen", len, buffer);
        print_bignum_var(out, ec_order, "ec_order", len, buffer);
        print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer);
        BIO_printf(out, "    int ok = 0;\n"
                        "    EC_GROUP *group = NULL;\n"
                        "    EC_POINT *point = NULL;\n"
                        "    BIGNUM *tmp_1 = NULL;\n"
                        "    BIGNUM *tmp_2 = NULL;\n"
                        "    BIGNUM *tmp_3 = NULL;\n"
                        "\n");

        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n"
                        "        goto err;\n"
                        "\n");
        BIO_printf(out, "    /* build generator */\n");
        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n");
        BIO_printf(out, "    if (point == NULL)\n"
                        "        goto err;\n");
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n"
                        "        goto err;\n"
                        "ok = 1;"
                        "\n");
        BIO_printf(out, "err:\n"
                        "    BN_free(tmp_1);\n"
                        "    BN_free(tmp_2);\n"
                        "    BN_free(tmp_3);\n"
                        "    EC_POINT_free(point);\n"
                        "    if (!ok) {\n"
                        "        EC_GROUP_free(group);\n"
                        "        return NULL;\n"
                        "    }\n"
                        "    return (group);\n"
                        "}\n");
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPKParameters_bio(out, group);
        else
            i = PEM_write_bio_ECPKParameters(out, group);
        if (!i) {
            BIO_printf(bio_err, "unable to write elliptic "
                       "curve parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (need_rand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    if (genkey) {
        EC_KEY *eckey = EC_KEY_new();

        if (eckey == NULL)
            goto end;

        assert(need_rand);

        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
            i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
                                           NULL, 0, NULL, NULL);
        EC_KEY_free(eckey);
    }

    if (need_rand)
        app_RAND_write_file(NULL);

    ret = 0;
 end:
    BN_free(ec_p);
    BN_free(ec_a);
    BN_free(ec_b);
    BN_free(ec_gen);
    BN_free(ec_order);
    BN_free(ec_cofactor);
    OPENSSL_free(buffer);
    BIO_free(in);
    BIO_free_all(out);
    EC_GROUP_free(group);
    return (ret);
}
示例#10
0
文件: openssl.c 项目: KaneRoot/COSE-C
EC_KEY * ECKey_From(const cn_cbor * pKey, int * cbGroup, cose_errback * perr)
{
	EC_KEY * pNewKey = EC_KEY_new();
	byte  rgbKey[512+1];
	const cn_cbor * p;
	int nidGroup = -1;
	EC_POINT * pPoint = NULL;

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Curve);
	CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);

	switch (p->v.sint) {
	case 1: // P-256
		nidGroup = NID_X9_62_prime256v1;
		*cbGroup = 256 / 8;
		break;

	case 2: // P-384
		nidGroup = NID_secp384r1;
		*cbGroup = 384 / 8;
		break;

	case 3: // P-521
		nidGroup = NID_secp521r1;
		*cbGroup = (521 + 7) / 8;
		break;

	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}

	EC_GROUP * ecgroup = EC_GROUP_new_by_curve_name(nidGroup);
	EC_KEY_set_group(pNewKey, ecgroup);

	rgbKey[0] = POINT_CONVERSION_UNCOMPRESSED;
	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_X);
	if (p == NULL) return NULL;
	if (p->type != CN_CBOR_BYTES) return NULL;
	memcpy(rgbKey+1, p->v.str, p->length);

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_Y);
	if (p == NULL) return NULL;
	if (p->type != CN_CBOR_BYTES) return NULL;
	memcpy(rgbKey + p->length+1, p->v.str, p->length);

	pPoint = EC_POINT_new(ecgroup);
	EC_POINT_oct2point(ecgroup, pPoint, rgbKey, p->length * 2 + 1, NULL);
	EC_KEY_set_public_key(pNewKey, pPoint);

	p = cn_cbor_mapget_int(pKey, COSE_Key_EC_d);
	if (p != NULL) {
		BIGNUM * pbn;

		pbn = BN_bin2bn(p->v.bytes, (int) p->length, NULL);
		EC_KEY_set_private_key(pNewKey, pbn);
	}
	
	return pNewKey;

 errorReturn:
	return NULL;
}
示例#11
0
CECKey::CECKey() {
    pkey = EC_KEY_new();
    assert(pkey != NULL);
    int result = EC_KEY_set_group(pkey, ecgroup_order::get());
    assert(result);
}
示例#12
0
PKI_EC_KEY * _pki_pkcs11_ecdsakey_new(PKI_KEYPARAMS  * kp,
                                      URL            * url,
                                      PKCS11_HANDLER * lib,
                                      void           * driver) {

	PKI_EC_KEY * ret = NULL;

	CK_OBJECT_HANDLE *handler_pubkey = NULL;
	CK_OBJECT_HANDLE *handler_privkey = NULL;

	CK_ATTRIBUTE privTemp[32];
	CK_ATTRIBUTE pubTemp[32];

	CK_RV rv;

	CK_ULONG i = 0;
	CK_ULONG n = 0;

	CK_ULONG bits = 0;

	size_t label_len = 0;

	unsigned char *data = NULL;
	CK_BYTE *esp = NULL;
	CK_ULONG size = 0;

	BIGNUM *bn = NULL;
	BIGNUM *id_num = NULL;

	CK_MECHANISM * EC_MECH_PTR = NULL;
	int   idx    = 0;

	char *id     = NULL;
	int   id_len = 8; 

	if ( !url || !url->addr ) {
		PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
		return ( NULL );
	}

	label_len = strlen( url->addr );

	/* Check the min size for the key */
	if ( kp ) {
		if( kp->bits < PKI_EC_KEY_MIN_SIZE ) {
			PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL);
		};
	} else {
		bits = PKI_EC_KEY_DEFAULT_SIZE;
	}

	// Look for a supported key generation mechanism
	for (idx = 0; idx < EC_MECH_LIST_SIZE; idx++) {

		// Checks if the mechanism is supported
		if (HSM_PKCS11_check_mechanism(lib, 
				EC_MECH_LIST[idx].mechanism) == PKI_OK) {

			// Set the pointer to the supported mechanism
			EC_MECH_PTR = &EC_MECH_LIST[idx];

			// Debugging Information
			PKI_DEBUG("Found EC KEY GEN MECHANISM 0x%8.8X",
				EC_MECH_LIST[idx].mechanism);

			// Breaks out of the loop
			break;

		} else {

			// Let's provide debug information for not-supported mechs
			PKI_DEBUG("EC KEY GEN MECHANISM 0x%8.8X not supported",
				RSA_MECH_LIST[idx].mechanism);
		}
	}

	// If no key gen algors are supported, abort
	if (EC_MECH_PTR == NULL) {
		PKI_ERROR(PKI_ERR_HSM_KEYPAIR_GENERATE, "No KeyGen Mechanisms supported!");
		return NULL;
	}

PKI_DEBUG("BITS FOR KEY GENERATION %lu (def: %lu)", bits, PKI_EC_KEY_DEFAULT_SIZE);

	if ( kp && kp->rsa.exponent > 3) {
		// TO be Implemented
	} else {
		if( BN_hex2bn(&bn, "10001") == 0 ) {
			PKI_log_debug("ERROR, can not convert 10001 to BIGNUM");
			return ( NULL );
		}
	}

	if( url->path != NULL ) {
		if((BN_hex2bn(&id_num, url->path )) == 0 ) {
			PKI_log_debug("ERROR, can not convert %s to BIGNUM",
						url->path );
			return ( NULL );
		}
		if((id_len = BN_num_bytes(id_num)) < 0 ) {
			if ( bn ) BN_free ( bn );
			if ( id_num ) BN_free ( id_num );
			return ( NULL );
		}
		id = PKI_Malloc ( (size_t ) id_len );
		BN_bn2bin( id_num, (unsigned char *) id );
	} else {
		id_len = 10;
		if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) {
			if ( bn ) BN_free ( bn );
			return ( NULL );
		}

		if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) {
			PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate RAND bytes");
			if( bn ) BN_free ( bn );
        	        return ( NULL );
        	}
	}

	PKI_DEBUG("Setting the Bits to %lu", bits);

	/* Setting Attributes for the public Key Template */
	n = 0;
	//HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]);
	//HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]);
	HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]);

	HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &pubTemp[n++]);
	HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &pubTemp[n++]);

	HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &pubTemp[n++]);
	HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &pubTemp[n++]);
	HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &pubTemp[n++]);

	/* Setting Attributes for the private Key Template */
	i = 0;
	//HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &privTemp[i++]);
	//HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &privTemp[i++]);
	//HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &privTemp[i++]);

	HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &privTemp[i++]);
	// HSM_PKCS11_set_attr_bool( CKA_NEVER_EXTRACTABLE, CK_TRUE, 
	// 						&privTemp[i++]);
	// HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &privTemp[i++]);
	HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &privTemp[i++]);

	// HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &privTemp[i++]);
	HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &privTemp[i++]);
	HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &privTemp[i++]);

	/* Allocate the handlers for pub and priv keys */
	handler_pubkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( 
						sizeof( CK_OBJECT_HANDLE ));
	handler_privkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( 
						sizeof( CK_OBJECT_HANDLE ));

	if( !handler_pubkey || !handler_privkey ) {
		if ( bn ) BN_free ( bn );
		if ( esp ) PKI_Free ( esp );
		return ( NULL );
	}

	PKI_log_debug("Generating a new Key ... ");
	rv = lib->callbacks->C_GenerateKeyPair (
			lib->session, EC_MECH_PTR, 
			pubTemp, n,
			privTemp, i,
			handler_pubkey, 
			handler_privkey);

	if( rv != CKR_OK ) {

		if ( rv == CKR_MECHANISM_INVALID ) {
			PKI_ERROR(PKI_ERR_HSM_SET_ALGOR, 
				"EC Algorithm is not supported by the Token");
		} else {
			PKI_log_debug ("Failed with code 0x%8.8X", rv );
		}

		if ( bn ) BN_free ( bn );
		if ( esp ) PKI_Free ( esp );

		return ( NULL );
	}

	/* Clean up the Memory we are not using anymore */
	if ( bn ) BN_free ( bn );
	if ( esp ) PKI_Free ( esp );

	/* Generate a new RSA container */
	if((ret = EC_KEY_new()) == NULL ) goto err;
	
	if( HSM_PKCS11_get_attribute(handler_pubkey,
                                 &lib->session,
                                 CKA_PUBLIC_EXPONENT,
                                 (void **) &data, 
						         &size,
						         lib) != PKI_OK ) {
		goto err;
	}

	EC_KEY_set_private_key(ret, BN_bin2bn( data, (int) size, NULL));
	PKI_Free(data);
	data = NULL;

	if( HSM_PKCS11_get_attribute(handler_pubkey,
                                 &lib->session,
                                 CKA_MODULUS,
                                 (void **) &data,
                                 &size,
                                 lib) != PKI_OK ) {
		goto err;
	}

	EC_KEY_set_public_key(ret, (const EC_POINT *) NULL);
	PKI_Free ( data );
	data = NULL;

/*
	ECDSA_set_method(ret, HSM_PKCS11_get_ecdsa_method());

#ifdef RSA_FLAG_SIGN_VER
# if OPENSSL_VERSION_NUMBER >= 0x1010000fL 
	RSA_set_flags( ret, RSA_FLAG_SIGN_VER);
# else
	ret->flags |= RSA_FLAG_SIGN_VER;
# endif
#endif

	// Push the priv and pub key handlers to the rsa->ex_data
	EC_KEY_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver );
	EC_KEY_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey );
	EC_KEY_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey );

	// Cleanup the memory for Templates
	HSM_PKCS11_clean_template ( pubTemp, (int) n );
	HSM_PKCS11_clean_template ( privTemp, (int) i );
*/

	// Let's return the RSA_KEY infrastructure
	return (ret);

err:
	if (ret) EC_KEY_free(ret);

	if ( handler_pubkey ) {
		if((rv = lib->callbacks->C_DestroyObject( lib->session, 
					*handler_pubkey )) != CKR_OK ) {
			PKI_log_debug ("Failed to delete pubkey object");
		}
		PKI_Free(handler_pubkey);
	}

	if( handler_privkey ) {
		if((rv = lib->callbacks->C_DestroyObject(lib->session, 
					                             *handler_privkey)) != CKR_OK) {
			PKI_log_debug ("Failed to delete privkey object");
		}
		PKI_Free(handler_privkey);
	}

	return NULL;
}
示例#13
0
文件: ectool.c 项目: LiTianjue/GmSSL
int main(int argc, const char *argv[])
{
	int r;
	int ok = 0;
	char *prog = "ecc";

	
	// libpopt var
	poptContext popt_ctx;
	const char **rest;
	int command = 0;
	char *curve_name = "secp192k1";
	int point_compressed = 0;
	point_conversion_form_t point_form;

	struct poptOption options[] = {
		{"curve-name",		'c', POPT_ARG_STRING, &curve_name, 0,		"elliptic curve name", "NAME"},
		{"point-compressed",	'z', POPT_ARG_NONE, &point_compressed, 0,	"point format, compress or uncompress", NULL},
		{"print-curve",		'p', POPT_ARG_VAL, &command, ECC_PRINT,		"print elliptic curve parameters", NULL},
		{"random-private-key",	 0,  POPT_ARG_VAL, &command, ECC_RAND_SKEY,	"random generate a private key\n", NULL},
		{"random-keypair",	 0,  POPT_ARG_VAL, &command, ECC_RAND_KEYPAIR,	"generate a random key pair\n", NULL},
		{"check-point",		'e', POPT_ARG_VAL, &command, ECC_CHECK_POINT,	"check if point is valid\n", NULL},
		{"point-add",		'a', POPT_ARG_VAL, &command, ECC_ADD,		"elliptic curve point addition", NULL},
		{"point-double",	'b', POPT_ARG_VAL, &command, ECC_DOUBLE,	"elliptic curve point double", NULL},
		{"point-mul",		'x', POPT_ARG_VAL, &command, ECC_MUL,		"k*G", NULL},
		{"point-mul-generator",	'X', POPT_ARG_VAL, &command, ECC_MUL_G,		"elliptic curve point scalar multiply", NULL},
		{"point-invert",	'i', POPT_ARG_VAL, &command, ECC_INVERT,	"elliptic curve point inverse", NULL},
		{"ecdsa-sign",		's', POPT_ARG_VAL, &command, ECC_SIGN,		"ecdsa sign", NULL},
		{"ecdsa-verify",	'v', POPT_ARG_VAL, &command, ECC_VERIFY,	"ecdsa verify", NULL},
		POPT_AUTOHELP
		POPT_TABLEEND
	};

	// openssl var
	EC_GROUP *ec_group = NULL;
	EC_POINT *P = NULL;
	EC_POINT *Q = NULL;
	EC_POINT *R = NULL;
	BIGNUM *k = BN_new();
	BN_CTX *bn_ctx = BN_CTX_new();


	// argument parsing
	popt_ctx = poptGetContext(argv[0], argc, argv, options, 0);
	if ((r = poptGetNextOpt(popt_ctx)) < -1) {
		fprintf(stderr, "%s: bad argument %s: %s\n", argv[0], 
			poptBadOption(popt_ctx, POPT_BADOPTION_NOALIAS), 
			poptStrerror(r));
		goto exit;
	}
	rest = poptGetArgs(popt_ctx);


	// check arguments
	ec_group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve_name));
	if (ec_group == NULL) {
		fprintf(stderr, "%s: unknown curve name\n", prog);
		goto exit;
	}

	P = EC_POINT_new(ec_group);
	Q = EC_POINT_new(ec_group);
	R = EC_POINT_new(ec_group);

	point_form = point_compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED;

	switch (command) {
	case ECC_PRINT:
		{
		BIGNUM *p = BN_new();
		BIGNUM *a = BN_new();
		BIGNUM *b = BN_new();
		char *generator;
		BIGNUM *order = BN_new();
		BIGNUM *cofactor = BN_new();

		EC_GROUP_get_curve_GFp(ec_group, p, a, b, bn_ctx);
		generator = EC_POINT_point2hex(ec_group, EC_GROUP_get0_generator(ec_group), point_form, bn_ctx);
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		EC_GROUP_get_cofactor(ec_group, cofactor, bn_ctx);
		
		fprintf(stdout, "Name      : %s\n", OBJ_nid2sn(EC_GROUP_get_curve_name(ec_group)));
		fprintf(stdout, "FieldType : %s\n", "PrimeField");
		fprintf(stdout, "Prime     : %s\n", BN_bn2hex(p));
		fprintf(stdout, "A         : %s\n", BN_bn2hex(a));
		fprintf(stdout, "B         : %s\n", BN_bn2hex(b));
		fprintf(stdout, "Generator : %s\n", generator);
		fprintf(stdout, "Order     : %s\n", BN_bn2hex(order));
		fprintf(stdout, "Cofactor  : %s\n", BN_bn2hex(cofactor));

		BN_free(p);
		BN_free(a);
		BN_free(b);
		BN_free(order);
		BN_free(cofactor);

		break;
		}
	case ECC_CHECK_POINT:
		{
		if (!rest) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (!rest[0]) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (EC_POINT_hex2point(ec_group, rest[0], P, bn_ctx))
			fprintf(stdout, "ture\n");
		else
			fprintf(stdout, "false\n");
		break;
		}
	case ECC_RAND_SKEY:
		{
		EC_KEY *ec_key = EC_KEY_new();
		EC_KEY_set_group(ec_key, ec_group);
		EC_KEY_generate_key(ec_key);
		fprintf(stdout, "%s\n", BN_bn2hex(EC_KEY_get0_private_key(ec_key)));
		EC_KEY_free(ec_key);
		break;
		}
	case ECC_RAND_KEYPAIR:
		{
		EC_KEY *ec_key = EC_KEY_new();
		EC_KEY_set_group(ec_key, ec_group);
		EC_KEY_generate_key(ec_key);
		fprintf(stdout, "%s\n", BN_bn2hex(EC_KEY_get0_private_key(ec_key)));
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, EC_KEY_get0_public_key(ec_key), point_form, bn_ctx));
		EC_KEY_free(ec_key);
		break;
		}
	case ECC_ADD:
		{
		if (!rest) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}
		if (!rest[0] || !rest[1]) {
			fprintf(stderr, "%s: short of point\n", prog);
			goto exit;
		}			
		if (!EC_POINT_hex2point(ec_group, rest[1], P, bn_ctx)) {
			fprintf(stderr, "%s: first point invalid\n", prog);
			goto exit;
		}
		if (!EC_POINT_hex2point(ec_group, rest[1], Q, bn_ctx)) {
			fprintf(stderr, "%s: second point invalid\n", prog);
			goto exit;
		}
		EC_POINT_add(ec_group, R, P, Q, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	case ECC_DOUBLE:
		{
		EC_POINT_dbl(ec_group, R, P, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	case ECC_MUL:
		{
		BIGNUM *order = NULL;

		if (!BN_hex2bn(&k, rest[0])) {
			fprintf(stderr, "%s: integer invalid\n", prog);
			goto exit;
		}
		
		order = BN_new();
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		if (BN_cmp(k, order) >= 0) {
			fprintf(stderr, "%s: integer value invalid\n", prog);
			BN_free(order);
			goto exit;
		}
		BN_free(order);

		if (!EC_POINT_hex2point(ec_group, rest[1], P, bn_ctx)) {
			fprintf(stderr, "%s: point invalid\n", prog);
			goto exit;
		}

		EC_POINT_mul(ec_group, R, k, P, NULL, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));

		break;
		}
	case ECC_MUL_G:
		{
		BIGNUM *order = NULL;
		if (!BN_hex2bn(&k, rest[0])) {
			fprintf(stderr, "%s: integer format invalid\n", prog);
			goto exit;
		}
		
		order = BN_new();
		EC_GROUP_get_order(ec_group, order, bn_ctx);
		if (BN_cmp(k, order) >= 0) {
			fprintf(stderr, "%s: integer value invalid\n", prog);
			BN_free(order);
			goto exit;
		}
		BN_free(order);
		
		EC_POINT_mul(ec_group, R, k, EC_GROUP_get0_generator(ec_group), NULL, bn_ctx);
		fprintf(stdout, "%s\n", EC_POINT_point2hex(ec_group, R, point_form, bn_ctx));
		break;
		}
	default:
		fprintf(stderr, "%s: command is required\n", prog);
		break;
	}
	ok = 1;

exit:
	if (ec_group) EC_GROUP_free(ec_group);
	if (P) EC_POINT_free(P);
	if (k) BN_free(k);
	if (bn_ctx) BN_CTX_free(bn_ctx);

	return ok ? 0 : -1;
}
示例#14
0
static int
ecdsa_verify_signature(hx509_context context,
                       const struct signature_alg *sig_alg,
                       const Certificate *signer,
                       const AlgorithmIdentifier *alg,
                       const heim_octet_string *data,
                       const heim_octet_string *sig)
{
    const AlgorithmIdentifier *digest_alg;
    const SubjectPublicKeyInfo *spi;
    heim_octet_string digest;
    int ret;
    EC_KEY *key = NULL;
    int groupnid;
    EC_GROUP *group;
    const unsigned char *p;
    long len;

    digest_alg = sig_alg->digest_alg;

    ret = _hx509_create_signature(context,
                                  NULL,
                                  digest_alg,
                                  data,
                                  NULL,
                                  &digest);
    if (ret)
        return ret;

    /* set up EC KEY */
    spi = &signer->tbsCertificate.subjectPublicKeyInfo;

    if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
        return HX509_CRYPTO_SIG_INVALID_FORMAT;

    /*
     * Find the group id
     */

    ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
    if (ret) {
        der_free_octet_string(&digest);
        return ret;
    }

    /*
     * Create group, key, parse key
     */

    key = EC_KEY_new();
    group = EC_GROUP_new_by_curve_name(groupnid);
    EC_KEY_set_group(key, group);
    EC_GROUP_free(group);

    p = spi->subjectPublicKey.data;
    len = spi->subjectPublicKey.length / 8;

    if (o2i_ECPublicKey(&key, &p, len) == NULL) {
        EC_KEY_free(key);
        return HX509_CRYPTO_SIG_INVALID_FORMAT;
    }

    ret = ECDSA_verify(-1, digest.data, digest.length,
                       sig->data, sig->length, key);
    der_free_octet_string(&digest);
    EC_KEY_free(key);
    if (ret != 1) {
        ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
        return ret;
    }

    return 0;
}
示例#15
0
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) 
	{
	GOST_KEY_TRANSPORT *gkt=NULL; 
	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
	struct gost_pmeth_data *data = (gost_pmeth_data*)EVP_PKEY_CTX_get_data(pctx);
	const struct gost_cipher_info *param=get_encryption_params(NULL);
	unsigned char ukm[8], shared_key[32], crypted_key[44];
	int ret=0;
	int key_is_ephemeral=1;
	gost_ctx cctx;
	EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
	if (data->shared_ukm) 
		{
		TINYCLR_SSL_MEMCPY(ukm, data->shared_ukm,8);
		} 
	else if (out) 
		{
		
		if (RAND_bytes(ukm,8)<=0)
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
				GOST_R_RANDOM_GENERATOR_FAILURE);
			return 0;
			}	
		}	
	/* Check for private key in the peer_key of context */	
	if (sec_key) 
		{
		key_is_ephemeral=0;
		if (!gost_get0_priv_key(sec_key)) 
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
			goto err;
			}	
		} 
	else 
		{
		key_is_ephemeral=1;
		if (out) 
			{
			sec_key = EVP_PKEY_new();
			EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
			EVP_PKEY_copy_parameters(sec_key,pubk);
			if (!gost2001_keygen((EC_KEY*)EVP_PKEY_get0(sec_key))) 
				{
				goto err;
				}	
			}
		}
	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
		{
		param= gost_cipher_list+1;
		}	
    if (out) 
		{
		VKO_compute_key(shared_key,32,EC_KEY_get0_public_key((const EC_KEY*)EVP_PKEY_get0(pubk)),(EC_KEY*)EVP_PKEY_get0(sec_key),ukm);
		gost_init(&cctx,param->sblock);	
		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
		}
	gkt = GOST_KEY_TRANSPORT_new();
	if (!gkt)
		{
		goto err;
		}	
	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
			ukm,8))
		{
		goto err;
		}	
	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
		{
		goto err;
		}
	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
		{
		goto err;
		}
	if (key_is_ephemeral) {	
		if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
					GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
			goto err;
			}	
	}		
	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	if (!key_is_ephemeral)
		{
		/* Set control "public key from client certificate used" */
		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
				GOST_R_CTRL_CALL_FAILED);
			goto err;
			}
		}
	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
	GOST_KEY_TRANSPORT_free(gkt);
	return ret;	
	err:		
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}
示例#16
0
/*
 * verify EC signature on JWT
 */
static apr_byte_t apr_jws_verify_ec(apr_pool_t *pool, apr_jwt_t *jwt,
		apr_jwk_t *jwk, apr_jwt_error_t *err) {

	int nid = apr_jws_ec_alg_to_curve(jwt->header.alg);
	if (nid == -1) {
		apr_jwt_error(err,
				"no OpenSSL Elliptic Curve identifier found for algorithm \"%s\"",
				jwt->header.alg);
		return FALSE;
	}

	EC_GROUP *curve = EC_GROUP_new_by_curve_name(nid);
	if (curve == NULL) {
		apr_jwt_error(err,
				"no OpenSSL Elliptic Curve found for algorithm \"%s\"",
				jwt->header.alg);
		return FALSE;
	}

	apr_byte_t rc = FALSE;

	/* get the OpenSSL digest function */
	const EVP_MD *digest = NULL;
	if ((digest = apr_jws_crypto_alg_to_evp(pool, jwt->header.alg, err)) == NULL)
		return FALSE;

	EVP_MD_CTX ctx;
	EVP_MD_CTX_init(&ctx);

	EC_KEY * pubkey = EC_KEY_new();
	EC_KEY_set_group(pubkey, curve);

	BIGNUM * x = BN_new();
	BIGNUM * y = BN_new();

	BN_bin2bn(jwk->key.ec->x, jwk->key.ec->x_len, x);
	BN_bin2bn(jwk->key.ec->y, jwk->key.ec->y_len, y);

	if (!EC_KEY_set_public_key_affine_coordinates(pubkey, x, y)) {
		apr_jwt_error_openssl(err, "EC_KEY_set_public_key_affine_coordinates");
		return FALSE;
	}

	EVP_PKEY* pEcKey = EVP_PKEY_new();
	if (!EVP_PKEY_assign_EC_KEY(pEcKey, pubkey)) {
		pEcKey = NULL;
		apr_jwt_error_openssl(err, "EVP_PKEY_assign_EC_KEY");
		goto end;
	}

	ctx.pctx = EVP_PKEY_CTX_new(pEcKey, NULL);

	if (!EVP_PKEY_verify_init(ctx.pctx)) {
		apr_jwt_error_openssl(err, "EVP_PKEY_verify_init");
		goto end;
	}
	if (!EVP_VerifyInit_ex(&ctx, digest, NULL)) {
		apr_jwt_error_openssl(err, "EVP_VerifyInit_ex");
		goto end;
	}
	if (!EVP_VerifyUpdate(&ctx, jwt->message, strlen(jwt->message))) {
		apr_jwt_error_openssl(err, "EVP_VerifyUpdate");
		goto end;
	}
	if (!EVP_VerifyFinal(&ctx, (const unsigned char *) jwt->signature.bytes,
			jwt->signature.length, pEcKey)) {
		apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal");
		goto end;
	}

	rc = TRUE;

end:

	if (pEcKey) {
		EVP_PKEY_free(pEcKey);
	} else if (pubkey) {
		EC_KEY_free(pubkey);
	}
	EVP_MD_CTX_cleanup(&ctx);

	return rc;
}
示例#17
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;

	signal(SIGPIPE, SIG_IGN);

	if (bio_err == NULL)
		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

	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 = malloc((int) (sizeof(EC_builtin_curve) * crv_len));

		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);
	if (buffer)
		free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	
	return (ret);
}
示例#18
0
int test_builtin(BIO *out) {
  size_t 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");

  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);
    degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
    if (degree < 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 = (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;
    raw_buf = OPENSSL_malloc(buf_len);
    if (raw_buf == 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);

  return ret;
}