void elliptic_curve_key::set_compressed(bool compressed)
		{
			if (compressed)
				EC_KEY_set_conv_form(key_, POINT_CONVERSION_COMPRESSED);
			else
				EC_KEY_set_conv_form(key_, POINT_CONVERSION_UNCOMPRESSED);
		}
Exemple #2
0
int main(int argc, const char **argv)
{
	EC_KEY *pub;
	char workbuf[BUFSIZE];
	const unsigned char *workbuf_p;
	size_t len, i;

	if (argv[1] == NULL)
	{
		fprintf(stderr, "usage: %s [base64key]\n", argv[0]);
		return EXIT_FAILURE;
	}

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

	pub = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
	EC_KEY_set_conv_form(pub, POINT_CONVERSION_COMPRESSED);

	len = base64_decode(argv[1], workbuf, BUFSIZE);
	workbuf_p = (unsigned char *) workbuf;

	o2i_ECPublicKey(&pub, &workbuf_p, len);
	if (!EC_KEY_check_key(pub))
	{
		fprintf(stderr, "Key data provided on commandline is inconsistent.\n");
		return EXIT_FAILURE;
	}

	printf("Public key (reassembled):\n");
	EC_KEY_print_fp(stdout, pub, 4);

	return EXIT_SUCCESS;
}
Exemple #3
0
/*
 * Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
 * representing an OID.
 */
static EC_KEY *
ec_key_new_from_group(VALUE arg)
{
    EC_KEY *ec;

    if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
	EC_GROUP *group;

	SafeRequire_EC_GROUP(arg, group);

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

	if (!EC_KEY_set_group(ec, group)) {
	    EC_KEY_free(ec);
	    ossl_raise(eECError, NULL);
	}
    } else {
	int nid = OBJ_sn2nid(StringValueCStr(arg));

	if (nid == NID_undef)
	    ossl_raise(eECError, "invalid curve name");

	if (!(ec = EC_KEY_new_by_curve_name(nid)))
	    ossl_raise(eECError, NULL);

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

    return ec;
}
Exemple #4
0
bool key_set_privkey(struct key *k, const void *privkey, size_t len) {
  BIGNUM *res;
  BIGNUM bn;
  int s;

  /*
   * Cf bitcoin/src/base58.h
   *    bitcoin/src/key.h
   *
   * If len == 33 and privkey[32] == 1, then:
   *   "the public key corresponding to this private key is (to be)
   *   compressed."
   */
  ASSERT(len == 32 || len == 33);

  BN_init(&bn);
  res = BN_bin2bn(privkey, 32, &bn);
  ASSERT(res);

  s = key_regenerate(k, &bn);
  ASSERT(s);
  ASSERT(EC_KEY_check_key(k->key));

  EC_KEY_set_conv_form(k->key, POINT_CONVERSION_COMPRESSED);

  ASSERT(k->pub_key == NULL);
  ASSERT(k->pub_len == 0);
  key_get_pubkey_int(k, &k->pub_key, &k->pub_len);

  BN_clear_free(&bn);
  ASSERT(EC_KEY_check_key(k->key));

  return 1;
}
Exemple #5
0
struct key *key_generate_new(void) {
  struct key *k;
  int s;

  k = key_alloc();

  s = EC_KEY_generate_key(k->key);
  if (s == 0) {
    Log(LGPFX " EC_KEY_generate_key failed.\n");
    goto exit;
  }
  s = EC_KEY_check_key(k->key);
  if (s == 0) {
    Log(LGPFX " EC_KEY_check_key failed.\n");
    goto exit;
  }

  EC_KEY_set_conv_form(k->key, POINT_CONVERSION_COMPRESSED);

  ASSERT(k->pub_key == NULL);
  ASSERT(k->pub_len == 0);
  key_get_pubkey_int(k, &k->pub_key, &k->pub_len);

  return k;
exit:
  key_free(k);
  return NULL;
}
    public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical )
    {
        int nV = c.data[0];
        if (nV<27 || nV>=35)
            FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );

        ECDSA_SIG *sig = ECDSA_SIG_new();
        BN_bin2bn(&c.data[1],32,sig->r);
        BN_bin2bn(&c.data[33],32,sig->s);

        if( check_canonical )
        {
            FC_ASSERT( is_canonical( c ), "signature is not canonical" );
        }

        my->_key = EC_KEY_new_by_curve_name(NID_secp256k1);

        if (nV >= 31)
        {
            EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
            nV -= 4;
//            fprintf( stderr, "compressed\n" );
        }

        if (detail::public_key_impl::ECDSA_SIG_recover_key_GFp(my->_key, sig, (unsigned char*)&digest, sizeof(digest), nV - 27, 0) == 1)
        {
            ECDSA_SIG_free(sig);
            return;
        }
        ECDSA_SIG_free(sig);
        FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
    }
Exemple #7
0
bool bp_key_secret_set(struct bp_key *key, const void *privkey_, size_t pk_len)
{
	bp_key_free(key);

	if (!privkey_ || pk_len != 32)
		return false;

	const unsigned char *privkey = privkey_;
	BIGNUM *bn = BN_bin2bn(privkey, 32, BN_new());
	if (!bn)
		return false;

	key->k = EC_KEY_new_by_curve_name(NID_secp256k1);
	if (!key->k)
		goto err_out;
	
	if (!EC_KEY_regenerate_key(key->k, bn))
		goto err_out;
	if (!EC_KEY_check_key(key->k))
		return false;

	EC_KEY_set_conv_form(key->k, POINT_CONVERSION_COMPRESSED);

	BN_clear_free(bn);
	return true;

err_out:
	bp_key_free(key);
	BN_clear_free(bn);
	return false;
}
 public_key_point_data public_key::serialize_ecc_point()const
 {
   public_key_point_data dat;
   if( !my->_key ) return dat;
   EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_UNCOMPRESSED );
   char* front = &dat.data[0];
   i2o_ECPublicKey( my->_key, (unsigned char**)&front ); // FIXME: questionable memory handling
   return dat;
 }
Exemple #9
0
void CECKey::GetPrivKey(CPrivKey &privkey, bool fCompressed) {
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    int nSize = i2d_ECPrivateKey(pkey, NULL);
    assert(nSize);
    privkey.resize(nSize);
    unsigned char* pbegin = &privkey[0];
    int nSize2 = i2d_ECPrivateKey(pkey, &pbegin);
    assert(nSize == nSize2);
}
Exemple #10
0
bool bp_pubkey_set(struct bp_key *key, const void *pubkey_, size_t pk_len)
{
	const unsigned char *pubkey = pubkey_;
	if (!o2i_ECPublicKey(&key->k, &pubkey, pk_len))
		return false;
	if (pk_len == 33)
		EC_KEY_set_conv_form(key->k, POINT_CONVERSION_COMPRESSED);
	return true;
}
Exemple #11
0
static ec_key ec_key_new_secp256k1_compressed()
{
    EC_KEY* key = EC_KEY_new_by_curve_name (NID_secp256k1);

    if (key == nullptr)  throw std::runtime_error ("EC_KEY_new_by_curve_name() failed");

    EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED);

    return ec_key((ec_key::pointer_t) key);
}
Exemple #12
0
void CECKey::GetPubKey(CPubKey &pubkey, bool fCompressed) {
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    int nSize = i2o_ECPublicKey(pkey, NULL);
    assert(nSize);
    assert(nSize <= 65);
    unsigned char c[65];
    unsigned char *pbegin = c;
    int nSize2 = i2o_ECPublicKey(pkey, &pbegin);
    assert(nSize == nSize2);
    pubkey.Set(&c[0], &c[nSize]);
}
Exemple #13
0
void CECKey::GetPubKey(std::vector<unsigned char> &pubkey, bool fCompressed) {
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    int nSize = i2o_ECPublicKey(pkey, NULL);
    assert(nSize);
    assert(nSize <= 65);
    pubkey.clear();
    pubkey.resize(nSize);
    unsigned char *pbegin(begin_ptr(pubkey));
    int nSize2 = i2o_ECPublicKey(pkey, &pbegin);
    assert(nSize == nSize2);
}
Exemple #14
0
bool bp_privkey_set(struct bp_key *key, const void *privkey_, size_t pk_len)
{
	const unsigned char *privkey = privkey_;
	if (!d2i_ECPrivateKey(&key->k, &privkey, pk_len))
		return false;
	if (!EC_KEY_check_key(key->k))
		return false;

	EC_KEY_set_conv_form(key->k, POINT_CONVERSION_COMPRESSED);

	return true;
}
static int mech_start(sasl_session_t *p, char **out, size_t *out_len)
{
	ecdsa_session_t *s = mowgli_alloc(sizeof(ecdsa_session_t));
	p->mechdata = s;

	s->pubkey = EC_KEY_new_by_curve_name(CURVE_IDENTIFIER);
	s->step = ECDSA_ST_ACCNAME;

	EC_KEY_set_conv_form(s->pubkey, POINT_CONVERSION_COMPRESSED);

	return ASASL_MORE;
}
Exemple #16
0
bool bp_key_generate(struct bp_key *key)
{
	if (!key->k)
		return false;

	if (!EC_KEY_generate_key(key->k))
		return false;
	if (!EC_KEY_check_key(key->k))
		return false;

	EC_KEY_set_conv_form(key->k, POINT_CONVERSION_COMPRESSED);

	return true;
}
 public_key_data public_key::serialize()const
 {
   public_key_data dat;
   if( !my->_key ) return dat;
   EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
   /*size_t nbytes = i2o_ECPublicKey( my->_key, nullptr ); */
   /*assert( nbytes == 33 )*/
   char* front = &dat.data[0];
   i2o_ECPublicKey( my->_key, (unsigned char**)&front ); // FIXME: questionable memory handling
   return dat;
   /*
    EC_POINT* pub   = EC_KEY_get0_public_key( my->_key );
    EC_GROUP* group = EC_KEY_get0_group( my->_key );
    EC_POINT_get_affine_coordinates_GFp( group, pub, self.my->_pub_x.get(), self.my->_pub_y.get(), nullptr );
    */
 }
Exemple #18
0
ec_key::ec_key (const ec_key& that)
{
    if (that.ptr == nullptr)
    {
        ptr = nullptr;
        return;
    }

    ptr = (pointer_t) EC_KEY_dup (get_EC_KEY (that));

    if (ptr == nullptr)
    {
        throw std::runtime_error ("ec_key::ec_key() : EC_KEY_dup failed");
    }

    EC_KEY_set_conv_form (get_EC_KEY (*this), POINT_CONVERSION_COMPRESSED);
}
Exemple #19
0
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;
}
EC_KEY *helper_gateway_key(const tal_t *ctx)
{
	const unsigned char *p = gateway_key;
	EC_KEY *priv = EC_KEY_new_by_curve_name(NID_secp256k1);
	EC_KEY **ptr;

	if (!d2i_ECPrivateKey(&priv, &p, sizeof(gateway_key)))
		abort();

	if (!EC_KEY_check_key(priv))
		abort();

	/* We *always* used compressed form keys. */
	EC_KEY_set_conv_form(priv, POINT_CONVERSION_COMPRESSED);

	/* To get tal to clean it up... */
	ptr = tal(ctx, EC_KEY *);
	*ptr = priv;
	tal_add_destructor(ptr, free_gateway_key);

	return priv;
}
Exemple #21
0
void CKey::SetCompressedPubKey()
{
    EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
    fCompressedPubKey = true;
}
Exemple #22
0
void CKey::SetUnCompressedPubKey()
{
    EC_KEY_set_conv_form(pkey, POINT_CONVERSION_UNCOMPRESSED);
    fCompressedPubKey = false;
}
Exemple #23
0
BitcoinResult Bitcoin_MakePublicKeyFromPrivateKey(
	struct BitcoinPublicKey *public_key,
	const struct BitcoinPrivateKey *private_key
)
{
	BN_CTX *ctx = NULL;
	EC_KEY *key = NULL;
	EC_POINT *ec_public = NULL;
	unsigned char *public_key_ptr = public_key->data;
	BIGNUM *private_key_bn;
	const EC_GROUP *group = NULL;
	int size, size2;
	unsigned compression = private_key->public_key_compression;
	size_t expected_public_key_size = 0;
	enum BitcoinPublicKeyCompression public_key_compression;

	switch (compression) {
		case BITCOIN_PUBLIC_KEY_COMPRESSED :
		case BITCOIN_PUBLIC_KEY_UNCOMPRESSED :
			break;
		default :
			applog(APPLOG_ERROR, __func__,
				"public key compression is not specified, please set using"
				" --public-key-compression compressed/uncompressed"
			);
			EC_KEY_free(key);
			return BITCOIN_ERROR_PRIVATE_KEY_INVALID_FORMAT;
			break;
	}

	key = EC_KEY_new_by_curve_name_NID_secp256k1();
	if (!key) {
		applog(APPLOG_ERROR, __func__,
			"EC_KEY_new_by_curve_name failed: %s",
			ERR_error_string(ERR_get_error(), NULL)
		);
		return BITCOIN_ERROR_LIBRARY_FAILURE;
	}

	group = EC_KEY_get0_group(key);
	if (!group) {
		applog(APPLOG_ERROR, __func__,
			"EC_KEY_get0_group failed: %s",
			ERR_error_string(ERR_get_error(), NULL)
		);
		EC_KEY_free(key);
		return BITCOIN_ERROR_LIBRARY_FAILURE;
	}

	private_key_bn = BN_new();
	BN_bin2bn(private_key->data, BITCOIN_PRIVATE_KEY_SIZE, private_key_bn);
	ec_public = EC_POINT_new(group);

	ctx = BN_CTX_new();
	if (!ctx) {
		applog(APPLOG_ERROR, __func__,
			"BN_CTX_new failed: %s",
			ERR_error_string(ERR_get_error(), NULL)
		);
		EC_KEY_free(key);
		return BITCOIN_ERROR_LIBRARY_FAILURE;
	}

	if (!EC_POINT_mul(group, ec_public, private_key_bn, NULL, NULL, ctx)) {
		applog(APPLOG_ERROR, __func__,
			"EC_POINT_mul failed: %s",
			ERR_error_string(ERR_get_error(), NULL)
		);
		EC_KEY_free(key);
		return BITCOIN_ERROR_LIBRARY_FAILURE;
	}

	EC_KEY_set_private_key(key, private_key_bn);
	EC_KEY_set_public_key(key, ec_public);

	if (compression == BITCOIN_PUBLIC_KEY_COMPRESSED) {
		EC_KEY_set_conv_form(key, POINT_CONVERSION_COMPRESSED);
		expected_public_key_size = BITCOIN_PUBLIC_KEY_COMPRESSED_SIZE;
		public_key_compression = BITCOIN_PUBLIC_KEY_COMPRESSED;
	} else {
		EC_KEY_set_conv_form(key, POINT_CONVERSION_UNCOMPRESSED);
		expected_public_key_size = BITCOIN_PUBLIC_KEY_UNCOMPRESSED_SIZE;
		public_key_compression = BITCOIN_PUBLIC_KEY_UNCOMPRESSED;
	}

	size = i2o_ECPublicKey(key, NULL);

	if (size != expected_public_key_size) {
		fprintf(stderr, "%s: invalid public key size (%u), should be %u\n",
			__func__,
			(unsigned)size,
			(unsigned)expected_public_key_size
		);
		BN_free(private_key_bn);
		EC_KEY_free(key);
		return BITCOIN_ERROR_PUBLIC_KEY_INVALID_FORMAT;
	}

	size2 = i2o_ECPublicKey(key, &public_key_ptr);
	if (size2 != expected_public_key_size) {
		fprintf(stderr, "%s: invalid public key size (%u), should be %u\n",
			__func__,
			(unsigned)size,
			(unsigned)expected_public_key_size
		);
		BN_free(private_key_bn);
		EC_KEY_free(key);
		return BITCOIN_ERROR_PUBLIC_KEY_INVALID_FORMAT;
	}

	/* public key appears to be valid by now, set the compression type */
	public_key->compression = public_key_compression;
	public_key->network_type = private_key->network_type;

	/* free resources */
	EC_POINT_clear_free(ec_public);
	BN_free(private_key_bn);
	BN_CTX_free(ctx);
	EC_KEY_free(key);

	return BITCOIN_SUCCESS;
}
Exemple #24
0
int CECKey::GetPrivKeySize(bool fCompressed) {
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    return i2d_ECPrivateKey(pkey, NULL);
}
Exemple #25
0
int CECKey::GetPrivKey(unsigned char* privkey, bool fCompressed) {
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    return i2d_ECPrivateKey(pkey, &privkey);
}
Exemple #26
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)
        rb_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) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
		ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
            }
            if (!ec) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
                ec = d2i_ECPrivateKey_bio(in, NULL);
            }
            if (!ec) {
                (void)BIO_reset(in);
                (void)ERR_get_error();
                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;
}
Exemple #27
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);
}
Exemple #28
0
void CKey::SetCompressedPubKey(bool fCompressed)
{
    EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
    fCompressedPubKey = true;
}
Exemple #29
0
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT    * ca_cert, 
                                   const PKI_X509_KEYPAIR * kPair,
                                   const PKI_X509_REQ     * req,
                                   const char             * subj_s, 
                                   const char             * serial_s,
                                   uint64_t                 validity,
                                   const PKI_X509_PROFILE * conf,
                                   const PKI_ALGOR        * algor,
                                   const PKI_CONFIG       * oids,
                                   HSM *hsm ) {
  PKI_X509_CERT *ret = NULL;
  PKI_X509_CERT_VALUE *val = NULL;
  PKI_X509_NAME *subj = NULL;
  PKI_X509_NAME *issuer = NULL;
  PKI_DIGEST_ALG *digest = NULL;
  PKI_X509_KEYPAIR_VALUE *signingKey = NULL;
  PKI_TOKEN *tk = NULL;

  PKI_X509_KEYPAIR_VALUE  *certPubKeyVal = NULL;

  int rv = 0;
  int ver = 2;

  int64_t notBeforeVal = 0;

  ASN1_INTEGER *serial = NULL;

  char *ver_s = NULL;

  /* Check if the REQUIRED PKEY has been passed */
  if (!kPair || !kPair->value) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return (NULL);
  };

  signingKey = kPair->value;

  /* TODO: This has to be fixed, to work on every option */
  if ( subj_s )
  {
    subj = PKI_X509_NAME_new ( subj_s );
  }
  else if (conf || req)
  {
    char *tmp_s = NULL;

    // Let's use the configuration option first
    if (conf) {

      // Get the value of the DN, if present
      if ((tmp_s = PKI_CONFIG_get_value( conf, 
                                 "/profile/subject/dn")) != NULL ) {
        // Builds from the DN in the config  
        subj = PKI_X509_NAME_new(tmp_s);
        PKI_Free ( tmp_s );
      }
    }

    // If we still do not have a name, let's check
    // the request for one
    if (req && !subj) {

      const PKI_X509_NAME * req_subj = NULL;

      // Copy the name from the request
      if ((req_subj = PKI_X509_REQ_get_data(req, 
				    PKI_X509_DATA_SUBJECT)) != NULL) {
        subj = PKI_X509_NAME_dup(req_subj);
      }
    }

    // If no name is provided, let's use an empty one
    // TODO: Shall we remove this and fail instead ?
    if (!subj) subj = PKI_X509_NAME_new( "" );
  }
  else
  {
    struct utsname myself;
    char tmp_name[1024];

    if (uname(&myself) < 0) {
      subj = PKI_X509_NAME_new( "" );
    } else {
      sprintf( tmp_name, "CN=%s", myself.nodename );
      subj = PKI_X509_NAME_new( tmp_name );
    }
  }

  if (!subj) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s );
    goto err;
  }

  if( ca_cert ) {
    const PKI_X509_NAME *ca_subject = NULL;

    /* Let's get the ca_cert subject and dup that data */
    // ca_subject = (PKI_X509_NAME *) 
    //     X509_get_subject_name( (X509 *) ca_cert );
    ca_subject = PKI_X509_CERT_get_data( ca_cert, 
        PKI_X509_DATA_SUBJECT );

    if( ca_subject ) {
      issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject);
    } else {
      PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
      goto err;
    }

  } else {
    issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj);
  }

  if( !issuer ) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  if(( ret = PKI_X509_CERT_new_null()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    goto err;
  }

  /* Alloc memory structure for the Certificate */
  if((ret->value = ret->cb->create()) == NULL ) {
    PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
    return (NULL);
  }

  val = ret->value;

  if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) {
    ver = atoi( ver_s ) - 1;
    if ( ver < 0 ) 
      ver = 0;
    PKI_Free ( ver_s );
  } else {
    ver = 2;
  };

  if (!X509_set_version(val,ver)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL);
    goto err;
  }

  if (serial_s) {
    char * tmp_s = (char *) serial_s;
    serial = s2i_ASN1_INTEGER(NULL, tmp_s);
  } else {
    // If cacert we assume it is a normal cert - let's create a
    // random serial number, otherwise - it's a self-signed, use
    // the usual 'fake' 0
    if ( ca_cert ) {
      unsigned char bytes[11];
      RAND_bytes(bytes, sizeof(bytes));
      bytes[0] = 0;

      serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes));
    } else {
      serial = s2i_ASN1_INTEGER( NULL, "0");
    };
  };

  if(!X509_set_serialNumber( val, serial )) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s);
    goto err;
  }

  /* Set the issuer Name */
  // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer);
  if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL);
    goto err;
  }

  /* Set the subject Name */
  if(!X509_set_subject_name(val, (X509_NAME *) subj)) {
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL);
    goto err;
  }

  /* Set the start date (notBefore) */
  if (conf)
  {
    int years = 0;
    int days  = 0;
    int hours = 0;
    int mins  = 0;
    int secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/years")) != NULL ) {
      years = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/days")) != NULL ) {
      days = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/hours")) != NULL ) {
      hours = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/minutes")) != NULL ) {
      mins = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/notBefore/seconds")) != NULL ) {
      secs = atoi( tmp_s );
      PKI_Free ( tmp_s );
    };

    notBeforeVal =   secs +
            ( mins * 60 ) + 
            ( hours * 3600 ) + 
            ( days   * 3600 * 24 ) + 
            ( years * 3600 * 24 * 365 );
  };

  /* Set the validity (notAfter) */
  if( conf && validity == 0 )
  {
    long long years = 0;
    long long days  = 0;
    long long hours = 0;
    long long mins  = 0;
    long long secs  = 0;

    char *tmp_s = NULL;

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/years")) != NULL ) {
      years = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/days")) != NULL ) {
      days = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/hours")) != NULL ) {
      hours = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      mins = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    if(( tmp_s = PKI_CONFIG_get_value( conf, 
        "/profile/validity/minutes")) != NULL ) {
      secs = atoll( tmp_s );
      PKI_Free ( tmp_s );
    };

    validity =   (unsigned long long) secs +
          (unsigned long long) ( mins   * 60 ) + 
          (unsigned long long) ( hours * 3600 ) + 
          (unsigned long long) ( days   * 3600 * 24 ) + 
          (unsigned long long) ( years * 3600 * 24 * 365 );
  };

  if (validity <= 0) validity = 30 * 3600 * 24;

#if ( LIBPKI_OS_BITS == LIBPKI_OS32 )
  long notBeforeVal32 = (long) notBeforeVal;
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL)
  {
#else
  if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL)
  {
#endif
    PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL);
    goto err;
  }

  /* Set the end date in a year */
  if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL)
  {
    PKI_DEBUG("ERROR: can not set notAfter field!");
    goto err;
  }

  /* Copy the PKEY if it is in the request, otherwise use the
     public part of the PKI_X509_CERT */
  if (req)
  {
    certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) 
       PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE);

    if( !certPubKeyVal ) {
      PKI_DEBUG("ERROR, can not get pubkey from req!");
      goto err;
    }
  }
  else
  {
    /* Self Signed -- Same Public Key! */
    certPubKeyVal = signingKey;
  }

  if (!ca_cert && conf)
  {
    char *tmp_s = NULL;

    if(( tmp_s = PKI_X509_PROFILE_get_value( conf, 
        "/profile/keyParams/algorithm")) != NULL )
    {
      PKI_ALGOR *myAlg = NULL;
      PKI_DIGEST_ALG *dgst = NULL;

      if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL )
      {
        if(!algor) algor = myAlg;

        if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL )
        {
          PKI_DEBUG("Got Signing Algorithm: %s, %s",
            PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg));
          digest = dgst;
        }
        else
        {
          PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s);
        }
      }
      else
      {
        PKI_DEBUG("Can not parse key algorithm from %s", tmp_s);
      }
      PKI_Free ( tmp_s );
    }
  }

  if (conf)
  {
    PKI_KEYPARAMS *kParams = NULL;
    PKI_SCHEME_ID scheme;

    scheme = PKI_ALGOR_get_scheme( algor );

    kParams = PKI_KEYPARAMS_new(scheme, conf);
    if (kParams)
    {
      /* Sets the point compression */
      switch ( kParams->scheme )
      {
#ifdef ENABLE_ECDSA
        case PKI_SCHEME_ECDSA:
            if ( (int) kParams->ec.form > 0 )
            {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
              EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, 
              			   (point_conversion_form_t) kParams->ec.form);
# else
              EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), 
              (point_conversion_form_t) kParams->ec.form);
# endif
            }
          if ( kParams->ec.asn1flags > -1 )
          {
# if OPENSSL_VERSION_NUMBER < 0x1010000fL
            EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec,
              kParams->ec.asn1flags );
# else
            EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal),
              kParams->ec.asn1flags );
# endif
          }
          break;
#endif
        case PKI_SCHEME_RSA:
        case PKI_SCHEME_DSA:
          break;

        default:
          // Nothing to do
          PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme);
          break;
      }
    }
  }

  if (!X509_set_pubkey(val, certPubKeyVal))
  {
    PKI_DEBUG("ERROR, can not set pubkey in cert!");
    goto err;
  }

  if (conf)
  {
    if((tk = PKI_TOKEN_new_null()) == NULL )
    {
      PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
      goto err;
    }

    PKI_TOKEN_set_cert(tk, ret);

    if (ca_cert) {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert);
    } else {
      PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret);
    }

    if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req );
    if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair );

    rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk);
    if (rv != PKI_OK)
    {
      PKI_DEBUG( "ERROR, can not set extensions!");

      tk->cert = NULL;
      tk->cacert = NULL;
      tk->req = NULL;
      tk->keypair = NULL;

      PKI_TOKEN_free ( tk );

      goto err;
    }

    // Cleanup for the token (used only to add extensions)
    tk->cert = NULL;
    tk->cacert = NULL;
    tk->req = NULL;
    tk->keypair = NULL;
    PKI_TOKEN_free ( tk );
  }

  if (!digest)
  {
    if (!algor)
    {
      PKI_log_debug("Getting the Digest Algorithm from the CA cert");

      // Let's get the Digest Algorithm from the CA Cert
      if (ca_cert)
      {
        if((algor = PKI_X509_CERT_get_data(ca_cert,
              PKI_X509_DATA_ALGORITHM )) == NULL)
        {
          PKI_log_err("Can not retrieve DATA algorithm from CA cert");
        }
      }
    }

    // If we have an Algor from either the passed argument or
    // the CA Certificate, extract the digest from it. Otherwise
    // get the digest from the signing key
    if (algor)
    {
      if((digest = PKI_ALGOR_get_digest(algor)) == NULL )
      {
        PKI_log_err("Can not get digest from algor");
      }
    }

    // Check, if still no digest, let's try from the signing Key
    if (digest == NULL)
    {
      if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL)
      {
        PKI_log_err("Can not infer digest algor from the key pair");
      }
    }
  }

  // No Digest Here ? We failed...
  if (digest == NULL)
  {
    PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!");
    return( NULL );
  }

  // Sign the data
  if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR)
  {
    PKI_log_err ("Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    PKI_X509_CERT_free ( ret );
    return NULL;
  }

#if ( OPENSSL_VERSION_NUMBER >= 0x0090900f )

# if OPENSSL_VERSION_NUMBER < 0x1010000fL
  PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value;

  if (cVal && cVal->cert_info)
  {
    PKI_log_debug("Signature = %s", 
      PKI_ALGOR_get_parsed(cVal->cert_info->signature));
  }
# endif

  //  PKI_X509_CINF_FULL *cFull = NULL;
  //  cFull = (PKI_X509_CINF_FULL *) cVal->cert_info;
  //  cFull->enc.modified = 1;
#endif

  return ret;

err:

  if (ret) PKI_X509_CERT_free(ret);
  if (subj) PKI_X509_NAME_free(subj);
  if (issuer) PKI_X509_NAME_free(issuer);

  return NULL;
}

/*!
 * \brief Signs a PKI_X509_CERT
 */

int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp,
    PKI_DIGEST_ALG *digest) {

  const PKI_ALGOR *alg = NULL;

  if( !cert || !cert->value || !kp || !kp->value ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  }

  if(!digest) {
    if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) {
      digest = PKI_ALGOR_get_digest ( alg );
    }
  }

  if(!digest) {
    if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) {
      PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor "
          "from key");
      return PKI_ERR;
    }
  }

  if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) {
    PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]",
      ERR_error_string(ERR_get_error(), NULL ));
    return PKI_ERR;
  }

  return PKI_OK;
};

/*!
 * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN
 */

int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk,
    PKI_DIGEST_ALG *digest) {

  PKI_X509_KEYPAIR *kp = NULL;

  if( !cert || !cert->value || !tk ) {
    PKI_ERROR(PKI_ERR_PARAM_NULL, NULL);
    return PKI_ERR;
  };

  if( PKI_TOKEN_login( tk ) == PKI_ERR ) {
    PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL);
    return PKI_ERR;
  };

  if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) {
    return PKI_ERR;
  };

  return PKI_X509_CERT_sign ( cert, kp, digest );
};
		void elliptic_curve_key::use_compressed()
		{
			// Use POINT_CONVERSION_UNCOMPRESSED for old style uncompressed keys.
			// Or just comment out the line below:
			EC_KEY_set_conv_form(key_, POINT_CONVERSION_COMPRESSED);
		}