📄 pkcs11-tool.c
字号:
p11_fatal("C_OpenSession", rv); rv = p11->C_GetSessionInfo(sess, &sessionInfo); if (rv != CKR_OK) p11_fatal("C_OpenSession", rv); if ((sessionInfo.state & CKS_RO_USER_FUNCTIONS) == 0) { printf("Key unwrap: not logged in, skipping key unwrap tests\n"); return errors; } firstMechType = find_mechanism(slot, CKF_UNWRAP | CKF_HW, 0); if (firstMechType == NO_MECHANISM) { printf("Unwrap: not implemented\n"); return errors; } printf("Key unwrap (RSA)\n"); for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) { printf(" testing key %ld ", j); if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) { printf("(%s) ", label); free(label); } if (!getUNWRAP(sess, privKeyObject)) { printf(" -- can't be used to unwrap, skipping\n"); continue; } printf("\n");#ifndef HAVE_OPENSSL printf("No OpenSSL support, unable to validate C_Unwrap\n");#else errors += wrap_unwrap(slot, sess, EVP_des_cbc(), privKeyObject); errors += wrap_unwrap(slot, sess, EVP_des_ede3_cbc(), privKeyObject); errors += wrap_unwrap(slot, sess, EVP_bf_cbc(), privKeyObject); errors += wrap_unwrap(slot, sess, EVP_cast5_cfb(), privKeyObject);#endif } return errors;}static inttest_random(CK_SLOT_ID slot){ CK_SESSION_HANDLE session; CK_BYTE buf1[100], buf2[100]; CK_BYTE seed1[100]; CK_RV rv; int errors = 0; printf("C_SeedRandom() and C_GenerateRandom():\n"); rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &session); if (rv != CKR_OK) p11_fatal("C_OpenSession", rv); rv = p11->C_SeedRandom(session, seed1, 10); if (rv == CKR_RANDOM_NO_RNG || rv == CKR_FUNCTION_NOT_SUPPORTED) { printf(" not implemented\n"); return 0; } if (rv == CKR_RANDOM_SEED_NOT_SUPPORTED) printf(" seeding (C_SeedRandom) not supported\n"); else if (rv != CKR_OK) { p11_perror("C_SeedRandom", rv); return 1; } rv = p11->C_GenerateRandom(session, buf1, 10); if (rv != CKR_OK) { p11_perror("C_GenerateRandom", rv); return 1; } rv = p11->C_GenerateRandom(session, buf1, 100); if (rv != CKR_OK) { p11_perror("C_GenerateRandom", rv); return 1; } rv = p11->C_GenerateRandom(session, buf1, 0); if (rv != CKR_OK) { p11_perror("C_GenerateRandom(,,0)", rv); return 1; } rv = p11->C_GenerateRandom(session, NULL, 100); if (rv != CKR_OK) { p11_perror("C_GenerateRandom(,NULL,)", rv); return 1; } if (memcmp(buf1, buf2, 100) == 0) { printf(" ERR: C_GenerateRandom returned twice the same value!!!\n"); errors++; } printf(" seems to be OK\n"); return 0;}static inttest_card_detection(int wait_for_event){ char buffer[256]; CK_SLOT_ID slot_id; CK_RV rv; printf("Testing card detection%s\n", wait_for_event? " using C_WaitForSlotEvent" : ""); while (1) { printf("Please press return to continue, x to exit: "); fflush(stdout); if (fgets(buffer, sizeof(buffer), stdin) == NULL || buffer[0] == 'x') break; if (wait_for_event) { printf("Calling C_WaitForSlotEvent: "); fflush(stdout); rv = p11->C_WaitForSlotEvent(0, &slot_id, NULL); if (rv != CKR_OK) { printf("failed.\n"); p11_perror("C_WaitForSlotEvent", rv); return 1; } printf("event on slot %u\n", (unsigned int) slot_id); } list_slots(); } return 0;}static intp11_test(CK_SLOT_ID slot, CK_SESSION_HANDLE session){ int errors = 0; errors += test_random(slot); errors += test_digest(slot); errors += test_signature(slot, session); errors += test_verify(slot, session); errors += test_unwrap(slot, session); errors += test_card_detection(0); errors += test_card_detection(1); if (errors == 0) printf("No errors\n"); else printf("%d errors\n", errors); return errors;}/* Does about the same as Mozilla does when you go to an on-line CA * for obtaining a certificate: key pair generation, signing the * cert request + some other tests, writing certs and changing * some attributes. */static voidtest_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session){ CK_MECHANISM mech = {CKM_RSA_PKCS, NULL_PTR, 0}; CK_MECHANISM_TYPE *mech_type = NULL; CK_OBJECT_HANDLE pub_key, priv_key; CK_ULONG i, num_mechs = 0; CK_RV rv; CK_BYTE buf[20], *tmp; CK_BYTE md5_and_digestinfo[34] = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; CK_BYTE *data, sig[512]; CK_ULONG data_len, sig_len; CK_BYTE *id = (CK_BYTE *) "abcdefghijklmnopqrst"; CK_ULONG id_len = 20; CK_BYTE *label = (CK_BYTE *) "Just a label"; CK_ULONG label_len = 12; CK_ATTRIBUTE attribs[3] = { {CKA_ID, id, id_len}, {CKA_LABEL, label, label_len}, {CKA_SUBJECT, (void *) "This won't be used in our lib", 29} }; FILE *f; get_mechanisms(slot, &mech_type, &num_mechs); for (i = 0; i < num_mechs; i++) { if (mech_type[i] == CKM_RSA_PKCS_KEY_PAIR_GEN) break; } if (i == num_mechs) { printf("ERR: no \"CKM_RSA_PKCS_KEY_PAIR_GEN\" found in the mechanism list\n"); return; } f = fopen(opt_file_to_write, "rb"); if (f == NULL) fatal("Couldn't open file \"%s\"\n", opt_file_to_write); fclose(f); /* Get for a not-yet-existing ID */ while(find_object(session, CKO_PRIVATE_KEY, &priv_key, id, id_len, 0)) id[0]++; printf("\n*** Generating a 1024 bit RSA key pair ***\n"); if (!gen_keypair(slot, session, &pub_key, &priv_key)) return; tmp = getID(session, priv_key, (CK_ULONG *) &opt_object_id_len); if (opt_object_id == NULL || opt_object_id_len == 0) { printf("ERR: newly generated private key has no (or an empty) CKA_ID\n"); return; } memcpy(opt_object_id, tmp, opt_object_id_len); printf("\n*** Changing the CKA_ID of private and public key into one of 20 bytes ***\n"); rv = p11->C_SetAttributeValue(session, priv_key, attribs, 1); if (rv != CKR_OK) p11_fatal("C_SetAttributeValue(priv_key)", rv); rv = p11->C_SetAttributeValue(session, pub_key, attribs, 1); if (rv != CKR_OK) p11_fatal("C_SetAttributeValue(pub_key)", rv); printf("\n*** Do a signature and verify it (presumably to test the keys) ***\n"); data = buf; data_len = 20; rv = p11->C_SignInit(session, &mech, priv_key); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); rv = p11->C_Sign(session, data, data_len, NULL, &sig_len); if (rv != CKR_OK) p11_fatal("C_Sign", rv); sig_len = 20; rv = p11->C_Sign(session, data, data_len, sig, &sig_len); if (rv != CKR_BUFFER_TOO_SMALL) { printf("ERR: C_Sign() didn't return CKR_BUFFER_TO_SMALL but %s\n", CKR2Str(rv)); return; } rv = p11->C_Sign(session, data, data_len, sig, &sig_len); if (rv != CKR_OK) p11_fatal("C_Sign", rv); rv = p11->C_VerifyInit(session, &mech, pub_key); if (rv != CKR_OK) p11_fatal("C_VerifyInit", rv); rv = p11->C_Verify(session, data, data_len, sig, sig_len); if (rv != CKR_OK) p11_fatal("C_Verify", rv); printf("\n*** Signing the certificate request ***\n"); /* Sign the certificate request */ data = md5_and_digestinfo; data_len = 20; rv = p11->C_SignInit(session, &mech, priv_key); rv = p11->C_Sign(session, data, data_len, sig, &sig_len); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); if (rv != CKR_OK) p11_fatal("C_Sign", rv); printf("\n*** In real life, the cert req should be sent to the CA ***\n"); printf("\n*** Changing the CKA_LABEL, CKA_ID and CKA_SUBJECT of the public key ***\n"); rv = p11->C_SetAttributeValue(session, pub_key, attribs, 3); if (rv != CKR_OK) p11_fatal("C_SetAttributeValue", rv); printf("\n*** Put a cert on the card (NOTE: doesn't correspond with the key!) ***\n"); opt_object_class = CKO_CERTIFICATE; memcpy(opt_object_id, id, id_len); opt_object_id_len = id_len; opt_object_label = (char *) label; if (!write_object(slot, session)) return; printf("\n==> OK, successfull! Should work with Mozilla\n"); }const char *p11_flag_names(struct flag_info *list, CK_FLAGS value){ static char buffer[1024]; const char *sepa = ""; buffer[0] = '\0'; while (list->value) { if (list->value & value) { strcat(buffer, sepa); strcat(buffer, list->name); value &= ~list->value; sepa = ", "; } list++; } if (value) { sprintf(buffer+strlen(buffer), "%sother flags=0x%x", sepa, (unsigned int) value); } return buffer;}const char *p11_slot_info_flags(CK_FLAGS value){ static struct flag_info slot_flags[] = { { CKF_TOKEN_PRESENT, "token present" }, { CKF_REMOVABLE_DEVICE, "removable device" }, { CKF_HW_SLOT, "hardware slot" }, { 0 } }; return p11_flag_names(slot_flags, value);}const char *p11_token_info_flags(CK_FLAGS value){ static struct flag_info slot_flags[] = { { CKF_RNG, "rng" }, { CKF_WRITE_PROTECTED, "readonly" }, { CKF_LOGIN_REQUIRED, "login required" }, { CKF_USER_PIN_INITIALIZED, "PIN initialized" }, { CKF_PROTECTED_AUTHENTICATION_PATH, "PIN pad present" }, { CKF_TOKEN_INITIALIZED, "token initialized" }, { 0 } }; return p11_flag_names(slot_flags, value);}const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len){ static char buffer[512]; size_t n, m; while (len && string[len-1] == ' ') len--; /* For now, simply copy this thing */ for (n = m = 0; n < sizeof(buffer) - 1; n++) { if (m >= len) break; buffer[n] = string[m++]; } buffer[n] = '\0'; return buffer;}voidp11_fatal(const char *func, CK_RV rv){ fatal("PKCS11 function %s failed: rv = %s (0x%0x)\n", func, CKR2Str(rv), (unsigned int) rv);}voidp11_perror(const char *msg, CK_RV rv){ fprintf(stderr, " ERR: %s failed: %s (0x%0x)\n", msg, CKR2Str(rv), (unsigned int) rv);}int hex_to_bin(const char *in, unsigned char *out, size_t *outlen){ size_t left, count = 0; if (in == NULL || *in == '\0') { *outlen = 0; return 1; } left = *outlen; while (*in != '\0') { int byte = 0, nybbles = 2; char c; while (nybbles-- && *in && *in != ':') { byte <<= 4; c = *in++; if ('0' <= c && c <= '9') c -= '0'; else if ('a' <= c && c <= 'f') c = c - 'a' + 10; else if ('A' <= c && c <= 'F') c = c - 'A' + 10; else { printf("hex_to_bin(): invalid char '%c' in hex string\n", c); *outlen = 0; return 0; } byte |= c; } if (*in == ':') in++; if (left <= 0) { printf("hex_to_bin(): hex string too long"); *outlen = 0; return 0; } out[count++] = (unsigned char) byte; left--; c++; } *outlen = count; return 1;}static struct mech_info p11_mechanisms[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA-PKCS-KEY-PAIR-GEN" }, { CKM_RSA_PKCS, "RSA-PKCS" }, { CKM_RSA_9796, "RSA-9796" }, { CKM_RSA_X_509, "RSA-X-509" }, { CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS" }, { CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5" }, { CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1" }, { CKM_RIPEMD128_RSA_PKCS, "RIPEMD128-RSA-PKCS" }, { CKM_RIPEMD160_RSA_PKCS, "RIPEMD160-RSA-PKCS", "rsa-ripemd160" }, { CKM_RSA_PKCS_OAEP, "RSA-PKCS-OAEP" }, { CKM_RSA_X9_31_KEY_PAIR_GEN,"RSA-X9-31-KEY-PAIR-GEN" }, { CKM_RSA_X9_31, "RSA-X9-31" }, { CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31" }, { CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS" }, { CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS" }, { CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN" }, { CKM_DSA, "DSA" }, { CKM_DSA_SHA1, "DSA-SHA1" }, { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN" }, { CKM_DH_PKCS_DERIVE, "DH-PKCS-DERIVE" }, { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN" }, { CKM_X9_42_DH_DERIVE, "X9-42-DH-DERIVE" }, { CKM_X9_42_DH_HYBRID_DERIVE,"X9-42-DH-HYBRID-DERIVE" }, { CKM_X9_42_MQV_DERIVE, "X9-42-MQV-DERIVE" }, { CKM_RC2_KEY_GEN, "RC2-KEY-GEN" }, { CKM_RC2_ECB, "RC2-ECB" }, { CKM_RC2_CBC, "RC2-CBC" }, { CKM_RC2_MAC, "RC2-MAC" }, { CKM_RC2_MAC_GENERAL, "RC2-MAC-GENERAL" }, { CKM_RC2_CBC_PAD, "RC2-CBC-PAD" }, { CKM_RC4_KEY_GEN, "RC4-KEY-GEN" }, { CKM_RC4, "RC4" }, { CKM_DES_KEY_GEN, "DES-KEY-GEN" }, { CKM_DES_ECB, "DES-ECB" }, { CKM_DES_CBC, "DES-CBC" }, { CKM_DES_MAC, "DES-MAC" }, { CKM_DES_MAC_GENERAL, "DES-MAC-GENERAL" }, { CKM_DES_CBC_PAD, "DES-CBC-PAD" }, { CKM_DES2_KEY_GEN, "DES2-KEY-GEN" }, { CKM_DES3_KEY_GEN, "DES3-KEY-GEN" }, { CKM_DES3_ECB, "DES3-ECB" }, { CKM_DES3_CBC, "DES3-CBC" }, { CKM_DES3_MAC, "DES3-MAC" }, { CKM_DES3_MAC_GENERAL, "DES3-MAC-GENERAL" }, { CKM_DES3_CBC_PAD, "DES3-CBC-PAD" }, { CKM_CDMF_KEY_GEN, "CDMF-KEY-GEN" }, { CKM_CDMF_ECB, "CDMF-ECB" }, { CKM_CDMF_CBC, "CDMF-CBC" }, { CKM_CDMF_MAC, "CDMF-MAC" }, { CKM_CDMF_MAC_GENERAL, "CDMF-MAC-GENERAL" }, { CKM_CDMF_CBC_PAD, "CDMF-CBC-PAD" }, { CKM_MD2, "MD2" }, { CKM_MD2_HMAC, "MD2-HMAC" }, { CKM_MD2_HMAC_GENERAL, "MD2-HMAC-GENERAL" }, { CKM_MD5, "MD5" }, { CKM_MD5_HMAC, "MD5-HMAC" }, { CKM_MD5_HMAC_GENERAL, "MD5-HMAC-GENERAL" }, { CKM_SHA_1, "SHA-1" }, { CKM_SHA_1_HMAC, "SHA-1-HMAC" }, { CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL" }, { CKM_RIPEMD128, "RIPEMD128" }, { CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC" }, { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL" }, { CKM_RIPEMD160, "RIPEMD160" }, { CKM_RIPEMD160_HMAC, "RIPEMD160-HMAC" }, { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL" }, { CKM_CAST_KEY_GEN, "CAST-KEY-GEN" }, { CKM_CAST_ECB, "CAST-ECB" }, { CKM_CAST_CBC, "CAST-CBC" }, { CKM_CAST_MAC, "CAST-MAC" }, { CKM_CAST_MAC_GENERAL, "CAST-MAC-GENERAL" }, { CKM_CAST_CBC_PAD, "CAST-CBC-PAD" }, { CKM_CAST3_KE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -