Skip to content

Instantly share code, notes, and snippets.

@cmouse
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmouse/10530331 to your computer and use it in GitHub Desktop.
Save cmouse/10530331 to your computer and use it in GitHub Desktop.
PKCS#11 RSA key generation
$ sqlite3 /var/lib/softhsm/slot4.db
SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE Token (variableID INTEGER PRIMARY KEY,value TEXT DEFAULT NULL);
INSERT INTO "Token" VALUES(0,'test4 ');
INSERT INTO "Token" VALUES(1,'66C782E8F95BA958F28ADAAE576C42A263C2449AF416FB844499BEF7FD41B2D0');
INSERT INTO "Token" VALUES(2,'66C782E8F95BA958F28ADAAE576C42A263C2449AF416FB844499BEF7FD41B2D0');
CREATE TABLE Objects (objectID INTEGER PRIMARY KEY);
INSERT INTO "Objects" VALUES(1);
CREATE TABLE Attributes (attributeID INTEGER PRIMARY KEY,objectID INTEGER DEFAULT NULL,type INTEGER DEFAULT NULL,value BLOB DEFAULT NULL,length INTEGER DEFAULT 0);
INSERT INTO "Attributes" VALUES(1,1,-2147483648,X'4853AB0100000000',8);
INSERT INTO "Attributes" VALUES(2,1,-2147483647,X'32303134303431323130353734362D30303030303034343737',25);
INSERT INTO "Attributes" VALUES(3,1,0,X'0300000000000000',8);
INSERT INTO "Attributes" VALUES(4,1,256,X'0000000000000000',8);
INSERT INTO "Attributes" VALUES(5,1,358,X'0000000000000000',8);
INSERT INTO "Attributes" VALUES(6,1,355,X'01',1);
INSERT INTO "Attributes" VALUES(7,1,3,X'7465737434',5);
INSERT INTO "Attributes" VALUES(8,1,258,X'01020304',4);
INSERT INTO "Attributes" VALUES(9,1,257,NULL,0);
INSERT INTO "Attributes" VALUES(10,1,2,X'01',1);
INSERT INTO "Attributes" VALUES(11,1,368,X'01',1);
INSERT INTO "Attributes" VALUES(12,1,1,X'01',1);
INSERT INTO "Attributes" VALUES(13,1,268,X'00',1);
INSERT INTO "Attributes" VALUES(14,1,528,X'01',1);
INSERT INTO "Attributes" VALUES(15,1,514,X'00',1);
INSERT INTO "Attributes" VALUES(16,1,259,X'01',1);
INSERT INTO "Attributes" VALUES(17,1,357,X'01',1);
INSERT INTO "Attributes" VALUES(18,1,261,X'01',1);
INSERT INTO "Attributes" VALUES(19,1,264,X'01',1);
INSERT INTO "Attributes" VALUES(20,1,265,X'01',1);
INSERT INTO "Attributes" VALUES(21,1,263,X'01',1);
INSERT INTO "Attributes" VALUES(22,1,354,X'00',1);
INSERT INTO "Attributes" VALUES(23,1,356,X'01',1);
INSERT INTO "Attributes" VALUES(24,1,272,X'',0);
INSERT INTO "Attributes" VALUES(25,1,273,X'',0);
INSERT INTO "Attributes" VALUES(26,1,288,X'C8F34CFB4BF2449E17C0853920A45F550A448FAA9182EF28D373E2ED054CB030674D3DD8C2EAA98A4900896E87C88873D5C9C7D950FB538F67E4A0C1F02736FF12E09CA04EE2B5EECF8E073B7A62466E4A418A1D22F42F014703798649DB5AEA608575A2074AE258B3832A1BAE8A930A6596AE698071075E70AE442173B6F5F9BA31DCD014D77D5109103A8A0F79273C9EFC815D1613199CB29B519AA18C165EED5A37C11C2F456BB6818C02CBB45CA2BBAE85DB061CC4AC249E3021538BBEE5181B477B422D6200C6A5574D9D7F1E5C4408828428B82928DF4E8875FC3F6C747D1E76F415FD1B4204B12DE9C73ECDE101A35F730083AC1F030345EB7D52EFBB',256);
INSERT INTO "Attributes" VALUES(27,1,290,X'010001',3);
INSERT INTO "Attributes" VALUES(28,1,291,X'192A7B3017854A39A050E07E548BB152B59BFB80098423CE7198D84905BA627055679380C37C5EEA2E154EA0D48975294893621F61A870010C2A5245A77D49C26D0B4B223A6EE308FADE57228843A97D63784CC3345EEF4A122A29BC7B206904E43CA28C3DAC8FA73B28088C79F1E9D34A00B26C0D055ABE658F358218FB47579B81DF0C58445ACB954780CBCDEEE23D4A4A9AECECD3B9B7786A58537744C9A75F98408A5F4D0FD117CF97FCE5A9EDA2F06EF2D759908FD0BDE42C4110EB72ECB63AAC40ADF779813144EA7744E07B2172B1ECBF0198D1B0183F16603D243FFC6D5415F50DDB28C4B7607BE7B58F7BFE68C2E80ECB62B32CB2CC2E0E3E079A01',256);
INSERT INTO "Attributes" VALUES(29,1,292,X'F866079612B24D390432FB77525F6402C06FD67E7A5A29E34A1556E2738899EE0152D8642A042091578355363E3C272A15FFB6DA17FD545D75140996EC6EF0DFA0202F3B8399C635D84706C0EB29516AB8CD4BC8F44AABF01BC4559C097249BBC2938D006FB8836DBF437DB98958668B3E1808C458AB10D566EADDF1AF7B5E01',128);
INSERT INTO "Attributes" VALUES(30,1,293,X'CF198F223B23FC2DA9C8AC6F4E6DDD1BF0CCAA22B8B5B0F23FEF1DDCAB94A2C1133763062D76F3312FEB857685ED425F75532136B8D1F6CB1D9D83FF3922F449A5B9DBFE1C9CD38E956889B786D8DD662426296636D9B685B2CCD996934B7C7FD396ADF795DAD60F1FC254EEE5D3840CB4E3E93A10C5D3E70014F2D32BDF45BB',128);
CREATE TRIGGER deleteTrigger BEFORE DELETE ON Objects BEGIN DELETE FROM Attributes WHERE objectID = OLD.objectID; END;
CREATE INDEX idxObject ON Attributes (objectID, type);
COMMIT;
sqlite>
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <string>
#include <string.h>
#include <p11-kit/p11-kit.h>
int main(void) {
// we only use known modules
p11_kit_initialize_registered();
CK_FUNCTION_LIST_PTR *modules = p11_kit_registered_modules();
CK_FUNCTION_LIST_PTR module = p11_kit_registered_name_to_module("softhsm");
/*
if (module == NULL) {
std::cerr << "No module named softhsm found" << std::endl;
return 1;
}*/
_CK_INFO info;
_CK_SLOT_INFO slotInfo;
_CK_TOKEN_INFO tokenInfo;
CK_SLOT_ID slotID;
// locate us a module which has a usable token
while((module = *modules)) {
unsigned long slots;
module->C_GetInfo(&info);
module->C_GetSlotList(1, NULL, &slots);
if (slots > 0) {
for(unsigned long i=0;i<slots;i++) {
module->C_GetSlotInfo(i, &slotInfo);
if ((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) {
module->C_GetTokenInfo(i, &tokenInfo);
if ((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED) {
slotID = i;
goto hasModule;
}
}
}
}
modules++;
}
if (module == NULL) return 1;
hasModule:
slotID = 4;
std::cout << "module name: " << p11_kit_registered_module_to_name(module) << std::endl;
std::cout << "Chosen manufacturer: " << info.manufacturerID << std::endl;
std::cout << "Chosen slot: " << slotID << std::endl;
// needs login?
CK_SESSION_HANDLE session;
std::cout << module->C_OpenSession(slotID, CKF_SERIAL_SESSION|CKF_RW_SESSION, 0, 0, &session) << std::endl;
if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED) {
// provide 1234
unsigned char pin[] = "1234";
std::cout << module->C_Login(session, CKU_USER, pin, 4) << std::endl;
}
CK_MECHANISM mech;
unsigned long objects;
// need key object
CK_OBJECT_HANDLE object, object2;
CK_ATTRIBUTE attr[6];
CK_ATTRIBUTE attr2[8];
char value = CK_TRUE;
CK_ULONG bits = 2048;
unsigned char pubExp[] = "\000\001\000\001";
unsigned char id[] = "\x01\x02\x03\x04";
unsigned char label[] = "test4";
// public attributes
attr[0].type = CKA_ENCRYPT;
attr[0].pValue = &value;
attr[0].ulValueLen = 1;
attr[1].type = CKA_VERIFY;
attr[1].pValue = &value;
attr[1].ulValueLen = 1;
attr[2].type = CKA_WRAP;
attr[2].pValue = &value;
attr[2].ulValueLen = 1;
attr[3].type = CKA_MODULUS_BITS;
attr[3].pValue = (void*)&bits;
attr[3].ulValueLen = sizeof(CK_ULONG);
attr[4].type = CKA_PUBLIC_EXPONENT;
attr[4].pValue = pubExp;
attr[4].ulValueLen = 4;
attr[5].type = CKA_LABEL;
attr[5].pValue = label;
attr[5].ulValueLen = 5;
// private attributes
attr2[0].type = CKA_TOKEN;
attr2[0].pValue = &value;
attr2[0].ulValueLen = 1;
attr2[1].type = CKA_PRIVATE;
attr2[1].pValue = &value;
attr2[1].ulValueLen = 1;
attr2[2].type = CKA_SENSITIVE;
attr2[2].pValue = &value;
attr2[2].ulValueLen = 1;
attr2[3].type = CKA_DECRYPT;
attr2[3].pValue = &value;
attr2[3].ulValueLen = 1;
attr2[4].type = CKA_SIGN;
attr2[4].pValue = &value;
attr2[4].ulValueLen = 1;
attr2[5].type = CKA_UNWRAP;
attr2[5].pValue = &value;
attr2[5].ulValueLen = 1;
attr2[6].type = CKA_ID;
attr2[6].pValue = id;
attr2[6].ulValueLen = 4;
attr2[7].type = CKA_LABEL;
attr2[7].pValue = label;
attr2[7].ulValueLen = 5;
mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
mech.pParameter = NULL;
mech.ulParameterLen = 0;
std::cout << module->C_GenerateKeyPair(session, &mech, attr, 6, attr2, 8, &object, &object2) << std::endl;
// need key object
attr[0].type = CKA_SIGN;
attr[0].pValue = &value;
attr[0].ulValueLen = 1;
attr[1].type = CKA_LABEL;
attr[1].pValue = const_cast<char*>("test");
attr[1].ulValueLen = 4;
std::cout << module->C_FindObjectsInit(session, attr, 2) << std::endl;
std::cout << module->C_FindObjects(session, &object, 1, &objects) << std::endl;
std::cout << module->C_FindObjectsFinal(session) << std::endl;
std::cout << "Found " << objects << " object(s)" << std::endl;
if (objects == 0) return 0;
mech.mechanism = CKM_SHA256_RSA_PKCS;
mech.pParameter = 0;
mech.ulParameterLen = 0;
unsigned char data[] = "A quick brown fox jumped over the lazy fox";
unsigned long datalen = sizeof(data);
unsigned char digest[4096];
unsigned long digestlen = sizeof(digest);
std::cout << module->C_SignInit(session, &mech, object) << std::endl;
std::cout << module->C_Sign(session, data, datalen, digest, &digestlen) << std::endl;
// try verify signature
attr[0].type = CKA_VERIFY;
attr[0].pValue = &value;
attr[0].ulValueLen = 1;
module->C_FindObjectsInit(session, attr, 1);
module->C_FindObjects(session, &object, 1, &objects);
module->C_FindObjectsFinal(session);
std::cout << module->C_VerifyInit(session, &mech, object) << std::endl;
std::cout << module->C_Verify(session, data, datalen, digest, digestlen) << std::endl;
p11_kit_finalize_registered();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment