Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pkcs11/pkcs11_library.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * Copyright (C) 2011-2015 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Copyright (C) 2010 Martin Willi
                      6:  * Copyright (C) 2010 revosec AG
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include "pkcs11_library.h"
                     20: 
1.1.1.2 ! misho      21: #ifndef WIN32
1.1       misho      22: #include <dlfcn.h>
1.1.1.2 ! misho      23: #else
        !            24: /* macro defined by synchapi.h that maps to CreateMutexA/W */
        !            25: #undef CreateMutex
        !            26: #endif
1.1       misho      27: 
                     28: #include <library.h>
                     29: #include <asn1/asn1.h>
                     30: #include <utils/debug.h>
                     31: #include <threading/mutex.h>
                     32: #include <collections/linked_list.h>
                     33: 
                     34: typedef struct private_pkcs11_library_t private_pkcs11_library_t;
                     35: 
                     36: 
                     37: ENUM_BEGIN(ck_rv_names, CKR_OK, CKR_CANT_LOCK,
                     38:        "OK",
                     39:        "CANCEL",
                     40:        "HOST_MEMORY",
                     41:        "SLOT_ID_INVALID",
                     42:        "(0x04)",
                     43:        "GENERAL_ERROR",
                     44:        "FUNCTION_FAILED",
                     45:        "ARGUMENTS_BAD",
                     46:        "NO_EVENT",
                     47:        "NEED_TO_CREATE_THREADS",
                     48:        "CANT_LOCK");
                     49: ENUM_NEXT(ck_rv_names, CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID,
                     50:                CKR_CANT_LOCK,
                     51:        "ATTRIBUTE_READ_ONLY",
                     52:        "ATTRIBUTE_SENSITIVE",
                     53:        "ATTRIBUTE_TYPE_INVALID",
                     54:        "ATTRIBUTE_VALUE_INVALID");
                     55: ENUM_NEXT(ck_rv_names, CKR_DATA_INVALID, CKR_DATA_LEN_RANGE,
                     56:                CKR_ATTRIBUTE_VALUE_INVALID,
                     57:        "DATA_INVALID",
                     58:        "DATA_LEN_RANGE");
                     59: ENUM_NEXT(ck_rv_names, CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED,
                     60:                CKR_DATA_LEN_RANGE,
                     61:        "DEVICE_ERROR",
                     62:        "DEVICE_MEMORY",
                     63:        "DEVICE_REMOVED");
                     64: ENUM_NEXT(ck_rv_names, CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE,
                     65:                CKR_DEVICE_REMOVED,
                     66:        "ENCRYPTED_DATA_INVALID",
                     67:        "ENCRYPTED_DATA_LEN_RANGE");
                     68: ENUM_NEXT(ck_rv_names, CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED,
                     69:                CKR_ENCRYPTED_DATA_LEN_RANGE,
                     70:        "FUNCTION_CANCELED",
                     71:        "FUNCTION_NOT_PARALLEL",
                     72:        "(0x52)",
                     73:        "(0x53)",
                     74:        "FUNCTION_NOT_SUPPORTED");
                     75: ENUM_NEXT(ck_rv_names, CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE,
                     76:                CKR_FUNCTION_NOT_SUPPORTED,
                     77:        "KEY_HANDLE_INVALID",
                     78:        "(0x61)",
                     79:        "KEY_SIZE_RANGE",
                     80:        "KEY_TYPE_INCONSISTENT",
                     81:        "KEY_NOT_NEEDED",
                     82:        "KEY_CHANGED",
                     83:        "KEY_NEEDED",
                     84:        "KEY_INDIGESTIBLE",
                     85:        "KEY_FUNCTION_NOT_PERMITTED",
                     86:        "KEY_NOT_WRAPPABLE",
                     87:        "KEY_UNEXTRACTABLE");
                     88: ENUM_NEXT(ck_rv_names, CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID,
                     89:                CKR_KEY_UNEXTRACTABLE,
                     90:        "MECHANISM_INVALID",
                     91:        "MECHANISM_PARAM_INVALID");
                     92: ENUM_NEXT(ck_rv_names, CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID,
                     93:                CKR_MECHANISM_PARAM_INVALID,
                     94:        "OBJECT_HANDLE_INVALID");
                     95: ENUM_NEXT(ck_rv_names, CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED,
                     96:                CKR_OBJECT_HANDLE_INVALID,
                     97:        "OPERATION_ACTIVE",
                     98:        "OPERATION_NOT_INITIALIZED");
                     99: ENUM_NEXT(ck_rv_names, CKR_PIN_INCORRECT, CKR_PIN_LOCKED,
                    100:                CKR_OPERATION_NOT_INITIALIZED,
                    101:        "PIN_INCORRECT",
                    102:        "PIN_INVALID",
                    103:        "PIN_LEN_RANGE",
                    104:        "PIN_EXPIRED",
                    105:        "PIN_LOCKED");
                    106: ENUM_NEXT(ck_rv_names, CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS,
                    107:                CKR_PIN_LOCKED,
                    108:        "SESSION_CLOSED",
                    109:        "SESSION_COUNT",
                    110:        "(0xb2)",
                    111:        "SESSION_HANDLE_INVALID",
                    112:        "SESSION_PARALLEL_NOT_SUPPORTED",
                    113:        "SESSION_READ_ONLY",
                    114:        "SESSION_EXISTS",
                    115:        "SESSION_READ_ONLY_EXISTS",
                    116:        "SESSION_READ_WRITE_SO_EXISTS");
                    117: ENUM_NEXT(ck_rv_names, CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE,
                    118:                CKR_SESSION_READ_WRITE_SO_EXISTS,
                    119:        "SIGNATURE_INVALID",
                    120:        "SIGNATURE_LEN_RANGE");
                    121: ENUM_NEXT(ck_rv_names, CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT,
                    122:                CKR_SIGNATURE_LEN_RANGE,
                    123:        "TEMPLATE_INCOMPLETE",
                    124:        "TEMPLATE_INCONSISTENT",
                    125: );
                    126: ENUM_NEXT(ck_rv_names, CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED,
                    127:                CKR_TEMPLATE_INCONSISTENT,
                    128:        "TOKEN_NOT_PRESENT",
                    129:        "TOKEN_NOT_RECOGNIZED",
                    130:        "TOKEN_WRITE_PROTECTED");
                    131: ENUM_NEXT(ck_rv_names, CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
                    132:                CKR_TOKEN_WRITE_PROTECTED,
                    133:        "UNWRAPPING_KEY_HANDLE_INVALID",
                    134:        "UNWRAPPING_KEY_SIZE_RANGE",
                    135:        "UNWRAPPING_KEY_TYPE_INCONSISTENT");
                    136: ENUM_NEXT(ck_rv_names, CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES,
                    137:                CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
                    138:        "USER_ALREADY_LOGGED_IN",
                    139:        "USER_NOT_LOGGED_IN",
                    140:        "USER_PIN_NOT_INITIALIZED",
                    141:        "USER_TYPE_INVALID",
                    142:        "USER_ANOTHER_ALREADY_LOGGED_IN",
                    143:        "USER_TOO_MANY_TYPES");
                    144: ENUM_NEXT(ck_rv_names, CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
                    145:                CKR_USER_TOO_MANY_TYPES,
                    146:        "WRAPPED_KEY_INVALID",
                    147:        "(0x111)",
                    148:        "WRAPPED_KEY_LEN_RANGE",
                    149:        "WRAPPING_KEY_HANDLE_INVALID",
                    150:        "WRAPPING_KEY_SIZE_RANGE",
                    151:        "WRAPPING_KEY_TYPE_INCONSISTENT");
                    152: ENUM_NEXT(ck_rv_names, CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG,
                    153:                CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
                    154:        "RANDOM_SEED_NOT_SUPPORTED",
                    155:        "RANDOM_NO_RNG");
                    156: ENUM_NEXT(ck_rv_names, CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID,
                    157:                CKR_RANDOM_NO_RNG,
                    158:        "DOMAIN_PARAMS_INVALID");
                    159: ENUM_NEXT(ck_rv_names, CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL,
                    160:                CKR_DOMAIN_PARAMS_INVALID,
                    161:        "BUFFER_TOO_SMALL");
                    162: ENUM_NEXT(ck_rv_names, CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID,
                    163:                CKR_BUFFER_TOO_SMALL,
                    164:        "SAVED_STATE_INVALID");
                    165: ENUM_NEXT(ck_rv_names, CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE,
                    166:                CKR_SAVED_STATE_INVALID,
                    167:        "INFORMATION_SENSITIVE");
                    168: ENUM_NEXT(ck_rv_names, CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE,
                    169:                CKR_INFORMATION_SENSITIVE,
                    170:        "STATE_UNSAVEABLE");
                    171: ENUM_NEXT(ck_rv_names, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED,
                    172:                CKR_STATE_UNSAVEABLE,
                    173:        "CRYPTOKI_NOT_INITIALIZED",
                    174:        "CRYPTOKI_ALREADY_INITIALIZED");
                    175: ENUM_NEXT(ck_rv_names, CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED,
                    176:                CKR_CRYPTOKI_ALREADY_INITIALIZED,
                    177:        "MUTEX_BAD",
                    178:        "MUTEX_NOT_LOCKED");
                    179: ENUM_NEXT(ck_rv_names, CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED,
                    180:                CKR_MUTEX_NOT_LOCKED,
                    181:        "FUNCTION_REJECTED");
                    182: ENUM_END(ck_rv_names, CKR_FUNCTION_REJECTED);
                    183: 
                    184: 
                    185: ENUM_BEGIN(ck_mech_names, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_DSA_SHA1,
                    186:        "RSA_PKCS_KEY_PAIR_GEN",
                    187:        "RSA_PKCS",
                    188:        "RSA_9796",
                    189:        "RSA_X_509",
                    190:        "MD2_RSA_PKCS",
                    191:        "MD5_RSA_PKCS",
                    192:        "SHA1_RSA_PKCS",
                    193:        "RIPEMD128_RSA_PKCS",
                    194:        "RIPEMD160_RSA_PKCS",
                    195:        "RSA_PKCS_OAEP",
                    196:        "RSA_X9_31_KEY_PAIR_GEN",
                    197:        "RSA_X9_31",
                    198:        "SHA1_RSA_X9_31",
                    199:        "RSA_PKCS_PSS",
                    200:        "SHA1_RSA_PKCS_PSS",
                    201:        "(0xf)",
                    202:        "DSA_KEY_PAIR_GEN",
                    203:        "DSA",
                    204:        "DSA_SHA1");
                    205: ENUM_NEXT(ck_mech_names, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE,
                    206:                CKM_DSA_SHA1,
                    207:        "DH_PKCS_KEY_PAIR_GEN",
                    208:        "DH_PKCS_DERIVE");
                    209: ENUM_NEXT(ck_mech_names, CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_MQV_DERIVE,
                    210:                CKM_DH_PKCS_DERIVE,
                    211:        "X9_42_DH_KEY_PAIR_GEN",
                    212:        "X9_42_DH_DERIVE",
                    213:        "X9_42_DH_HYBRID_DERIVE",
                    214:        "X9_42_MQV_DERIVE");
                    215: ENUM_NEXT(ck_mech_names, CKM_SHA256_RSA_PKCS, CKM_SHA512_RSA_PKCS_PSS,
                    216:                CKM_X9_42_MQV_DERIVE,
                    217:        "SHA256_RSA_PKCS",
                    218:        "SHA384_RSA_PKCS",
                    219:        "SHA512_RSA_PKCS",
                    220:        "SHA256_RSA_PKCS_PSS",
                    221:        "SHA384_RSA_PKCS_PSS",
                    222:        "SHA512_RSA_PKCS_PSS");
                    223: ENUM_NEXT(ck_mech_names, CKM_RC2_KEY_GEN, CKM_RC2_CBC_PAD,
                    224:                CKM_SHA512_RSA_PKCS_PSS,
                    225:        "RC2_KEY_GEN",
                    226:        "RC2_ECB",
                    227:        "RC2_CBC",
                    228:        "RC2_MAC",
                    229:        "RC2_MAC_GENERAL",
                    230:        "RC2_CBC_PAD");
                    231: ENUM_NEXT(ck_mech_names, CKM_RC4_KEY_GEN, CKM_RC4,
                    232:                CKM_RC2_CBC_PAD,
                    233:        "RC4_KEY_GEN",
                    234:        "RC4");
                    235: ENUM_NEXT(ck_mech_names, CKM_DES_KEY_GEN, CKM_DES_CBC_PAD,
                    236:                CKM_RC4,
                    237:        "DES_KEY_GEN",
                    238:        "DES_ECB",
                    239:        "DES_CBC",
                    240:        "DES_MAC",
                    241:        "DES_MAC_GENERAL",
                    242:        "DES_CBC_PAD");
                    243: ENUM_NEXT(ck_mech_names, CKM_DES2_KEY_GEN, CKM_DES3_CBC_PAD,
                    244:                CKM_DES_CBC_PAD,
                    245:        "DES2_KEY_GEN",
                    246:        "DES3_KEY_GEN",
                    247:        "DES3_ECB",
                    248:        "DES3_CBC",
                    249:        "DES3_MAC",
                    250:        "DES3_MAC_GENERAL",
                    251:        "DES3_CBC_PAD");
                    252: ENUM_NEXT(ck_mech_names, CKM_CDMF_KEY_GEN, CKM_CDMF_CBC_PAD,
                    253:                CKM_DES3_CBC_PAD,
                    254:        "CDMF_KEY_GEN",
                    255:        "CDMF_ECB",
                    256:        "CDMF_CBC",
                    257:        "CDMF_MAC",
                    258:        "CDMF_MAC_GENERAL",
                    259:        "CDMF_CBC_PAD");
                    260: ENUM_NEXT(ck_mech_names, CKM_MD2, CKM_MD2_HMAC_GENERAL,
                    261:                CKM_CDMF_CBC_PAD,
                    262:        "MD2",
                    263:        "MD2_HMAC",
                    264:        "MD2_HMAC_GENERAL");
                    265: ENUM_NEXT(ck_mech_names, CKM_MD5, CKM_MD5_HMAC_GENERAL,
                    266:                CKM_MD2_HMAC_GENERAL,
                    267:        "MD5",
                    268:        "MD5_HMAC",
                    269:        "MD5_HMAC_GENERAL");
                    270: ENUM_NEXT(ck_mech_names, CKM_SHA_1, CKM_SHA_1_HMAC_GENERAL,
                    271:                CKM_MD5_HMAC_GENERAL,
                    272:        "SHA_1",
                    273:        "SHA_1_HMAC",
                    274:        "SHA_1_HMAC_GENERAL");
                    275: ENUM_NEXT(ck_mech_names, CKM_RIPEMD128, CKM_RIPEMD128_HMAC_GENERAL,
                    276:                CKM_SHA_1_HMAC_GENERAL,
                    277:        "RIPEMD128",
                    278:        "RIPEMD128_HMAC",
                    279:        "RIPEMD128_HMAC_GENERAL");
                    280: ENUM_NEXT(ck_mech_names, CKM_RIPEMD160, CKM_RIPEMD160_HMAC_GENERAL,
                    281:                CKM_RIPEMD128_HMAC_GENERAL,
                    282:        "RIPEMD160",
                    283:        "RIPEMD160_HMAC",
                    284:        "RIPEMD160_HMAC_GENERAL");
                    285: ENUM_NEXT(ck_mech_names, CKM_SHA256, CKM_SHA256_HMAC_GENERAL,
                    286:                CKM_RIPEMD160_HMAC_GENERAL,
                    287:        "SHA256",
                    288:        "SHA256_HMAC",
                    289:        "SHA256_HMAC_GENERAL");
                    290: ENUM_NEXT(ck_mech_names, CKM_SHA384, CKM_SHA384_HMAC_GENERAL,
                    291:                CKM_SHA256_HMAC_GENERAL,
                    292:        "SHA384",
                    293:        "SHA384_HMAC",
                    294:        "SHA384_HMAC_GENERAL");
                    295: ENUM_NEXT(ck_mech_names, CKM_SHA512, CKM_SHA512_HMAC_GENERAL,
                    296:                CKM_SHA384_HMAC_GENERAL ,
                    297:        "SHA512",
                    298:        "SHA512_HMAC",
                    299:        "SHA512_HMAC_GENERAL");
                    300: ENUM_NEXT(ck_mech_names, CKM_CAST_KEY_GEN, CKM_CAST_CBC_PAD,
                    301:                CKM_SHA512_HMAC_GENERAL,
                    302:        "CAST_KEY_GEN",
                    303:        "CAST_ECB",
                    304:        "CAST_CBC",
                    305:        "CAST_MAC",
                    306:        "CAST_MAC_GENERAL",
                    307:        "CAST_CBC_PAD");
                    308: ENUM_NEXT(ck_mech_names, CKM_CAST3_KEY_GEN, CKM_CAST3_CBC_PAD,
                    309:                CKM_CAST_CBC_PAD,
                    310:        "CAST3_KEY_GEN",
                    311:        "CAST3_ECB",
                    312:        "CAST3_CBC",
                    313:        "CAST3_MAC",
                    314:        "CAST3_MAC_GENERAL",
                    315:        "CAST3_CBC_PAD");
                    316: ENUM_NEXT(ck_mech_names, CKM_CAST128_KEY_GEN, CKM_CAST128_CBC_PAD,
                    317:                CKM_CAST3_CBC_PAD,
                    318:        "CAST128_KEY_GEN",
                    319:        "CAST128_ECB",
                    320:        "CAST128_CBC",
                    321:        "CAST128_MAC",
                    322:        "CAST128_MAC_GENERAL",
                    323:        "CAST128_CBC_PAD");
                    324: ENUM_NEXT(ck_mech_names, CKM_RC5_KEY_GEN, CKM_RC5_CBC_PAD,
                    325:                CKM_CAST128_CBC_PAD,
                    326:        "RC5_KEY_GEN",
                    327:        "RC5_ECB",
                    328:        "RC5_CBC",
                    329:        "RC5_MAC",
                    330:        "RC5_MAC_GENERAL",
                    331:        "RC5_CBC_PAD");
                    332: ENUM_NEXT(ck_mech_names, CKM_IDEA_KEY_GEN, CKM_IDEA_CBC_PAD,
                    333:                CKM_RC5_CBC_PAD,
                    334:        "IDEA_KEY_GEN",
                    335:        "IDEA_ECB",
                    336:        "IDEA_CBC",
                    337:        "IDEA_MAC",
                    338:        "IDEA_MAC_GENERAL",
                    339:        "IDEA_CBC_PAD");
                    340: ENUM_NEXT(ck_mech_names, CKM_GENERIC_SECRET_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN,
                    341:                CKM_IDEA_CBC_PAD,
                    342:        "GENERIC_SECRET_KEY_GEN");
                    343: ENUM_NEXT(ck_mech_names, CKM_CONCATENATE_BASE_AND_KEY, CKM_EXTRACT_KEY_FROM_KEY,
                    344:                CKM_GENERIC_SECRET_KEY_GEN,
                    345:        "CONCATENATE_BASE_AND_KEY",
                    346:        "(0x361)",
                    347:        "CONCATENATE_BASE_AND_DATA",
                    348:        "CONCATENATE_DATA_AND_BASE",
                    349:        "XOR_BASE_AND_DATA",
                    350:        "EXTRACT_KEY_FROM_KEY");
                    351: ENUM_NEXT(ck_mech_names, CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_MASTER_KEY_DERIVE_DH,
                    352:                CKM_EXTRACT_KEY_FROM_KEY,
                    353:        "SSL3_PRE_MASTER_KEY_GEN",
                    354:        "SSL3_MASTER_KEY_DERIVE",
                    355:        "SSL3_KEY_AND_MAC_DERIVE",
                    356:        "SSL3_MASTER_KEY_DERIVE_DH",
                    357:        "TLS_PRE_MASTER_KEY_GEN",
                    358:        "TLS_MASTER_KEY_DERIVE",
                    359:        "TLS_KEY_AND_MAC_DERIVE",
                    360:        "TLS_MASTER_KEY_DERIVE_DH");
                    361: ENUM_NEXT(ck_mech_names, CKM_SSL3_MD5_MAC, CKM_SSL3_SHA1_MAC,
                    362:                CKM_TLS_MASTER_KEY_DERIVE_DH,
                    363:        "SSL3_MD5_MAC",
                    364:        "SSL3_SHA1_MAC");
                    365: ENUM_NEXT(ck_mech_names, CKM_MD5_KEY_DERIVATION, CKM_SHA1_KEY_DERIVATION,
                    366:                CKM_SSL3_SHA1_MAC,
                    367:        "MD5_KEY_DERIVATION",
                    368:        "MD2_KEY_DERIVATION",
                    369:        "SHA1_KEY_DERIVATION");
                    370: ENUM_NEXT(ck_mech_names, CKM_PBE_MD2_DES_CBC, CKM_PBE_SHA1_RC2_40_CBC,
                    371:                CKM_SHA1_KEY_DERIVATION,
                    372:        "PBE_MD2_DES_CBC",
                    373:        "PBE_MD5_DES_CBC",
                    374:        "PBE_MD5_CAST_CBC",
                    375:        "PBE_MD5_CAST3_CBC",
                    376:        "PBE_MD5_CAST128_CBC",
                    377:        "PBE_SHA1_CAST128_CBC",
                    378:        "PBE_SHA1_RC4_128",
                    379:        "PBE_SHA1_RC4_40",
                    380:        "PBE_SHA1_DES3_EDE_CBC",
                    381:        "PBE_SHA1_DES2_EDE_CBC",
                    382:        "PBE_SHA1_RC2_128_CBC",
                    383:        "PBE_SHA1_RC2_40_CBC");
                    384: ENUM_NEXT(ck_mech_names, CKM_PKCS5_PBKD2, CKM_PKCS5_PBKD2,
                    385:                CKM_PBE_SHA1_RC2_40_CBC,
                    386:        "PKCS5_PBKD2");
                    387: ENUM_NEXT(ck_mech_names, CKM_PBA_SHA1_WITH_SHA1_HMAC, CKM_PBA_SHA1_WITH_SHA1_HMAC,
                    388:                CKM_PKCS5_PBKD2,
                    389:        "PBA_SHA1_WITH_SHA1_HMAC");
                    390: ENUM_NEXT(ck_mech_names, CKM_KEY_WRAP_LYNKS, CKM_KEY_WRAP_SET_OAEP,
                    391:                CKM_PBA_SHA1_WITH_SHA1_HMAC,
                    392:        "KEY_WRAP_LYNKS",
                    393:        "KEY_WRAP_SET_OAEP");
                    394: ENUM_NEXT(ck_mech_names, CKM_SKIPJACK_KEY_GEN, CKM_SKIPJACK_RELAYX,
                    395:                CKM_KEY_WRAP_SET_OAEP,
                    396:        "SKIPJACK_KEY_GEN",
                    397:        "SKIPJACK_ECB64",
                    398:        "SKIPJACK_CBC64",
                    399:        "SKIPJACK_OFB64",
                    400:        "SKIPJACK_CFB64",
                    401:        "SKIPJACK_CFB32",
                    402:        "SKIPJACK_CFB16",
                    403:        "SKIPJACK_CFB8",
                    404:        "SKIPJACK_WRAP",
                    405:        "SKIPJACK_PRIVATE_WRAP",
                    406:        "SKIPJACK_RELAYX");
                    407: ENUM_NEXT(ck_mech_names, CKM_KEA_KEY_PAIR_GEN, CKM_KEA_KEY_DERIVE,
                    408:                CKM_SKIPJACK_RELAYX,
                    409:        "KEA_KEY_PAIR_GEN",
                    410:        "KEA_KEY_DERIVE");
                    411: ENUM_NEXT(ck_mech_names, CKM_FORTEZZA_TIMESTAMP, CKM_FORTEZZA_TIMESTAMP,
                    412:                CKM_KEA_KEY_DERIVE,
                    413:        "FORTEZZA_TIMESTAMP");
                    414: ENUM_NEXT(ck_mech_names, CKM_BATON_KEY_GEN, CKM_BATON_WRAP,
                    415:                CKM_FORTEZZA_TIMESTAMP,
                    416:        "BATON_KEY_GEN",
                    417:        "BATON_ECB128",
                    418:        "BATON_ECB96",
                    419:        "BATON_CBC128",
                    420:        "BATON_COUNTER",
                    421:        "BATON_SHUFFLE",
                    422:        "BATON_WRAP");
                    423: ENUM_NEXT(ck_mech_names, CKM_ECDSA_KEY_PAIR_GEN, CKM_ECDSA_SHA1,
                    424:                CKM_BATON_WRAP,
                    425:        "ECDSA_KEY_PAIR_GEN",
                    426:        "ECDSA",
                    427:        "ECDSA_SHA1");
                    428: ENUM_NEXT(ck_mech_names, CKM_ECDH1_DERIVE, CKM_ECMQV_DERIVE,
                    429:                CKM_ECDSA_SHA1,
                    430:        "ECDH1_DERIVE",
                    431:        "ECDH1_COFACTOR_DERIVE",
                    432:        "ECMQV_DERIVE");
                    433: ENUM_NEXT(ck_mech_names, CKM_JUNIPER_KEY_GEN, CKM_JUNIPER_WRAP,
                    434:                CKM_ECMQV_DERIVE,
                    435:        "JUNIPER_KEY_GEN",
                    436:        "JUNIPER_ECB128",
                    437:        "JUNIPER_CBC128",
                    438:        "JUNIPER_COUNTER",
                    439:        "JUNIPER_SHUFFLE",
                    440:        "JUNIPER_WRAP");
                    441: ENUM_NEXT(ck_mech_names, CKM_FASTHASH, CKM_FASTHASH,
                    442:                CKM_JUNIPER_WRAP,
                    443:        "FASTHASH");
                    444: ENUM_NEXT(ck_mech_names, CKM_AES_KEY_GEN, CKM_AES_CBC_PAD,
                    445:                CKM_FASTHASH,
                    446:        "AES_KEY_GEN",
                    447:        "AES_ECB",
                    448:        "AES_CBC",
                    449:        "AES_MAC",
                    450:        "AES_MAC_GENERAL",
                    451:        "AES_CBC_PAD");
                    452: ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN,
                    453:                CKM_AES_CBC_PAD,
                    454:        "DSA_PARAMETER_GEN",
                    455:        "DH_PKCS_PARAMETER_GEN",
                    456:        "X9_42_DH_PARAMETER_GEN");
                    457: ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN);
                    458: 
                    459: 
                    460: ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL,
                    461:        "CLASS",
                    462:        "TOKEN",
                    463:        "PRIVATE",
                    464:        "LABEL");
                    465: ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL,
                    466:        "APPLICATION",
                    467:        "VALUE",
                    468:        "OBJECT_ID");
                    469: ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
                    470:                CKA_OBJECT_ID,
                    471:        "CERTIFICATE_TYPE",
                    472:        "ISSUER",
                    473:        "SERIAL_NUMBER",
                    474:        "AC_ISSUER",
                    475:        "OWNER",
                    476:        "ATTR_TYPES",
                    477:        "TRUSTED",
                    478:        "CERTIFICATE_CATEGORY",
                    479:        "JAVA_MIDP_SECURITY_DOMAIN",
                    480:        "URL",
                    481:        "HASH_OF_SUBJECT_PUBLIC_KEY",
                    482:        "HASH_OF_ISSUER_PUBLIC_KEY");
                    483: ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE,
                    484:                CKA_HASH_OF_ISSUER_PUBLIC_KEY,
                    485:        "CHECK_VALUE");
                    486: ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE,
                    487:        "KEY_TYPE",
                    488:        "SUBJECT",
                    489:        "ID",
                    490:        "SENSITIVE",
                    491:        "ENCRYPT",
                    492:        "DECRYPT",
                    493:        "WRAP",
                    494:        "UNWRAP",
                    495:        "SIGN",
                    496:        "SIGN_RECOVER",
                    497:        "VERIFY",
                    498:        "VERIFY_RECOVER",
                    499:        "DERIVE");
                    500: ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE,
                    501:        "START_DATE",
                    502:        "END_DATE");
                    503: ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE,
                    504:        "MODULUS",
                    505:        "MODULUS_BITS",
                    506:        "PUBLIC_EXPONENT",
                    507:        "PRIVATE_EXPONENT",
                    508:        "PRIME_1",
                    509:        "PRIME_2",
                    510:        "EXPONENT_1",
                    511:        "EXPONENT_2",
                    512:        "COEFFICIENT");
                    513: ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT,
                    514:        "PRIME",
                    515:        "SUBPRIME",
                    516:        "BASE",
                    517:        "PRIME_BITS",
                    518:        "SUB_PRIME_BITS");
                    519: ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM,
                    520:                CKA_SUB_PRIME_BITS,
                    521:        "VALUE_BITS",
                    522:        "VALUE_LEN",
                    523:        "EXTRACTABLE",
                    524:        "LOCAL",
                    525:        "NEVER_EXTRACTABLE",
                    526:        "ALWAYS_SENSITIVE",
                    527:        "KEY_GEN_MECHANISM");
                    528: ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM,
                    529:        "MODIFIABLE");
                    530: ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE,
                    531:        "EC_PARAMS",
                    532:        "EC_POINT");
                    533: ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE,
                    534:                CKA_EC_POINT,
                    535:        "SECONDARY_AUTH",
                    536:        "AUTH_PIN_FLAGS",
                    537:        "ALWAYS_AUTHENTICATE");
                    538: ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED,
                    539:                CKA_ALWAYS_AUTHENTICATE,
                    540:        "WRAP_WITH_TRUSTED");
                    541: ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET,
                    542:                CKA_WRAP_WITH_TRUSTED,
                    543:        "HW_FEATURE_TYPE",
                    544:        "RESET_ON_INIT",
                    545:        "HAS_RESET");
                    546: ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET,
                    547:        "PIXEL_X",
                    548:        "PIXEL_Y",
                    549:        "RESOLUTION",
                    550:        "CHAR_ROWS",
                    551:        "CHAR_COLUMNS",
                    552:        "COLOR",
                    553:        "BITS_PER_PIXEL");
                    554: ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL,
                    555:        "CHAR_SETS",
                    556:        "ENCODING_METHODS",
                    557:        "MIME_TYPES");
                    558: ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES,
                    559:                CKA_MIME_TYPES,
                    560:        "MECHANISM_TYPE",
                    561:        "REQUIRED_CMS_ATTRIBUTES",
                    562:        "DEFAULT_CMS_ATTRIBUTES",
                    563:        "SUPPORTED_CMS_ATTRIBUTES");
                    564: ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE,
                    565:                CKA_SUPPORTED_CMS_ATTRIBUTES,
                    566:        "WRAP_TEMPLATE",
                    567:        "UNWRAP_TEMPLATE");
                    568: ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS,
                    569:                CKA_UNWRAP_TEMPLATE,
                    570:        "ALLOWED_MECHANISMS");
                    571: ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS);
                    572: /* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED
                    573:  * will overflow and is thus not defined here */
                    574: 
                    575: 
                    576: 
                    577: /**
                    578:  * Private data of an pkcs11_library_t object.
                    579:  */
                    580: struct private_pkcs11_library_t {
                    581: 
                    582:        /**
                    583:         * Public pkcs11_library_t interface.
                    584:         */
                    585:        pkcs11_library_t public;
                    586: 
                    587:        /**
                    588:         * dlopen() handle
                    589:         */
                    590:        void *handle;
                    591: 
                    592:        /**
                    593:         * Name as passed to the constructor
                    594:         */
                    595:        char *name;
                    596: 
                    597:        /**
                    598:         * Supported feature set
                    599:         */
                    600:        pkcs11_feature_t features;
                    601: };
                    602: 
                    603: METHOD(pkcs11_library_t, get_name, char*,
                    604:        private_pkcs11_library_t *this)
                    605: {
                    606:        return this->name;
                    607: }
                    608: 
                    609: METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
                    610:        private_pkcs11_library_t *this)
                    611: {
                    612:        return this->features;
                    613: }
                    614: 
                    615: /**
                    616:  * Object enumerator
                    617:  */
                    618: typedef struct {
                    619:        /* implements enumerator_t */
                    620:        enumerator_t public;
                    621:        /* session */
                    622:        CK_SESSION_HANDLE session;
                    623:        /* pkcs11 library */
                    624:        pkcs11_library_t *lib;
                    625:        /* attributes to retrieve */
                    626:        CK_ATTRIBUTE_PTR attr;
                    627:        /* number of attributes */
                    628:        CK_ULONG count;
                    629:        /* object handle in case of a single object */
                    630:        CK_OBJECT_HANDLE object;
                    631:        /* currently allocated attributes, to free */
                    632:        linked_list_t *freelist;
                    633: } object_enumerator_t;
                    634: 
                    635: /**
                    636:  * Free contents of attributes in a list
                    637:  */
                    638: static void free_attrs(object_enumerator_t *this)
                    639: {
                    640:        CK_ATTRIBUTE_PTR attr;
                    641: 
                    642:        while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
                    643:        {
                    644:                free(attr->pValue);
                    645:                attr->pValue = NULL;
                    646:                attr->ulValueLen = 0;
                    647:        }
                    648: }
                    649: 
                    650: /**
                    651:  * CKA_EC_POINT is encoded as ASN.1 octet string, we can't handle that and
                    652:  * some tokens actually return them even unwrapped.
                    653:  *
                    654:  * Because ASN1_OCTET_STRING is 0x04 and uncompressed EC_POINTs also begin with
                    655:  * 0x04 (compressed ones with 0x02 or 0x03) there will be an attempt to parse
                    656:  * unwrapped uncompressed EC_POINTs.  This will fail in most cases as the length
                    657:  * will not be correct, however, there is a small chance that the key's first
                    658:  * byte denotes the correct length.  Checking the first byte of the key should
                    659:  * further reduce the risk of false positives, though.
                    660:  *
                    661:  * The original memory is freed if the value is unwrapped.
                    662:  */
                    663: static void unwrap_ec_point(chunk_t *data)
                    664: {
                    665:        chunk_t wrapped, unwrapped;
                    666: 
                    667:        wrapped = unwrapped = *data;
                    668:        if (asn1_unwrap(&unwrapped, &unwrapped) == ASN1_OCTET_STRING &&
                    669:                unwrapped.len && unwrapped.ptr[0] >= 0x02 && unwrapped.ptr[0] <= 0x04)
                    670:        {
                    671:                *data = chunk_clone(unwrapped);
                    672:                free(wrapped.ptr);
                    673:        }
                    674: }
                    675: 
                    676: /**
                    677:  * Get attributes for a given object during enumeration
                    678:  */
                    679: static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
                    680: {
                    681:        chunk_t data;
                    682:        CK_RV rv;
                    683:        int i;
                    684: 
                    685:        free_attrs(this);
                    686: 
                    687:        /* get length of objects first */
                    688:        rv = this->lib->f->C_GetAttributeValue(this->session, object,
                    689:                                                                                   this->attr, this->count);
                    690:        if (rv != CKR_OK)
                    691:        {
                    692:                DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
                    693:                return FALSE;
                    694:        }
                    695:        /* allocate required chunks */
                    696:        for (i = 0; i < this->count; i++)
                    697:        {
                    698:                if (this->attr[i].pValue == NULL &&
                    699:                        this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
                    700:                {
                    701:                        this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
                    702:                        this->freelist->insert_last(this->freelist, &this->attr[i]);
                    703:                }
                    704:        }
                    705:        /* get the data */
                    706:        rv = this->lib->f->C_GetAttributeValue(this->session, object,
                    707:                                                                                   this->attr, this->count);
                    708:        if (rv != CKR_OK)
                    709:        {
                    710:                free_attrs(this);
                    711:                DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
                    712:                return FALSE;
                    713:        }
                    714:        for (i = 0; i < this->count; i++)
                    715:        {
                    716:                if (this->attr[i].type == CKA_EC_POINT)
                    717:                {
                    718:                        data = chunk_create(this->attr[i].pValue, this->attr[i].ulValueLen);
                    719:                        unwrap_ec_point(&data);
                    720:                        this->attr[i].pValue = data.ptr;
                    721:                        this->attr[i].ulValueLen = data.len;
                    722:                }
                    723:        }
                    724:        return TRUE;
                    725: }
                    726: 
                    727: METHOD(enumerator_t, object_enumerate, bool,
                    728:        object_enumerator_t *this, va_list args)
                    729: {
                    730:        CK_OBJECT_HANDLE object, *out;
                    731:        CK_ULONG found;
                    732:        CK_RV rv;
                    733: 
                    734:        VA_ARGS_VGET(args, out);
                    735: 
                    736:        if (!this->object)
                    737:        {
                    738:                rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
                    739:                if (rv != CKR_OK)
                    740:                {
                    741:                        DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
                    742:                        return FALSE;
                    743:                }
                    744:        }
                    745:        else
                    746:        {
                    747:                object = this->object;
                    748:                found = 1;
                    749:        }
                    750:        if (found)
                    751:        {
                    752:                if (this->attr)
                    753:                {
                    754:                        if (!get_attributes(this, object))
                    755:                        {
                    756:                                return FALSE;
                    757:                        }
                    758:                }
                    759:                if (out)
                    760:                {
                    761:                        *out = object;
                    762:                }
                    763:                return TRUE;
                    764:        }
                    765:        return FALSE;
                    766: }
                    767: 
                    768: METHOD(enumerator_t, object_destroy, void,
                    769:        object_enumerator_t *this)
                    770: {
                    771:        if (!this->object)
                    772:        {
                    773:                this->lib->f->C_FindObjectsFinal(this->session);
                    774:        }
                    775:        free_attrs(this);
                    776:        this->freelist->destroy(this->freelist);
                    777:        free(this);
                    778: }
                    779: 
                    780: METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
                    781:        private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
                    782:        CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
                    783:        CK_ATTRIBUTE_PTR attr, CK_ULONG acount)
                    784: {
                    785:        object_enumerator_t *enumerator;
                    786:        CK_RV rv;
                    787: 
                    788:        rv = this->public.f->C_FindObjectsInit(session, tmpl, tcount);
                    789:        if (rv != CKR_OK)
                    790:        {
                    791:                DBG1(DBG_CFG, "C_FindObjectsInit() failed: %N", ck_rv_names, rv);
                    792:                return enumerator_create_empty();
                    793:        }
                    794: 
                    795:        INIT(enumerator,
                    796:                .public = {
                    797:                        .enumerate = enumerator_enumerate_default,
                    798:                        .venumerate = _object_enumerate,
                    799:                        .destroy = _object_destroy,
                    800:                },
                    801:                .session = session,
                    802:                .lib = &this->public,
                    803:                .attr = attr,
                    804:                .count = acount,
                    805:                .freelist = linked_list_create(),
                    806:        );
                    807:        return &enumerator->public;
                    808: }
                    809: 
                    810: METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*,
                    811:        private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
                    812:        CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attr, CK_ULONG count)
                    813: {
                    814:        object_enumerator_t *enumerator;
                    815: 
                    816:        INIT(enumerator,
                    817:                .public = {
                    818:                        .enumerate = enumerator_enumerate_default,
                    819:                        .venumerate = _object_enumerate,
                    820:                        .destroy = _object_destroy,
                    821:                },
                    822:                .session = session,
                    823:                .lib = &this->public,
                    824:                .attr = attr,
                    825:                .count = count,
                    826:                .object = object,
                    827:                .freelist = linked_list_create(),
                    828:        );
                    829:        return &enumerator->public;
                    830: }
                    831: 
                    832: /**
                    833:  * Enumerator over mechanisms
                    834:  */
                    835: typedef struct {
                    836:        /* implements enumerator_t */
                    837:        enumerator_t public;
                    838:        /* PKCS#11 library */
                    839:        pkcs11_library_t *lib;
                    840:        /* slot of token */
                    841:        CK_SLOT_ID slot;
                    842:        /* mechanism type list */
                    843:        CK_MECHANISM_TYPE_PTR mechs;
                    844:        /* number of mechanism types */
                    845:        CK_ULONG count;
                    846:        /* current mechanism */
                    847:        CK_ULONG current;
                    848: } mechanism_enumerator_t;
                    849: 
                    850: METHOD(enumerator_t, enumerate_mech, bool,
                    851:        mechanism_enumerator_t *this, va_list args)
                    852: {
                    853:        CK_MECHANISM_INFO *info;
                    854:        CK_MECHANISM_TYPE *type;
                    855:        CK_RV rv;
                    856: 
                    857:        VA_ARGS_VGET(args, type, info);
                    858: 
                    859:        if (this->current >= this->count)
                    860:        {
                    861:                return FALSE;
                    862:        }
                    863:        if (info)
                    864:        {
                    865:                rv = this->lib->f->C_GetMechanismInfo(this->slot,
                    866:                                                                                          this->mechs[this->current], info);
                    867:                if (rv != CKR_OK)
                    868:                {
                    869:                        DBG1(DBG_CFG, "C_GetMechanismInfo() failed: %N", ck_rv_names, rv);
                    870:                        return FALSE;
                    871:                }
                    872:        }
                    873:        *type = this->mechs[this->current++];
                    874:        return TRUE;
                    875: }
                    876: 
                    877: METHOD(enumerator_t, destroy_mech, void,
                    878:        mechanism_enumerator_t *this)
                    879: {
                    880:        free(this->mechs);
                    881:        free(this);
                    882: }
                    883: 
                    884: METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
                    885:        private_pkcs11_library_t *this, CK_SLOT_ID slot)
                    886: {
                    887:        mechanism_enumerator_t *enumerator;
                    888:        CK_RV rv;
                    889: 
                    890:        INIT(enumerator,
                    891:                .public = {
                    892:                        .enumerate = enumerator_enumerate_default,
                    893:                        .venumerate = _enumerate_mech,
                    894:                        .destroy = _destroy_mech,
                    895:                },
                    896:                .lib = &this->public,
                    897:                .slot = slot,
                    898:        );
                    899: 
                    900:        rv = enumerator->lib->f->C_GetMechanismList(slot, NULL, &enumerator->count);
                    901:        if (rv != CKR_OK)
                    902:        {
                    903:                DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
                    904:                free(enumerator);
                    905:                return enumerator_create_empty();
                    906:        }
                    907:        enumerator->mechs = malloc(sizeof(CK_MECHANISM_TYPE) * enumerator->count);
                    908:        rv = enumerator->lib->f->C_GetMechanismList(slot, enumerator->mechs,
                    909:                                                                                                &enumerator->count);
                    910:        if (rv != CKR_OK)
                    911:        {
                    912:                DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv);
                    913:                destroy_mech(enumerator);
                    914:                return enumerator_create_empty();
                    915:        }
                    916:        return &enumerator->public;
                    917: }
                    918: 
                    919: METHOD(pkcs11_library_t, get_ck_attribute, bool,
                    920:        private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
                    921:        CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, chunk_t *data)
                    922: {
                    923:        CK_ATTRIBUTE attr = { type, NULL, 0 };
                    924:        CK_RV rv;
                    925:        rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
                    926:        if (rv != CKR_OK)
                    927:        {
                    928:                DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
                    929:                         ck_rv_names, rv);
                    930:                return FALSE;
                    931:        }
                    932:        *data = chunk_alloc(attr.ulValueLen);
                    933:        attr.pValue = data->ptr;
                    934:        rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
                    935:        if (rv != CKR_OK)
                    936:        {
                    937:                DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
                    938:                         ck_rv_names, rv);
                    939:                chunk_free(data);
                    940:                return FALSE;
                    941:        }
                    942:        if (attr.type == CKA_EC_POINT)
                    943:        {
                    944:                unwrap_ec_point(data);
                    945:        }
                    946:        return TRUE;
                    947: }
                    948: 
                    949: METHOD(pkcs11_library_t, destroy, void,
                    950:        private_pkcs11_library_t *this)
                    951: {
                    952:        this->public.f->C_Finalize(NULL);
                    953:        dlclose(this->handle);
                    954:        free(this->name);
                    955:        free(this);
                    956: }
                    957: 
                    958: /**
                    959:  * See header
                    960:  */
                    961: void pkcs11_library_trim(char *str, int len)
                    962: {
                    963:        int i;
                    964: 
                    965:        str[len - 1] = '\0';
                    966:        for (i = len - 2; i > 0; i--)
                    967:        {
                    968:                if (str[i] == ' ')
                    969:                {
                    970:                        str[i] = '\0';
                    971:                        continue;
                    972:                }
                    973:                break;
                    974:        }
                    975: }
                    976: 
                    977: /**
                    978:  * Mutex creation callback
                    979:  */
                    980: static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
                    981: {
                    982:        *data = mutex_create(MUTEX_TYPE_RECURSIVE);
                    983:        return CKR_OK;
                    984: }
                    985: 
                    986: /**
                    987:  * Mutex destruction callback
                    988:  */
                    989: static CK_RV DestroyMutex(CK_VOID_PTR data)
                    990: {
                    991:        mutex_t *mutex = (mutex_t*)data;
                    992: 
                    993:        mutex->destroy(mutex);
                    994:        return CKR_OK;
                    995: }
                    996: 
                    997: /**
                    998:  * Mutex lock callback
                    999:  */
                   1000: static CK_RV LockMutex(CK_VOID_PTR data)
                   1001: {
                   1002:        mutex_t *mutex = (mutex_t*)data;
                   1003: 
                   1004:        mutex->lock(mutex);
                   1005:        return CKR_OK;
                   1006: }
                   1007: 
                   1008: /**
                   1009:  * Mutex unlock callback
                   1010:  */
                   1011: static CK_RV UnlockMutex(CK_VOID_PTR data)
                   1012: {
                   1013:        mutex_t *mutex = (mutex_t*)data;
                   1014: 
                   1015:        mutex->unlock(mutex);
                   1016:        return CKR_OK;
                   1017: }
                   1018: 
                   1019: /**
                   1020:  * Check if the library has at least a given cryptoki version
                   1021:  */
                   1022: static bool has_version(CK_INFO *info, int major, int minor)
                   1023: {
                   1024:        return info->cryptokiVersion.major > major ||
                   1025:                        (info->cryptokiVersion.major == major &&
                   1026:                         info->cryptokiVersion.minor >= minor);
                   1027: }
                   1028: 
                   1029: /**
                   1030:  * Check for optional PKCS#11 library functionality
                   1031:  */
                   1032: static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
                   1033: {
                   1034:        if (has_version(info, 2, 20))
                   1035:        {
                   1036:                this->features |= PKCS11_TRUSTED_CERTS;
                   1037:                this->features |= PKCS11_ALWAYS_AUTH_KEYS;
                   1038:        }
                   1039: }
                   1040: 
                   1041: /**
                   1042:  * Initialize a PKCS#11 library
                   1043:  */
                   1044: static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
                   1045:                                           bool os_locking)
                   1046: {
                   1047:        CK_C_GetFunctionList pC_GetFunctionList;
                   1048:        CK_INFO info;
                   1049:        CK_RV rv;
                   1050:        static CK_C_INITIALIZE_ARGS args = {
                   1051:                .CreateMutex = CreateMutex,
                   1052:                .DestroyMutex = DestroyMutex,
                   1053:                .LockMutex = LockMutex,
                   1054:                .UnlockMutex = UnlockMutex,
                   1055:        };
                   1056:        static CK_C_INITIALIZE_ARGS args_os = {
                   1057:                .flags = CKF_OS_LOCKING_OK,
                   1058:        };
                   1059: 
                   1060:        pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
                   1061:        if (!pC_GetFunctionList)
                   1062:        {
                   1063:                DBG1(DBG_CFG, "C_GetFunctionList not found for '%s': %s", name, dlerror());
                   1064:                return FALSE;
                   1065:        }
                   1066:        rv = pC_GetFunctionList(&this->public.f);
                   1067:        if (rv != CKR_OK)
                   1068:        {
                   1069:                DBG1(DBG_CFG, "C_GetFunctionList() error for '%s': %N",
                   1070:                         name, ck_rv_names, rv);
                   1071:                return FALSE;
                   1072:        }
                   1073:        if (os_locking)
                   1074:        {
                   1075:                rv = CKR_CANT_LOCK;
                   1076:        }
                   1077:        else
                   1078:        {
                   1079:                rv = this->public.f->C_Initialize(&args);
                   1080:        }
                   1081:        if (rv == CKR_CANT_LOCK)
                   1082:        {       /* fallback to OS locking */
                   1083:                os_locking = TRUE;
                   1084:                rv = this->public.f->C_Initialize(&args_os);
                   1085:        }
                   1086:        if (rv != CKR_OK)
                   1087:        {
                   1088:                DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
                   1089:                         name, ck_rv_names, rv);
                   1090:                return FALSE;
                   1091:        }
                   1092:        rv = this->public.f->C_GetInfo(&info);
                   1093:        if (rv != CKR_OK)
                   1094:        {
                   1095:                DBG1(DBG_CFG, "C_GetInfo() error for '%s': %N",
                   1096:                         name, ck_rv_names, rv);
                   1097:                this->public.f->C_Finalize(NULL);
                   1098:                return FALSE;
                   1099:        }
                   1100: 
                   1101:        pkcs11_library_trim(info.manufacturerID,
                   1102:                        strnlen(info.manufacturerID, sizeof(info.manufacturerID)));
                   1103:        pkcs11_library_trim(info.libraryDescription,
                   1104:                        strnlen(info.libraryDescription, sizeof(info.libraryDescription)));
                   1105: 
                   1106:        DBG1(DBG_CFG, "loaded PKCS#11 v%d.%d library '%s' (%s)",
                   1107:                 info.cryptokiVersion.major, info.cryptokiVersion.minor, name, file);
                   1108:        DBG1(DBG_CFG, "  %s: %s v%d.%d",
                   1109:                 info.manufacturerID, info.libraryDescription,
                   1110:                 info.libraryVersion.major, info.libraryVersion.minor);
                   1111:        if (os_locking)
                   1112:        {
                   1113:                DBG1(DBG_CFG, "  uses OS locking functions");
                   1114:        }
                   1115: 
                   1116:        check_features(this, &info);
                   1117:        return TRUE;
                   1118: }
                   1119: 
                   1120: /**
                   1121:  * See header
                   1122:  */
                   1123: pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
                   1124: {
                   1125:        private_pkcs11_library_t *this;
                   1126: 
                   1127:        INIT(this,
                   1128:                .public = {
                   1129:                        .get_name = _get_name,
                   1130:                        .get_features = _get_features,
                   1131:                        .create_object_enumerator = _create_object_enumerator,
                   1132:                        .create_object_attr_enumerator = _create_object_attr_enumerator,
                   1133:                        .create_mechanism_enumerator = _create_mechanism_enumerator,
                   1134:                        .get_ck_attribute = _get_ck_attribute,
                   1135:                        .destroy = _destroy,
                   1136:                },
                   1137:                .name = strdup(name),
                   1138:                .handle = dlopen(file, RTLD_LAZY),
                   1139:        );
                   1140: 
                   1141:        if (!this->handle)
                   1142:        {
                   1143:                DBG1(DBG_CFG, "opening PKCS#11 library failed: %s", dlerror());
                   1144:                free(this);
                   1145:                return NULL;
                   1146:        }
                   1147: 
                   1148:        if (!initialize(this, name, file, os_locking))
                   1149:        {
                   1150:                dlclose(this->handle);
                   1151:                free(this);
                   1152:                return NULL;
                   1153:        }
                   1154: 
                   1155:        return &this->public;
                   1156: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>