void digidoc::PKCS11Signer::unloadDriver() { if(d->ctx == NULL) return; if(d->slots != NULL) { // Release all slots. PKCS11_release_all_slots(d->ctx, d->slots, d->numberOfSlots); d->slots = NULL; } // Release PKCS #11 context. PKCS11_CTX_unload(d->ctx); PKCS11_CTX_free(d->ctx); d->ctx = NULL; }
/* Finish engine operations initialized with pkcs11_init() */ int pkcs11_finish(ENGINE_CTX *ctx) { if (ctx) { if (ctx->slot_list) { PKCS11_release_all_slots(ctx->pkcs11_ctx, ctx->slot_list, ctx->slot_count); ctx->slot_list = NULL; ctx->slot_count = 0; } if (ctx->pkcs11_ctx) { /* Modules cannot be unloaded in pkcs11_finish() nor * pkcs11_destroy() because of a deadlock in PKCS#11 * modules that internally use OpenSSL engines. * A memory leak is better than a deadlock... */ /* PKCS11_CTX_unload(ctx->pkcs11_ctx); */ PKCS11_CTX_free(ctx->pkcs11_ctx); ctx->pkcs11_ctx = NULL; } } return 1; }
int pkcs11_finish(ENGINE_CTX *ctx) { if (ctx) { if (ctx->slot_list) { PKCS11_release_all_slots(ctx->pkcs11_ctx, ctx->slot_list, ctx->slot_count); } if (ctx->pkcs11_ctx) { PKCS11_CTX_unload(ctx->pkcs11_ctx); PKCS11_CTX_free(ctx->pkcs11_ctx); } destroy_pin(ctx); OPENSSL_free(ctx->module); OPENSSL_free(ctx->init_args); #if OPENSSL_VERSION_NUMBER >= 0x10100004L CRYPTO_THREAD_lock_free(ctx->rwlock); #else if (ctx->rwlock) CRYPTO_destroy_dynlockid(ctx->rwlock); #endif OPENSSL_free(ctx); } return 1; }
static int tap11_store_cert( const char *libp11, const char *pin, const char *certid, const char *certfile) { int rc; unsigned int nslots; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *cert; X509 *x509; BIO *bio; p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx,libp11); if (rc) { fprintf(stderr,"PKCS11_CTX_load\n"); return -1; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr,"PKCS11_enumerate_slots\n"); return -1; } /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { fprintf(stderr,"PKCS11_find_token\n"); return -1; } fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer); fprintf(stderr,"Slot description.......: %s\n", slot->description); fprintf(stderr,"Slot token label.......: %s\n", slot->token->label); fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer); fprintf(stderr,"Slot token model.......: %s\n", slot->token->model); fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr); rc = PKCS11_open_session(slot, 1); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_open_session %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_login(slot, 0, pin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_login %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } /* load cert */ if ((bio = BIO_new(BIO_s_file())) == NULL) { fprintf(stderr,"BIO_new\n"); return -1; } if (BIO_read_filename(bio,certfile) <= 0) { fprintf(stderr,"BIO_read_filename\n"); return -1; } x509 = PEM_read_bio_X509_AUX(bio,NULL, NULL, NULL); if (x509 == NULL) { fprintf(stderr,"PKCS11_enumerate_certs\n"); return -1; } /* store cert */ rc = PKCS11_store_certificate(slot->token,x509, (char*)certid,(unsigned char*)certid,strlen(certid),&cert); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_store_certificate %s rc:%d\n", ERR_reason_error_string(ERR_get_error()),rc); return -1; } X509_free(x509); BIO_free(bio); PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); fprintf(stderr,"\n\nstore cert succeed\n"); return 0; }
int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs; PKCS11_KEY *authkey; PKCS11_CERT *authcert; EVP_PKEY *pubkey = NULL; unsigned char *random = NULL, *signature = NULL; char password[20]; int rc = 0, fd; unsigned int nslots, ncerts, siglen; if (argc < 2) { fprintf(stderr, "usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n", argv[0]); return 1; } do_fork(); ctx = PKCS11_CTX_new(); error_queue("PKCS11_CTX_new"); /* load pkcs #11 module */ do_fork(); rc = PKCS11_CTX_load(ctx, argv[1]); error_queue("PKCS11_CTX_load"); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ do_fork(); rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); error_queue("PKCS11_enumerate_slots"); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } /* get first slot with a token */ do_fork(); slot = PKCS11_find_token(ctx, slots, nslots); error_queue("PKCS11_find_token"); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); if (!slot->token->loginRequired) goto loggedin; /* get password */ if (argc > 2) { strcpy(password, argv[2]); } else { exit(1); } loggedin: /* perform pkcs #11 login */ do_fork(); rc = PKCS11_login(slot, 0, password); error_queue("PKCS11_login"); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); goto failed; } /* get all certs */ do_fork(); rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); error_queue("PKCS11_enumerate_certs"); if (rc) { fprintf(stderr, "PKCS11_enumerate_certs failed\n"); goto failed; } if (ncerts <= 0) { fprintf(stderr, "no certificates found\n"); goto failed; } /* use the first cert */ authcert=&certs[0]; /* get random bytes */ random = OPENSSL_malloc(RANDOM_SIZE); if (random == NULL) goto failed; fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); goto failed; } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); goto failed; } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); goto failed; } close(fd); do_fork(); authkey = PKCS11_find_key(authcert); error_queue("PKCS11_find_key"); if (authkey == NULL) { fprintf(stderr, "no key matching certificate available\n"); goto failed; } /* ask for a sha1 hash of the random data, signed by the key */ siglen = MAX_SIGSIZE; signature = OPENSSL_malloc(MAX_SIGSIZE); if (signature == NULL) goto failed; /* do the operations in child */ do_fork(); rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen, authkey); error_queue("PKCS11_sign"); if (rc != 1) { fprintf(stderr, "fatal: pkcs11_sign failed\n"); goto failed; } /* verify the signature */ pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); goto failed; } /* now verify the result */ rc = RSA_verify(NID_sha1, random, RANDOM_SIZE, signature, siglen, pubkey->pkey.rsa); if (rc != 1) { fprintf(stderr, "fatal: RSA_verify failed\n"); goto failed; } if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) OPENSSL_free(random); if (signature != NULL) OPENSSL_free(signature); PKCS11_release_all_slots(ctx, slots, nslots); PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); printf("authentication successfull.\n"); return 0; failed: notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); printf("authentication failed.\n"); return 1; }
int main(int argc, char *argv[]) { PKCS11_CTX *ctx=NULL; PKCS11_SLOT *slots=NULL, *slot; PKCS11_KEY *keys; unsigned int nslots, nkeys; char password[20]; int rc = 0; if (argc < 2) { fprintf(stderr, "usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n", argv[0]); return 1; } ctx = PKCS11_CTX_new(); error_queue("PKCS11_CTX_new"); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); error_queue("PKCS11_CTX_load"); CHECK_ERR(rc < 0, "loading pkcs11 engine failed", 1); /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); error_queue("PKCS11_enumerate_slots"); CHECK_ERR(rc < 0, "no slots available", 2); /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); error_queue("PKCS11_find_token"); CHECK_ERR(!slot || !slot->token, "no token available", 3); printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get public keys */ rc = PKCS11_enumerate_public_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_public_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_public_keys failed", 4); CHECK_ERR(nkeys == 0, "No public keys found", 5); list_keys("Public keys", keys, nkeys); if (slot->token->loginRequired && argc > 2) { strcpy(password, argv[2]); /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, password); error_queue("PKCS11_login"); memset(password, 0, strlen(password)); CHECK_ERR(rc < 0, "PKCS11_login failed", 6); } /* get private keys */ rc = PKCS11_enumerate_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_keys failed", 7); CHECK_ERR(nkeys == 0, "No private keys found", 8); list_keys("Private keys", keys, nkeys); end: if (slots) PKCS11_release_all_slots(ctx, slots, nslots); if (ctx) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); if (rc) printf("Failed (error code %d).\n", rc); else printf("Success.\n"); return rc; }
void openconnect_vpninfo_free(struct openconnect_info *vpninfo) { openconnect_close_https(vpninfo, 1); if (vpninfo->proto->udp_shutdown) vpninfo->proto->udp_shutdown(vpninfo); if (vpninfo->tncc_fd != -1) closesocket(vpninfo->tncc_fd); if (vpninfo->cmd_fd_write != -1) { closesocket(vpninfo->cmd_fd); closesocket(vpninfo->cmd_fd_write); } #ifdef HAVE_ICONV if (vpninfo->ic_utf8_to_legacy != (iconv_t)-1) iconv_close(vpninfo->ic_utf8_to_legacy); if (vpninfo->ic_legacy_to_utf8 != (iconv_t)-1) iconv_close(vpninfo->ic_legacy_to_utf8); #endif #ifdef _WIN32 if (vpninfo->cmd_event) CloseHandle(vpninfo->cmd_event); if (vpninfo->ssl_event) CloseHandle(vpninfo->ssl_event); if (vpninfo->dtls_event) CloseHandle(vpninfo->dtls_event); #endif free(vpninfo->peer_addr); free(vpninfo->ip_info.gateway_addr); free_optlist(vpninfo->csd_env); free_optlist(vpninfo->script_env); free_optlist(vpninfo->cookies); free_optlist(vpninfo->cstp_options); free_optlist(vpninfo->dtls_options); free_split_routes(vpninfo); free(vpninfo->hostname); free(vpninfo->unique_hostname); free(vpninfo->urlpath); free(vpninfo->redirect_url); free(vpninfo->cookie); free(vpninfo->proxy_type); free(vpninfo->proxy); free(vpninfo->proxy_user); free(vpninfo->proxy_pass); free(vpninfo->vpnc_script); free(vpninfo->cafile); free(vpninfo->ifname); free(vpninfo->dtls_cipher); #ifdef OPENCONNECT_GNUTLS gnutls_free(vpninfo->cstp_cipher); /* In OpenSSL this is const */ #ifdef HAVE_DTLS gnutls_free(vpninfo->gnutls_dtls_cipher); #endif #endif free(vpninfo->dtls_addr); if (vpninfo->csd_scriptname) { unlink(vpninfo->csd_scriptname); free(vpninfo->csd_scriptname); } free(vpninfo->mobile_platform_version); free(vpninfo->mobile_device_type); free(vpninfo->mobile_device_uniqueid); free(vpninfo->csd_token); free(vpninfo->csd_ticket); free(vpninfo->csd_stuburl); free(vpninfo->csd_starturl); free(vpninfo->csd_waiturl); free(vpninfo->csd_preurl); free(vpninfo->platname); if (vpninfo->opaque_srvdata) xmlFreeNode(vpninfo->opaque_srvdata); free(vpninfo->profile_url); free(vpninfo->profile_sha1); /* These are const in openconnect itself, but for consistency of the library API we do take ownership of the strings we're given, and thus we have to free them too. */ if (vpninfo->cert != vpninfo->sslkey) free((void *)vpninfo->sslkey); free((void *)vpninfo->cert); if (vpninfo->peer_cert) { #if defined(OPENCONNECT_OPENSSL) X509_free(vpninfo->peer_cert); #elif defined(OPENCONNECT_GNUTLS) gnutls_x509_crt_deinit(vpninfo->peer_cert); #endif vpninfo->peer_cert = NULL; } while (vpninfo->pin_cache) { struct pin_cache *cache = vpninfo->pin_cache; free(cache->token); memset(cache->pin, 0x5a, strlen(cache->pin)); free(cache->pin); vpninfo->pin_cache = cache->next; free(cache); } free(vpninfo->peer_cert_sha1); free(vpninfo->peer_cert_sha256); free(vpninfo->localname); free(vpninfo->useragent); free(vpninfo->authgroup); #ifdef HAVE_LIBSTOKEN if (vpninfo->stoken_pin) free(vpninfo->stoken_pin); if (vpninfo->stoken_ctx) stoken_destroy(vpninfo->stoken_ctx); #endif if (vpninfo->oath_secret) { #ifdef HAVE_LIBPSKC if (vpninfo->pskc) pskc_done(vpninfo->pskc); else #endif /* HAVE_LIBPSKC */ free(vpninfo->oath_secret); } #ifdef HAVE_LIBPCSCLITE if (vpninfo->token_mode == OC_TOKEN_MODE_YUBIOATH) { SCardDisconnect(vpninfo->pcsc_card, SCARD_LEAVE_CARD); SCardReleaseContext(vpninfo->pcsc_ctx); } memset(vpninfo->yubikey_pwhash, 0, sizeof(vpninfo->yubikey_pwhash)); free(vpninfo->yubikey_objname); #endif #ifdef HAVE_LIBP11 if (vpninfo->pkcs11_ctx) { if (vpninfo->pkcs11_slot_list) PKCS11_release_all_slots(vpninfo->pkcs11_ctx, vpninfo->pkcs11_slot_list, vpninfo->pkcs11_slot_count); PKCS11_CTX_unload(vpninfo->pkcs11_ctx); PKCS11_CTX_free(vpninfo->pkcs11_ctx); } free(vpninfo->pkcs11_cert_id); #endif /* These check strm->state so they are safe to call multiple times */ inflateEnd(&vpninfo->inflate_strm); deflateEnd(&vpninfo->deflate_strm); free(vpninfo->deflate_pkt); free(vpninfo->tun_pkt); free(vpninfo->dtls_pkt); free(vpninfo->cstp_pkt); free(vpninfo); }
static int tap11_change_pin( const char *p11lib, int is_so, const char *pin, const char *newpin) { int rc = 0; unsigned int nslots; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx,p11lib); if (rc) { fprintf(stderr,"PKCS11_CTX_load\n"); return -1; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr,"PKCS11_enumerate_slots\n"); return -1; } /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { fprintf(stderr,"PKCS11_find_token\n"); return -1; } fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer); fprintf(stderr,"Slot description.......: %s\n", slot->description); fprintf(stderr,"Slot token label.......: %s\n", slot->token->label); fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer); fprintf(stderr,"Slot token model.......: %s\n", slot->token->model); fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr); /* rw mode */ rc = PKCS11_open_session(slot, 1); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_open_session %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_login(slot, is_so, pin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_init_login %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } rc = PKCS11_change_pin(slot,pin,newpin); if (rc != 0) { ERR_load_PKCS11_strings(); fprintf(stderr,"PKCS11_change_pin %s\n", ERR_reason_error_string(ERR_get_error())); return -1; } PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); fprintf(stderr,"\n\npin change succeed\n"); return 0; }
PKI_MEM_STACK *URL_get_data_pkcs11_url ( URL *url, ssize_t size ) { #ifdef HAVE_P11 // PKCS11_CTX *ctx = NULL; PKCS11_SLOT *slots = NULL; PKCS11_TOKEN *tk = NULL; char *libfile = NULL; int num = 0; int i = 0; char * search_label = NULL; char * search_id = NULL; char * search_slot = NULL; char * search_slotid = NULL; PKI_MEM *tmp_mem = NULL; PKI_MEM_STACK *sk = NULL; if( !url ) return (NULL); /* if((libfile = pkcs11_parse_url_libpath ( url )) == NULL ) { return( NULL ); } */ /* slot = pkcs11_parse_url_slot ( url ); id = pkcs11_parse_url_id ( url ); */ if( ctx == NULL ) { if((ctx = PKCS11_CTX_new ()) == NULL ) { return(NULL); } PKI_log_debug("Loading %s Library", url->addr ); if(( i = PKCS11_CTX_load(ctx, url->addr)) != 0 ) { PKI_log_err("Can not load library %s [err::%d]", url->addr, i); // ERR_print_errors_fp( stderr ); } } if( PKCS11_enumerate_slots( ctx, &slots, &num ) == -1 ) { PKI_log_err ("Can not enumerate slots"); goto err; }; if(( sk = PKI_STACK_MEM_new()) == NULL ) { goto err; } search_slot = pkcs11_parse_url_getval( url, "slot" ); search_slotid = pkcs11_parse_url_getval( url, "slotid" ); search_label = pkcs11_parse_url_getval( url, "label" ); search_id = pkcs11_parse_url_getval( url, "id" ); if( search_slot ) PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOT => %s\n", search_slot); if( search_slotid ) PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOTID => %s\n", search_slotid); if( search_label ) PKI_log_debug("DEBUG::PKCS11::SEARCH::LABEL => %s\n", search_label); if( search_id ) PKI_log_debug("DEBUG::PKCS11::SEARCH::ID => %s\n", search_id); for(i = 0; i < num; i++ ) { BIO *mem = NULL; BUF_MEM *mem_buf = NULL; PKCS11_CERT *certs = NULL; PKCS11_SLOT *p = NULL; PKCS11_CERT *x = NULL; PKCS11_KEY *keyList = NULL; PKCS11_KEY *key = NULL; EVP_PKEY *evp_pkey = NULL; int n = 0; int t = 0; int n_objs = 0; int p_ret = 0; p = &slots[i]; if((!p) || ((tk = p->token) == NULL) ) { continue; } if( (search_slot) && ( strncmp_nocase( search_slot, tk->label, strlen(search_slot) == 0) )) { continue; } if( (search_slotid) && ( atoi(search_slotid) != i )) { PKI_log_debug("PKCS11::SLOTID is %s (%d), curr is %d\n", search_slotid, atoi(search_slotid), i); continue; } if( strncmp_nocase( url->attrs, "cert", 4 ) == 0) { PKI_log_debug("PKCS11::CERT DATATYPE SELECTED!\n"); if((mem = BIO_new(BIO_s_mem())) == NULL ) { goto err; } /* Get the list of certificates in the slot */ p_ret = PKCS11_enumerate_certs( tk, &certs, &n_objs); for( n = 0; n < n_objs; n++ ) { /* Pointer to the current certificate */ x = &certs[n]; PKI_log_debug("PKCS11::CERT label=%s\n", x->label); PKI_log_debug("PKCS11::CERT id="); for( t = 0; t < x->id_len; t ++ ) { printf("%c", x->id[t] ); } printf("\n"); if( (search_label) && (strncmp_nocase( search_label, x->label, strlen( search_label)) != 0 )){ PKI_log_debug("PKCS11::LABEL does not" "match, SKIPPING!!!!\n"); continue; } if( search_id ) { int stop = 0; for( t = 0; t < x->id_len; t ++ ) { if( search_id[t] != x->id[t] ) { stop = 1; break; } } if( stop == 1 ) { printf("DEBUG::PKCS11::ID does not" "match, SKIPPING!!!!\n"); continue; } } /* Write the cert in PEM format to memory */ p_ret = PEM_write_bio_X509( mem, x->x509 ); /* Get the pointer to the memory buffer */ BIO_get_mem_ptr( mem, &mem_buf ); /* Push a PKI_MEM buffer on the stack */ tmp_mem = PKI_MEM_new_null(); PKI_MEM_add ( tmp_mem, mem_buf->data, mem_buf->length); PKI_STACK_push( sk, tmp_mem ); } /* Free the temp memory buffer */ if( mem ) BIO_free( mem ); } else if (strncmp_nocase( url->attrs, "key", 3) == 0 ) { char *pin = NULL; PKI_log_debug("PKCS11::KEY DATATYPE SELECTED!\n"); pin = pkcs11_parse_url_getval( url, "pin" ); if ( (tk->loginRequired == 1) && (pin != NULL ) ) { p_ret = PKCS11_login ( p, 0, pin ); PKI_log_debug("PKCS11::LOGIN Result %d\n", p_ret ); } if((mem = BIO_new(BIO_s_mem())) == NULL ) { goto err; } p_ret = PKCS11_enumerate_keys ( tk, &keyList, &n_objs ); for( n = 0; n < n_objs; n++ ) { key = &keyList[n]; printf("DEBUG::PKCS11::KEY label=%s\n", key->label); printf("DEBUG::PKCS11::KEY id="); for( t = 0; t < key->id_len; t ++ ) { printf("%c", key->id[t] ); } printf("\n"); if( (search_label) && (strncmp_nocase( search_label, x->label, strlen( search_label)) != 0 )){ printf("DEBUG::PKCS11::LABEL does not" "match, SKIPPING!!!!\n"); continue; } if( search_id ) { int stop = 0; for( t = 0; t < x->id_len; t ++ ) { if( search_id[t] != x->id[t] ) { stop = 1; break; } } if( stop == 1 ) { printf("DEBUG::PKCS11::ID does not" "match, SKIPPING!!!!\n"); continue; } } /* Get Private Key in OpenSSL format */ evp_pkey = PKCS11_get_private_key( key ); /* Write the cert in PEM format to memory */ p_ret = PEM_write_bio_PUBKEY( mem, evp_pkey ); /* Get the pointer to the memory buffer */ BIO_get_mem_ptr( mem, &mem_buf ); /* Push a PKI_MEM buffer on the stack */ tmp_mem = PKI_MEM_new_null(); PKI_MEM_add ( tmp_mem, mem_buf->data, mem_buf->length); PKI_STACK_push( sk, tmp_mem ); } if( mem ) BIO_free ( mem ); } else { printf("DEBUG::PKCS11::OTHER DATATYPE SELECTED!\n"); } } err: if( slots ) PKCS11_release_all_slots( ctx, slots, num ); /* if( ctx ) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } */ if( libfile ) PKI_Free (libfile); if( search_slot ) PKI_Free ( search_slot ); if( search_slotid ) PKI_Free ( search_slotid ); if( search_label ) PKI_Free ( search_label ); if( search_id ) PKI_Free ( search_id ); return ( sk ); #else return ( NULL ); #endif }
int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; unsigned char random[10]; int rc = 0, i, len; unsigned int nslots; if (argc != 2) { fprintf(stderr, "usage: getrandom /usr/lib/opensc-pkcs11.so\n"); return 1; } /* new context */ ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } printf("%d slots available\n", nslots); /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); if (!slot || !slot->token) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get 10 random bytes */ len = sizeof(random); rc = PKCS11_generate_random(slot, random, len); if (rc < 0) { fprintf(stderr, "generate_random failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 4; goto norandom; } printf("\nRandom numbers generated by the token: "); for (i = 0; i < len; i++) printf("%02X ", random[i]); printf("\n"); rc = 0; norandom: notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); return rc; }
/** * Finds all slots connected with the computer, if the slots have tokens, lists all * certificates found in token. If there are more that 1 certificate lets the user * application select (by calling the <code>selectSignCertificate</code> callback * function) the certificate used for signing. * * @return returns certificate used for signing. * @throws throws exception if failed to select the signing certificate. For example * no cards found or card has no certificate. */ X509* digidoc::PKCS11Signer::getCert() throw(SignException) { DEBUG("PKCS11Signer::getCert()"); // If certificate is already selected return it. if(d->sign.certificate != NULL && d->sign.slot != NULL) { return d->sign.certificate->x509; } // Set selected state to 'no certificate selected'. d->sign.certificate = NULL; d->sign.slot = NULL; if(d->slots != NULL) { // Release all slots. PKCS11_release_all_slots(d->ctx, d->slots, d->numberOfSlots); } // Load all slots. if(PKCS11_enumerate_slots(d->ctx, &d->slots, &d->numberOfSlots) != 0) { THROW_SIGNEXCEPTION("Could not find any ID-Cards in any readers: %s", ERR_reason_error_string(ERR_get_error())); } // Iterate over all found slots, if the slot has a token, check if the token has any certificates. std::vector<PKCS11Signer::PKCS11Cert> certificates; std::vector<SignSlot> certSlotMapping; for(unsigned int i = 0; i < d->numberOfSlots; i++) { PKCS11_SLOT* slot = d->slots + i; if(slot->token != NULL) { PKCS11_CERT* certs = NULL; unsigned int numberOfCerts = 0; if(PKCS11_enumerate_certs(slot->token, &certs, &numberOfCerts)) { // XXX: Should this throw an exception instead? WARN("Could not get certificates from token '%s'.", slot->token->label); continue; } // If no certificates on token skip the token. if(numberOfCerts <= 0) { continue; } // List all certificates found on this token. for(unsigned int j = 0; j < numberOfCerts; j++) { PKCS11_CERT* cert = certs + j; if(!d->checkCert(cert->x509)) break; SignSlot signSlot = { cert, slot }; certSlotMapping.push_back( signSlot ); certificates.push_back(d->createPKCS11Cert(slot, cert)); } } } if(certificates.size() == 0) { THROW_SIGNEXCEPTION("No certificates found."); } // Let the application select the signing certificate. X509* selectedCert = selectSigningCertificate(certificates).cert; if(selectedCert == NULL) { THROW_SIGNEXCEPTION("No certificate selected."); } // Find the corresponding slot and PKCS11 certificate struct. for(std::vector<SignSlot>::const_iterator iter = certSlotMapping.begin(); iter != certSlotMapping.end(); iter++) { if(iter->certificate->x509 == selectedCert) { d->sign = *iter; break; } } if(d->sign.certificate == NULL || d->sign.slot == NULL) { THROW_SIGNEXCEPTION("Could not find slot for selected certificate."); } return d->sign.certificate->x509; }
int main (int argc, char * const argv[]) { // insert code here... //std::cout << "Hello World!\n"; PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs; PKCS11_KEY *authkey; PKCS11_CERT *authcert; EVP_PKEY *pubkey = NULL; unsigned char *random = NULL, *signature = NULL; char password[20]; int rc = 0, fd; unsigned int nslots, ncerts, siglen; if (argc != 2) { printf("usage: auth /usr/lib/opensc-pkcs11.so\n"); //return 1; } ctx = PKCS11_CTX_new(); rc = PKCS11_CTX_load(ctx, "opensc-pkcs11.so");//argv[1]); if (rc) { printf("loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; PKCS11_CTX_free(ctx); return 0;//goto nolib; } // get information on all slots rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { printf("no slots available\n"); rc = 2; PKCS11_CTX_unload(ctx); return 0;//goto noslots; } // get first slot with a token slot = PKCS11_find_token(ctx, slots, nslots); if (!slot || !slot->token) { printf("no token available\n"); rc = 3; PKCS11_release_all_slots(ctx, slots, nslots); return 0;//goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { printf("PKCS11_enumerate_certs failed\n"); return 0;//goto failed; } if (ncerts <= 0) { printf("no certificates found\n"); return 0;//goto failed; } authcert=&certs[0]; if (!slot->token->loginRequired) return 0;//goto loggedin; /*struct termios old, new; if (tcgetattr(0, &old) != 0) goto failed; new = old; new.c_lflag &= ~ECHO; if (tcsetattr(0, TCSAFLUSH, &new) != 0) goto failed; printf("Password for token %.32s: ", slot->token->label); fgets(password, sizeof(password), stdin); (void)tcsetattr(0, TCSAFLUSH, &old); rc = strlen(password); if (rc <= 0) goto failed; password[rc-1]=0; rc = PKCS11_login(slot, 0, password); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); goto failed; } loggedin: random = malloc(RANDOM_SIZE); if (!random) goto failed; fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); goto failed; } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); goto failed; } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); goto failed; } close(fd); authkey = PKCS11_find_key(authcert); if (!authkey) { fprintf(stderr, "no key matching certificate available\n"); goto failed; } siglen = MAX_SIGSIZE; signature = malloc(MAX_SIGSIZE); if (!signature) goto failed; rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen, authkey); if (rc != 1) { fprintf(stderr, "fatal: pkcs11_sign failed\n"); goto failed; } pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); goto failed; } rc = RSA_verify(NID_sha1, random, RANDOM_SIZE, signature, siglen, pubkey->pkey.rsa); if (rc != 1) { fprintf(stderr, "fatal: RSA_verify failed\n"); goto failed; } if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) free(random); if (signature != NULL) free(signature); PKCS11_release_all_slots(ctx, slots, nslots); PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); ERR_remove_state(0); printf("authentication successfull.\n"); return 0; failed: ERR_print_errors_fp(stderr); notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); //----- */ std::cout << "end\n"; return 0; }
static Bool LoadEnginePKCS11(SSL_CTX *ctx, ENGINE **e, const char *p11lib, const char *slotstr) { char certid[PKCS11_BUF_SIZE]; char certidbuf[PKCS11_BUF_SIZE]; char pinbuf[PKCS11_BUF_SIZE]; char *pin = NULL; EVP_PKEY *key = NULL; X509 *x509 = NULL; int rc = 0; int i; unsigned int nslots,ncerts; int nslot = 0; PKCS11_CTX *p11ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs,*cert; pin = GetPasswordString(pinbuf, sizeof(pinbuf), PKCS11_ASKPIN_PROMPT); if (pin == NULL){ Message("PIN input was canceled\n"); return FALSE; } p11ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(p11ctx, p11lib); if (rc) { SSL_Error("loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); return FALSE; } /* get information on all slots */ rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots); if (rc < 0) { SSL_Error("no slots available\n"); return FALSE; } /* get certificate and keyid by PKCS#11 */ if (strcmp("",slotstr)){ nslot = atoi(slotstr); if (nslot < nslots) { slot = (PKCS11_SLOT*)&slots[nslot]; if (!slot || !slot->token) { SSL_Error("no token available\n"); return FALSE; } } else { SSL_Error("no token available\n"); return FALSE; } } else { /* get first slot with a token */ slot = PKCS11_find_token(p11ctx, slots, nslots); if (!slot || !slot->token) { SSL_Error("no token available\n"); return FALSE; } for(i=0;i<nslots;i++) { if (&slots[i] == slot) { nslot = i; } } } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, pin); if (rc != 0) { SSL_Error("PKCS11_login failed\n"); return FALSE; } /* get all certs */ rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { SSL_Error("PKCS11_enumerate_certs failed\n"); return FALSE; } if (ncerts <= 0) { SSL_Error("no certificates found\n"); return FALSE; } /* use the first cert */ cert=(PKCS11_CERT*)&certs[0]; sprintf(certid,"slot_%d-id_",nslot); for(i=0;i<cert->id_len;i++) { sprintf(certidbuf,"%02x",(unsigned int)(cert->id[i])); strcat(certid,certidbuf); } printf("id:[%s] label:%s [%p]\n",certid,cert->label,cert->x509); x509 = X509_dup(cert->x509); PKCS11_logout(slot); PKCS11_release_all_slots(p11ctx, slots, nslots); PKCS11_CTX_unload(p11ctx); PKCS11_CTX_free(p11ctx); /* setup OpenSSL ENGINE */ if (!(*e = InitEnginePKCS11(p11lib, pin))){ return FALSE; } if(!(key = ENGINE_load_private_key(*e, certid, NULL, NULL))) { SSL_Error(_d("ENGINE_load_private_key failure:\n %s\n"), GetSSLErrorString()); return FALSE; } /* set key and cert to SSL_CTX */ if (key){ if (!SSL_CTX_use_certificate_with_check(ctx, x509)){ SSL_Error(_d("SSL_CTX_use_certificate failure:\n %s"), GetSSLErrorString()); return FALSE; } if (!SSL_CTX_use_PrivateKey(ctx, key)){ SSL_Error(_d("SSL_CTX_use_PrivateKey failure:\n %s"), GetSSLErrorString()); return FALSE; } if (!SSL_CTX_check_private_key(ctx)){ SSL_Error(_d("SSL_CTX_check_private_key failure:\n %s\n"), GetSSLErrorString()); return FALSE; } } memset(pin, 0, sizeof(pinbuf)); return TRUE; }