// Constructors
OSSLRSAPublicKey::OSSLRSAPublicKey()
{
	rsa = RSA_new();

	// Use the OpenSSL implementation and not any engine
	RSA_set_method(rsa, RSA_PKCS1_SSLeay());
}
// Constructors
OSSLRSAPrivateKey::OSSLRSAPrivateKey()
{
	rsa = RSA_new();

	// Use the OpenSSL implementation and not any engine
	RSA_set_method(rsa, RSA_get_default_method());
}
Exemple #3
0
static RSA *
read_key(ENGINE *engine, const char *rsa_key)
{
    unsigned char buf[1024 * 4];
    const unsigned char *p;
    size_t size;
    RSA *rsa;
    FILE *f;

    f = fopen(rsa_key, "rb");
    if (f == NULL)
	err(1, "could not open file %s", rsa_key);
    rk_cloexec_file(f);

    size = fread(buf, 1, sizeof(buf), f);
    fclose(f);
    if (size == 0)
	err(1, "failed to read file %s", rsa_key);
    if (size == sizeof(buf))
	err(1, "key too long in file %s!", rsa_key);

    p = buf;
    rsa = d2i_RSAPrivateKey(NULL, &p, size);
    if (rsa == NULL)
	err(1, "failed to parse key in file %s", rsa_key);

    RSA_set_method(rsa, ENGINE_get_RSA(engine));

    if (!key_blinding)
	rsa->flags |= RSA_FLAG_NO_BLINDING;

    return rsa;
}
Exemple #4
0
/*
 * Build an EVP_PKEY object
 */
static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY *key)
{
	EVP_PKEY *pk;
	RSA *rsa;

	rsa = pkcs11_get_rsa(key);
	if (rsa == NULL)
		return NULL;
	pk = EVP_PKEY_new();
	if (pk == NULL) {
		RSA_free(rsa);
		return NULL;
	}
	EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */

	if (key->isPrivate)
		RSA_set_method(rsa, PKCS11_get_rsa_method());
	/* TODO: Retrieve the RSA private key object attributes instead,
	 * unless the key has the "sensitive" attribute set */

#if OPENSSL_VERSION_NUMBER < 0x01010000L
	/* RSA_FLAG_SIGN_VER is no longer needed since OpenSSL 1.1 */
	rsa->flags |= RSA_FLAG_SIGN_VER;
#endif
	RSA_set_ex_data(rsa, rsa_ex_index, key);
	RSA_free(rsa); /* Drops our reference to it */
	return pk;
}
static int
set_private_key(hx509_context context,
		SecKeychainItemRef itemRef,
		hx509_cert cert)
{
    struct kc_rsa *kc;
    hx509_private_key key;
    RSA *rsa;
    int ret;

    ret = _hx509_private_key_init(&key, NULL, NULL);
    if (ret)
	return ret;

    kc = calloc(1, sizeof(*kc));
    if (kc == NULL)
	_hx509_abort("out of memory");

    kc->item = itemRef;

    rsa = RSA_new();
    if (rsa == NULL)
	_hx509_abort("out of memory");

    /* Argh, fake modulus since OpenSSL API is on crack */
    {
	SecKeychainAttributeList *attrs = NULL;
	uint32_t size;
	void *data;

	rsa->n = BN_new();
	if (rsa->n == NULL) abort();

	ret = getAttribute(itemRef, kSecKeyKeySizeInBits, &attrs);
	if (ret) abort();

	size = *(uint32_t *)attrs->attr[0].data;
	SecKeychainItemFreeAttributesAndData(attrs, NULL);

	kc->keysize = (size + 7) / 8;

	data = malloc(kc->keysize);
	memset(data, 0xe0, kc->keysize);
	BN_bin2bn(data, kc->keysize, rsa->n);
	free(data);
    }
    rsa->e = NULL;

    RSA_set_method(rsa, &kc_rsa_pkcs1_method);
    ret = RSA_set_app_data(rsa, kc);
    if (ret != 1)
	_hx509_abort("RSA_set_app_data");

    _hx509_private_key_assign_rsa(key, rsa);
    _hx509_cert_assign_key(cert, key);

    return 0;
}
Exemple #6
0
int
tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert)
{
  RSA *rsa = NULL;
  RSA *pub_rsa;
  RSA_METHOD *rsa_meth;

  ASSERT (NULL != ctx);
  ASSERT (NULL != cert);

  /* allocate custom RSA method object */
  ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD);
  rsa_meth->name = "OpenVPN external private key RSA Method";
  rsa_meth->rsa_pub_enc = rsa_pub_enc;
  rsa_meth->rsa_pub_dec = rsa_pub_dec;
  rsa_meth->rsa_priv_enc = rsa_priv_enc;
  rsa_meth->rsa_priv_dec = rsa_priv_dec;
  rsa_meth->init = NULL;
  rsa_meth->finish = rsa_finish;
  rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
  rsa_meth->app_data = NULL;

  /* allocate RSA object */
  rsa = RSA_new();
  if (rsa == NULL)
    {
      SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
      goto err;
    }

  /* get the public key */
  ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */
  pub_rsa = cert->cert_info->key->pkey->pkey.rsa;

  /* initialize RSA object */
  rsa->n = BN_dup(pub_rsa->n);
  rsa->flags |= RSA_FLAG_EXT_PKEY;
  if (!RSA_set_method(rsa, rsa_meth))
    goto err;

  /* bind our custom RSA object to ssl_ctx */
  if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
    goto err;

  RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
  return 1;

 err:
  if (rsa)
    RSA_free(rsa);
  else
    {
      if (rsa_meth)
	free(rsa_meth);
    }
  msg (M_SSLERR, "Cannot enable SSL external private key capability");
  return 0;
}
OSSLRSAPrivateKey::OSSLRSAPrivateKey(const RSA* inRSA)
{
	rsa = RSA_new();

	// Use the OpenSSL implementation and not any engine
	RSA_set_method(rsa, RSA_PKCS1_SSLeay());

	setFromOSSL(inRSA);
}
static
PKCS11H_BOOL
__pkcs11h_openssl_session_setRSA(
	IN const pkcs11h_openssl_session_t openssl_session,
	IN EVP_PKEY * evp
) {
	PKCS11H_BOOL ret = FALSE;
	RSA *rsa = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setRSA - entered openssl_session=%p, evp=%p",
		(void *)openssl_session,
		(void *)evp
	);

	if (
		(rsa = EVP_PKEY_get1_RSA (evp)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
		goto cleanup;
	}

	RSA_set_method (rsa, __openssl_methods.rsa);
	RSA_set_ex_data (rsa, __openssl_methods.rsa_index, openssl_session);
#if OPENSSL_VERSION_NUMBER < 0x10100001L
	rsa->flags |= RSA_FLAG_SIGN_VER;
#endif

#ifdef BROKEN_OPENSSL_ENGINE
	if (!rsa->engine) {
		rsa->engine = ENGINE_get_default_RSA ();
	}

	ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->rsa);
	_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
#endif

	ret = TRUE;

cleanup:

	if (rsa != NULL) {
		RSA_free (rsa);
		rsa = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setRSA - return ret=%d",
		ret
	);

	return ret;
}
/* redirect the private key encrypt operation to the ssh-pkcs11-helper */
static int
wrap_key(RSA *rsa)
{
	static RSA_METHOD helper_rsa;

	memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
	helper_rsa.name = "ssh-pkcs11-helper";
	helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
	RSA_set_method(rsa, &helper_rsa);
	return (0);
}
Exemple #10
0
Qt::HANDLE QSmartCard::key()
{
	RSA *rsa = RSAPublicKey_dup( (RSA*)d->t.authCert().publicKey().handle() );
	if ( !rsa )
		return 0;

	RSA_set_method( rsa, &d->method );
	rsa->flags |= RSA_FLAG_SIGN_VER;
	RSA_set_app_data( rsa, d );
	EVP_PKEY *key = EVP_PKEY_new();
	EVP_PKEY_set1_RSA( key, rsa );
	RSA_free( rsa );
	return Qt::HANDLE(key);
}
static int extract_certificate_and_pkey(PluginInstance *inst,
					X509 **x509_out,
					EVP_PKEY **pkey_out)
{
	int r;
	X509 *x509 = NULL;
	struct sc_pkcs15_id cert_id;
	struct sc_priv_data *priv = NULL;
        EVP_PKEY *pkey = NULL;
        RSA *rsa = NULL;
	
        r = init_pkcs15(inst);
        if (r)
                goto err;
        r = get_certificate(inst, &x509, &cert_id);
        if (r)
                goto err;

	r = -1;
        pkey = X509_get_pubkey(x509);
        if (pkey == NULL)
        	goto err;
        if (pkey->type != EVP_PKEY_RSA)
        	goto err;
	rsa = EVP_PKEY_get1_RSA(pkey); /* increases ref count */
	if (rsa == NULL)
		goto err;
	rsa->flags |= RSA_FLAG_SIGN_VER;
	RSA_set_method(rsa, sc_get_method());
	priv = (struct sc_priv_data *) calloc(1, sizeof(*priv));
	if (priv == NULL)
		goto err;
	priv->cert_id = cert_id;
	priv->ref_count = 1;
	RSA_set_app_data(rsa, priv);
	RSA_free(rsa);		/* decreases ref count */
	
	*x509_out = x509;
	*pkey_out = pkey;

	return 0;
err:
	if (pkey)
		EVP_PKEY_free(pkey);
	if (x509)
		X509_free(x509);
	return -1;
	
}
static void
convert_rsa_to_rsa1(Key * in, Key * out)
{
	struct sc_priv_data *priv;

	out->rsa->flags = in->rsa->flags;
	out->flags = in->flags;
	RSA_set_method(out->rsa, RSA_get_method(in->rsa));
	BN_copy(out->rsa->n, in->rsa->n);
	BN_copy(out->rsa->e, in->rsa->e);
	priv = RSA_get_app_data(in->rsa);
	priv->ref_count++;
	RSA_set_app_data(out->rsa, priv);
	return;
}
static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD *ui_method,
        void *callback_data) {
    ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);

    Keystore_Reply reply;
    if (keystore_cmd(CommandCodes[GET_PUBKEY], &reply, 1, strlen(key_id), key_id) != NO_ERROR) {
        ALOGV("Cannot get public key for %s", key_id);
        return NULL;
    }

    const unsigned char* tmp = reinterpret_cast<const unsigned char*>(reply.get());
    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, reply.length()));
    if (pkey.get() == NULL) {
        ALOGW("Cannot convert pubkey");
        return NULL;
    }

    switch (EVP_PKEY_type(pkey->type)) {
    case EVP_PKEY_RSA: {
        Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
        if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
            ALOGW("Could not set ex_data for loaded RSA key");
            return NULL;
        }

        RSA_set_method(rsa.get(), &keystore_rsa_meth);
        RSA_blinding_off(rsa.get());

        /*
         * This should probably be an OpenSSL API, but EVP_PKEY_free calls
         * ENGINE_finish(), so we need to call ENGINE_init() here.
         */
        ENGINE_init(e);
        rsa->engine = e;
        rsa->flags |= RSA_FLAG_EXT_PKEY;

        break;
    }
    default:
        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
        return NULL;
    }

    return pkey.release();
}
Exemple #14
0
int aos_signature_init(struct aos_signature *sign)
{
	memset(sign, 0, sizeof(struct aos_signature));
	
	sign->rsa = RSA_new();
	if(sign->rsa == NULL)
		return 0;
	
	RSA_set_method(sign->rsa, RSA_PKCS1_SSLeay());
	
	sign->rsa->e = BN_new();
	if(sign->rsa->e == NULL)
		return 0;
	
	BN_set_word(sign->rsa->e, 3);
	
	return 1;
}
Exemple #15
0
static CK_RV
add_pubkey_info(struct gpkcs11_st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
{
    switch (key_type) {
    case CKK_RSA: {
	CK_BYTE *modulus = NULL;
	size_t modulus_len = 0;
	CK_ULONG modulus_bits = 0;
	CK_BYTE *exponent = NULL;
	size_t exponent_len = 0;

	modulus_bits = BN_num_bits(key->pkey.rsa->n);

	modulus_len = BN_num_bytes(key->pkey.rsa->n);
	modulus = malloc(modulus_len);
	BN_bn2bin(key->pkey.rsa->n, modulus);
	
	exponent_len = BN_num_bytes(key->pkey.rsa->e);
	exponent = malloc(exponent_len);
	BN_bn2bin(key->pkey.rsa->e, exponent);
	
	add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
	add_object_attribute(o, 0, CKA_MODULUS_BITS,
			     &modulus_bits, sizeof(modulus_bits));
	add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
			     exponent, exponent_len);

	RSA_set_method(key->pkey.rsa, RSA_PKCS1_SSLeay());

	free(modulus);
	free(exponent);
    }
    default:
	/* XXX */
	break;
    }
    return CKR_OK;
}
Exemple #16
0
		ExternalPKIImpl(SSL_CTX* ssl_ctx, ::X509* cert, ExternalPKIBase* external_pki_arg)
			: external_pki(external_pki_arg), n_errors(0)
		{
			RSA *rsa = NULL;
			RSA_METHOD *rsa_meth = NULL;
			RSA *pub_rsa = NULL;
			const char *errtext = "";

			/* allocate custom RSA method object */
			rsa_meth = new RSA_METHOD;
			std::memset(rsa_meth, 0, sizeof(RSA_METHOD));
			rsa_meth->name = "OpenSSLContext::ExternalPKIImpl private key RSA Method";
			rsa_meth->rsa_pub_enc = rsa_pub_enc;
			rsa_meth->rsa_pub_dec = rsa_pub_dec;
			rsa_meth->rsa_priv_enc = rsa_priv_enc;
			rsa_meth->rsa_priv_dec = rsa_priv_dec;
			rsa_meth->init = NULL;
			rsa_meth->finish = rsa_finish;
			rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
			rsa_meth->app_data = (char *)this;

			/* allocate RSA object */
			rsa = RSA_new();
			if (rsa == NULL)
			{
				SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
				errtext = "RSA_new";
				goto err;
			}

			/* get the public key */
			if (cert->cert_info->key->pkey == NULL) /* NULL before SSL_CTX_use_certificate() is called */
			{
				errtext = "pkey is NULL";
				goto err;
			}
			pub_rsa = cert->cert_info->key->pkey->pkey.rsa;

			/* initialize RSA object */
			rsa->n = BN_dup(pub_rsa->n);
			rsa->flags |= RSA_FLAG_EXT_PKEY;
			if (!RSA_set_method(rsa, rsa_meth))
			{
				errtext = "RSA_set_method";
				goto err;
			}

			/* bind our custom RSA object to ssl_ctx */
			if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
			{
				errtext = "SSL_CTX_use_RSAPrivateKey";
				goto err;
			}

			RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
			return;

err:
			if (rsa)
				RSA_free(rsa);
			else
			{
				if (rsa_meth)
					free(rsa_meth);
			}
			OPENVPN_THROW(OpenSSLException, "OpenSSLContext::ExternalPKIImpl: " << errtext);
		}
Exemple #17
0
int main(int argc, char *argv[])
{
	int r, c, long_optind = 0;
	sc_context_param_t ctx_param;
	sc_card_t *card = NULL;
	sc_context_t *ctx = NULL;
	sc_file_t *file = NULL;
	sc_path_t path;
	RSA	*rsa = NULL;
	BIGNUM	*bn = NULL;
	BIO	*mem = NULL;
	static const char *pin = NULL;
	static const char *puk = NULL;

	while (1)
	{
		c = getopt_long(argc, argv, "r:wgol:ix:y:nut:fj:k:hv", \
			options, &long_optind);
		if (c == -1)
			break;
		if (c == '?' || c == 'h')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c)
		{
			case 'r':
				opt_reader = optarg;
				break;
			case 'w':
				opt_wait = 1;
				break;
			case 'g':
				if(keylen == 0) keylen = 1536;
				break;
			case 'o':
				overwrite = 1;
				break;
			case 'l':
				keylen = atoi(optarg);
				break;
			case 'i':
				install_pin = 1;
				break;
			case 'x':
				util_get_pin(optarg, &pin);
				break;
			case 'y':
				util_get_pin(optarg, &puk);
				break;
			case 'n':
				new_pin = 1;
				break;
			case 'u':
				unlock = 1;
				break;
			case 't':
				cert = optarg;
				break;
			case 'f':
				finalize = 1;
				break;
			case 'j':
				get_filename = optarg;
				break;
			case 'k':
				put_filename = optarg;
				break;
			case 'v':
				verbose++;
				break;
		}
	}

	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = argv[0];

	r = sc_context_create(&ctx, &ctx_param);
	if (r)
	{
		printf("Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	if (verbose > 1) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	if (opt_driver != NULL)
	{
		r = sc_set_card_driver(ctx, opt_driver);
		if (r)
		{
			printf("Driver '%s' not found!\n", opt_driver);
			goto out;
		}
	}

	r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0);
	if (r)
		goto out;

	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);
	if(r) goto out;

	if(install_pin)
	{
		sc_format_path("AAAA", &path);
		r = sc_select_file(card, &path, NULL);
		if(r)
		{
			if(r != SC_ERROR_FILE_NOT_FOUND) goto out;

			file = sc_file_new();
			if(file == NULL)
			{
				printf("Not enougth memory.\n");
				goto out;
			}

			file->type = SC_FILE_TYPE_INTERNAL_EF;
			file->ef_structure = SC_FILE_EF_TRANSPARENT;
			file->shareable = 0;

			file->id = 0xAAAA;
			file->size = 37;

			r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0);
			if(r) goto out;
			r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_NONE, 0);
			if(r) goto out;
			r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_NONE, 0);
			if(r) goto out;

			/* sc_format_path("3F00AAAA", &(file->path)); */
			file->path = path;
			r = sc_create_file(card, file);
			if(r) goto out;
		}

		if(pin != NULL)
		{
			sc_changekey_t ck;
			struct sc_pin_cmd_pin pin_cmd;
			int ret;

			memset(&pin_cmd, 0, sizeof(pin_cmd));
			memset(&ck, 0, sizeof(ck));

			memcpy(ck.key_template, "\x1e\x00\x00\x10", 4);

			pin_cmd.encoding = SC_PIN_ENCODING_GLP;
			pin_cmd.len = strlen(pin);
			pin_cmd.data = (u8*)pin;
			pin_cmd.max_length = 8;

			ret = sc_build_pin(ck.new_key.key_value,
				sizeof(ck.new_key.key_value), &pin_cmd, 1);
			if(ret < 0)
				goto out;

			ck.new_key.key_len = ret;
			r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck);
			if(r) goto out;
		}

		if(puk != NULL)
		{
			sc_changekey_t ck;
			struct sc_pin_cmd_pin puk_cmd;
			int ret;

			memset(&puk_cmd, 0, sizeof(puk_cmd));
			memset(&ck, 0, sizeof(ck));

			memcpy(ck.key_template, "\x1e\x00\x00\x20", 4);

			puk_cmd.encoding = SC_PIN_ENCODING_GLP;
			puk_cmd.len = strlen(puk);
			puk_cmd.data = (u8*)puk;
			puk_cmd.max_length = 8;

			ret = sc_build_pin(ck.new_key.key_value,
				sizeof(ck.new_key.key_value), &puk_cmd, 1);
			if(ret < 0)
				goto out;

			ck.new_key.key_len = ret;
			r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck);
			if(r) goto out;
		}
	}

	if(new_pin)
	{
		if(change_pin(card, 0, pin, puk))
			printf("Wrong pin.\n");
		goto out;
	}

	if(unlock)
	{
		if(unlock_pin(card, 0, puk, pin))
			printf("Error unblocking pin.\n");
		goto out;
	}

	printf("verify pin.\n");
	{
		if(verify_pin(card, 0, pin))
		{
			printf("Wrong pin.\n");
			goto out;
		}
	}

	if(keylen)
	{
		size_t lg;
		struct sc_pkcs15_pubkey key;
		struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa);
		u8 *pdata;

		memset(&key, 0, sizeof(key));
		key.algorithm = SC_ALGORITHM_RSA;

		printf("Generate key of length %d.\n", keylen);

#if OPENSSL_VERSION_NUMBER>=0x00908000L
		rsa = RSA_new();
		bn = BN_new();
		mem = BIO_new(BIO_s_mem());

		if(rsa == NULL || bn == NULL || mem == NULL)
		{
			printf("Not enougth memory.\n");
			goto out;
		}

		if(!BN_set_word(bn, RSA_F4) ||
			!RSA_generate_key_ex(rsa, keylen, bn, NULL))
#else
		rsa = RSA_generate_key(keylen, RSA_F4, NULL, NULL);
		mem = BIO_new(BIO_s_mem());

		if(mem == NULL)
		{
			printf("Not enougth memory.\n");
			goto out;
		}

		if (!rsa)
#endif
		{
			printf("RSA_generate_key_ex return %ld\n", ERR_get_error());
			goto out;
		}

		RSA_set_method(rsa, RSA_PKCS1_OpenSSL());

		if(!i2d_RSAPrivateKey_bio(mem, rsa))
		{
			printf("i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error());
			goto out;
		}

		lg = BIO_get_mem_data(mem, &pdata);

		sc_format_path("0001", &path);
		r = sc_select_file(card, &path, NULL);
		if(r)
		{
			if(r != SC_ERROR_FILE_NOT_FOUND) goto out;

			file = sc_file_new();
			if(file == NULL)
			{
				printf("Not enougth memory.\n");
				goto out;
			}

			file->type = SC_FILE_TYPE_WORKING_EF;
			file->ef_structure = SC_FILE_EF_TRANSPARENT;
			file->shareable = 0;

			file->size = ((lg/4)+1)*4;

			r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_CHV, 0);
			if(r) goto out;
			r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0);
			if(r) goto out;
			r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0);
			if(r) goto out;

			file->path = path;

			printf("File key creation %s, size %"SC_FORMAT_LEN_SIZE_T"d.\n",
			       file->path.value,
			       file->size);

			r = sc_create_file(card, file);
			if(r) goto out;
		}
		else
		{
			if(!overwrite)
			{
				printf("Key file already exist,"\
						" use -o to replace it.\n");
				goto out;
			}
		}

		printf("Private key length is %"SC_FORMAT_LEN_SIZE_T"d\n", lg);

		printf("Write private key.\n");
		r = sc_update_binary(card,0,pdata,lg,0);
		if(r<0) goto out;
		printf("Private key correctly written.\n");

		r = create_file_cert(card);
		if(r) goto out;

		{
			const BIGNUM *rsa_n, *rsa_e;

			RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);

			if (!do_convert_bignum(&dst->modulus, rsa_n)
			 || !do_convert_bignum(&dst->exponent, rsa_e))
				goto out;

		}

		r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg);
		if(r) goto out;

		printf("Public key length %"SC_FORMAT_LEN_SIZE_T"d\n", lg);

		sc_format_path("3F000002", &path);
		r = sc_select_file(card, &path, NULL);
		if(r) goto out;

		printf("Write public key.\n");
		r = sc_update_binary(card,0,pdata,lg,0);
		if(r<0) goto out;
		printf("Public key correctly written.\n");

	}

	if(cert)
	{
		BIO *bio;
		X509 *xp;
		u8 *pdata;

		bio = BIO_new(BIO_s_file());
		if (BIO_read_filename(bio, cert) <= 0)
		{
			BIO_free(bio);
			printf("Can't open file %s.\n", cert);
			goto out;
		}
		xp = PEM_read_bio_X509(bio, NULL, NULL, NULL);
		BIO_free(bio);
		if (xp == NULL)
		{
			print_openssl_error();
			goto out;
		}
		else
		{
			int lg = cert2der(xp, &pdata);

			sc_format_path("0002", &path);
			r = sc_select_file(card, &path, NULL);
			if(r) goto out;

			/* FIXME: verify if the file has a compatible size... */
			printf("Write certificate %s.\n", cert);

			r = sc_update_binary(card,0,pdata,lg,0);
			if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
			{
				if(verify_pin(card, 0, pin))
				{
					printf("Wrong pin.\n");
				}
				else
				{
					r = sc_update_binary(card,0,pdata,lg,0);
				}
			}
			if(r<0)
			{
				if(pdata) free(pdata);
				goto out;
			}
			if(xp) X509_free(xp);
			if(pdata) free(pdata);

			printf("Certificate correctly written.\n");
		}
	}

	if(finalize)
	{
		int mode = SC_CARDCTRL_LIFECYCLE_USER;

		if(card->atr.value[10] != 0x82)
		{
			sc_format_path("0001", &path);
			r = sc_select_file(card, &path, NULL);
			if(r)
			{
				printf("This card don't have private key"\
					" and can't be finalize.\n");
				goto out;
			}
			printf("Finalize card...\n");
			if(sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL) ||
				sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &mode))
			{
				printf("Error finalizing card,"\
					" card isn't secure.\n");
				goto out;
			}
		}
		printf("Card correctly finalized.\n");
	}

	if(get_filename)
	{
		FILE *fp;
		u8 *b;

		if(file)
		{
			sc_file_free(file);
			file = NULL;
		}

		sc_format_path(get_filename, &path);
		r = sc_select_file(card, &path, &file);
		if(r)
		{
				printf("Error file not found.\n");
				goto out;
		}

		b = malloc(file->size);
		if(b == NULL)
		{
				printf("Not enougth memory.\n");
				goto out;
		}

		r = sc_read_binary(card, 0, b, file->size, 0);
		if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
		{
			if(verify_pin(card, 0, pin))
			{
				printf("Wrong pin.\n");
				goto out;
			}
			r = sc_read_binary(card, 0, b, file->size, 0);
		}

		if(r<0)
		{
				printf("Error reading file.\n");
				goto out;
		}

		fp = fopen(get_filename, "wb");
		fwrite(b, 1, file->size, fp);
		fclose(fp);

		free(b);
	}

	if(put_filename)
	{
		FILE *fp;
		u8 *b;

		if(file)
		{
			sc_file_free(file);
			file = NULL;
		}

		sc_format_path(put_filename, &path);
		r = sc_select_file(card, &path, &file);
		if(r)
		{
				printf("File not found.\n");
				goto out;
		}

		b = malloc(file->size);
		if(b == NULL)
		{
				printf("Not enougth memory.\n");
				goto out;
		}

		memset(b, 0, file->size);

		fp = fopen(put_filename, "rb");
		fread(b, 1, file->size, fp);
		fclose(fp);

		r = sc_update_binary(card, 0, b, file->size, 0);
		if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
		{
			if(verify_pin(card, 0, pin))
			{
				printf("Wrong pin.\n");
			}
			else
			{
				r = sc_update_binary(card, 0, b, file->size, 0);
			}
		}
		if(r<0)
		{
				free(b);
				printf("Error writing file.\n");
				goto out;
		}

		free(b);
	}

out:

	if(mem)
		BIO_free(mem);
	if(bn)
		BN_free(bn);
	if(rsa)
		RSA_free(rsa);

	if(file)
		sc_file_free(file);

	if (card)
	{
		sc_unlock(card);
		sc_disconnect_card(card);
	}

	sc_release_context(ctx);

	return EXIT_SUCCESS;
}
Exemple #18
0
/*
 * Generate key
 */
static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
						sc_pkcs15_card_t *p15card,
						sc_pkcs15_object_t *obj,
						sc_pkcs15_pubkey_t *pubkey)
{
#ifndef ENABLE_OPENSSL
	return SC_ERROR_NOT_SUPPORTED;
#else
	int r = SC_ERROR_UNKNOWN;
	long lg;
	u8 *p;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	RSA *rsa = NULL;
	BIGNUM *bn = NULL;
	BIO *mem = NULL;

	sc_file_t *prkf = NULL;

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		return SC_ERROR_NOT_SUPPORTED;
	}

#if OPENSSL_VERSION_NUMBER>=0x00908000L
	rsa = RSA_new();
	bn = BN_new();
	mem = BIO_new(BIO_s_mem());

	if(rsa == NULL || bn == NULL || mem == NULL)
	{
		r = SC_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	if(!BN_set_word(bn, RSA_F4) ||
		!RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL))
#else
	mem = BIO_new(BIO_s_mem());

	if(mem == NULL)
	{
		r = SC_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL);
	if (!rsa)
#endif
	{
		r = SC_ERROR_UNKNOWN;
		goto out;
	}

	RSA_set_method(rsa, RSA_PKCS1_OpenSSL());

	if(pubkey != NULL)
	{
		if(!i2d_RSAPublicKey_bio(mem, rsa))
		{
			r = SC_ERROR_UNKNOWN;
			goto out;
		}

		lg = BIO_get_mem_data(mem, &p);

		pubkey->algorithm = SC_ALGORITHM_RSA;

		r = sc_pkcs15_decode_pubkey(p15card->card->ctx, pubkey, p, lg);
		if (r < 0)
			goto out;
	}

	(void) BIO_reset(mem);

	if(!i2d_RSAPrivateKey_bio(mem, rsa))
	{
		r = SC_ERROR_UNKNOWN;
		goto out;
	}

	lg = BIO_get_mem_data(mem, &p);

	/* Get the private key file */
	r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf);
	if (r < 0)
	{
		char pbuf[SC_MAX_PATH_STRING_SIZE];

		r = sc_path_print(pbuf, sizeof(pbuf), &key_info->path);
		if (r != SC_SUCCESS)
			pbuf[0] = '\0';

		goto out;
	}

	prkf->size = lg;

	r = sc_pkcs15init_create_file(profile, p15card, prkf);
	if(r) goto out;

	r = sc_pkcs15init_update_file(profile, p15card, prkf, p, lg);
	if(r) goto out;

out:
	if(mem)
		BIO_free(mem);
	if(bn)
		BN_free(bn);
	if(rsa)
		RSA_free(rsa);
	sc_file_free(prkf);

	return r;
#endif
}
Exemple #19
0
PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url,
					PKCS11_HANDLER *lib, void *driver) {

	PKI_RSA_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_MECHANISM * RSA_MECH_PTR = NULL;

	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;

	char *id     = NULL;
	int   id_len = 8; 

	int idx = 0;

	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_RSA_KEY_MIN_SIZE ) {
			PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL);
		} else {
			bits = (CK_ULONG) kp->bits;
		}
	} else {
		bits = PKI_RSA_KEY_DEFAULT_SIZE;
	}

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

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

			// Set the pointer to the supported mechanism
			RSA_MECH_PTR = &RSA_MECH_LIST[idx];

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

			// Breaks out of the loop
			break;

		} else {

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

	// If no key gen algors are supported, abort
	if (RSA_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_RSA_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("HSM_PKCS11_KEYPAIR_new()::Generating a new Key ... ");
	rv = lib->callbacks->C_GenerateKeyPair (
			lib->session, RSA_MECH_PTR, 
			pubTemp, n,
			privTemp, i,
			handler_pubkey, 
			handler_privkey);

	if( rv != CKR_OK ) {
		if ( rv == CKR_MECHANISM_INVALID ) {
			PKI_log_err("HSM_PKCS11_KEYPAIR_new()::RSA Algorithm "
				"is not supported by the Token" );
		} else {
			PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::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 = RSA_new()) == NULL ) {
		goto err;
	};
	
	if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session,
			CKA_PUBLIC_EXPONENT, (void **) &data, 
						&size, lib ) != PKI_OK ) {
		goto err;
	};

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	RSA_set0_key(ret, NULL, BN_bin2bn( data, (int) size, NULL), NULL);
#else
	ret->e = BN_bin2bn( data, (int) size, NULL );
#endif
	PKI_Free ( data );
	data = NULL;

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

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	RSA_set0_key(ret, BN_bin2bn(data, (int) size, NULL), NULL, NULL);
#else
	ret->n = BN_bin2bn( data, (int) size, NULL );
#endif
	PKI_Free ( data );
	data = NULL;

	/* Let's get the Attributes from the Keypair and store into the
	   key's pointer */
	RSA_set_method( ret, HSM_PKCS11_get_rsa_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 */
	RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver );
	RSA_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey );
	RSA_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 ) RSA_free ((RSA *) ret );

	if ( handler_pubkey ) {
		if((rv = lib->callbacks->C_DestroyObject( lib->session, 
					*handler_pubkey )) != CKR_OK ) {
		PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::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 ("HSM_PKCS11_KEYPAIR_new()::Failed to delete "
			"privkey object");
		};
		PKI_Free ( handler_privkey );
	}

	PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Key material DELETED!");

	return ( NULL );

}
static int
sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
{
	int r;
	sc_pkcs15_cert_t *cert = NULL;
	struct sc_priv_data *priv = NULL;
	sc_pkcs15_cert_info_t *cinfo = cert_obj->data;

	X509 *x509 = NULL;
	EVP_PKEY *pubkey = NULL;
	u8 *p;
	char *tmp;

	debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
	r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
	if (r) {
		logit("Certificate read failed: %s", sc_strerror(r));
		goto err;
	}
	x509 = X509_new();
	if (x509 == NULL) {
		r = -1;
		goto err;
	}
	p = cert->data;
	if (!d2i_X509(&x509, &p, cert->data_len)) {
		logit("Unable to parse X.509 certificate");
		r = -1;
		goto err;
	}
	sc_pkcs15_free_certificate(cert);
	cert = NULL;
	pubkey = X509_get_pubkey(x509);
	X509_free(x509);
	x509 = NULL;
	if (pubkey->type != EVP_PKEY_RSA) {
		logit("Public key is of unknown type");
		r = -1;
		goto err;
	}
	k->rsa = EVP_PKEY_get1_RSA(pubkey);
	EVP_PKEY_free(pubkey);

	k->rsa->flags |= RSA_FLAG_SIGN_VER;
	RSA_set_method(k->rsa, sc_get_rsa_method());
	priv = xmalloc(sizeof(struct sc_priv_data));
	priv->cert_id = cinfo->id;
	priv->ref_count = 1;
	RSA_set_app_data(k->rsa, priv);

	k->flags = KEY_FLAG_EXT;
	tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
	debug("fingerprint %d %s", key_size(k), tmp);
	xfree(tmp);

	return 0;
err:
	if (cert)
		sc_pkcs15_free_certificate(cert);
	if (pubkey)
		EVP_PKEY_free(pubkey);
	if (x509)
		X509_free(x509);
	return r;
}
Exemple #21
0
static int
collect_private_key(hx509_context context,
		    struct p11_module *p, struct p11_slot *slot,
		    CK_SESSION_HANDLE session,
		    CK_OBJECT_HANDLE object,
		    void *ptr, CK_ATTRIBUTE *query, int num_query)
{
    struct hx509_collector *collector = ptr;
    hx509_private_key key;
    heim_octet_string localKeyId;
    int ret;
    RSA *rsa;
    struct p11_rsa *p11rsa;

    localKeyId.data = query[0].pValue;
    localKeyId.length = query[0].ulValueLen;

    ret = _hx509_private_key_init(&key, NULL, NULL);
    if (ret)
	return ret;

    rsa = RSA_new();
    if (rsa == NULL)
	_hx509_abort("out of memory");

    /* 
     * The exponent and modulus should always be present according to
     * the pkcs11 specification, but some smartcards leaves it out,
     * let ignore any failure to fetch it.
     */
    rsa->n = getattr_bn(p, slot, session, object, CKA_MODULUS);
    rsa->e = getattr_bn(p, slot, session, object, CKA_PUBLIC_EXPONENT);

    p11rsa = calloc(1, sizeof(*p11rsa));
    if (p11rsa == NULL)
	_hx509_abort("out of memory");

    p11rsa->p = p;
    p11rsa->slot = slot;
    p11rsa->private_key = object;
    
    p->refcount++;
    if (p->refcount == 0)
	_hx509_abort("pkcs11 refcount to high");

    RSA_set_method(rsa, &p11_rsa_pkcs1_method);
    ret = RSA_set_app_data(rsa, p11rsa);
    if (ret != 1)
	_hx509_abort("RSA_set_app_data");

    _hx509_private_key_assign_rsa(key, rsa);

    ret = _hx509_collector_private_key_add(context,
					   collector,
					   hx509_signature_rsa(),
					   key,
					   NULL,
					   &localKeyId);

    if (ret) {
	_hx509_private_key_free(&key);
	return ret;
    }
    return 0;
}
Exemple #22
0
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
{
    HCERTSTORE cs;
    X509 *cert = NULL;
    RSA *rsa = NULL, *pub_rsa;
    CAPI_DATA *cd = calloc(1, sizeof(*cd));
    RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method));

    if (cd == NULL || my_rsa_method == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
	goto err;
    }
    /* search CURRENT_USER first, then LOCAL_MACHINE */
    cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER |
		       CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
    if (cs == NULL) {
	CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
	goto err;
    }
    cd->cert_context = find_certificate_in_store(cert_prop, cs);
    CertCloseStore(cs, 0);
    if (!cd->cert_context) {
	cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE |
			   CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
	if (cs == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
	    goto err;
	}
	cd->cert_context = find_certificate_in_store(cert_prop, cs);
	CertCloseStore(cs, 0);
	if (cd->cert_context == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE);
	    goto err;
	}
    }

    /* cert_context->pbCertEncoded is the cert X509 DER encoded. */
    cert = d2i_X509(NULL, (unsigned char **) &cd->cert_context->pbCertEncoded,
		    cd->cert_context->cbCertEncoded);
    if (cert == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB);
	goto err;
    }

    /* set up stuff to use the private key */
#ifdef __MINGW32_VERSION
    /* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1
     * anyway. This is a hack around that problem. */
    if (crypt32dll == NULL) {
	crypt32dll = LoadLibrary("crypt32");
	if (crypt32dll == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_LOAD_LIBRARY);
	    goto err;
	}
    }
    if (CryptAcquireCertificatePrivateKey == NULL) {
	CryptAcquireCertificatePrivateKey = GetProcAddress(crypt32dll,
		"CryptAcquireCertificatePrivateKey");
	if (CryptAcquireCertificatePrivateKey == NULL) {
	    CRYPTOAPIerr(CRYPTOAPI_F_GET_PROC_ADDRESS);
	    goto err;
	}
    }
#endif
    if (!CryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
	    NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) {
	/* if we don't have a smart card reader here, and we try to access a
	 * smart card certificate, we get:
	 * "Error 1223: The operation was canceled by the user." */
	CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY);
	goto err;
    }
    /* here we don't need to do CryptGetUserKey() or anything; all necessary key
     * info is in cd->cert_context, and then, in cd->crypt_prov.  */

    my_rsa_method->name = "Microsoft CryptoAPI RSA Method";
    my_rsa_method->rsa_pub_enc = rsa_pub_enc;
    my_rsa_method->rsa_pub_dec = rsa_pub_dec;
    my_rsa_method->rsa_priv_enc = rsa_priv_enc;
    my_rsa_method->rsa_priv_dec = rsa_priv_dec;
    /* my_rsa_method->init = init; */
    my_rsa_method->finish = finish;
    my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK;
    my_rsa_method->app_data = (char *) cd;

    rsa = RSA_new();
    if (rsa == NULL) {
	SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
	goto err;
    }

    /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(),
     * so we do it here then...  */
    if (!SSL_CTX_use_certificate(ssl_ctx, cert))
	goto err;
    /* the public key */
    pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
    /* SSL_CTX_use_certificate() increased the reference count in 'cert', so
     * we decrease it here with X509_free(), or it will never be cleaned up. */
    X509_free(cert);
    cert = NULL;

    /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */
    /* rsa->n indicates the key size */
    rsa->n = BN_dup(pub_rsa->n);
    rsa->flags |= RSA_FLAG_EXT_PKEY;
    if (!RSA_set_method(rsa, my_rsa_method))
	goto err;

    if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
	goto err;
    /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so
     * we decrease it here with RSA_free(), or it will never be cleaned up. */
    RSA_free(rsa);
    return 1;

  err:
    if (cert)
	X509_free(cert);
    if (rsa)
	RSA_free(rsa);
    else {
	if (my_rsa_method)
	    free(my_rsa_method);
	if (cd) {
	    if (cd->free_crypt_prov && cd->crypt_prov)
		CryptReleaseContext(cd->crypt_prov, 0);
	    if (cd->cert_context)
		CertFreeCertificateContext(cd->cert_context);
	    free(cd);
	}
    }
    return 0;
}
static int
set_private_key(hx509_context context, hx509_cert cert, SecKeyRef pkey)
{
    const SubjectPublicKeyInfo *spi;
    const Certificate *c;
    struct kc_rsa *kc;
    RSAPublicKey pk;
    hx509_private_key key;
    size_t size;
    RSA *rsa;
    int ret;

    ret = hx509_private_key_init(&key, NULL, NULL);
    if (ret)
	return ret;

    kc = calloc(1, sizeof(*kc));
    if (kc == NULL)
	_hx509_abort("out of memory");

    CFRetain(pkey);
    kc->pkey = pkey;

    rsa = RSA_new();
    if (rsa == NULL)
	_hx509_abort("out of memory");

    RSA_set_method(rsa, &kc_rsa_pkcs1_method);
    ret = RSA_set_app_data(rsa, kc);
    if (ret != 1)
	_hx509_abort("RSA_set_app_data");

    /*
     * Set up n and e to please RSA_size()
     */

    c = _hx509_get_cert(cert);
    spi = &c->tbsCertificate.subjectPublicKeyInfo;

    ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
			      spi->subjectPublicKey.length / 8,
			      &pk, &size);
    if (ret) {
	RSA_free(rsa);
	return 0;
    }
    rsa->n = _hx509_int2BN(&pk.modulus);
    rsa->e = _hx509_int2BN(&pk.publicExponent);
    free_RSAPublicKey(&pk);

    kc->keysize = BN_num_bytes(rsa->n);

    /*
     *
     */

    hx509_private_key_assign_rsa(key, rsa);
    _hx509_cert_set_key(cert, key);

    hx509_private_key_free(&key);

    return 0;
}
Exemple #24
0
CK_RV
gpkcs11_add_credentials(char *label,
			const char *cert_file,
			const char *private_key_file,
			char *id,
			int anchor)
{
    struct gpkcs11_st_object *o = NULL;
    CK_BBOOL bool_true = CK_TRUE;
    CK_BBOOL bool_false = CK_FALSE;
    CK_OBJECT_CLASS c;
    CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
    CK_KEY_TYPE key_type;
    CK_MECHANISM_TYPE mech_type;
    CK_RV ret = CKR_GENERAL_ERROR;
    void *subject_data = NULL;
    size_t subject_length;
    X509 *cert, *proxy_cert = NULL;
    EVP_PKEY *public_key;
    FILE *f = NULL;
    size_t id_len = strlen(id);

    f = fopen(cert_file, "r");
    if (f == NULL) {
	gpkcs11_log("failed to open file %s\n", cert_file);
	return CKR_GENERAL_ERROR;
    }

    while (1) {
	cert = PEM_read_X509(f, NULL, NULL, NULL);
	if (cert == NULL) {
	    if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
		break;
	    ret = CKR_GENERAL_ERROR;
	    goto out;
	}
	if (proxy_cert == NULL)
	    proxy_cert = cert;
	ret = gpkcs11_add_certificate(label, cert, id, anchor);
	if (ret)
	    goto out;
    }

    public_key = X509_get_pubkey(proxy_cert);
    switch (EVP_PKEY_type(public_key->type)) {
    case EVP_PKEY_RSA:
	key_type = CKK_RSA;
	break;
    case EVP_PKEY_DSA:
	key_type = CKK_DSA;
	break;
    default:
	/* XXX */
	break;
    }

    OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length, 
			       X509_get_subject_name(proxy_cert), ret);
    if (ret)
	goto out;


    if (private_key_file) {
	CK_FLAGS flags;
	FILE *f;

	o = add_st_object();
	if (o == NULL) {
	    ret = CKR_DEVICE_MEMORY;
	    goto out;
	}
	o->type = STO_T_PRIVATE_KEY;
	o->u.private_key.file = strdup(private_key_file);
	o->u.private_key.key = NULL;

	o->u.private_key.cert = proxy_cert;

	c = CKO_PRIVATE_KEY;
	add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
	add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
	add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
	add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));

	add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
	add_object_attribute(o, 0, CKA_ID, id, id_len);
	add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
	add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
	add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
	add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
	mech_type = CKM_RSA_X_509;
	add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));

	add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
	add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
	flags = 0;
	add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));

	add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
	add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
	add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));

	add_pubkey_info(o, key_type, public_key);

	f = fopen(private_key_file, "r");
	if (f == NULL) {
	    gpkcs11_log("failed to open private key\n");
	    return CKR_GENERAL_ERROR;
	}

	o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL);
	fclose(f);
	if (o->u.private_key.key == NULL) {
	    gpkcs11_log("failed to read private key a startup\n");
	    /* don't bother with this failure for now, 
	       fix it at C_Login time */;
	} else {
	    /* XXX verify keytype */

	    if (key_type == CKK_RSA)
		RSA_set_method(o->u.private_key.key->pkey.rsa, 
			       RSA_PKCS1_SSLeay());

	    if (X509_check_private_key(proxy_cert, o->u.private_key.key) != 1) {
		EVP_PKEY_free(o->u.private_key.key);	    
		o->u.private_key.key = NULL;
		gpkcs11_log("private key doesn't verify\n");
	    } else {
		gpkcs11_log("private key usable\n");
		gpkcs11_soft_token.flags.login_done = 1;
	    }
	}
    }

    ret = CKR_OK;
 out:
    if (ret != CKR_OK) {
	gpkcs11_log("something went wrong when adding cert!\n");

	/* XXX wack o */;
    }

    if (f)
	fclose(f);

    return ret;
}