📄 pkcs11-tool.c
字号:
p11_fatal("C_FindObjects", rv);done: if (count == 0) *ret = CK_INVALID_HANDLE; p11->C_FindObjectsFinal(sess); return count;}CK_MECHANISM_TYPEfind_mechanism(CK_SLOT_ID slot, CK_FLAGS flags, int stop_if_not_found){ CK_MECHANISM_TYPE *mechs = NULL, result; CK_MECHANISM_INFO info; CK_ULONG n, count = 0; CK_RV rv; get_mechanisms(slot, &mechs, &count); result = NO_MECHANISM; for (n = 0; n < count; n++) { rv = p11->C_GetMechanismInfo(slot, mechs[n], &info); if (rv != CKR_OK) continue; if ((info.flags & flags) == flags) { result = mechs[n]; break; } } if (stop_if_not_found && result == NO_MECHANISM) fatal("No appropriate mechanism found"); free(mechs); return result;}#define ATTR_METHOD(ATTR, TYPE) \TYPE \get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) \{ \ TYPE type; \ CK_ATTRIBUTE attr = { CKA_##ATTR, &type, sizeof(type) }; \ CK_RV rv; \ \ rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \ if (rv != CKR_OK) \ p11_fatal("C_GetAttributeValue(" #ATTR ")", rv); \ return type; \}#define VARATTR_METHOD(ATTR, TYPE) \TYPE * \get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \{ \ CK_ATTRIBUTE attr = { CKA_##ATTR, NULL, 0 }; \ CK_RV rv; \ \ rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \ if (rv == CKR_OK) { \ if (!(attr.pValue = calloc(1, attr.ulValueLen + 1))) \ fatal("out of memory in get" #ATTR ": %m"); \ rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \ } \ if (rv != CKR_OK) \ p11_fatal("C_GetAttributeValue(" #ATTR ")", rv); \ if (pulCount) \ *pulCount = attr.ulValueLen / sizeof(TYPE); \ return (TYPE *) attr.pValue; \}/* * Define attribute accessors */ATTR_METHOD(CLASS, CK_OBJECT_CLASS);ATTR_METHOD(TOKEN, CK_BBOOL);ATTR_METHOD(LOCAL, CK_BBOOL);ATTR_METHOD(SENSITIVE, CK_BBOOL);ATTR_METHOD(ALWAYS_SENSITIVE, CK_BBOOL);ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL);ATTR_METHOD(PRIVATE, CK_BBOOL);ATTR_METHOD(MODIFIABLE, CK_BBOOL);ATTR_METHOD(ENCRYPT, CK_BBOOL);ATTR_METHOD(DECRYPT, CK_BBOOL);ATTR_METHOD(SIGN, CK_BBOOL);ATTR_METHOD(SIGN_RECOVER, CK_BBOOL);ATTR_METHOD(VERIFY, CK_BBOOL);ATTR_METHOD(VERIFY_RECOVER, CK_BBOOL);ATTR_METHOD(WRAP, CK_BBOOL);ATTR_METHOD(UNWRAP, CK_BBOOL);ATTR_METHOD(DERIVE, CK_BBOOL);ATTR_METHOD(EXTRACTABLE, CK_BBOOL);ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE);ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE);ATTR_METHOD(MODULUS_BITS, CK_ULONG);VARATTR_METHOD(LABEL, char);VARATTR_METHOD(ID, unsigned char);VARATTR_METHOD(VALUE, unsigned char);voidshow_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj){ CK_OBJECT_CLASS cls = getCLASS(sess, obj); switch (cls) { case CKO_PUBLIC_KEY: show_key(sess, obj, 1); break; case CKO_PRIVATE_KEY: show_key(sess, obj, 0); break; case CKO_CERTIFICATE: show_cert(sess, obj); break; default: printf("Object %u, type %u\n", (unsigned int) obj, (unsigned int) cls); }}voidshow_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int pub){ CK_KEY_TYPE key_type = getKEY_TYPE(sess, obj); CK_ULONG size; unsigned char *id; char *label, *sepa; printf("%s Key Object", pub? "Public" : "Private"); switch (key_type) { case CKK_RSA: printf("; RSA %lu bits\n", getMODULUS_BITS(sess, obj)); break; default: printf("; unknown key algorithm %lu\n", key_type); break; } if ((label = getLABEL(sess, obj, NULL)) != NULL) { printf(" label: %s\n", label); free(label); } if ((id = getID(sess, obj, &size)) != NULL && size) { unsigned int n; printf(" ID: "); for (n = 0; n < size; n++) printf("%02x", id[n]); printf("\n"); free(id); } printf(" Usage: "); sepa = ""; if (getENCRYPT(sess, obj)) { printf("%sencrypt", sepa); sepa = ", "; } if (getDECRYPT(sess, obj)) { printf("%sdecrypt", sepa); sepa = ", "; } if (getSIGN(sess, obj)) { printf("%ssign", sepa); sepa = ", "; } if (getVERIFY(sess, obj)) { printf("%sverify", sepa); sepa = ", "; } if (getWRAP(sess, obj)) { printf("%swrap", sepa); sepa = ", "; } if (getUNWRAP(sess, obj)) { printf("%sunwrap", sepa); sepa = ", "; } if (!*sepa) printf("none"); printf("\n");}voidshow_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj){ CK_CERTIFICATE_TYPE cert_type = getCERTIFICATE_TYPE(sess, obj); CK_ULONG size; unsigned char *id; char *label; printf("Certificate Object, type = "); switch (cert_type) { case CKC_X_509: printf("X.509 cert\n"); break; case CKC_X_509_ATTR_CERT: printf("X.509 attribute cert\n"); break; case CKC_VENDOR_DEFINED: printf("vendor defined"); break; default: printf("; unknown cert type\n"); break; } if ((label = getLABEL(sess, obj, NULL)) != NULL) { printf(" label: %s\n", label); free(label); } if ((id = getID(sess, obj, &size)) != NULL && size) { unsigned int n; printf(" ID: "); for (n = 0; n < size; n++) printf("%02x", id[n]); printf("\n"); free(id); }}voidget_token_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info){ CK_RV rv; rv = p11->C_GetTokenInfo(slot, info); if (rv != CKR_OK) p11_fatal("C_GetTokenInfo", rv);}voidget_mechanisms(CK_SLOT_ID slot, CK_MECHANISM_TYPE_PTR *pList, CK_ULONG_PTR pulCount){ CK_RV rv; rv = p11->C_GetMechanismList(slot, *pList, pulCount); *pList = (CK_MECHANISM_TYPE *) calloc(*pulCount, sizeof(*pList)); if (*pList == NULL) fatal("calloc failed: %m"); rv = p11->C_GetMechanismList(slot, *pList, pulCount); if (rv != CKR_OK) p11_fatal("C_GetMechanismList", rv);}static inttest_digest(CK_SLOT_ID slot){ int errors = 0; CK_RV rv; CK_SESSION_HANDLE session; CK_MECHANISM ck_mech = { CKM_MD5, NULL, 0 }; CK_ULONG i, j; unsigned char data[100]; unsigned char hash1[64], hash2[64]; CK_ULONG hashLen1, hashLen2; CK_MECHANISM_TYPE firstMechType; CK_MECHANISM_TYPE mechTypes[] = { CKM_MD5, CKM_SHA_1, CKM_RIPEMD160, 0xffffff }; unsigned char *digests[] = { (unsigned char *) "\x7a\x08\xb0\x7e\x84\x64\x17\x03\xe5\xf2\xc8\x36\xaa\x59\xa1\x70", (unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", (unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd" }; CK_ULONG digestLens[] = { 16, 20, 20 }; firstMechType = find_mechanism(slot, CKF_DIGEST, 0); if (firstMechType == NO_MECHANISM) { printf("Digests: not implemented\n"); return errors; } else printf("Digests:\n"); rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &session); if (rv != CKR_OK) p11_fatal("C_OpenSession", rv); /* 1st test */ ck_mech.mechanism = firstMechType; rv = p11->C_DigestInit(session, &ck_mech); if (rv != CKR_OK) p11_fatal("C_DigestInit", rv); rv = p11->C_DigestUpdate(session, data, 5); if (rv == CKR_FUNCTION_NOT_SUPPORTED) { printf(" Note: C_DigestUpdate(), DigestFinal() not supported\n"); /* finish the digest operation */ hashLen2 = sizeof(hash2); rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2); if (rv != CKR_OK) p11_fatal("C_Digest", rv); } else { if (rv != CKR_OK) p11_fatal("C_DigestUpdate", rv); rv = p11->C_DigestUpdate(session, data + 5, 50); if (rv != CKR_OK) p11_fatal("C_DigestUpdate", rv); rv = p11->C_DigestUpdate(session, data + 55, sizeof(data) - 55); if (rv != CKR_OK) p11_fatal("C_DigestUpdate", rv); hashLen1 = sizeof(hash1); rv = p11->C_DigestFinal(session, hash1, &hashLen1); if (rv != CKR_OK) p11_fatal("C_DigestFinal", rv); rv = p11->C_DigestInit(session, &ck_mech); if (rv != CKR_OK) p11_fatal("C_DigestInit", rv); hashLen2 = sizeof(hash2); rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2); if (rv != CKR_OK) p11_fatal("C_Digest", rv); if (hashLen1 != hashLen2) { errors++; printf(" ERR: digest lengths returned by C_DigestFinal() different from C_Digest()\n"); } else if (memcmp(hash1, hash2, hashLen1) != 0) { errors++; printf(" ERR: digests returned by C_DigestFinal() different from C_Digest()\n"); } else printf(" all 4 digest functions seem to work\n"); } /* 2nd test */ /* input = "01234567890123456...456789" */ for (i = 0; i < 10; i++) for (j = 0; j < 10; j++) data[10 * i + j] = (unsigned char) (0x30 + j); for (i = 0; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; rv = p11->C_DigestInit(session, &ck_mech); if (rv == CKR_MECHANISM_INVALID) continue; /* mechanism not implemented, don't test */ if (rv != CKR_OK) p11_fatal("C_DigestInit", rv); printf(" %s: ", p11_mechanism_to_name(mechTypes[i])); hashLen1 = sizeof(hash1); rv = p11->C_Digest(session, data, sizeof(data), hash1, &hashLen1); if (rv != CKR_OK) p11_fatal("C_Digest", rv); if (hashLen1 != digestLens[i]) { errors++; printf("ERR: wrong digest length: %ld instead of %ld\n", hashLen1, digestLens[i]); } else if (memcmp(hash1, digests[i], hashLen1) != 0) { errors++; printf("ERR: wrong digest value\n"); } else printf("OK\n"); } /* 3rd test */ ck_mech.mechanism = firstMechType; rv = p11->C_DigestInit(session, &ck_mech); if (rv != CKR_OK) p11_fatal("C_DigestInit", rv); hashLen2 = 1; /* too short */ rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2); if (rv != CKR_BUFFER_TOO_SMALL) { errors++; printf(" ERR: C_Digest() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv); } /* output buffer = NULL */ rv = p11->C_Digest(session, data, sizeof(data), NULL, &hashLen2); if (rv != CKR_OK) { errors++; printf(" ERR: C_Digest() didn't return CKR_OK for a NULL output buffer, but %s (0x%0x)\n", CKR2Str(rv), (int) rv); } rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2); if (rv == CKR_OPERATION_NOT_INITIALIZED) { printf(" ERR: digest operation ended prematurely\n"); errors++; } else if (rv != CKR_OK) p11_fatal("C_Sign", rv); rv = p11->C_CloseSession(session); if (rv != CKR_OK) p11_fatal("C_CloseSession", rv); return errors;}#ifdef HAVE_OPENSSLEVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject){ unsigned char *id; CK_ULONG idLen; CK_OBJECT_HANDLE pubkeyObject; unsigned char *pubkey, *pubkey_sav; CK_ULONG pubkeyLen; EVP_PKEY *pkey; id = NULL; id = getID(session, privKeyObject, &idLen); if (id == NULL) { printf("private key has no ID, can't lookup the corresponding pubkey for verification\n"); return NULL; } if (!find_object(session, CKO_PUBLIC_KEY, &pubkeyObject, id, idLen, 0)) { free(id); printf("coudn't find the corresponding pubkey for validation\n"); return NULL; } free(id); pubkey = getVALUE(session, pubkeyObject, &pubkeyLen); if (pubkey == NULL) { printf("couldn't get the pubkey VALUE attribute, no validation done\n"); return NULL; } pubkey_sav = pubkey; /* The function below may change pubkey */ pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey, pubkeyLen); free(pubkey_sav); if (pkey == NULL) { printf(" couldn't parse pubkey, no verification done\n"); /* ERR_print_errors_fp(stderr); */ return NULL; } return pkey;}#endifint sign_verify_openssl(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_MECHANISM *ck_mech, CK_OBJECT_HANDLE privKeyObject, unsigned char *data, CK_ULONG dataLen, unsigned char *verifyData, CK_ULONG verifyDataLen, int modLenBytes, int evp_md_index){ int errors = 0; CK_RV rv; unsigned char sig1[1024]; CK_ULONG sigLen1;#ifdef HAVE_OPENSSL int err; EVP_PKEY *pkey; EVP_MD_CTX md_ctx; const EVP_MD *evp_mds[] = { EVP_sha1(), EVP_sha1(), EVP_sha1(), EVP_md5(), EVP_ripemd160(), };#endif rv = p11->C_SignInit(session, ck_mech, privKeyObject); /* mechanism not implemented, don't test */ if (rv == CKR_MECHANISM_INVALID) return errors; if (rv != CKR_OK) p11_fatal("C_SignInit", rv); printf(" %s: ", p11_mechanism_to_name(ck_mech->mechanism)); sigLen1 = sizeof(sig1); rv = p11->C_Sign(session, data, dataLen, sig1, &sigLen1); if (rv != CKR_OK) p11_fatal("C_Sign", rv); if (sigLen1 != modLenBytes) { errors++; printf(" ERR: wrong signature length: %u instead of %u\n", (unsigned int) sigLen1, (unsigned int) modLenBytes); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -