diff --git a/bin/pkcs11/pkcs11-destroy.c b/bin/pkcs11/pkcs11-destroy.c new file mode 100644 index 0000000000..e7068e4d62 --- /dev/null +++ b/bin/pkcs11/pkcs11-destroy.c @@ -0,0 +1,178 @@ +/* destroyobj [-s $slot] [-i $id | -l $label] [-p $pin] */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + CK_RV rv; + CK_SLOT_ID slot = 0; + CK_SESSION_HANDLE hSession; + CK_UTF8CHAR *pin = NULL; + CK_BYTE attr_id[2]; + CK_OBJECT_HANDLE akey[50]; + char *label = NULL; + int error = 0; + int id = 0, i = 0; + int c, errflg = 0; + CK_ULONG ulObjectCount; + CK_ATTRIBUTE search_template[] = { + {CKA_ID, &attr_id, sizeof(attr_id)} + }; + extern char *optarg; + extern int optopt; + + while ((c = getopt(argc, argv, ":s:i:l:p:")) != -1) { + switch (c) { + case 's': + slot = atoi(optarg); + break; + case 'i': + id = atoi(optarg); + id &= 0xffff; + break; + case 'l': + label = optarg; + break; + case 'p': + pin = (CK_UTF8CHAR *)optarg; + break; + case ':': + fprintf(stderr, "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + default: + fprintf(stderr, "Unrecognised option: -%c\n", optopt); + errflg++; + } + } + if (errflg || ((!id) && (!label))) { + fprintf(stderr, + "usage: destroykey [-s slot] [-i id | -l label] [-p pin]\n"); + exit(1); + } + if (id) { + printf("id %i\n", id); + attr_id[0] = (id >> 8) & 0xff; + attr_id[1] = id & 0xff; + } else if (label) { + printf("label %s\n", label); + search_template[0].type = CKA_LABEL; + search_template[0].pValue = label; + search_template[0].ulValueLen = strlen(label); + } + + /* Initialize the CRYPTOKI library */ + rv = C_Initialize(NULL_PTR); + if (rv != CKR_OK) { + fprintf(stderr, "C_Initialize: Error = 0x%.8X\n", rv); + exit(1); + } + + /* Open a session on the slot found */ + rv = C_OpenSession(slot, CKF_RW_SESSION+CKF_SERIAL_SESSION, + NULL_PTR, NULL_PTR, &hSession); + if (rv != CKR_OK) { + fprintf(stderr, "C_OpenSession: Error = 0x%.8X\n", rv); + error = 1; + goto exit_program; + } + + /* Login to the Token (Keystore) */ + if (!pin) +#ifndef HAVE_GETPASS + pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); +#else + pin = (CK_UTF8CHAR *)getpass("Enter Pin: "); +#endif + rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); + memset(pin, 0, strlen((char *)pin)); + if (rv != CKR_OK) { + fprintf(stderr, "C_Login: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + + rv = C_FindObjectsInit(hSession, search_template, + ((id != 0) || (label != NULL)) ? 1 : 0); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + + rv = C_FindObjects(hSession, akey, 50, &ulObjectCount); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjects: Error = 0x%.8X\n", rv); + error = 1; + goto exit_search; + } + + for (i = 0; i < ulObjectCount; i++) { + CK_OBJECT_CLASS oclass = 0; + CK_BYTE labelbuf[64 + 1]; + CK_BYTE idbuf[64]; + CK_ATTRIBUTE attr_template[] = { + {CKA_CLASS, &oclass, sizeof(oclass)}, + {CKA_LABEL, labelbuf, sizeof(labelbuf) - 1}, + {CKA_ID, idbuf, sizeof(idbuf)} + }; + int j, len; + + memset(labelbuf, 0, sizeof(labelbuf)); + memset(idbuf, 0, sizeof(idbuf)); + + rv = C_GetAttributeValue(hSession, akey[i], attr_template, 3); + if (rv != CKR_OK) { + fprintf(stderr, "C_GetAttributeValue[%d]: rv = 0x%.8X\n", i, rv); + error = 1; + goto exit_search; + } + len = attr_template[2].ulValueLen; + printf("object[%d]: class %d label '%s' id[%u] ", + i, oclass, labelbuf, attr_template[2].ulValueLen); + if (len > 4) + len = 4; + for (j = 0; j < len; j++) + printf("%02x", idbuf[j]); + if (attr_template[2].ulValueLen > len) + printf("...\n"); + else + printf("\n"); + } + + /* give a chance to kill this */ + printf("sleeping 5 seconds...\n"); + sleep(5); + + for (i = 0; i < ulObjectCount; i++) { + rv = C_DestroyObject(hSession, akey[i]); + if (rv != CKR_OK) { + fprintf(stderr, "C_DestroyObject[%d]: rv = 0x%.8X\n", i, rv); + error = 1; + } + } + + exit_search: + rv = C_FindObjectsFinal(hSession); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8X\n", rv); + error = 1; + } + + exit_session: + (void) C_CloseSession(hSession); + + exit_program: + (void) C_Finalize(NULL_PTR); + + exit(error); +} diff --git a/bin/pkcs11/pkcs11-keygen.c b/bin/pkcs11/pkcs11-keygen.c new file mode 100644 index 0000000000..45a9e3cd68 --- /dev/null +++ b/bin/pkcs11/pkcs11-keygen.c @@ -0,0 +1,201 @@ +/* genkey - pkcs11 rsa key generator + * + * create RSASHA1 key in the keystore of an SCA6000 + * The calculation of key tag is left to the script + * that converts the key into a DNSKEY RR and inserts + * it into a zone file. + * + * usage: + * genkey [-P] [-s slot] -b keysize -l label [-p pin] + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define static key template values */ +static CK_BBOOL truevalue = TRUE; +static CK_BBOOL falsevalue = FALSE; + +int +main(int argc, char *argv[]) +{ + CK_RV rv; + CK_SLOT_ID slot = 0; + CK_MECHANISM genmech; + CK_SESSION_HANDLE hSession; + CK_UTF8CHAR *pin = NULL; + CK_ULONG modulusbits = 0; + CK_CHAR *label = NULL; + CK_OBJECT_HANDLE privatekey, publickey; + CK_BYTE public_exponent[3]; + int error = 0; + int i = 0; + int c, errflg = 0; + int hide = 1; + CK_ULONG ulObjectCount; + /* Set search template */ + CK_ATTRIBUTE search_template[] = { + {CKA_LABEL, NULL_PTR, 0} + }; + CK_ATTRIBUTE publickey_template[] = { + {CKA_LABEL, NULL_PTR, 0}, + {CKA_VERIFY, &truevalue, sizeof (truevalue)}, + {CKA_TOKEN, &truevalue, sizeof (truevalue)}, + {CKA_MODULUS_BITS, &modulusbits, sizeof (modulusbits)}, + {CKA_PUBLIC_EXPONENT, &public_exponent, sizeof (public_exponent)} + }; + CK_ATTRIBUTE privatekey_template[] = { + {CKA_LABEL, NULL_PTR, 0}, + {CKA_SIGN, &truevalue, sizeof (truevalue)}, + {CKA_TOKEN, &truevalue, sizeof (truevalue)}, + {CKA_PRIVATE, &truevalue, sizeof (truevalue)}, + {CKA_SENSITIVE, &truevalue, sizeof (truevalue)}, + {CKA_EXTRACTABLE, &falsevalue, sizeof (falsevalue)} + }; + extern char *optarg; + extern int optopt; + + while ((c = getopt(argc, argv, ":Ps:b:i:l:p:")) != -1) { + switch (c) { + case 'P': + hide = 0; + break; + case 's': + slot = atoi(optarg); + break; + case 'b': + modulusbits = atoi(optarg); + break; + case 'l': + label = (CK_CHAR *)optarg; + break; + case 'p': + pin = (CK_UTF8CHAR *)optarg; + break; + case ':': + fprintf(stderr, "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + default: + fprintf(stderr, "Unrecognised option: -%c\n", optopt); + errflg++; + } + } + if ((errflg) || (!modulusbits) || (!label)) { + fprintf(stderr, + "usage: genkey [-P] [-s slot] -b keysize -l label [-p pin]\n"); + exit(2); + } + + search_template[0].pValue = label; + search_template[0].ulValueLen = strlen((char *)label); + publickey_template[0].pValue = label; + publickey_template[0].ulValueLen = strlen((char *)label); + privatekey_template[0].pValue = label; + privatekey_template[0].ulValueLen = strlen((char *)label); + + /* Set public exponent to 65537 */ + public_exponent[0] = 0x01; + public_exponent[1] = 0x00; + public_exponent[2] = 0x01; + + /* Set up mechanism for generating key pair */ + genmech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; + genmech.pParameter = NULL_PTR; + genmech.ulParameterLen = 0; + + /* Initialize the CRYPTOKI library */ + rv = C_Initialize(NULL_PTR); + + if (rv != CKR_OK) { + fprintf(stderr, "C_Initialize: Error = 0x%.8X\n", rv); + exit(1); + } + + /* Open a session on the slot found */ + rv = C_OpenSession(slot, CKF_RW_SESSION+CKF_SERIAL_SESSION, + NULL_PTR, NULL_PTR, &hSession); + + if (rv != CKR_OK) { + fprintf(stderr, "C_OpenSession: Error = 0x%.8X\n", rv); + error = 1; + goto exit_program; + } + + /* Login to the Token (Keystore) */ + if (!pin) +#ifndef HAVE_GETPASS + pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); +#else + pin = (CK_UTF8CHAR *)getpass("Enter Pin: "); +#endif + rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); + memset(pin, 0, strlen((char *)pin)); + if (rv != CKR_OK) { + fprintf(stderr, "C_Login: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + + /* check if a key with the same id already exists */ + rv = C_FindObjectsInit(hSession, search_template, 1); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + rv = C_FindObjects(hSession, &privatekey, 1, &ulObjectCount); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjects: Error = 0x%.8X\n", rv); + error = 1; + goto exit_search; + } + if (ulObjectCount != 0) { + fprintf(stderr, "Key already exists.\n"); + error = 1; + goto exit_search; + } + + /* Set attributes if the key is not to be hidden */ + if (!hide) { + privatekey_template[4].pValue = &falsevalue; + privatekey_template[5].pValue = &truevalue; + } + + /* Generate Key pair for signing/verifying */ + rv = C_GenerateKeyPair(hSession, &genmech, publickey_template, + (sizeof (publickey_template) / + sizeof (CK_ATTRIBUTE)), + privatekey_template, + (sizeof (privatekey_template) / + sizeof (CK_ATTRIBUTE)), + &publickey, &privatekey); + + if (rv != CKR_OK) { + fprintf(stderr, "C_GenerateKeyPair: Error = 0x%.8X\n", rv); + error = 1; + } + + exit_search: + rv = C_FindObjectsFinal(hSession); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8X\n", rv); + error = 1; + } + + exit_session: + (void) C_CloseSession(hSession); + + exit_program: + (void) C_Finalize(NULL_PTR); + + exit(error); +} diff --git a/bin/pkcs11/pkcs11-list.c b/bin/pkcs11/pkcs11-list.c new file mode 100644 index 0000000000..3fb6eaa80f --- /dev/null +++ b/bin/pkcs11/pkcs11-list.c @@ -0,0 +1,192 @@ +/* listobjs [-P] [-s slot] [-i $id | -l $label] [-p $pin] */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + CK_RV rv; + CK_SLOT_ID slot = 0; + CK_SESSION_HANDLE hSession; + CK_UTF8CHAR *pin = NULL; + CK_BYTE attr_id[2]; + CK_OBJECT_HANDLE akey[50]; + char *label = NULL; + int error = 0, public = 0, all = 0; + int i = 0, id = 0; + int c, errflg = 0; + CK_ULONG ulObjectCount; + CK_ATTRIBUTE search_template[] = { + {CKA_ID, &attr_id, sizeof(attr_id)} + }; + extern char *optarg; + extern int optopt; + + while ((c = getopt(argc, argv, ":s:i:l:p:P")) != -1) { + switch (c) { + case 'P': + public = 1; + break; + case 's': + slot = atoi(optarg); + break; + case 'i': + id = atoi(optarg); + id &= 0xffff; + break; + case 'l': + label = optarg; + break; + case 'p': + pin = (CK_UTF8CHAR *)optarg; + break; + case ':': + fprintf(stderr, "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + default: + fprintf(stderr, "Unrecognised option: -%c\n", optopt); + errflg++; + } + } + if (errflg) { + fprintf(stderr, + "usage: listobjs [-P] [-s slot] [-p pin] -i id | $label\n"); + exit(1); + } + if ((!id) && (!label)) + all = 1; + if (slot) + printf("slot %d\n", slot); + if (id) { + printf("id %i\n", id); + attr_id[0] = (id >> 8) & 0xff; + attr_id[1] = id & 0xff; + } else if (label) { + printf("label %s\n", label); + search_template[0].type = CKA_LABEL; + search_template[0].pValue = label; + search_template[0].ulValueLen = strlen(label); + } + + /* Initialize the CRYPTOKI library */ + rv = C_Initialize(NULL_PTR); + if (rv != CKR_OK) { + fprintf(stderr, "C_Initialize: Error = 0x%.8X\n", rv); + exit(1); + } + + /* Open a session on the slot found */ + rv = C_OpenSession(slot, CKF_SERIAL_SESSION, + NULL_PTR, NULL_PTR, &hSession); + if (rv != CKR_OK) { + fprintf(stderr, "C_OpenSession: Error = 0x%.8X\n", rv); + error = 1; + goto exit_program; + } + + /* Login to the Token (Keystore) */ + if (!public) { + if (!pin) +#ifndef HAVE_GETPASS + pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); +#else + pin = (CK_UTF8CHAR *)getpass("Enter Pin: "); +#endif + rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); + memset(pin, 0, strlen((char *)pin)); + if (rv != CKR_OK) { + fprintf(stderr, "C_Login: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + } + + rv = C_FindObjectsInit(hSession, search_template, all ? 0 : 1); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8X\n", rv); + error = 1; + goto exit_session; + } + + ulObjectCount = 1; + while (ulObjectCount) { + rv = C_FindObjects(hSession, akey, 50, &ulObjectCount); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjects: Error = 0x%.8X\n", rv); + error = 1; + goto exit_search; + } + + for (i = 0; i < ulObjectCount; i++) { + CK_OBJECT_CLASS oclass = 0; + CK_BYTE labelbuf[64 + 1]; + CK_BYTE idbuf[64]; + CK_ATTRIBUTE attr_template[] = { + {CKA_CLASS, &oclass, sizeof(oclass)}, + {CKA_LABEL, labelbuf, sizeof(labelbuf) - 1}, + {CKA_ID, idbuf, sizeof(idbuf)} + }; + int j, len; + + memset(labelbuf, 0, sizeof(labelbuf)); + memset(idbuf, 0, sizeof(idbuf)); + + rv = C_GetAttributeValue(hSession, akey[i], attr_template, 3); + if (rv != CKR_OK) { + fprintf(stderr, + "C_GetAttributeValue[%d]: rv = 0x%.8X\n", i, rv); + if (rv = CKR_BUFFER_TOO_SMALL) + fprintf(stderr, "%d too small: %u %u %u\n", i, + attr_template[0].ulValueLen, + attr_template[1].ulValueLen, + attr_template[2].ulValueLen); + error = 1; + continue; + } + + len = attr_template[2].ulValueLen; + printf("object[%d]: handle %u class %d label[%u] '%s' id[%u] ", + i, akey[i], oclass, + attr_template[1].ulValueLen, labelbuf, + attr_template[2].ulValueLen); + if (len == 2) { + id = (idbuf[0] << 8) & 0xff00; + id |= idbuf[1] & 0xff; + printf("%i\n", id); + } else { + if (len > 8) + len = 8; + for (j = 0; j < len; j++) + printf("%02x", idbuf[j]); + if (attr_template[2].ulValueLen > len) + printf("...\n"); + else + printf("\n"); + } + } + } + + exit_search: + rv = C_FindObjectsFinal(hSession); + if (rv != CKR_OK) { + fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8X\n", rv); + error = 1; + } + + exit_session: + (void) C_CloseSession(hSession); + + exit_program: + (void) C_Finalize(NULL_PTR); + + exit(error); +}