// 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()); }
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; }
/* * 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; }
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); }
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(); }
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; }
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; }
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); }
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; }
/* * 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 }
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; }
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; }
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; }
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; }