Esempio n. 1
0
static int dasync_pub_dec(int flen, const unsigned char *from,
                    unsigned char *to, RSA *rsa, int padding) {
    /* Ignore errors - we carry on anyway */
    dummy_pause_job();
    return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())
        (flen, from, to, rsa, padding);
}
Esempio n. 2
0
static int dasync_rsa_priv_enc(int flen, const unsigned char *from,
                      unsigned char *to, RSA *rsa, int padding)
{
    /* Ignore errors - we carry on anyway */
    dummy_pause_job();
    return RSA_PKCS1_OpenSSL()->rsa_priv_enc(flen, from, to, rsa, padding);
}
Esempio n. 3
0
/*
 * This internal function is used by ENGINE_ubsec() and possibly by the
 * "dynamic" ENGINE support too
 */
static int bind_helper(ENGINE *e)
{
#  ifndef OPENSSL_NO_RSA
    const RSA_METHOD *meth1;
#  endif
#  ifndef OPENSSL_NO_DH
#   ifndef HAVE_UBSEC_DH
    const DH_METHOD *meth3;
#   endif                       /* HAVE_UBSEC_DH */
#  endif
    if (!ENGINE_set_id(e, engine_ubsec_id) ||
        !ENGINE_set_name(e, engine_ubsec_name) ||
#  ifndef OPENSSL_NO_RSA
        !ENGINE_set_RSA(e, &ubsec_rsa) ||
#  endif
#  ifndef OPENSSL_NO_DSA
        !ENGINE_set_DSA(e, &ubsec_dsa) ||
#  endif
#  ifndef OPENSSL_NO_DH
        !ENGINE_set_DH(e, &ubsec_dh) ||
#  endif
        !ENGINE_set_destroy_function(e, ubsec_destroy) ||
        !ENGINE_set_init_function(e, ubsec_init) ||
        !ENGINE_set_finish_function(e, ubsec_finish) ||
        !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
        !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
        return 0;

#  ifndef OPENSSL_NO_RSA
    /*
     * We know that the "PKCS1_OpenSSL()" functions hook properly to the
     * Broadcom-specific mod_exp and mod_exp_crt so we use those functions.
     * NB: We don't use ENGINE_openssl() or anything "more generic" because
     * something like the RSAref code may not hook properly, and if you own
     * one of these cards then you have the right to do RSA operations on it
     * anyway!
     */
    meth1 = RSA_PKCS1_OpenSSL();
    ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
    ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
    ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
    ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#  endif

#  ifndef OPENSSL_NO_DH
#   ifndef HAVE_UBSEC_DH
    /* Much the same for Diffie-Hellman */
    meth3 = DH_OpenSSL();
    ubsec_dh.generate_key = meth3->generate_key;
    ubsec_dh.compute_key = meth3->compute_key;
#   endif                       /* HAVE_UBSEC_DH */
#  endif

    /* Ensure the ubsec error handling is set up */
    ERR_load_UBSEC_strings();
    return 1;
}
Esempio n. 4
0
static int
cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
    struct crypt_kop kop;
    int ret = 1;

    if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
        /* XXX 0 means failure?? */
        return (0);
    }

    memset(&kop, 0, sizeof(kop));
    kop.crk_op = CRK_MOD_EXP_CRT;
    /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
    if (bn2crparam(rsa->p, &kop.crk_param[0]))
        goto err;
    if (bn2crparam(rsa->q, &kop.crk_param[1]))
        goto err;
    if (bn2crparam(I, &kop.crk_param[2]))
        goto err;
    if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
        goto err;
    if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
        goto err;
    if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
        goto err;
    kop.crk_iparams = 6;

    if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        printf("OCF asym process failed, running in Software\n");
        ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx);

    } else if (ECANCELED == kop.crk_status) {
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        printf("OCF hardware operation cancelled. Running in Software\n");
        ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx);
    }
    /* else cryptodev operation worked ok ==> ret = 1 */

 err:
    zapparams(&kop);
    return (ret);
}
Esempio n. 5
0
static int
cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
{
    struct crypt_kop kop;
    int ret = 1;

    /*
     * Currently, we know we can do mod exp iff we can do any asymmetric
     * operations at all.
     */
    if (cryptodev_asymfeat == 0) {
        ret = BN_mod_exp(r, a, p, m, ctx);
        return (ret);
    }

    memset(&kop, 0, sizeof(kop));
    kop.crk_op = CRK_MOD_EXP;

    /* inputs: a^p % m */
    if (bn2crparam(a, &kop.crk_param[0]))
        goto err;
    if (bn2crparam(p, &kop.crk_param[1]))
        goto err;
    if (bn2crparam(m, &kop.crk_param[2]))
        goto err;
    kop.crk_iparams = 3;

    if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        printf("OCF asym process failed, Running in software\n");
        ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);

    } else if (ECANCELED == kop.crk_status) {
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        printf("OCF hardware operation cancelled. Running in Software\n");
        ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
    }
    /* else cryptodev operation worked ok ==> ret = 1 */

 err:
    zapparams(&kop);
    return (ret);
}
Esempio n. 6
0
const RSA_METHOD *RSA_get_default_method(void)
{
    if (default_RSA_meth == NULL) {
#ifdef RSA_NULL
        default_RSA_meth = RSA_null_method();
#else
        default_RSA_meth = RSA_PKCS1_OpenSSL();
#endif
    }

    return default_RSA_meth;
}
Esempio n. 7
0
/*
 * This function is aliased to mod_exp (with the mont stuff dropped).
 */
static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                              const BIGNUM *m, BN_CTX *ctx,
                              BN_MONT_CTX *m_ctx)
{
    int ret = 0;

    /* Do in software if the key is too large for the hardware. */
    if (BN_num_bits(m) > max_key_len) {
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx);
    } else {
        ret = ubsec_mod_exp(r, a, p, m, ctx);
    }

    return ret;
}
Esempio n. 8
0
static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
                             BN_CTX *ctx)
{
    int to_return = 0;

    if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
        UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
        goto err;
    }

    to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
                                  rsa->dmq1, rsa->iqmp, ctx);
    if (to_return == FAIL_TO_SOFTWARE) {
        /*
         * Do in software as hardware failed.
         */
        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
        to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx);
    }
 err:
    return to_return;
}
Esempio n. 9
0
int neverbleed_init(neverbleed_t *nb, char *errbuf)
{
    int pipe_fds[2] = {-1, -1}, listen_fd = -1;
    char *tempdir = NULL;

#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100001L
    const RSA_METHOD *default_method = RSA_PKCS1_OpenSSL();
#else
    const RSA_METHOD *default_method = RSA_PKCS1_SSLeay();
#endif
    rsa_method.rsa_pub_enc = default_method->rsa_pub_enc;
    rsa_method.rsa_pub_dec = default_method->rsa_pub_dec;
    rsa_method.rsa_verify = default_method->rsa_verify;

    /* setup the daemon */
    if (pipe(pipe_fds) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno));
        goto Fail;
    }
    set_cloexec(pipe_fds[1]);
    if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory");
        goto Fail;
    }
    if (mkdtemp(tempdir) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno));
        goto Fail;
    }
    memset(&nb->sun_, 0, sizeof(nb->sun_));
    nb->sun_.sun_family = AF_UNIX;
    snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir);
    RAND_bytes(nb->auth_token, sizeof(nb->auth_token));
    if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno));
        goto Fail;
    }
    if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno));
        goto Fail;
    }
    if (listen(listen_fd, SOMAXCONN) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno));
        goto Fail;
    }
    nb->daemon_pid = fork();
    switch (nb->daemon_pid) {
    case -1:
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno));
        goto Fail;
    case 0:
        close(pipe_fds[1]);
#ifdef __linux__
        prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
#endif
        daemon_vars.nb = nb;
        daemon_main(listen_fd, pipe_fds[0], tempdir);
        break;
    default:
        break;
    }
    close(listen_fd);
    listen_fd = -1;
    close(pipe_fds[0]);
    pipe_fds[0] = -1;

    /* setup engine */
    if ((nb->engine = ENGINE_new()) == NULL || !ENGINE_set_id(nb->engine, "neverbleed") ||
        !ENGINE_set_name(nb->engine, "privilege separation software engine") || !ENGINE_set_RSA(nb->engine, &rsa_method)) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine");
        goto Fail;
    }
    ENGINE_add(nb->engine);

    /* setup thread key */
    pthread_key_create(&nb->thread_key, dispose_thread_data);

    free(tempdir);
    return 0;
Fail:
    if (pipe_fds[0] != -1)
        close(pipe_fds[0]);
    if (pipe_fds[1] != -1)
        close(pipe_fds[1]);
    if (tempdir != NULL) {
        unlink_dir(tempdir);
        free(tempdir);
    }
    if (listen_fd != -1)
        close(listen_fd);
    if (nb->engine != NULL) {
        ENGINE_free(nb->engine);
        nb->engine = NULL;
    }
    return -1;
}
Esempio n. 10
0
static int dasync_rsa_finish(RSA *rsa)
{
    return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa);
}
Esempio n. 11
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
}
Esempio n. 12
0
static int dasync_rsa_init(RSA *rsa)
{
    return RSA_PKCS1_OpenSSL()->init(rsa);
}
Esempio n. 13
0
static int dasync_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
    /* Ignore errors - we carry on anyway */
    dummy_pause_job();
    return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())(r0, I, rsa, ctx);
}
Esempio n. 14
0
void ENGINE_load_cryptodev(void)
{
    ENGINE *engine = ENGINE_new();
    int fd;

    if (engine == NULL)
        return;
    if ((fd = get_dev_crypto()) < 0) {
        ENGINE_free(engine);
        return;
    }

    /*
     * find out what asymmetric crypto algorithms we support
     */
    if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
        put_dev_crypto(fd);
        ENGINE_free(engine);
        return;
    }
    put_dev_crypto(fd);

    if (!ENGINE_set_id(engine, "cryptodev") ||
        !ENGINE_set_name(engine, "BSD cryptodev engine") ||
        !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
        !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
        !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
        !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
        ENGINE_free(engine);
        return;
    }

    if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
        const RSA_METHOD *rsa_meth = RSA_PKCS1_OpenSSL();

        cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
        cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
        cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
        cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
        cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
        cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
        if (cryptodev_asymfeat & CRF_MOD_EXP) {
            cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
            if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
                cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp;
            else
                cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp;
        }
    }

    if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
        const DSA_METHOD *meth = DSA_OpenSSL();

        memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
        if (cryptodev_asymfeat & CRF_DSA_SIGN)
            cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
        if (cryptodev_asymfeat & CRF_MOD_EXP) {
            cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
            cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
        }
        if (cryptodev_asymfeat & CRF_DSA_VERIFY)
            cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
    }

#ifndef OPENSSL_NO_DH
    if (ENGINE_set_DH(engine, &cryptodev_dh)) {
        const DH_METHOD *dh_meth = DH_OpenSSL();

        cryptodev_dh.generate_key = dh_meth->generate_key;
        cryptodev_dh.compute_key = dh_meth->compute_key;
        cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
        if (cryptodev_asymfeat & CRF_MOD_EXP) {
            cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
            if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
                cryptodev_dh.compute_key = cryptodev_dh_compute_key;
        }
    }
#endif

    ENGINE_add(engine);
    ENGINE_free(engine);
    ERR_clear_error();
}
Esempio n. 15
0
static int dasync_rsa_finish(RSA *rsa)
{
    return RSA_PKCS1_OpenSSL()->finish(rsa);
}
Esempio n. 16
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;
}
Esempio n. 17
0
/*
 * This internal function is used by ENGINE_ibmca() and possibly by the
 * "dynamic" ENGINE support too
 */
static int bind_helper(ENGINE *e)
{
#  ifndef OPENSSL_NO_RSA
    const RSA_METHOD *meth1;
#  endif
#  ifndef OPENSSL_NO_DSA
    const DSA_METHOD *meth2;
#  endif
#  ifndef OPENSSL_NO_DH
    const DH_METHOD *meth3;
#  endif
    if (!ENGINE_set_id(e, engine_ibmca_id) ||
        !ENGINE_set_name(e, engine_ibmca_name) ||
#  ifndef OPENSSL_NO_RSA
        !ENGINE_set_RSA(e, &ibmca_rsa) ||
#  endif
#  ifndef OPENSSL_NO_DSA
        !ENGINE_set_DSA(e, &ibmca_dsa) ||
#  endif
#  ifndef OPENSSL_NO_DH
        !ENGINE_set_DH(e, &ibmca_dh) ||
#  endif
        !ENGINE_set_RAND(e, &ibmca_rand) ||
        !ENGINE_set_destroy_function(e, ibmca_destroy) ||
        !ENGINE_set_init_function(e, ibmca_init) ||
        !ENGINE_set_finish_function(e, ibmca_finish) ||
        !ENGINE_set_ctrl_function(e, ibmca_ctrl) ||
        !ENGINE_set_cmd_defns(e, ibmca_cmd_defns))
        return 0;

#  ifndef OPENSSL_NO_RSA
    /*
     * We know that the "PKCS1_OpenSSL()" functions hook properly to the
     * ibmca-specific mod_exp and mod_exp_crt so we use those functions. NB:
     * We don't use ENGINE_openssl() or anything "more generic" because
     * something like the RSAref code may not hook properly, and if you own
     * one of these cards then you have the right to do RSA operations on it
     * anyway!
     */
    meth1 = RSA_PKCS1_OpenSSL();
    ibmca_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
    ibmca_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
    ibmca_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
    ibmca_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#  endif

#  ifndef OPENSSL_NO_DSA
    /*
     * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits.
     */
    meth2 = DSA_OpenSSL();
    ibmca_dsa.dsa_do_sign = meth2->dsa_do_sign;
    ibmca_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
    ibmca_dsa.dsa_do_verify = meth2->dsa_do_verify;
#  endif

#  ifndef OPENSSL_NO_DH
    /* Much the same for Diffie-Hellman */
    meth3 = DH_OpenSSL();
    ibmca_dh.generate_key = meth3->generate_key;
    ibmca_dh.compute_key = meth3->compute_key;
#  endif

    /* Ensure the ibmca error handling is set up */
    ERR_load_IBMCA_strings();
    return 1;
}
Esempio n. 18
0
/*
 * This internal function is used by ENGINE_chil() and possibly by the
 * "dynamic" ENGINE support too
 */
static int bind_helper(ENGINE *e)
{
#  ifndef OPENSSL_NO_RSA
    const RSA_METHOD *meth1;
#  endif
#  ifndef OPENSSL_NO_DH
    const DH_METHOD *meth2;
#  endif

    chil_lock = CRYPTO_THREAD_lock_new();
    if (chil_lock == NULL) {
        HWCRHKerr(HWCRHK_F_BIND_HELPER, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    if (!ENGINE_set_id(e, engine_hwcrhk_id) ||
        !ENGINE_set_name(e, engine_hwcrhk_name) ||
#  ifndef OPENSSL_NO_RSA
        !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
#  endif
#  ifndef OPENSSL_NO_DH
        !ENGINE_set_DH(e, &hwcrhk_dh) ||
#  endif
        !ENGINE_set_RAND(e, &hwcrhk_rand) ||
        !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
        !ENGINE_set_init_function(e, hwcrhk_init) ||
        !ENGINE_set_finish_function(e, hwcrhk_finish) ||
        !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
        !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
        !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
        !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
        return 0;

#  ifndef OPENSSL_NO_RSA
    /*
     * We know that the "PKCS1_OpenSSL()" functions hook properly to the
     * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB:
     * We don't use ENGINE_openssl() or anything "more generic" because
     * something like the RSAref code may not hook properly, and if you own
     * one of these cards then you have the right to do RSA operations on it
     * anyway!
     */
    meth1 = RSA_PKCS1_OpenSSL();
    hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
    hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
    hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
    hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#  endif

#  ifndef OPENSSL_NO_DH
    /* Much the same for Diffie-Hellman */
    meth2 = DH_OpenSSL();
    hwcrhk_dh.generate_key = meth2->generate_key;
    hwcrhk_dh.compute_key = meth2->compute_key;
#  endif

    /* Ensure the hwcrhk error handling is set up */
    ERR_load_HWCRHK_strings();

    return 1;
}