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 clean(int argc, char **argv) { CK_UTF8CHAR_PTR opt_pin = NULL; CK_ULONG opt_pin_len = 0; CK_RV rc; CK_ULONG nslots, opt_slot = -1; CK_SLOT_ID *pslots = NULL; CK_SESSION_HANDLE h_session; char *opt_module = NULL, *opt_dir = NULL; int long_optind = 0, rw = 0, destroy = 0, i; char c; while (1) { c = getopt_long(argc, argv, "hrd:p:s:m:", 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 'r': rw = 1; 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) { /* TODO: Look in pslots */ pslots = &opt_slot; nslots = 1; } else { if(nslots == 1) { opt_slot = pslots[0]; } else { fprintf(stdout, "Found %ld slots, use --slot parameter to choose.\n", nslots); exit(-1); } } rc = pkcs11_login_session(funcs, stdout, opt_slot, &h_session, CK_TRUE, CKU_USER, opt_pin, opt_pin_len); free(opt_pin); if (rc != CKR_OK) { return rc; } CK_OBJECT_CLASS pkey = CKO_PRIVATE_KEY; CK_ATTRIBUTE search_all[] = { { CKA_CLASS, &pkey, sizeof(pkey)} }; CK_OBJECT_HANDLE all_keys[65536]; CK_ULONG key_count = sizeof(all_keys) / sizeof(CK_OBJECT_HANDLE); rc = funcs->C_FindObjectsInit(h_session, search_all, 1); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsInit", rc); return rc; } rc = funcs->C_FindObjects(h_session, all_keys, key_count, &key_count); if (rc != CKR_OK) { show_error(stdout, "C_FindObjects", rc); return rc; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsFinal", rc); return rc; } fprintf(stdout, "Found %lu private keys\n", key_count); for(i = 0; i < key_count; i++) { CK_BYTE id[32]; CK_OBJECT_CLASS crt = CKO_CERTIFICATE; CK_ATTRIBUTE search_crt[] = { { CKA_ID, &id, 32 }, { CKA_CLASS, &crt, sizeof(crt)} }; CK_OBJECT_HANDLE h_crt; CK_ULONG crt_count = 1; rc = funcs->C_GetAttributeValue(h_session, all_keys[i], search_crt, 1); if (rc != CKR_OK) { show_error(stdout, "C_GetAttributeValue", rc); return rc; } fprintf(stdout, "Handling key #%d with handle 0x%lx\n", i, all_keys[i]); dump_generic(stdout, "Key ID", id, search_crt[0].ulValueLen); rc = funcs->C_FindObjectsInit(h_session, search_crt, 2); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsInit", rc); return rc; } rc = funcs->C_FindObjects(h_session, &h_crt, 1, &crt_count); if (rc != CKR_OK) { show_error(stdout, "C_FindObjects", rc); return rc; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsFinal", rc); return rc; } if(crt_count == 0) { CK_OBJECT_CLASS pub = CKO_PUBLIC_KEY; CK_ATTRIBUTE search_pub[] = { { CKA_ID, &id, search_crt[0].ulValueLen }, { CKA_CLASS, &pub, sizeof(pub)} }; CK_OBJECT_HANDLE h_pub; CK_ULONG pub_count = 1; fprintf(stdout, "Didn't find matching certificate. Now looking for public key.\n"); rc = funcs->C_FindObjectsInit(h_session, search_pub, 2); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsInit", rc); return rc; } rc = funcs->C_FindObjects(h_session, &h_pub, 1, &pub_count); if (rc != CKR_OK) { show_error(stdout, "C_FindObjects", rc); return rc; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsFinal", rc); return rc; } if(pub_count == 0) { fprintf(stdout, "Didn't find matching public key. Skipping\n"); } else { if(!rw) { fprintf(stdout, "Read-only mode: Found candidate private key and public key with handles 0x%lx 0x%lx\n", all_keys[i], h_pub); } else { fprintf(stdout, "Deleting private key and public key with handles 0x%lx 0x%lx\n", all_keys[i], h_pub); rc = funcs->C_DestroyObject(h_session, all_keys[i]); if (rc != CKR_OK) { show_error(stdout, "C_DestroyObject", rc); } rc = funcs->C_DestroyObject(h_session, h_pub); if (rc != CKR_OK) { show_error(stdout, "C_DestroyObject", rc); } destroy += 2; } } } else { fprintf(stdout, "Found matching certificate\n"); } } pkey = CKO_SECRET_KEY; rc = funcs->C_FindObjectsInit(h_session, search_all, 1); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsInit", rc); return rc; } key_count = sizeof(all_keys) / sizeof(CK_OBJECT_HANDLE); rc = funcs->C_FindObjects(h_session, all_keys, key_count, &key_count); if (rc != CKR_OK) { show_error(stdout, "C_FindObjects", rc); return rc; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { show_error(stdout, "C_FindObjectsFinal", rc); return rc; } fprintf(stdout, "Found %lu secret keys\n", key_count); for(i = 0; i < key_count; i++) { rc = funcs->C_DestroyObject(h_session, all_keys[i]); if (rc != CKR_OK) { show_error(stdout, "C_DestroyObject", rc); } destroy += 1; } if(destroy > 0) { fprintf(stdout, "\nDeleted %d objects\n", destroy); } rc = pkcs11_close(stdout, funcs, h_session); return rc; }
int keygen(int argc, char **argv) { CK_ULONG nslots, keysize; CK_SLOT_ID *pslots = NULL; CK_FUNCTION_LIST *funcs = NULL; CK_SESSION_HANDLE h_session; CK_BYTE_PTR opt_label = NULL; CK_UTF8CHAR_PTR opt_pin = NULL; CK_ULONG opt_pin_len = 0; CK_ULONG opt_slot = -1; CK_RV rc; char *opt_module = NULL, *opt_dir = NULL; char *gen_param = NULL, *tmp; int long_optind = 0; int genkey = 0; char c; init_crypto(); while (1) { c = getopt_long(argc, argv, "d:hl:p:s:k:m:", options, &long_optind); if (c == -1) break; switch (c) { case 'd': opt_dir = optarg; break; case 'l': opt_label = (CK_BYTE_PTR)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 'k': gen_param = optarg; genkey = 1; break; case 'h': default: print_usage_and_die(app_name, options, option_help); } } if(!genkey) { 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; } } else { if(nslots == 1) { opt_slot = pslots[0]; } else { fprintf(stdout, "Found %ld slots, use --slot parameter to choose.\n", nslots); exit(-1); } } rc = pkcs11_login_session(funcs, stdout, opt_slot, &h_session, CK_TRUE, CKU_USER, opt_pin, opt_pin_len); free(opt_pin); if (rc != CKR_OK) { return rc; } fprintf(stdout, "Generating key with param '%s'\n", gen_param); keysize = strtol(gen_param, &tmp, 10); if(gen_param != tmp) { fprintf(stdout, "Generating RSA key with size %ld\n", keysize); rc = generateRsaKeyPair(funcs, h_session, keysize, opt_label); } else if(strncmp(gen_param, "gost", 4) == 0) { fprintf(stdout, "Generating GOST R34.10-2001 key (%s) in slot %ld\n", gen_param, opt_slot); rc = generateGostKeyPair(funcs, h_session, gen_param, opt_label); } else if((strncmp(gen_param, "secp", 4) == 0) || (strncmp(gen_param, "nistp", 5) == 0) || (strncmp(gen_param, "prime", 5) == 0) || (strncmp(gen_param, "ansiX9", 6) == 0)) { CK_BBOOL full; rc = ecdsaNeedsEcParams(funcs, opt_slot, &full); if(rc == CKR_OK) { fprintf(stdout, "Generating ECDSA key with curve '%s' " "in slot %ld with %s\n", gen_param, opt_slot, full ? "EC Parameters" : "Named Curve"); rc = generateEcdsaKeyPair(funcs, h_session, gen_param, full, opt_label); } } else if(strncmp(gen_param, "aes", 3) == 0) { if(strcmp(gen_param, "aes256") == 0) { fprintf(stdout, "Generating 256-bit AES key in slot %ld\n", opt_slot); generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 256 / 8, opt_label); } else if(strcmp(gen_param, "aes192") == 0) { fprintf(stdout, "Generating 192-bit AES key in slot %ld\n", opt_slot); generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 192 /8, opt_label); } else if((strcmp(gen_param, "aes128") == 0) || (strcmp(gen_param, "aes") == 0)) { fprintf(stdout, "Generating 128-bit AES key in slot %ld\n", opt_slot); generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 128 / 8, opt_label); } else { fprintf(stdout, "Unknown key type '%s'\n", gen_param); return -1; } } else if(strncmp(gen_param, "des3", 4) == 0) { fprintf(stdout, "Generating 3DES key in slot %ld\n", opt_slot); generateKey(funcs, h_session, CKK_DES3, CKM_DES3_KEY_GEN, 0, opt_label); } else { fprintf(stdout, "Unknown key type '%s'\n", gen_param); return -1; } rc = pkcs11_close(stdout, funcs, h_session); return rc; }