CK_FUNCTION_LIST * p11_init(void) { CK_RV rv; CK_RV (*pfoo)(); char *loc1_lib = "/usr/lib/pkcs11/PKCS11_API.so64"; char *loc2_lib = "libopencryptoki.so"; CK_FUNCTION_LIST *funcs = NULL; p11_lib = dlopen(loc1_lib, RTLD_NOW); if (p11_lib != NULL) goto get_list; p11_lib = dlopen(loc2_lib, RTLD_NOW); if (p11_lib == NULL) { print_error("Couldn't get a handle to the PKCS#11 library."); return NULL; } get_list: pfoo = (CK_RV (*)())dlsym(p11_lib,"C_GetFunctionList"); if (pfoo == NULL) { print_error("Couldn't get the address of the C_GetFunctionList routine."); dlclose(p11_lib); return NULL; } rv = pfoo(&funcs); if (rv != CKR_OK) { p11_error("C_GetFunctionList", rv); dlclose(p11_lib); return NULL; } rv = funcs->C_Initialize(NULL_PTR); if (rv != CKR_OK) { p11_error("C_Initialize", rv); dlclose(p11_lib); return NULL; } if (v_flag > 1) printf("PKCS#11 library initialized\n"); return funcs; }
int main(int argc, char **argv) { CK_ULONG nslots; CK_SLOT_ID *pslots = NULL; CK_FUNCTION_LIST *funcs = NULL; CK_UTF8CHAR_PTR opt_pin = NULL; CK_ULONG opt_pin_len = 0; CK_RV rc; CK_ULONG opt_slot = -1; CK_SESSION_HANDLE h_session; char *opt_module = NULL, *opt_dir = NULL; /* struct sockaddr_un sockaddr; */ int long_optind = 0; int fd, verbose = 0; key_id_t *rsa_keys, *ec_keys; CK_ULONG rsa_len = 0, ec_len = 0, i; init_crypto(); while (1) { char c = getopt_long(argc, argv, "d:hp:s:m:v", options, &long_optind); if (c == -1) break; switch (c) { case 'd': opt_dir = optarg; break; case 'p': opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg); if(opt_pin) { opt_pin_len = strlen(optarg); } break; case 's': opt_slot = (CK_SLOT_ID) atoi(optarg); break; case 'm': opt_module = optarg; break; case 'v': verbose = 1; break; case 'h': default: print_usage_and_die(app_name, options, option_help); } } rc = pkcs11_load_init(opt_module, opt_dir, stderr, &funcs); if (rc != CKR_OK) { return rc; } rc = pkcs11_get_slots(funcs, stderr, &pslots, &nslots); if (rc != CKR_OK) { return rc; } if(opt_slot == -1) { if(nslots < 1) { /* No slots */ return -1; } else { opt_slot = pslots[0]; } } else { /* Check selected slot is in pslots */ } fprintf(stderr, "Slot: %ld\n", opt_slot); rc = pkcs11_login_session(funcs, stderr, opt_slot, &h_session, CK_TRUE, CKU_USER, opt_pin, opt_pin_len); if (rc != CKR_OK) { show_error(stderr, "Login", rc); return rc; } load_keys(funcs, h_session, CKK_RSA, &rsa_keys, &rsa_len); load_keys(funcs, h_session, CKK_EC, &ec_keys, &ec_len); /* fd = nw_unix_server("pkcs11d.sock", &sockaddr, 0, 0, 0, 64); */ /* close(fd); */ fd = nw_tcp_server(1234, 0, 64); do { struct sockaddr address; socklen_t a_len = sizeof(address); int s = accept(fd, &address, &a_len); BIO *b = BIO_new_socket(s, BIO_NOCLOSE); BIO *buf = BIO_new(BIO_f_buffer()); b = BIO_push(buf, b); char buffer[4096], sig[4096], keyid[KEY_ID_SIZE + 1]; int l, slen = 0, plen = 0; CK_KEY_TYPE type; CK_ATTRIBUTE_TYPE operation; EVP_PKEY *pkey = NULL; l = BIO_gets(b, buffer, sizeof(buffer)); if(l <= 0) { fprintf(stderr, "Error reading query line\n"); goto end; } if(strncmp(buffer, "POST /sign/rsa/", 15) == 0) { memcpy(keyid, buffer + 15, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_SIGN; } else if(strncmp(buffer, "POST /decrypt/rsa/", 18) == 0) { memcpy(keyid, buffer + 18, KEY_ID_SIZE - 1); type = CKK_RSA; operation = CKA_DECRYPT; } else if(strncmp(buffer, "POST /sign/ec/", 14) == 0) { memcpy(keyid, buffer + 14, KEY_ID_SIZE - 1); type = CKK_EC; operation = CKA_SIGN; } else { goto end; } keyid[KEY_ID_SIZE] = '\0'; l = BIO_gets(b, buffer, sizeof(buffer)); if((l <= 0) || strncmp(buffer, "Content-Length: ", 16) != 0) { fprintf(stderr, "Invalid content length line = %s\n", buffer); goto end; } plen = atoi(buffer + 16); l = BIO_gets(b, buffer, sizeof(buffer)); l = BIO_read(b, buffer, plen); if(l < plen) { fprintf(stderr, "Error reading payload\n"); goto end; } if(type == CKK_RSA) { for(i = 0; (i < rsa_len) && (pkey == NULL); i++) { if(strncmp(rsa_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = rsa_keys[i].key; } } } else if(type == CKK_EC) { for(i = 0; (i < ec_len) && (pkey == NULL); i++) { if(strncmp(ec_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) { pkey = ec_keys[i].key; } } } if(pkey == NULL) { fprintf(stderr, "Key not found\n"); goto end; } else if(verbose) { fprintf(stderr, "Key '%s'found\n", keyid); } if(type == CKK_RSA && operation == CKA_SIGN) { if(verbose) { fprintf(stderr, "RSA signature operation requested\n"); } l = RSA_private_encrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if(type == CKK_RSA && operation == CKA_DECRYPT) { if(verbose) { fprintf(stderr, "RSA decryption operation requested\n"); } l = RSA_private_decrypt(plen, (unsigned char *)buffer, (unsigned char *)sig, EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING); } else if (type == CKK_EC && operation == CKA_SIGN) { unsigned char *ptr = (unsigned char *)sig; ECDSA_SIG *s = ECDSA_do_sign((unsigned char *)buffer, plen, EVP_PKEY_get1_EC_KEY(pkey)); l = i2d_ECDSA_SIG(s, &ptr); ECDSA_SIG_free(s); } else { if(verbose) { fprintf(stderr, "Invalid operation requested\n"); } goto end; } slen = l; if(l <= 0) { if(verbose) { fprintf(stderr, "Error unsuccessful\n"); } goto end; } else if(verbose) { fprintf(stderr, "Operation successful\n"); } BIO_printf(b, "200 Ok\r\n"); BIO_printf(b, "Content-Length: %d\r\n\r\n", slen); l = BIO_write(b, sig, slen); BIO_flush(b); i= 0; /* for(i = 0; i < rsa_len; i++) { BIO_write(b, rsa_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_RSAPrivateKey(b, EVP_PKEY_get1_RSA(rsa_keys[i].key), NULL, NULL, 0, NULL, NULL); } for(i = 0; i < ec_len; i++) { BIO_write(b, ec_keys[i].id, KEY_ID_SIZE); BIO_write(b, "\n", 1); PEM_write_bio_ECPrivateKey(b, EVP_PKEY_get1_EC_KEY(ec_keys[i].key), NULL, NULL, 0, NULL, NULL); } */ end: close(s); BIO_free(b); } while(1); close(fd); if(opt_pin) { funcs->C_CloseAllSessions(opt_slot); free(opt_pin); } rc = funcs->C_Finalize(NULL); if (rc != CKR_OK) { show_error(stderr, "C_Finalize", rc); return rc; } return rc; }
int mechanisms(int argc, char **argv) { CK_ULONG nslots, islot; CK_SLOT_ID *pslots = NULL; CK_FUNCTION_LIST *funcs = NULL; CK_RV rc; CK_ULONG opt_slot = -1; char *opt_module = NULL, *opt_dir = NULL; int long_optind = 0; while (1) { char c = getopt_long(argc, argv, "d:hs:m:", options, &long_optind); if (c == -1) break; switch (c) { case 'd': opt_dir = optarg; break; case 's': opt_slot = (CK_SLOT_ID) atoi(optarg); break; case 'm': opt_module = optarg; break; case 'h': default: print_usage_and_die(app_name, options, option_help); } } rc = pkcs11_load_init(opt_module, opt_dir, stdout, &funcs); if (rc != CKR_OK) { return rc; } rc = pkcs11_get_slots(funcs, stdout, &pslots, &nslots); if (rc != CKR_OK) { return rc; } if(opt_slot != -1) { CK_ULONG i = 0; while (i < nslots && pslots[i] != opt_slot) { i++; } if (i == nslots) { fprintf(stderr, "Unknown slot '%lu'\n", opt_slot); return -1; } pslots[0] = opt_slot; nslots = 1; } for (islot = 0; islot < nslots; islot++) { do_GetTokenMech(funcs, pslots[islot]); } rc = funcs->C_Finalize(NULL); if (rc != CKR_OK) { show_error(stdout, "C_Finalize", rc); return rc; } return rc; }
int main(int argc, char *argv[]) { int opt, c_flag = 0; CK_SLOT_ID slot_id = 0; char *so_pin = NULL, *user_pin = NULL, *data_store = NULL; CK_FUNCTION_LIST *funcs; CK_ULONG slot_count; CK_SESSION_HANDLE sess; CK_RV rv; struct object *objs_to_migrate = NULL, *tmp, *to_free; int exit_code = 0, rc; lib_csulcca = dlopen("libcsulcca.so", (RTLD_GLOBAL | RTLD_NOW)); if (lib_csulcca == NULL) { print_error("Couldn't get a handle to the CCA library."); return NULL; } CSNDKTC = dlsym(lib_csulcca, "CSNDKTC_32"); CSNBKTC = dlsym(lib_csulcca, "CSNBKTC_32"); while ((opt = getopt(argc, argv, "c:d:s:u:nvh")) != -1) { switch (opt) { case 'c': c_flag++; slot_id = atoi(optarg); break; case 'd': data_store = strdup(optarg); break; case 's': so_pin = strdup(optarg); break; case 'u': user_pin = strdup(optarg); break; case 'n': n_flag++; break; case 'v': v_flag++; break; case 'h': usage(argv[0]); return 0; default: usage(argv[0]); return 1; } } if (!c_flag || !data_store || !so_pin || !user_pin) { usage(argv[0]); return 1; } if (n_flag) printf("Dry-run of migration in progress\n"); funcs = p11_init(); if (!funcs) { return 2; } rv = funcs->C_GetSlotList(TRUE, NULL_PTR, &slot_count); if (rv != CKR_OK) { p11_error("C_GetSlotList", rv); exit_code = 3; goto finalize; } if (slot_id >= slot_count) { print_error("%lu is not a valid slot ID.", slot_id); exit_code = 4; goto finalize; } if (v_flag > 1) printf("Slot id %lu is valid\n", slot_id); /* Open a r/w session */ rv = funcs->C_OpenSession(slot_id, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &sess); if (rv != CKR_OK) { p11_error("C_OpenSession", rv); exit_code = 5; goto finalize; } if (v_flag > 1) printf("PKCS#11 r/w session opened\n"); /* Login as the SO just validate the supplied pin */ rv = funcs->C_Login(sess, CKU_SO, (CK_BYTE *)so_pin, strlen(so_pin)); if (rv != CKR_OK) { p11_error("C_Login (SO)", rv); exit_code = 6; goto finalize; } if (v_flag > 1) printf("PKCS#11 SO login successful\n"); /* Logout the SO */ rv = funcs->C_Logout(sess); if (rv != CKR_OK) { p11_error("C_Logout", rv); exit_code = 7; goto finalize; } /* Login as the USER to validate the supplied pin and do the migration */ rv = funcs->C_Login(sess, CKU_USER, (CK_BYTE *)user_pin, strlen(user_pin)); if (rv != CKR_OK) { p11_error("C_Login (USER)", rv); exit_code = 8; goto finalize; } if (v_flag > 1) printf("PKCS#11 USER login successful\n"); /* Find the affected PKCS#11 objects */ rc = find_opaque_objects(funcs, sess, &objs_to_migrate); if (rc) { exit_code = 9; goto close; } /* XXX Print status: migrating X pub keys, X priv keys, X 3DES keys... */ /* Use the CCA lib to migrate them to the new master key */ rv = migrate_objects(objs_to_migrate); if (rv != CKR_OK) { exit_code = 10; goto close; } /* XXX Print status */ /* Delete the old PKCS#11 objects (or just attribs if possible) and replace with the * migrated data */ rc = replace_objects(funcs, sess, objs_to_migrate); if (rc) { exit_code = 11; goto close; } /* XXX Print status: X objects successfully migrated */ /* Free the list of PKCS#11 objects */ for (to_free = objs_to_migrate; to_free; to_free = tmp) { tmp = to_free->next; free(to_free->opaque_attr); free(to_free); } /* Migrate the keys used to encrypt the data store */ rc = migrate_master_keys(so_pin, user_pin, data_store); if (rc) { exit_code = 12; goto close; } close: funcs->C_CloseSession(sess); finalize: p11_fini(funcs); return exit_code; }