diff --git a/ykcs11/Makefile.am b/ykcs11/Makefile.am index 22fbfea..f891949 100644 --- a/ykcs11/Makefile.am +++ b/ykcs11/Makefile.am @@ -36,6 +36,7 @@ lib_LTLIBRARIES = libykcs11.la libykcs11_la_SOURCES = ykcs11.c version.c ykcs11.pc.in ykcs11.map libykcs11_la_SOURCES += vendors.c vendor.h yubico.c yubico.h libykcs11_la_SOURCES += utils.h utils.c +libykcs11_la_SOURCES += obj_types.h objects.h objects.c #internal.h #libykcs11_la_SOURCES += error.c diff --git a/ykcs11/obj_types.h b/ykcs11/obj_types.h new file mode 100644 index 0000000..0c58c4a --- /dev/null +++ b/ykcs11/obj_types.h @@ -0,0 +1,88 @@ +#ifndef OBJ_TYPES_H +#define OBJ_TYPES_H + +#include "pkcs11t.h" + +// TODO: this is mostly from OpenSC, how to give credit? +typedef enum { + PIV_OBJ_CCC = 0, // Card capability container + PIV_OBJ_CHUI, // Cardholder unique id + /* PIV_OBJ_UCHUI is not in new with 800-73-2 */ + PIV_OBJ_X509_PIV_AUTH, // PIV authentication + PIV_OBJ_CHF, // Cardholder fingerprints + PIV_OBJ_SEC_OBJ, // Security object + PIV_OBJ_CHFI, // Cardholder facial images + PIV_OBJ_X509_CARD_AUTH, // Certificate for card authentication + PIV_OBJ_X509_DS, // Certificate for digital signature + PIV_OBJ_X509_KM, // Certificate for key management + PIV_OBJ_PI, // Cardholder printed information + PIV_OBJ_DISCOVERY, // Discovery object + PIV_OBJ_HISTORY, // History object + PIV_OBJ_RETIRED_X509_1, // Retired certificate for KM 1 + PIV_OBJ_RETIRED_X509_2, // Retired certificate for KM 2 + PIV_OBJ_RETIRED_X509_3, // Retired certificate for KM 3 + PIV_OBJ_RETIRED_X509_4, // Retired certificate for KM 4 + PIV_OBJ_RETIRED_X509_5, // Retired certificate for KM 5 + PIV_OBJ_RETIRED_X509_6, // Retired certificate for KM 6 + PIV_OBJ_RETIRED_X509_7, // Retired certificate for KM 7 + PIV_OBJ_RETIRED_X509_8, // Retired certificate for KM 8 + PIV_OBJ_RETIRED_X509_9, // Retired certificate for KM 9 + PIV_OBJ_RETIRED_X509_10, // Retired certificate for KM 10 + PIV_OBJ_RETIRED_X509_11, // Retired certificate for KM 11 + PIV_OBJ_RETIRED_X509_12, // Retired certificate for KM 12 + PIV_OBJ_RETIRED_X509_13, // Retired certificate for KM 13 + PIV_OBJ_RETIRED_X509_14, // Retired certificate for KM 14 + PIV_OBJ_RETIRED_X509_15, // Retired certificate for KM 15 + PIV_OBJ_RETIRED_X509_16, // Retired certificate for KM 16 + PIV_OBJ_RETIRED_X509_17, // Retired certificate for KM 17 + PIV_OBJ_RETIRED_X509_18, // Retired certificate for KM 18 + PIV_OBJ_RETIRED_X509_19, // Retired certificate for KM 19 + PIV_OBJ_RETIRED_X509_20, // Retired certificate for KM 20 + PIV_OBJ_IRIS_IMAGE, // Cardholder iris images + PIV_OBJ_BITGT, // Biometric information templates group template + PIV_OBJ_SM_SIGNER, // Secure messaging signer + PIV_OBJ_PC_REF_DATA, // Pairing code reference data + PIV_OBJ_9B03, // NON-STANDARD TODO: remove? + PIV_OBJ_9A06, // NON-STANDARD + PIV_OBJ_9C06, // NON-STANDARD + PIV_OBJ_9D06, // NON-STANDARD + PIV_OBJ_9E06, // NON-STANDARD + PIV_OBJ_8206, // NON-STANDARD + PIV_OBJ_8306, // NON-STANDARD + PIV_OBJ_8406, // NON-STANDARD + PIV_OBJ_8506, // NON-STANDARD + PIV_OBJ_8606, // NON-STANDARD + PIV_OBJ_8706, // NON-STANDARD + PIV_OBJ_8806, // NON-STANDARD + PIV_OBJ_8906, // NON-STANDARD + PIV_OBJ_8A06, // NON-STANDARD + PIV_OBJ_8B06, // NON-STANDARD + PIV_OBJ_8C06, // NON-STANDARD + PIV_OBJ_8D06, // NON-STANDARD + PIV_OBJ_8E06, // NON-STANDARD + PIV_OBJ_8F06, // NON-STANDARD + PIV_OBJ_9006, // NON-STANDARD + PIV_OBJ_9106, // NON-STANDARD + PIV_OBJ_9206, // NON-STANDARD + PIV_OBJ_9306, // NON-STANDARD + PIV_OBJ_9406, // NON-STANDARD + PIV_OBJ_9506, // NON-STANDARD + PIV_OBJ_LAST_ENUM +} piv_obj_id_t; + +#define PIV_OBJECT_TYPE_CERT 1 +#define PIV_OBJECT_TYPE_PUBKEY 2 +#define PIV_OBJECT_NOT_PRESENT 4 + +typedef struct { + //const CK_OBJECT_CLASS class; + piv_obj_id_t type; + const CK_CHAR_PTR name; // TODO: or utf8 + const CK_CHAR_PTR oid; + CK_BYTE tag_len; // TODO: or ulong? + CK_BYTE tag_value[3]; + CK_BYTE containerid[2]; /* will use as relative paths for simulation */ // TODO: needed? + CK_ULONG flags; /* object has some internal object like a cert */ +} piv_obj_t; + +#endif diff --git a/ykcs11/objects.c b/ykcs11/objects.c new file mode 100644 index 0000000..e2e9678 --- /dev/null +++ b/ykcs11/objects.c @@ -0,0 +1,281 @@ +#include "objects.h" +#include +#include + +//TODO: this is mostly a snippet from OpenSC how to give credit? +/* Must be in order, and one per enumerated PIV_OBJ */ +static const piv_obj_t objects[] = { + { PIV_OBJ_CCC, "Card Capability Container", + "2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", 0}, + { PIV_OBJ_CHUI, "Card Holder Unique Identifier", + "2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 0}, + { PIV_OBJ_X509_PIV_AUTH, "X.509 Certificate for PIV Authentication", + "2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01", PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_CHF, "Card Holder Fingerprints", + "2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10", 0}, + { PIV_OBJ_SEC_OBJ, "Security Object", + "2.16.840.1.101.3.7.2.144.0", 3, "\x5F\xC1\x06", "\x90\x00", 0}, + { PIV_OBJ_CHFI, "Cardholder Facial Images", + "2.16.840.1.101.3.7.2.96.48", 3, "\x5F\xC1\x08", "\x60\x30", 0}, + { PIV_OBJ_X509_CARD_AUTH, "X.509 Certificate for Card Authentication", + "2.16.840.1.101.3.7.2.5.0", 3, "\x5F\xC1\x01", "\x05\x00", PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_X509_DS, "X.509 Certificate for Digital Signature", + "2.16.840.1.101.3.7.2.1.0", 3, "\x5F\xC1\x0A", "\x01\x00", PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_X509_KM, "X.509 Certificate for Key Management", + "2.16.840.1.101.3.7.2.1.2", 3, "\x5F\xC1\x0B", "\x01\x02", PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_PI, "Printed Information", + "2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01", 0}, + { PIV_OBJ_DISCOVERY, "Discovery Object", + "2.16.840.1.101.3.7.2.96.80", 1, "\x7E", "\x60\x50", 0}, + { PIV_OBJ_HISTORY, "Key History Object", + "2.16.840.1.101.3.7.2.96.96", 3, "\x5F\xC1\x0C", "\x60\x60", 0}, + +/* 800-73-3, 21 new objects, 20 history certificates */ + { PIV_OBJ_RETIRED_X509_1, "Retired X.509 Certificate for Key Management 1", + "2.16.840.1.101.3.7.2.16.1", 3, "\x5F\xC1\x0D", "\x10\x01", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_2, "Retired X.509 Certificate for Key Management 2", + "2.16.840.1.101.3.7.2.16.2", 3, "\x5F\xC1\x0E", "\x10\x02", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_3, "Retired X.509 Certificate for Key Management 3", + "2.16.840.1.101.3.7.2.16.3", 3, "\x5F\xC1\x0F", "\x10\x03", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_4, "Retired X.509 Certificate for Key Management 4", + "2.16.840.1.101.3.7.2.16.4", 3, "\x5F\xC1\x10", "\x10\x04", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_5, "Retired X.509 Certificate for Key Management 5", + "2.16.840.1.101.3.7.2.16.5", 3, "\x5F\xC1\x11", "\x10\x05", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_6, "Retired X.509 Certificate for Key Management 6", + "2.16.840.1.101.3.7.2.16.6", 3, "\x5F\xC1\x12", "\x10\x06", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_7, "Retired X.509 Certificate for Key Management 7", + "2.16.840.1.101.3.7.2.16.7", 3, "\x5F\xC1\x13", "\x10\x07", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_8, "Retired X.509 Certificate for Key Management 8", + "2.16.840.1.101.3.7.2.16.8", 3, "\x5F\xC1\x14", "\x10\x08", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_9, "Retired X.509 Certificate for Key Management 9", + "2.16.840.1.101.3.7.2.16.9", 3, "\x5F\xC1\x15", "\x10\x09", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_10, "Retired X.509 Certificate for Key Management 10", + "2.16.840.1.101.3.7.2.16.10", 3, "\x5F\xC1\x16", "\x10\x0A", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_11, "Retired X.509 Certificate for Key Management 11", + "2.16.840.1.101.3.7.2.16.11", 3, "\x5F\xC1\x17", "\x10\x0B", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_12, "Retired X.509 Certificate for Key Management 12", + "2.16.840.1.101.3.7.2.16.12", 3, "\x5F\xC1\x18", "\x10\x0C", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_13, "Retired X.509 Certificate for Key Management 13", + "2.16.840.1.101.3.7.2.16.13", 3, "\x5F\xC1\x19", "\x10\x0D", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_14, "Retired X.509 Certificate for Key Management 14", + "2.16.840.1.101.3.7.2.16.14", 3, "\x5F\xC1\x1A", "\x10\x0E", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_15, "Retired X.509 Certificate for Key Management 15", + "2.16.840.1.101.3.7.2.16.15", 3, "\x5F\xC1\x1B", "\x10\x0F", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_16, "Retired X.509 Certificate for Key Management 16", + "2.16.840.1.101.3.7.2.16.16", 3, "\x5F\xC1\x1C", "\x10\x10", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_17, "Retired X.509 Certificate for Key Management 17", + "2.16.840.1.101.3.7.2.16.17", 3, "\x5F\xC1\x1D", "\x10\x11", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_18, "Retired X.509 Certificate for Key Management 18", + "2.16.840.1.101.3.7.2.16.18", 3, "\x5F\xC1\x1E", "\x10\x12", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_19, "Retired X.509 Certificate for Key Management 19", + "2.16.840.1.101.3.7.2.16.19", 3, "\x5F\xC1\x1F", "\x10\x13", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + { PIV_OBJ_RETIRED_X509_20, "Retired X.509 Certificate for Key Management 20", + "2.16.840.1.101.3.7.2.16.20", 3, "\x5F\xC1\x20", "\x10\x14", + PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT}, + + { PIV_OBJ_IRIS_IMAGE, "Cardholder Iris Images", + "2.16.840.1.101.3.7.2.16.21", 3, "\x5F\xC1\x21", "\x10\x15", 0}, + { PIV_OBJ_BITGT, "Biometric Information Templates Group Template", + "2.16.840.1.101.3.7.2.16.22", 2, "\x7F\x61", "\x10\x16" }, + { PIV_OBJ_SM_SIGNER, "Secure Messaging Certificate Signer", + "2.16.840.1.101.3.7.2.16.23", 3, "\x5F\xC1\x22", "\x10\x17"}, + { PIV_OBJ_PC_REF_DATA, "Pairing Code Reference Data Container", + "2.16.840.1.101.3.7.2.16.24", 3, "\x5F\xC1\x23", "\x10\x18"}, + +/* following not standard , to be used by piv-tool only for testing */ + { PIV_OBJ_9B03, "3DES-ECB ADM", + "2.16.840.1.101.3.7.2.9999.3", 2, "\x9B\x03", "\x9B\x03", 0}, + /* Only used when signing a cert req, usually from engine + * after piv-tool generated the key and saved the pub key + * to a file. Note RSA key can be 1024, 2048 or 3072 + * but still use the "9x06" name. + */ + { PIV_OBJ_9A06, "RSA 9A Pub key from last genkey", + "2.16.840.1.101.3.7.2.9999.20", 2, "\x9A\x06", "\x9A\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9C06, "Pub 9C key from last genkey", + "2.16.840.1.101.3.7.2.9999.21", 2, "\x9C\x06", "\x9C\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9D06, "Pub 9D key from last genkey", + "2.16.840.1.101.3.7.2.9999.22", 2, "\x9D\x06", "\x9D\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9E06, "Pub 9E key from last genkey", + "2.16.840.1.101.3.7.2.9999.23", 2, "\x9E\x06", "\x9E\x06", PIV_OBJECT_TYPE_PUBKEY}, + + { PIV_OBJ_8206, "Pub 82 key ", + "2.16.840.1.101.3.7.2.9999.101", 2, "\x82\x06", "\x82\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8306, "Pub 83 key ", + "2.16.840.1.101.3.7.2.9999.102", 2, "\x83\x06", "\x83\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8406, "Pub 84 key ", + "2.16.840.1.101.3.7.2.9999.103", 2, "\x84\x06", "\x84\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8506, "Pub 85 key ", + "2.16.840.1.101.3.7.2.9999.104", 2, "\x85\x06", "\x85\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8606, "Pub 86 key ", + "2.16.840.1.101.3.7.2.9999.105", 2, "\x86\x06", "\x86\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8706, "Pub 87 key ", + "2.16.840.1.101.3.7.2.9999.106", 2, "\x87\x06", "\x87\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8806, "Pub 88 key ", + "2.16.840.1.101.3.7.2.9999.107", 2, "\x88\x06", "\x88\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8906, "Pub 89 key ", + "2.16.840.1.101.3.7.2.9999.108", 2, "\x89\x06", "\x89\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8A06, "Pub 8A key ", + "2.16.840.1.101.3.7.2.9999.109", 2, "\x8A\x06", "\x8A\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8B06, "Pub 8B key ", + "2.16.840.1.101.3.7.2.9999.110", 2, "\x8B\x06", "\x8B\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8C06, "Pub 8C key ", + "2.16.840.1.101.3.7.2.9999.111", 2, "\x8C\x06", "\x8C\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8D06, "Pub 8D key ", + "2.16.840.1.101.3.7.2.9999.112", 2, "\x8D\x06", "\x8D\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8E06, "Pub 8E key ", + "2.16.840.1.101.3.7.2.9999.113", 2, "\x8E\x06", "\x8E\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_8F06, "Pub 8F key ", + "2.16.840.1.101.3.7.2.9999.114", 2, "\x8F\x06", "\x8F\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9006, "Pub 90 key ", + "2.16.840.1.101.3.7.2.9999.115", 2, "\x90\x06", "\x90\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9106, "Pub 91 key ", + "2.16.840.1.101.3.7.2.9999.116", 2, "\x91\x06", "\x91\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9206, "Pub 92 key ", + "2.16.840.1.101.3.7.2.9999.117", 2, "\x92\x06", "\x92\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9306, "Pub 93 key ", + "2.16.840.1.101.3.7.2.9999.118", 2, "\x93\x06", "\x93\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9406, "Pub 94 key ", + "2.16.840.1.101.3.7.2.9999.119", 2, "\x94\x06", "\x94\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_9506, "Pub 95 key ", + "2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY}, + { PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0} +}; + +static const CK_ULONG n_objects = sizeof(objects) / sizeof(piv_obj_t); + +static CK_RV get_object_class(CK_OBJECT_HANDLE obj, CK_OBJECT_CLASS_PTR class) { + if ((objects[obj].flags & PIV_OBJECT_TYPE_PUBKEY)) + *class = CKO_PUBLIC_KEY; + else if ((objects[obj].flags & PIV_OBJECT_TYPE_CERT)) + *class = CKO_CERTIFICATE; + else + *class - CKO_DATA; // TODO: other possibilities? + return CKR_OK; +} + +static CK_RV get_object_label(CK_OBJECT_HANDLE obj, CK_UTF8CHAR_PTR label) { + strcpy(label, objects[obj].name); +} + +static CK_RV get_object_oid(CK_OBJECT_HANDLE obj, CK_UTF8CHAR_PTR oid) { +// strcpy(oid, objects[obj].oid); + oid[0] = 0x2b; + oid[1] = 0x06; + oid[2] = 0x01; + oid[3] = 0x04; + oid[4] = 0x01; + oid[5] = 0x82; + oid[6] = 0x37; + oid[7] = 0x15; + oid[8] = 0x14; +} + + +CK_RV get_attribute(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { + fprintf(stderr, "FOR OBJECT %lu, I WANT ", obj); + CK_ULONG i; + + switch (template->type) { + case CKA_CLASS: + fprintf(stderr, "CLASS\n"); + get_object_class(obj, template->pValue); + return CKR_OK; + + case CKA_TOKEN: + //get_object + case CKA_PRIVATE: + template->ulValueLen = CK_UNAVAILABLE_INFORMATION; + return CKR_OK; + + case CKA_LABEL: + fprintf(stderr, "LABEL\n"); + get_object_label(obj, template->pValue); + return CKR_OK; + + case CKA_APPLICATION: + fprintf(stderr, "APPLICATION\n"); + get_object_label(obj, template->pValue); + return CKR_OK; + + case CKA_VALUE: + case CKA_OBJECT_ID: + fprintf(stderr, "OID\n!!!"); // TODO: this is a DER encoded byte array + + get_object_oid(obj, template->pValue); + template->ulValueLen = 9; + return CKR_OK; + + case CKA_CERTIFICATE_TYPE: + case CKA_ISSUER: + case CKA_SERIAL_NUMBER: + case CKA_KEY_TYPE: + fprintf(stderr, "Return the key type\n"); + return CKR_OK; + + case CKA_SUBJECT: + case CKA_ID: + case CKA_SENSITIVE: + case CKA_ENCRYPT: + case CKA_DECRYPT: + case CKA_WRAP: + case CKA_UNWRAP: + case CKA_SIGN: + case CKA_SIGN_RECOVER: + case CKA_VERIFY: + case CKA_VERIFY_RECOVER: + case CKA_DERIVE: + case CKA_START_DATE: + case CKA_END_DATE: + case CKA_MODULUS: + case CKA_MODULUS_BITS: + case CKA_PUBLIC_EXPONENT: + case CKA_PRIVATE_EXPONENT: + case CKA_PRIME_1: + case CKA_PRIME_2: + case CKA_EXPONENT_1: + case CKA_EXPONENT_2: + case CKA_COEFFICIENT: + case CKA_PRIME: + case CKA_SUBPRIME: + case CKA_BASE: + case CKA_VALUE_BITS: + case CKA_VALUE_LEN: + case CKA_EXTRACTABLE: + case CKA_LOCAL: + case CKA_NEVER_EXTRACTABLE: + case CKA_ALWAYS_SENSITIVE: + case CKA_MODIFIABLE: + fprintf(stderr, "MODIFIABLE\n"); + *((CK_ULONG_PTR)template->pValue) = CK_FALSE; + return CKR_OK; + case CKA_VENDOR_DEFINED: + default: + fprintf(stderr, "UNKNOWN ATTRIBUTE!!!!! %lu\n", template[0].type); + + return CKR_FUNCTION_FAILED; + } + + // Never reached + return CKR_FUNCTION_FAILED; + +} diff --git a/ykcs11/objects.h b/ykcs11/objects.h new file mode 100644 index 0000000..e7539ea --- /dev/null +++ b/ykcs11/objects.h @@ -0,0 +1,12 @@ +#ifndef OBJECTS_H +#define OBJECTS_H + +#include "pkcs11t.h" +#include "obj_types.h" + +#include // TODO: delete + +CK_RV get_attribute(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template); +//CK_RV get_object_class(CK_OBJECT_HANDLE obj, CK_OBJECT_CLASS_PTR class); + +#endif diff --git a/ykcs11/pkcs11t.h b/ykcs11/pkcs11t.h index ddb608e..3d10176 100644 --- a/ykcs11/pkcs11t.h +++ b/ykcs11/pkcs11t.h @@ -375,6 +375,7 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE; #define CKA_LABEL 0x00000003 #define CKA_APPLICATION 0x00000010 #define CKA_VALUE 0x00000011 +#define CKA_OBJECT_ID 0x00000012 #define CKA_CERTIFICATE_TYPE 0x00000080 #define CKA_ISSUER 0x00000081 #define CKA_SERIAL_NUMBER 0x00000082 diff --git a/ykcs11/utils.h b/ykcs11/utils.h index 2e40461..804cef0 100644 --- a/ykcs11/utils.h +++ b/ykcs11/utils.h @@ -1,7 +1,7 @@ #ifndef UTILS_H #define UTILS_H -#include "pkcs11.h" +#include "pkcs11t.h" #include "vendors.h" typedef struct { diff --git a/ykcs11/vendors.c b/ykcs11/vendors.c index 609453d..b4fd55d 100644 --- a/ykcs11/vendors.c +++ b/ykcs11/vendors.c @@ -29,6 +29,8 @@ vendor_t get_vendor(vendor_id_t vid) { v.get_token_mechanisms_num = YUBICO_get_token_mechanisms_num; v.get_token_mechanism_list = YUBICO_get_token_mechanism_list; v.get_token_mechanism_info = YUBICO_get_token_mechanism_info; + v.get_token_objects_num = YUBICO_get_token_objects_num; + v.get_token_object_list = YUBICO_get_token_object_list; break; case UNKNOWN: @@ -46,6 +48,8 @@ vendor_t get_vendor(vendor_id_t vid) { v.get_token_mechanisms_num = NULL; v.get_token_mechanism_list = NULL; v.get_token_mechanism_info = NULL; + v.get_token_objects_num = NULL; + v.get_token_object_list = NULL; } return v; diff --git a/ykcs11/vendors.h b/ykcs11/vendors.h index ace8dee..73e00ac 100644 --- a/ykcs11/vendors.h +++ b/ykcs11/vendors.h @@ -2,6 +2,7 @@ #define VENDORS_H #include "pkcs11.h" +#include "objects.h" typedef enum { UNKNOWN = 0x00, @@ -21,6 +22,8 @@ typedef CK_RV (*get_t_serial_f)(CK_CHAR_PTR, CK_ULONG); typedef CK_RV (*get_t_mechanisms_num_f)(CK_ULONG_PTR); typedef CK_RV (*get_t_mechanism_list_f)(CK_MECHANISM_TYPE_PTR, CK_ULONG); typedef CK_RV (*get_t_mechanism_info_f)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR); +typedef CK_RV (*get_t_objects_num_f)(CK_ULONG_PTR); +typedef CK_RV (*get_t_object_list_f)(piv_obj_id_t *, CK_ULONG); typedef struct { @@ -37,6 +40,8 @@ typedef struct { get_t_mechanisms_num_f get_token_mechanisms_num; get_t_mechanism_list_f get_token_mechanism_list; get_t_mechanism_info_f get_token_mechanism_info; + get_t_objects_num_f get_token_objects_num; + get_t_object_list_f get_token_object_list; } vendor_t; vendor_id_t get_vendor_id(char *vendor_name); diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 271b4dd..9a977d4 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -12,7 +12,7 @@ } while (0) #define YKCS11_DBG 1 // General debug, must be either 1 or 0 -#define YKCS11_DINOUT 1 // Function in/out debug, must be either 1 or 0 +#define YKCS11_DINOUT 0 // Function in/out debug, must be either 1 or 0 #define YKCS11_MANUFACTURER "Yubico (www.yubico.com)" #define YKCS11_LIBDESC "PKCS#11 PIV Library (SP-800-73)" @@ -47,6 +47,25 @@ static CK_ULONG n_slots_with_token = 0; static CK_SESSION_HANDLE session = CK_INVALID_HANDLE; // TODO: support multiple sessions? static CK_SESSION_INFO session_info; +static struct { + CK_BBOOL active; + CK_ULONG idx; + CK_BBOOL all; + CK_OBJECT_CLASS class; +} find_obj; + +static piv_obj_id_t piv_objects[] = { // Mandatory PIV objects + PIV_OBJ_CCC, // Card capability container + PIV_OBJ_CHUI, // Cardholder unique id + PIV_OBJ_X509_PIV_AUTH, // PIV authentication + PIV_OBJ_CHF, // Cardholder fingerprints + PIV_OBJ_CHFI, // Cardholder facial images + PIV_OBJ_X509_DS, // Certificate for digital signature + PIV_OBJ_X509_KM, // Certificate for key management + PIV_OBJ_X509_CARD_AUTH, // Certificate for card authentication + PIV_OBJ_SEC_OBJ // Security object +}; + extern CK_FUNCTION_LIST function_list; // TODO: check all return values /* General Purpose */ @@ -79,8 +98,9 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( DBG(("Found %lu slot(s) of which %lu tokenless/unsupported", n_slots, n_slots - n_slots_with_token)); + find_obj.active = CK_FALSE; // TODO: FILL OUT INIT ARGS; - + DOUT; return CKR_OK; } @@ -369,7 +389,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)( { DIN; vendor_t vendor; - + if (piv_state == NULL) { DBG(("libykpiv is not initialized or already finalized")); return CKR_CRYPTOKI_NOT_INITIALIZED; @@ -391,7 +411,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)( if (vendor.get_token_mechanism_info(type, pInfo) != CKR_OK) return CKR_MECHANISM_INVALID; - + DOUT; return CKR_OK; } @@ -712,7 +732,33 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)( ) { DIN; - DBG(("TODO!!!")); + + if (piv_state == NULL) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + if (session != YKCS11_SESSION_ID) + return CKR_SESSION_CLOSED; + + if (hSession != session) + return CKR_SESSION_HANDLE_INVALID; + + if (pTemplate == NULL_PTR || ulCount == 0) + return CKR_ARGUMENTS_BAD; + + if (find_obj.active != CK_TRUE) + return CKR_OPERATION_NOT_INITIALIZED; + + if (pTemplate[0].pValue == NULL_PTR) { + DBG(("Just get size")); + pTemplate[0].ulValueLen = 1024; // TODO: get attribute size + DOUT; + return CKR_OK; + } + DBG(("Trying to get object %lx", hObject)); + DBG(("Type: 0x%lx Value: %lu Len: %lu", pTemplate[0].type, *((CK_ULONG_PTR)pTemplate[0].pValue), pTemplate[0].ulValueLen)); + // TODO: here for i in ulCount + return get_attribute(hObject, pTemplate); + DOUT; return CKR_OK; } @@ -737,11 +783,48 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)( ) { DIN; - DBG(("TODO!!!")); + CK_ULONG i; + + if (piv_state == NULL) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + if (session != YKCS11_SESSION_ID) + return CKR_SESSION_CLOSED; + + if (hSession != session) + return CKR_SESSION_HANDLE_INVALID; + + if (find_obj.active == CK_TRUE) + return CKR_OPERATION_ACTIVE; + + if (ulCount == 0) { + DBG(("Find ALL the objects!")); + find_obj.active = CK_TRUE; + find_obj.all = CK_TRUE; + find_obj.idx = 0; + DOUT; + return CKR_OK; + } + return CKR_FUNCTION_FAILED; + DBG(("Initialized search for %lu objects", ulCount)); + + if (pTemplate == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + find_obj.active = CK_TRUE; + + for (i = 0; i < ulCount; i++) { + DBG(("Object %lu\nType: %lu Value: %lu Len: %lu", i, pTemplate[i].type, *((CK_ULONG_PTR)pTemplate[i].pValue), pTemplate[i].ulValueLen)); + + // if () + + } + + DOUT; return CKR_OK; } - +CK_ULONG bla = 1; // TODO: delete CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, @@ -750,7 +833,34 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)( ) { DIN; - DBG(("TODO!!!")); + + if (piv_state == NULL) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + if (session != YKCS11_SESSION_ID) + return CKR_SESSION_CLOSED; + + if (hSession != session) + return CKR_SESSION_HANDLE_INVALID; + + if (phObject == NULL_PTR || + ulMaxObjectCount == 0 || + pulObjectCount == NULL_PTR) + return CKR_ARGUMENTS_BAD; + + if (find_obj.active != CK_TRUE) + return CKR_OPERATION_NOT_INITIALIZED; + + DBG(("Can return %lu object(s)", ulMaxObjectCount)); + if (find_obj.all == CK_TRUE) { + // Trying to get all the objects, just return the next + //*phObject = piv_objects[find_obj.idx++]; + //*pulObjectCount = 1; + *phObject = piv_objects[bla]; + *pulObjectCount = bla--; + } + + DOUT; return CKR_OK; } @@ -760,7 +870,21 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)( ) { DIN; - DBG(("TODO!!!")); + + if (piv_state == NULL) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + if (session != YKCS11_SESSION_ID) + return CKR_SESSION_CLOSED; + + if (hSession != session) + return CKR_SESSION_HANDLE_INVALID; + + if (find_obj.active != CK_TRUE) + return CKR_OPERATION_NOT_INITIALIZED; + + find_obj.active = CK_FALSE; + DOUT; return CKR_OK; } diff --git a/ykcs11/yubico.c b/ykcs11/yubico.c index 1004ace..dd968a4 100644 --- a/ykcs11/yubico.c +++ b/ykcs11/yubico.c @@ -67,6 +67,10 @@ static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH {0, 0, CKF_DIGEST} // CKM_SHA512 }; +static const piv_obj_id_t token_objects[] = { + +}; +static const CK_ULONG token_objects_num = sizeof(token_objects) / sizeof(piv_obj_id_t); CK_RV YUBICO_get_slot_description(CK_UTF8CHAR_PTR str, CK_ULONG len) { @@ -212,3 +216,13 @@ CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_P return CKR_MECHANISM_INVALID; } + +CK_RV YUBICO_get_token_objects_num(CK_ULONG_PTR num) { + + *num = token_objects_num; + return CKR_OK; +} + +CK_RV YUBICO_get_token_object_list(piv_obj_id_t *obj, CK_ULONG len) { + +} diff --git a/ykcs11/yubico.h b/ykcs11/yubico.h index c10500d..979c71e 100644 --- a/ykcs11/yubico.h +++ b/ykcs11/yubico.h @@ -2,6 +2,7 @@ #define YUBICO_H #include "pkcs11.h" +#include "obj_types.h" CK_RV YUBICO_get_slot_description(CK_UTF8CHAR_PTR str, CK_ULONG len); CK_RV YUBICO_get_slot_manufacturer(CK_UTF8CHAR_PTR str, CK_ULONG len); @@ -16,5 +17,7 @@ CK_RV YUBICO_get_token_version(CK_UTF8CHAR_PTR v_str, CK_ULONG v_str_len, CK_VER CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num); CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num); CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info); +CK_RV YUBICO_get_token_objects_num(CK_ULONG_PTR num); +CK_RV YUBICO_get_token_object_list(piv_obj_id_t * obj, CK_ULONG num); #endif