예제 #1
0
static VALUE ossl_ec_key_to_string(VALUE self, int format)
{
    EC_KEY *ec;
    BIO *out;
    int i = -1;
    int private = 0;
#if 0  /* unused now */
    EVP_CIPHER *cipher = NULL;
    char *password = NULL;
#endif
    VALUE str;

    Require_EC_KEY(self, ec);

    if (EC_KEY_get0_public_key(ec) == NULL)
        rb_raise(eECError, "can't export - no public key set");

    if (EC_KEY_check_key(ec) != 1)
	ossl_raise(eECError, "can't export - EC_KEY_check_key failed");

    if (EC_KEY_get0_private_key(ec))
        private = 1;

    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");

    switch(format) {
    case EXPORT_PEM:
    	if (private) {
#if 0  /* unused now */
    	    if (cipher || password)
/* BUG: finish cipher/password key export */
    	        rb_notimplement();
            i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
#endif
            i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
    	} else {
#if 0  /* unused now */
    	    if (cipher || password)
                rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
#endif

            i = PEM_write_bio_EC_PUBKEY(out, ec);
        }

    	break;
    case EXPORT_DER:
        if (private) {
#if 0  /* unused now */
    	    if (cipher || password)
                rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
#endif

            i = i2d_ECPrivateKey_bio(out, ec);
        } else {
#if 0  /* unused now */
    	    if (cipher || password)
예제 #2
0
static std::string
ECDSAKeyToPEMString (EC_KEY *pkey_)
{
  BIO *temp_memory_bio = BIO_new (BIO_s_mem() );

  if (!temp_memory_bio) {
    GST_ERROR ("Failed to allocate temporary memory bio");
    return "";
  }

  if (!PEM_write_bio_ECPrivateKey (
        temp_memory_bio, pkey_, nullptr, nullptr, 0, nullptr, nullptr) ) {
    GST_ERROR ("Failed to write ECDSA key");
    BIO_free (temp_memory_bio);
    return "";
  }

  BIO_write (temp_memory_bio, "\0", 1);
  char *buffer;
  BIO_get_mem_data (temp_memory_bio, &buffer);
  std::string priv_key_str = buffer;
  BIO_free (temp_memory_bio);

  return priv_key_str;
}
예제 #3
0
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
{
    EC_KEY *ec;
    BIO *out;
    int i = -1;
    int private = 0;
    char *password = NULL;
    VALUE str;

    Require_EC_KEY(self, ec);

    if (EC_KEY_get0_public_key(ec) == NULL)
        ossl_raise(eECError, "can't export - no public key set");

    if (EC_KEY_check_key(ec) != 1)
	ossl_raise(eECError, "can't export - EC_KEY_check_key failed");

    if (EC_KEY_get0_private_key(ec))
        private = 1;

    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");

    switch(format) {
    case EXPORT_PEM:
    	if (private) {
	    const EVP_CIPHER *cipher;
	    if (!NIL_P(ciph)) {
		cipher = GetCipherPtr(ciph);
		if (!NIL_P(pass)) {
		    StringValue(pass);
		    if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
			ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
		    password = RSTRING_PTR(pass);
		}
	    }
	    else {
		cipher = NULL;
	    }
            i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
    	} else {
            i = PEM_write_bio_EC_PUBKEY(out, ec);
        }

    	break;
    case EXPORT_DER:
        if (private) {
            i = i2d_ECPrivateKey_bio(out, ec);
        } else {
예제 #4
0
/* convert SSH v2 key in OpenSSL PEM format */
static int
sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
    const char *_passphrase, const char *comment)
{
	int success, r;
	int blen, len = strlen(_passphrase);
	u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
	const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
	const u_char *bptr;
	BIO *bio = NULL;

	if (len > 0 && len <= 4)
		return SSH_ERR_PASSPHRASE_TOO_SHORT;
	if ((bio = BIO_new(BIO_s_mem())) == NULL)
		return SSH_ERR_ALLOC_FAIL;

	switch (key->type) {
	case KEY_DSA:
		success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
		    cipher, passphrase, len, NULL, NULL);
		break;
	case KEY_ECDSA:
		success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
		    cipher, passphrase, len, NULL, NULL);
		break;
	case KEY_RSA:
		success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
		    cipher, passphrase, len, NULL, NULL);
		break;
	default:
		success = 0;
		break;
	}
	if (success == 0) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
		r = SSH_ERR_INTERNAL_ERROR;
		goto out;
	}
	if ((r = sshbuf_put(blob, bptr, blen)) != 0)
		goto out;
	r = 0;
 out:
	BIO_free(bio);
	return r;
}
예제 #5
0
파일: main.c 프로젝트: aszrul/atheme
int
main(int argc, const char **argv)
{
	if (! libathemecore_early_init())
		return EXIT_FAILURE;

	BIO *out;
	EC_KEY *prv;
	unsigned char *workbuf, *workbuf_p;
	char encbuf[BUFSIZE];
	size_t len;

	memset(encbuf, '\0', sizeof encbuf);

	prv = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

	EC_KEY_set_conv_form(prv, POINT_CONVERSION_COMPRESSED);
	EC_KEY_generate_key(prv);

	len = i2o_ECPublicKey(prv, NULL);
	workbuf = mowgli_alloc(len);
	workbuf_p = workbuf;
	i2o_ECPublicKey(prv, &workbuf_p);
	workbuf_p = workbuf;

	if (base64_encode(workbuf_p, len, encbuf, sizeof encbuf) == (size_t) -1)
	{
		fprintf(stderr, "Failed to encode public key!\n");
		return EXIT_FAILURE;
	}

	printf("Keypair:\n");
	EC_KEY_print_fp(stdout, prv, 4);

	printf("Private key:\n");
	out = BIO_new_fp(stdout, 0);
	PEM_write_bio_ECPrivateKey(out, prv, NULL, NULL, 0, NULL, NULL);

	printf("Public key (atheme format):\n");
	printf("%s\n", encbuf);

	return EXIT_SUCCESS;
}
예제 #6
0
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
{
    EC_KEY *ec;
    BIO *out;
    int i = -1;
    int private = 0;
    VALUE str;

    Require_EC_KEY(self, ec);

    if (EC_KEY_get0_public_key(ec) == NULL)
        ossl_raise(eECError, "can't export - no public key set");

    if (EC_KEY_check_key(ec) != 1)
	ossl_raise(eECError, "can't export - EC_KEY_check_key failed");

    if (EC_KEY_get0_private_key(ec))
        private = 1;

    if (!(out = BIO_new(BIO_s_mem())))
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");

    switch(format) {
    case EXPORT_PEM:
    	if (private) {
	    const EVP_CIPHER *cipher = NULL;
	    if (!NIL_P(ciph)) {
		cipher = GetCipherPtr(ciph);
		pass = ossl_pem_passwd_value(pass);
	    }
            i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass);
    	} else {
            i = PEM_write_bio_EC_PUBKEY(out, ec);
        }

    	break;
    case EXPORT_DER:
        if (private) {
            i = i2d_ECPrivateKey_bio(out, ec);
        } else {
예제 #7
0
파일: ecparam.c 프로젝트: benwh4/libressl
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);
}
예제 #8
0
파일: pkcs11d.c 프로젝트: zhulianhai/pkcs11
int load_keys(CK_FUNCTION_LIST *funcs,
              CK_SESSION_HANDLE h_session,
              CK_KEY_TYPE       type,
              key_id_t        **out,
              CK_ULONG_PTR      len)
{
    CK_RV             rc;
    CK_ULONG          l, i, j = 0;
    CK_OBJECT_HANDLE  handles[1024];
    key_id_t         *keys = NULL;
    CK_OBJECT_CLASS   pkey = CKO_PRIVATE_KEY;
    const EVP_MD *hash = EVP_sha256();
    unsigned char md[EVP_MAX_MD_SIZE];
    char key_id[KEY_ID_SIZE + 1];
    CK_ATTRIBUTE search[2] = {
        { CKA_CLASS,    &pkey, sizeof(pkey)},
        { CKA_KEY_TYPE, &type, sizeof(type)     },
    };

    rc = funcs->C_FindObjectsInit(h_session, search, 2);
    if (rc != CKR_OK) {
        show_error(stderr, "C_FindObjectsInit", rc);
        return 1;
    }

    rc = funcs->C_FindObjects(h_session, handles, 1024, &l);
    if (rc != CKR_OK) {
        show_error(stderr, "C_FindObjects", rc);
        return 1;
    }

    rc = funcs->C_FindObjectsFinal(h_session);
    if (rc != CKR_OK) {
        show_error(stderr, "C_FindObjectsFinal", rc);
    }

    keys = (key_id_t*)calloc(l, sizeof(key_id_t));
    if(keys == NULL) {
        return 1;
    }

    fprintf(stderr, "Found: %ld objects\n", l);
    BIO *bio = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
    for(i = 0; i < l; i++) {
        // print_object_info(funcs, stderr, i, h_session, handles[i]);
        keys[j].key = load_pkcs11_key(funcs, h_session, handles[i]);
        if(keys[j].key) {
            unsigned int k, l, n;
            BIO *s = BIO_new(BIO_s_null());
            BIO *h = BIO_new(BIO_f_md());
            BIO_set_md(h, hash);
            s = BIO_push(h, s);
            if(type == CKK_RSA) {
                i2d_RSAPublicKey_bio(s, EVP_PKEY_get1_RSA(keys[j].key));
                PEM_write_bio_RSAPrivateKey(bio, EVP_PKEY_get1_RSA(keys[j].key), NULL, NULL, 0, NULL, NULL);
            } if(type == CKK_EC) {
                i2d_EC_PUBKEY_bio(s, EVP_PKEY_get1_EC_KEY(keys[j].key));
                PEM_write_bio_ECPrivateKey(bio, EVP_PKEY_get1_EC_KEY(keys[j].key), NULL, NULL, 0, NULL, NULL);
            }
            n = BIO_gets(h, (char*)md, EVP_MAX_MD_SIZE);
            for(k = 0, l = 0; k < n; k++) {
                l += sprintf(key_id + l, "%02X", md[k]);
            }
            memcpy(keys[j].id, key_id, KEY_ID_SIZE);
            BIO_free_all(s);
            j += 1;
        }
    }
    if (bio) {
        BIO_free_all(bio);
    }

    if(out) {
        *out = keys;
    } else {
        for(i = 0; i < j; i++) {
            unload_pkcs11_key(keys[i].key);
        }
    }

    if(len) {
        *len = j;
    }

    return 0;
}
예제 #9
0
int MAIN(int argc, char **argv)
{
    int ret = 1;
    EC_KEY *eckey = NULL;
    const EC_GROUP *group;
    int i, badops = 0;
    const EVP_CIPHER *enc = NULL;
    BIO *in = NULL, *out = NULL;
    int informat, outformat, text = 0, noout = 0;
    int pubin = 0, pubout = 0, param_out = 0;
    char *infile, *outfile, *prog, *engine;
    char *passargin = NULL, *passargout = NULL;
    char *passin = NULL, *passout = 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;

    apps_startup();

    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;

    engine = NULL;
    infile = NULL;
    outfile = NULL;
    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, "-passin") == 0) {
            if (--argc < 1)
                goto bad;
            passargin = *(++argv);
        } else if (strcmp(*argv, "-passout") == 0) {
            if (--argc < 1)
                goto bad;
            passargout = *(++argv);
        } else if (strcmp(*argv, "-engine") == 0) {
            if (--argc < 1)
                goto bad;
            engine = *(++argv);
        } else if (strcmp(*argv, "-noout") == 0)
            noout = 1;
        else if (strcmp(*argv, "-text") == 0)
            text = 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, "-param_out") == 0)
            param_out = 1;
        else if (strcmp(*argv, "-pubin") == 0)
            pubin = 1;
        else if (strcmp(*argv, "-pubout") == 0)
            pubout = 1;
        else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) {
            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 - "
                   "DER or PEM\n");
        BIO_printf(bio_err, " -outform arg    output format - "
                   "DER or PEM\n");
        BIO_printf(bio_err, " -in arg         input file\n");
        BIO_printf(bio_err, " -passin arg     input file pass "
                   "phrase source\n");
        BIO_printf(bio_err, " -out arg        output file\n");
        BIO_printf(bio_err, " -passout arg    output file pass "
                   "phrase source\n");
        BIO_printf(bio_err, " -engine e       use engine e, "
                   "possibly a hardware device.\n");
        BIO_printf(bio_err, " -des            encrypt PEM output, "
                   "instead of 'des' every other \n"
                   "                 cipher "
                   "supported by OpenSSL can be used\n");
        BIO_printf(bio_err, " -text           print the key\n");
        BIO_printf(bio_err, " -noout          don't print key out\n");
        BIO_printf(bio_err, " -param_out      print the elliptic "
                   "curve parameters\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");
        goto end;
    }

    ERR_load_crypto_strings();

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

    if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
        BIO_printf(bio_err, "Error getting passwords\n");
        goto end;
    }

    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;
        }
    }

    BIO_printf(bio_err, "read EC key\n");
    if (informat == FORMAT_ASN1) {
        if (pubin)
            eckey = d2i_EC_PUBKEY_bio(in, NULL);
        else
            eckey = d2i_ECPrivateKey_bio(in, NULL);
    } else if (informat == FORMAT_PEM) {
        if (pubin)
            eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
        else
            eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin);
    } else {
        BIO_printf(bio_err, "bad input format specified for key\n");
        goto end;
    }
    if (eckey == NULL) {
        BIO_printf(bio_err, "unable to load Key\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
# ifdef OPENSSL_SYS_VMS
        {
            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
            out = BIO_push(tmpbio, out);
        }
# endif
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            goto end;
        }
    }

    group = EC_KEY_get0_group(eckey);

    if (new_form)
        EC_KEY_set_conv_form(eckey, form);

    if (new_asn1_flag)
        EC_KEY_set_asn1_flag(eckey, asn1_flag);

    if (text)
        if (!EC_KEY_print(out, eckey, 0)) {
            perror(outfile);
            ERR_print_errors(bio_err);
            goto end;
        }

    if (noout) {
        ret = 0;
        goto end;
    }

    BIO_printf(bio_err, "writing EC key\n");
    if (outformat == FORMAT_ASN1) {
        if (param_out)
            i = i2d_ECPKParameters_bio(out, group);
        else if (pubin || pubout)
            i = i2d_EC_PUBKEY_bio(out, eckey);
        else
            i = i2d_ECPrivateKey_bio(out, eckey);
    } else if (outformat == FORMAT_PEM) {
        if (param_out)
            i = PEM_write_bio_ECPKParameters(out, group);
        else if (pubin || pubout)
            i = PEM_write_bio_EC_PUBKEY(out, eckey);
        else
            i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
                                           NULL, 0, NULL, passout);
    } else {
        BIO_printf(bio_err, "bad output format specified for " "outfile\n");
        goto end;
    }

    if (!i) {
        BIO_printf(bio_err, "unable to write private key\n");
        ERR_print_errors(bio_err);
    } else
        ret = 0;
 end:
    if (in)
        BIO_free(in);
    if (out)
        BIO_free_all(out);
    if (eckey)
        EC_KEY_free(eckey);
    if (passin)
        OPENSSL_free(passin);
    if (passout)
        OPENSSL_free(passout);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
예제 #10
0
static LUA_FUNCTION(openssl_pkey_export)
{
  EVP_PKEY * key;
  int ispriv = 0;
  int exraw = 0;
  int expem = 1;
  size_t passphrase_len = 0;
  BIO * bio_out = NULL;
  int ret = 0;
  const EVP_CIPHER * cipher;
  const char * passphrase = NULL;

  key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey");
  ispriv = openssl_pkey_is_private(key);

  if (!lua_isnoneornil(L, 2))
    expem = lua_toboolean(L, 2);

  if (expem)
  {
    if (!lua_isnoneornil(L, 3))
      exraw = lua_toboolean(L, 3);
    passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len);
  } else
  {
    passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len);
  }

  if (passphrase)
  {
    cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
  }
  else
  {
    cipher = NULL;
  }

  bio_out = BIO_new(BIO_s_mem());
  if (expem)
  {
    if (exraw==0)
    {
      ret = ispriv ?
        PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) :
        PEM_write_bio_PUBKEY(bio_out, key);
    }
    else
    {
      /* export raw key format */
      switch (EVP_PKEY_type(key->type))
      {
      case EVP_PKEY_RSA:
      case EVP_PKEY_RSA2:
        ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
          : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa);
      break;
      case EVP_PKEY_DSA:
      case EVP_PKEY_DSA2:
      case EVP_PKEY_DSA3:
      case EVP_PKEY_DSA4:
      {
        ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
          : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa);
      }
      break;
      case EVP_PKEY_DH:
        ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh);
      break;
#ifndef OPENSSL_NO_EC
      case EVP_PKEY_EC:
        ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
        : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec);
      break;
#endif
      default:
      ret = 0;
      break;
      }
    }
  }
  else
  {
    if (ispriv)
    {
      if (passphrase == NULL)
      {
        ret = i2d_PrivateKey_bio(bio_out, key);
      } else
      {
        ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL);
      }
    } else
    {
      int l;
      l = i2d_PublicKey(key, NULL);
      if (l > 0)
      {
        unsigned char* p = malloc(l);
        unsigned char* pp = p;
        l = i2d_PublicKey(key, &pp);
        if (l > 0)
        {
          BIO_write(bio_out, p, l);
          ret = 1;
        } else
          ret = 0;
        free(p);
      } else
        ret = 0;
    }
  }

  
  if (ret)
  {
    char * bio_mem_ptr;
    long bio_mem_len;

    bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr);

    lua_pushlstring(L, bio_mem_ptr, bio_mem_len);
    ret  = 1;
  }

  if (bio_out)
  {
    BIO_free(bio_out);
  }
  return ret;
}
예제 #11
0
파일: ecparam.c 프로젝트: 375670450/openssl
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);
}
예제 #12
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;
};