📄 pkcs11-tool.c
字号:
#ifndef HAVE_OPENSSL printf("unable to verify signature (compile with HAVE_OPENSSL)\n");#else if (!(pkey = get_public_key(session, privKeyObject))) return errors; EVP_VerifyInit(&md_ctx, evp_mds[evp_md_index]); EVP_VerifyUpdate(&md_ctx, verifyData, verifyDataLen); err = EVP_VerifyFinal(&md_ctx, sig1, sigLen1, pkey); if (err == 0) { printf("ERR: verification failed\n"); errors++; } else if (err != 1) { printf("openssl error during verification: 0x%0x (%d)\n", err, err); /* ERR_print_errors_fp(stderr); */ } else printf("OK\n"); /* free(cert); */#endif return errors;}/* * Test signature functions */static inttest_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session){ int errors = 0; CK_RV rv; CK_OBJECT_HANDLE privKeyObject; CK_SESSION_HANDLE sess; CK_MECHANISM ck_mech = { CKM_MD5, NULL, 0 }; CK_MECHANISM_TYPE firstMechType; CK_SESSION_INFO sessionInfo; CK_ULONG i, j; unsigned char data[200]; CK_ULONG modLenBytes; CK_ULONG dataLen; unsigned char sig1[1024], sig2[1024]; CK_ULONG sigLen1, sigLen2; unsigned char verifyData[100]; char *label; CK_MECHANISM_TYPE mechTypes[] = { CKM_RSA_X_509, CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_MD5_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, 0xffffff }; unsigned char *datas[] = { /* PCKS1_wrap(SHA1_encode(SHA-1(verifyData))), * is done further on */ NULL, /* SHA1_encode(SHA-1(verifyData)) */ (unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", verifyData, verifyData, verifyData, }; CK_ULONG dataLens[] = { 0, /* should be modulus length, is done further on */ 35, sizeof(verifyData), sizeof(verifyData), sizeof(verifyData), }; rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &sess); if (rv != CKR_OK) 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("Signatures: not logged in, skipping signature tests\n"); return errors; } firstMechType = find_mechanism(slot, CKF_SIGN | CKF_HW, 0); if (firstMechType == NO_MECHANISM) { printf("Signatures: not implemented\n"); return errors; } printf("Signatures (currently only RSA signatures)\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 (!getSIGN(sess, privKeyObject)) { printf(" -- can't be used for signature, skipping\n"); continue; } printf("\n"); break; } if (privKeyObject == CK_INVALID_HANDLE) { printf("Signatures: no private key found in this slot\n"); return 0; } data[0] = 0; modLenBytes = (getMODULUS_BITS(sess, privKeyObject) + 7) / 8; /* 1st test */ switch (firstMechType) { case CKM_RSA_PKCS: dataLen = 35; break; case CKM_RSA_X_509: dataLen = modLenBytes; break; default: dataLen = sizeof(data); /* let's hope it's OK */ break; } ck_mech.mechanism = firstMechType; rv = p11->C_SignInit(sess, &ck_mech, privKeyObject); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); rv = p11->C_SignUpdate(sess, data, 5); if (rv == CKR_FUNCTION_NOT_SUPPORTED) { printf(" Note: C_SignUpdate(), SignFinal() not supported\n"); /* finish the digest operation */ sigLen2 = sizeof(sig2); rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2); if (rv != CKR_OK) p11_fatal("C_Sign", rv); } else { if (rv != CKR_OK) p11_fatal("C_SignUpdate", rv); rv = p11->C_SignUpdate(sess, data + 5, 10); if (rv != CKR_OK) p11_fatal("C_SignUpdate", rv); rv = p11->C_SignUpdate(sess, data + 15, dataLen - 15); if (rv != CKR_OK) p11_fatal("C_SignUpdate", rv); sigLen1 = sizeof(sig1); rv = p11->C_SignFinal(sess, sig1, &sigLen1); if (rv != CKR_OK) p11_fatal("C_SignFinal", rv); rv = p11->C_SignInit(sess, &ck_mech, privKeyObject); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); sigLen2 = sizeof(sig2); rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2); if (rv != CKR_OK) p11_fatal("C_Sign", rv); if (sigLen1 != sigLen2) { errors++; printf(" ERR: signature lengths returned by C_SignFinal() different from C_Sign()\n"); } else if (memcmp(sig1, sig2, sigLen1) != 0) { errors++; printf(" ERR: signatures returned by C_SignFinal() different from C_Sign()\n"); } else printf(" all 4 signature functions seem to work\n"); } /* 2nd test */ ck_mech.mechanism = firstMechType; rv = p11->C_SignInit(sess, &ck_mech, privKeyObject); if (rv != CKR_OK) p11_fatal("C_SignInit", rv); sigLen2 = 1; /* too short */ rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2); if (rv != CKR_BUFFER_TOO_SMALL) { errors++; printf(" ERR: C_Sign() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv); } /* output buf = NULL */ rv = p11->C_Sign(sess, data, dataLen, NULL, &sigLen2); if (rv != CKR_OK) { errors++; printf(" ERR: C_Sign() didn't return CKR_OK for a NULL output buf, but %s (0x%0x)\n", CKR2Str(rv), (int) rv); } rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2); if (rv == CKR_OPERATION_NOT_INITIALIZED) { printf(" ERR: signature operation ended prematurely\n"); errors++; } else if (rv != CKR_OK) p11_fatal("C_Sign", rv); /* 3rd test */ /* input = "01234567890123456...456789" */ for (i = 0; i < 10; i++) for (j = 0; j < 10; j++) verifyData[10 * i + j] = (unsigned char) (0x30 + j); /* Fill in data[0] and dataLens[0] */ dataLen = modLenBytes; data[1] = 0x01; memset(data + 2, 0xFF, dataLen - 3 - dataLens[1]); data[dataLen - 36] = 0x00; memcpy(data + (dataLen - dataLens[1]), datas[1], dataLens[1]); datas[0] = data; dataLens[0] = dataLen; printf(" testing signature mechanisms:\n"); for (i = 0; mechTypes[i] != 0xffffff; i++) { ck_mech.mechanism = mechTypes[i]; errors += sign_verify_openssl(slot, sess, &ck_mech, privKeyObject, datas[i], dataLens[i], verifyData, sizeof(verifyData), modLenBytes, i); } /* 4rd test: the other signature keys */ for (i = 0; mechTypes[i] != 0xffffff; i++) if (i == firstMechType) break; ck_mech.mechanism = mechTypes[i]; j = 1; /* j-th signature key */ while (find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j++) != 0) { printf(" testing key %d ", (int) (j-1)); if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) { printf("(%s) ", label); free(label); } printf("with 1 signature mechanism\n"); errors += sign_verify_openssl(slot, sess, &ck_mech, privKeyObject, datas[i], dataLens[i], verifyData, sizeof(verifyData), modLenBytes, i); } return errors;}static intsign_verify(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv_key, int key_len, CK_OBJECT_HANDLE pub_key, int one_test){ CK_RV rv; CK_MECHANISM_TYPE mech_types[] = { CKM_RSA_X_509, CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_MD5_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, 0xffffff }; CK_MECHANISM_TYPE *mech_type; unsigned char buf[512] = {0}; unsigned char *datas[] = { buf, (unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1", buf, buf, buf }; int data_lens[] = { key_len, 35, 234, 345, 456 }; unsigned char signat[512]; CK_ULONG signat_len; int j, errors = 0; for (j = 0, mech_type = mech_types; *mech_type != 0xffffff; mech_type++, j++) { CK_MECHANISM mech = {*mech_type, NULL, 0}; rv = p11->C_SignInit(session, &mech, priv_key); if (rv == CKR_MECHANISM_INVALID) break; if (rv != CKR_OK) { printf(" ERR: C_SignInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv); return ++errors; } printf(" %s: ", p11_mechanism_to_name(*mech_type)); signat_len = sizeof(signat); rv = p11->C_Sign(session, datas[j], data_lens[j], signat, &signat_len); if (rv != CKR_OK) { printf(" ERR: C_Sign() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv); return ++errors; } rv = p11->C_VerifyInit(session, &mech, pub_key); if (rv != CKR_OK) { printf(" ERR: C_VerifyInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv); return ++errors; } rv = p11->C_Verify(session, datas[j], data_lens[j], signat, signat_len); if (rv == CKR_SIGNATURE_INVALID) { printf(" ERR: verification failed"); errors++; } if (rv != CKR_OK) { printf(" ERR: C_Verify() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv); return ++errors; } else printf("OK\n"); if (one_test) return errors; } return errors;}static inttest_verify(CK_SLOT_ID slot, CK_SESSION_HANDLE sess){ int key_len, i, errors = 0; CK_OBJECT_HANDLE priv_key, pub_key; CK_MECHANISM_TYPE first_mech_type; CK_SESSION_INFO sessionInfo; CK_RV rv; rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &sess); if (rv != CKR_OK) 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("Verify: not logged in, skipping verify tests\n"); return errors; } first_mech_type = find_mechanism(slot, CKF_VERIFY, 0); if (first_mech_type == NO_MECHANISM) { printf("Verify: not implemented\n"); return errors; } printf("Verify (currently only for RSA):\n"); for (i = 0; find_object(sess, CKO_PRIVATE_KEY, &priv_key, NULL, 0, i); i++) { char *label; unsigned char *id; CK_ULONG id_len; printf(" testing key %d", i); if ((label = getLABEL(sess, priv_key, NULL)) != NULL) { printf(" (%s)", label); free(label); } if (i != 0) printf(" with 1 mechanism"); printf("\n"); if (!getSIGN(sess, priv_key)) { printf(" -- can't be used to sign/verify, skipping\n"); continue; } if ((id = getID(sess, priv_key, &id_len)) != NULL) { int r; r = find_object(sess, CKO_PUBLIC_KEY, &pub_key, id, id_len, 0); free(id); if (r == 0) { printf(" -- can't find corresponding public key, skipping\n"); continue; } } else { printf(" -- can't get the ID for looking up the public key, skipping\n"); continue; } key_len = (getMODULUS_BITS(sess, priv_key) + 7) / 8; errors += sign_verify(slot, sess, priv_key, key_len, pub_key, i != 0); } if (i == 0) printf(" No private key found for testing\n"); return errors;}#ifdef HAVE_OPENSSLstatic intwrap_unwrap(CK_SLOT_ID slot, CK_SESSION_HANDLE session, const EVP_CIPHER *algo, CK_OBJECT_HANDLE privKeyObject){ CK_OBJECT_HANDLE cipherKeyObject; CK_RV rv; EVP_PKEY *pkey; EVP_CIPHER_CTX seal_ctx; unsigned char keybuf[512], *key = keybuf; int key_len; unsigned char iv[32], ciphered[1024], cleartext[1024]; int ciphered_len, cleartext_len, len; CK_MECHANISM mech; CK_ULONG key_type = CKM_DES_CBC; CK_ATTRIBUTE key_template = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; pkey = get_public_key(session, privKeyObject); if (pkey == NULL) return 0; printf(" %s: ", OBJ_nid2sn(EVP_CIPHER_nid(algo))); EVP_SealInit(&seal_ctx, algo, &key, &key_len, iv, &pkey, 1); /* Encrypt something */ len = sizeof(ciphered); EVP_SealUpdate(&seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11); ciphered_len = len; len = sizeof(ciphered) - ciphered_len; EVP_SealFinal(&seal_ctx, ciphered + ciphered_len, &len); ciphered_len += len; mech.mechanism = CKM_RSA_PKCS; rv = p11->C_UnwrapKey(session, &mech, privKeyObject, key, key_len, &key_template, 1, &cipherKeyObject); /* mechanism not implemented, don't test */ if (rv == CKR_MECHANISM_INVALID) return 0; if (rv != CKR_OK) { p11_perror("C_UnwrapKey", rv); return 1; } /* Try to decrypt */ key = getVALUE(session, cipherKeyObject, (unsigned long *) &key_len); if (key == NULL) { printf(" Could not get unwrapped key\n"); return 1; } if (key_len != EVP_CIPHER_key_length(algo)) { printf(" Key length mismatch (%d != %d)\n", key_len, EVP_CIPHER_key_length(algo)); return 1; } EVP_DecryptInit(&seal_ctx, algo, key, iv); len = sizeof(cleartext); EVP_DecryptUpdate(&seal_ctx, cleartext, &len, ciphered, ciphered_len); cleartext_len = len; len = sizeof(cleartext) - len; EVP_DecryptFinal(&seal_ctx, cleartext + cleartext_len, &len); cleartext_len += len; if (cleartext_len != 11 || memcmp(cleartext, "hello world", 11)) { printf(" resulting cleartext doesn't match input\n"); return 1; } printf("OK\n"); return 0;}#endif/* * Test unwrap functions */static inttest_unwrap(CK_SLOT_ID slot, CK_SESSION_HANDLE session){ int errors = 0; CK_RV rv; CK_OBJECT_HANDLE privKeyObject; CK_SESSION_HANDLE sess; CK_MECHANISM_TYPE firstMechType; CK_SESSION_INFO sessionInfo; CK_ULONG j; char *label; rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &sess); if (rv != CKR_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -