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; }
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; }
static EVP_PKEY *pkcs11_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, UI_METHOD * ui_method, void *callback_data, int isPrivate) { PKCS11_SLOT *slot; PKCS11_SLOT *found_slot = NULL; PKCS11_TOKEN *tok, *match_tok = NULL; PKCS11_KEY *keys, *selected_key = NULL; PKCS11_CERT *certs; EVP_PKEY *pk; unsigned int cert_count, key_count, n, m; unsigned char key_id[MAX_VALUE_LEN / 2]; size_t key_id_len = sizeof(key_id); char *key_label = NULL; int slot_nr = -1; char tmp_pin[MAX_PIN_LENGTH]; size_t tmp_pin_len = sizeof(tmp_pin); char flags[64]; if (pkcs11_init_libp11(ctx)) /* Delayed libp11 initialization */ return NULL; if (ctx->verbose) fprintf(stderr, "Loading %s key \"%s\"\n", (char *)(isPrivate ? "private" : "public"), s_slot_key_id); if (s_slot_key_id && *s_slot_key_id) { if (!strncmp(s_slot_key_id, "pkcs11:", 7)) { n = parse_pkcs11_uri(s_slot_key_id, &match_tok, key_id, &key_id_len, tmp_pin, &tmp_pin_len, &key_label); if (n && tmp_pin_len > 0 && tmp_pin[0] != 0) { destroy_pin(ctx); ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH * sizeof(char)); if (ctx->pin != NULL) { memset(ctx->pin, 0, MAX_PIN_LENGTH * sizeof(char)); memcpy(ctx->pin, tmp_pin, tmp_pin_len); ctx->pin_length = tmp_pin_len; } } if (!n) { fprintf(stderr, "The certificate ID is not a valid PKCS#11 URI\n" "The PKCS#11 URI format is defined by RFC7512\n"); return NULL; } } else { n = parse_slot_id_string(s_slot_key_id, &slot_nr, key_id, &key_id_len, &key_label); if (!n) { fprintf(stderr, "The certificate ID is not a valid PKCS#11 URI\n" "The PKCS#11 URI format is defined by RFC7512\n" "The legacy ENGINE_pkcs11 ID format is also " "still accepted for now\n"); return NULL; } } if (ctx->verbose) { fprintf(stderr, "Looking in slot %d for key: ", slot_nr); if (key_label == NULL) { for (n = 0; n < key_id_len; n++) fprintf(stderr, "%02x", key_id[n]); fprintf(stderr, "\n"); } else fprintf(stderr, "label: %s\n", key_label); } } for (n = 0; n < ctx->slot_count; n++) { slot = ctx->slot_list + n; flags[0] = '\0'; if (slot->token) { if (!slot->token->initialized) strcat(flags, "uninitialized, "); else if (!slot->token->userPinSet) strcat(flags, "no pin, "); if (slot->token->loginRequired) strcat(flags, "login, "); if (slot->token->readOnly) strcat(flags, "ro, "); } else { strcpy(flags, "no token"); } if ((m = strlen(flags)) != 0) { flags[m - 2] = '\0'; } if (slot_nr != -1 && slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) { found_slot = slot; } if (match_tok && slot->token && (match_tok->label == NULL || !strcmp(match_tok->label, slot->token->label)) && (match_tok->manufacturer == NULL || !strcmp(match_tok->manufacturer, slot->token->manufacturer)) && (match_tok->serialnr == NULL || !strcmp(match_tok->serialnr, slot->token->serialnr)) && (match_tok->model == NULL || !strcmp(match_tok->model, slot->token->model))) { found_slot = slot; } if (ctx->verbose) { fprintf(stderr, "[%lu] %-25.25s %-16s", PKCS11_get_slotid_from_slot(slot), slot->description, flags); if (slot->token) { fprintf(stderr, " (%s)", slot->token->label[0] ? slot->token->label : "no label"); } fprintf(stderr, "\n"); } } if (match_tok) { OPENSSL_free(match_tok->model); OPENSSL_free(match_tok->manufacturer); OPENSSL_free(match_tok->serialnr); OPENSSL_free(match_tok->label); OPENSSL_free(match_tok); } if (found_slot) { slot = found_slot; } else if (match_tok) { fprintf(stderr, "Specified object not found\n"); return NULL; } else if (slot_nr == -1) { if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx, ctx->slot_list, ctx->slot_count))) { fprintf(stderr, "No tokens found\n"); return NULL; } } else { fprintf(stderr, "Invalid slot number: %d\n", slot_nr); return NULL; } tok = slot->token; if (tok == NULL) { fprintf(stderr, "Found empty token\n"); return NULL; } /* The following check is non-critical to ensure interoperability * with some other (which ones?) PKCS#11 libraries */ if (!tok->initialized) fprintf(stderr, "Found uninitialized token\n"); if (isPrivate && !tok->userPinSet && !tok->readOnly) { fprintf(stderr, "Found slot without user PIN\n"); return NULL; } if (ctx->verbose) { fprintf(stderr, "Found slot: %s\n", slot->description); fprintf(stderr, "Found token: %s\n", slot->token->label); } if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) { fprintf(stderr, "Unable to enumerate certificates\n"); return NULL; } if (ctx->verbose) { fprintf(stderr, "Found %u certificate%s:\n", cert_count, (cert_count <= 1) ? "" : "s"); for (n = 0; n < cert_count; n++) { PKCS11_CERT *c = certs + n; char *dn = NULL; fprintf(stderr, " %2u %s", n + 1, c->label); if (c->x509) dn = X509_NAME_oneline(X509_get_subject_name(c->x509), NULL, 0); if (dn) { fprintf(stderr, " (%s)", dn); OPENSSL_free(dn); } fprintf(stderr, "\n"); } } if (isPrivate) { /* Perform login to the token if required */ if (!pkcs11_login(ctx, slot, tok, ui_method, callback_data)) { fprintf(stderr, "login to token failed, returning NULL...\n"); return NULL; } /* Make sure there is at least one private key on the token */ if (PKCS11_enumerate_keys(tok, &keys, &key_count)) { fprintf(stderr, "Unable to enumerate private keys\n"); return NULL; } } else { /* Make sure there is at least one public key on the token */ if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) { fprintf(stderr, "Unable to enumerate public keys\n"); return NULL; } } if (key_count == 0) { fprintf(stderr, "No %s keys found.\n", (char *)(isPrivate ? "private" : "public")); return NULL; } if (ctx->verbose) fprintf(stderr, "Found %u %s key%s:\n", key_count, (char *)(isPrivate ? "private" : "public"), (key_count == 1) ? "" : "s"); if (s_slot_key_id && *s_slot_key_id && (key_id_len != 0 || key_label != NULL)) { for (n = 0; n < key_count; n++) { PKCS11_KEY *k = keys + n; if (ctx->verbose) { fprintf(stderr, " %2u %c%c %s\n", n + 1, k->isPrivate ? 'P' : ' ', k->needLogin ? 'L' : ' ', k->label); } if (key_label == NULL) { if (key_id_len != 0 && k->id_len == key_id_len && memcmp(k->id, key_id, key_id_len) == 0) { selected_key = k; } } else { if (strcmp(k->label, key_label) == 0) { selected_key = k; } } } } else { selected_key = keys; /* Use the first key */ } if (selected_key == NULL) { fprintf(stderr, "Key not found.\n"); return NULL; } pk = isPrivate ? PKCS11_get_private_key(selected_key) : PKCS11_get_public_key(selected_key); if (key_label != NULL) OPENSSL_free(key_label); return pk; }
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; }
static X509 *pkcs11_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id) { PKCS11_SLOT *slot; PKCS11_SLOT *found_slot = NULL; PKCS11_TOKEN *tok, *match_tok = NULL; PKCS11_CERT *certs, *selected_cert = NULL; X509 *x509; unsigned int cert_count, n, m; unsigned char cert_id[MAX_VALUE_LEN / 2]; size_t cert_id_len = sizeof(cert_id); char *cert_label = NULL; char tmp_pin[MAX_PIN_LENGTH]; size_t tmp_pin_len = sizeof(tmp_pin); int slot_nr = -1; char flags[64]; if (pkcs11_init_libp11(ctx)) /* Delayed libp11 initialization */ return NULL; if (s_slot_cert_id && *s_slot_cert_id) { if (!strncmp(s_slot_cert_id, "pkcs11:", 7)) { n = parse_pkcs11_uri(s_slot_cert_id, &match_tok, cert_id, &cert_id_len, tmp_pin, &tmp_pin_len, &cert_label); if (n && tmp_pin_len > 0 && tmp_pin[0] != 0) { destroy_pin(ctx); ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH * sizeof(char)); if (ctx->pin != NULL) { memcpy(ctx->pin, tmp_pin, tmp_pin_len); ctx->pin_length = tmp_pin_len; } memset(ctx->pin, 0, MAX_PIN_LENGTH * sizeof(char)); } if (!n) { fprintf(stderr, "The certificate ID is not a valid PKCS#11 URI\n" "The PKCS#11 URI format is defined by RFC7512\n"); return NULL; } } else { n = parse_slot_id_string(s_slot_cert_id, &slot_nr, cert_id, &cert_id_len, &cert_label); if (!n) { fprintf(stderr, "The certificate ID is not a valid PKCS#11 URI\n" "The PKCS#11 URI format is defined by RFC7512\n" "The legacy ENGINE_pkcs11 ID format is also " "still accepted for now\n"); return NULL; } } if (ctx->verbose) { fprintf(stderr, "Looking in slot %d for certificate: ", slot_nr); if (cert_label == NULL) { for (n = 0; n < cert_id_len; n++) fprintf(stderr, "%02x", cert_id[n]); fprintf(stderr, "\n"); } else fprintf(stderr, "label: %s\n", cert_label); } } for (n = 0; n < ctx->slot_count; n++) { slot = ctx->slot_list + n; flags[0] = '\0'; if (slot->token) { if (!slot->token->initialized) strcat(flags, "uninitialized, "); else if (!slot->token->userPinSet) strcat(flags, "no pin, "); if (slot->token->loginRequired) strcat(flags, "login, "); if (slot->token->readOnly) strcat(flags, "ro, "); } else { strcpy(flags, "no token"); } if ((m = strlen(flags)) != 0) { flags[m - 2] = '\0'; } if (slot_nr != -1 && slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) { found_slot = slot; } if (match_tok && slot->token && (match_tok->label == NULL || !strcmp(match_tok->label, slot->token->label)) && (match_tok->manufacturer == NULL || !strcmp(match_tok->manufacturer, slot->token->manufacturer)) && (match_tok->serialnr == NULL || !strcmp(match_tok->serialnr, slot->token->serialnr)) && (match_tok->model == NULL || !strcmp(match_tok->model, slot->token->model))) { found_slot = slot; } if (ctx->verbose) { fprintf(stderr, "[%lu] %-25.25s %-16s", PKCS11_get_slotid_from_slot(slot), slot->description, flags); if (slot->token) { fprintf(stderr, " (%s)", slot->token->label[0] ? slot->token->label : "no label"); } fprintf(stderr, "\n"); } } if (match_tok) { OPENSSL_free(match_tok->model); OPENSSL_free(match_tok->manufacturer); OPENSSL_free(match_tok->serialnr); OPENSSL_free(match_tok->label); OPENSSL_free(match_tok); } if (found_slot) { slot = found_slot; } else if (match_tok) { fprintf(stderr, "Specified object not found\n"); return NULL; } else if (slot_nr == -1) { if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx, ctx->slot_list, ctx->slot_count))) { fprintf(stderr, "No tokens found\n"); return NULL; } } else { fprintf(stderr, "Invalid slot number: %d\n", slot_nr); return NULL; } tok = slot->token; if (tok == NULL) { fprintf(stderr, "Empty token found\n"); return NULL; } if (ctx->verbose) { fprintf(stderr, "Found slot: %s\n", slot->description); fprintf(stderr, "Found token: %s\n", slot->token->label); } /* In several tokens certificates are marked as private. We use the pin-value */ if (tok->loginRequired && ctx->pin) { /* Now login in with the (possibly NULL) pin */ if (PKCS11_login(slot, 0, ctx->pin)) { /* Login failed, so free the PIN if present */ destroy_pin(ctx); fprintf(stderr, "Login failed\n"); return NULL; } } if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) { fprintf(stderr, "Unable to enumerate certificates\n"); return NULL; } if (ctx->verbose) { fprintf(stderr, "Found %u cert%s:\n", cert_count, (cert_count <= 1) ? "" : "s"); } if ((s_slot_cert_id && *s_slot_cert_id) && (cert_id_len != 0 || cert_label != NULL)) { for (n = 0; n < cert_count; n++) { PKCS11_CERT *k = certs + n; if (cert_label == NULL) { if (cert_id_len != 0 && k->id_len == cert_id_len && memcmp(k->id, cert_id, cert_id_len) == 0) selected_cert = k; } else { if (strcmp(k->label, cert_label) == 0) selected_cert = k; } } } else { selected_cert = certs; /* Use the first certificate */ } if (selected_cert == NULL) { fprintf(stderr, "Certificate not found.\n"); return NULL; } x509 = X509_dup(selected_cert->x509); if (cert_label != NULL) OPENSSL_free(cert_label); return x509; }
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; }
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; }
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; }