39 #include <libxml/tree.h>
40 #include <libxml/parser.h>
41 #include <libxml/xpath.h>
42 #include <libxml/xpathInternals.h>
43 #include <libxml/relaxng.h>
52 #define HSM_TOKEN_LABEL_LENGTH 32
59 ldns_pkcs11_rv_str(CK_RV rv)
68 return "CKR_HOST_MEMORY";
70 return "CKR_GENERAL_ERROR";
72 return "CKR_FUNCTION_FAILED";
74 return "CKR_SLOT_ID_INVALID";
76 return "CKR_ATTRIBUTE_READ_ONLY";
78 return "CKR_ATTRIBUTE_SENSITIVE";
80 return "CKR_ATTRIBUTE_TYPE_INVALID";
82 return "CKR_ATTRIBUTE_VALUE_INVALID";
84 return "CKR_DATA_INVALID";
86 return "CKR_DATA_LEN_RANGE";
88 return "CKR_DEVICE_ERROR";
90 return "CKR_DEVICE_MEMORY";
92 return "CKR_DEVICE_REMOVED";
94 return "CKR_ENCRYPTED_DATA_INVALID";
96 return "CKR_ENCRYPTED_DATA_LEN_RANGE";
98 return "CKR_FUNCTION_CANCELED";
100 return "CKR_FUNCTION_NOT_PARALLEL";
102 return "CKR_KEY_HANDLE_INVALID";
104 return "CKR_KEY_SIZE_RANGE";
106 return "CKR_KEY_TYPE_INCONSISTENT";
108 return "CKR_MECHANISM_INVALID";
110 return "CKR_MECHANISM_PARAM_INVALID";
112 return "CKR_OBJECT_HANDLE_INVALID";
114 return "CKR_OPERATION_ACTIVE";
116 return "CKR_OPERATION_NOT_INITIALIZED";
118 return "CKR_PIN_INCORRECT";
120 return "CKR_PIN_INVALID";
122 return "CKR_PIN_LEN_RANGE";
124 return "CKR_SESSION_CLOSED";
126 return "CKR_SESSION_COUNT";
128 return "CKR_SESSION_HANDLE_INVALID";
130 return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
132 return "CKR_SESSION_READ_ONLY";
134 return "CKR_SESSION_EXISTS";
136 return "CKR_SIGNATURE_INVALID";
138 return "CKR_SIGNATURE_LEN_RANGE";
140 return "CKR_TEMPLATE_INCOMPLETE";
142 return "CKR_TEMPLATE_INCONSISTENT";
144 return "CKR_TOKEN_NOT_PRESENT";
146 return "CKR_TOKEN_NOT_RECOGNIZED";
148 return "CKR_TOKEN_WRITE_PROTECTED";
150 return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
152 return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
154 return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
156 return "CKR_USER_ALREADY_LOGGED_IN";
158 return "CKR_USER_NOT_LOGGED_IN";
160 return "CKR_USER_PIN_NOT_INITIALIZED";
162 return "CKR_USER_TYPE_INVALID";
164 return "CKR_WRAPPED_KEY_INVALID";
166 return "CKR_WRAPPED_KEY_LEN_RANGE";
168 return "CKR_WRAPPING_KEY_HANDLE_INVALID";
170 return "CKR_WRAPPING_KEY_SIZE_RANGE";
172 return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
174 return "CKR_RANDOM_SEED_NOT_SUPPORTED";
176 return "CKR_VENDOR_DEFINED";
178 return "CKR_BUFFER_TOO_SMALL";
180 return "CKR_SAVED_STATE_INVALID";
182 return "CKR_INFORMATION_SENSITIVE";
184 return "CKR_STATE_UNSAVEABLE";
186 return "CKR_CRYPTOKI_NOT_INITIALIZED";
188 return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
190 return "CKR_MUTEX_BAD";
192 return "CKR_MUTEX_NOT_LOCKED";
194 return "Unknown error";
210 hsm_ctx_set_error(
hsm_ctx_t *ctx,
int error,
const char *action,
211 const char *message, ...)
215 if (ctx && ctx->
error == 0) {
219 va_start(args, message);
238 hsm_pkcs11_check_error(
hsm_ctx_t *ctx, CK_RV rv,
const char *action)
241 if (ctx && ctx->
error == 0) {
242 ctx->
error = (int) rv;
253 hsm_pkcs11_unload_functions(
void *handle)
257 #if defined(HAVE_LOADLIBRARY)
259 #elif defined(HAVE_DLOPEN)
260 result = dlclose(handle);
269 CK_C_GetFunctionList pGetFunctionList = NULL;
271 if (module && module->
path) {
274 #if defined(HAVE_LOADLIBRARY)
276 HINSTANCE hDLL = LoadLibrary(_T(module->
path));
284 pGetFunctionList = (CK_C_GetFunctionList)
285 GetProcAddress(hDLL, _T(
"C_GetFunctionList"));
287 #elif defined(HAVE_DLOPEN)
289 void* pDynLib = dlopen(module->
path, RTLD_NOW | RTLD_LOCAL);
291 if (pDynLib == NULL) {
297 pGetFunctionList = (CK_C_GetFunctionList) dlsym(pDynLib,
"C_GetFunctionList");
306 #ifdef HAVE_PKCS11_MODULE
307 return C_GetFunctionList(pkcs11_functions);
313 if (pGetFunctionList == NULL) {
329 if (data == NULL || len == NULL)
return;
333 while ((
unsigned short int)(*p) == 0 && l > 1) {
345 hsm_pkcs11_check_token_name(
hsm_ctx_t *ctx,
348 const char *token_name)
357 if (hsm_pkcs11_check_error(ctx, rv,
"C_GetTokenInfo")) {
363 memcpy(token_name_bytes, token_name, strlen(token_name));
368 result = memcmp(token_info.
label,
379 const char *token_name, CK_SLOT_ID *slotId)
387 if (token_name == NULL || slotId == NULL)
return HSM_ERROR;
390 if (hsm_pkcs11_check_error(ctx, rv,
"get slot list")) {
395 hsm_ctx_set_error(ctx,
HSM_ERROR,
"hsm_get_slot_id()",
396 "No slots found in HSM");
400 slotIds = malloc(
sizeof(CK_SLOT_ID) * slotCount);
402 if (hsm_pkcs11_check_error(ctx, rv,
"get slot list")) {
406 for (cur_slot = 0; cur_slot < slotCount; cur_slot++) {
407 if (hsm_pkcs11_check_token_name(ctx,
411 *slotId = slotIds[cur_slot];
418 hsm_ctx_set_error(ctx, -1,
"hsm_get_slot_id()",
419 "could not find token with the name %s", token_name);
428 hsm_module_new(
const char *repository,
429 const char *token_label,
435 if (!repository || !path)
return NULL;
439 if (!module)
return NULL;
453 module->
name = strdup(repository);
455 module->
path = strdup(path);
466 if (module->
name) free(module->
name);
468 if (module->
path) free(module->
path);
476 hsm_session_new(
hsm_module_t *module, CK_SESSION_HANDLE session_handle)
481 session->
session = session_handle;
504 const char *repository,
const char *token_label,
505 const char *module_path,
const char *pin,
512 CK_SESSION_HANDLE session_handle;
513 int first = 1, result;
518 module = hsm_module_new(repository, token_label, module_path, config);
520 rv = hsm_pkcs11_load_functions(module);
523 "hsm_session_init()",
524 "PKCS#11 module load failed: %s", module_path);
525 hsm_module_free(module);
532 if (hsm_pkcs11_check_error(ctx, rv,
"Initialization")) {
533 hsm_module_free(module);
541 hsm_module_free(module);
549 if (hsm_pkcs11_check_error(ctx, rv,
"Open first session")) {
550 hsm_module_free(module);
555 (
unsigned char *) pin,
556 strlen((
char *)pin));
559 *session = hsm_session_new(module, session_handle);
563 if (session_handle) {
565 C_CloseSession(session_handle);
566 if (hsm_pkcs11_check_error(ctx, rv,
567 "finalize after failed login")) {
568 hsm_module_free(module);
576 if (hsm_pkcs11_check_error(ctx, rv,
"finalize after failed login")) {
577 hsm_module_free(module);
581 hsm_module_free(module);
586 "hsm_session_init()",
587 "Incorrect PIN for repository %s", repository);
601 CK_SESSION_HANDLE session_handle;
609 if (result !=
HSM_OK)
return NULL;
616 if (hsm_pkcs11_check_error(ctx, rv,
"Clone session")) {
619 new_session = hsm_session_new(session->
module, session_handle);
642 hsm_session_free(ctx->
session[i]);
665 (void) hsm_pkcs11_check_error(ctx, rv,
"Logout");
670 (void) hsm_pkcs11_check_error(ctx, rv,
"Close session");
675 (void) hsm_pkcs11_check_error(ctx, rv,
"Finalize");
678 hsm_module_free(session->
module);
681 hsm_session_free(session);
691 hsm_ctx_close(
hsm_ctx_t *ctx,
int unload)
700 hsm_session_close(ctx, ctx->
session[i], unload);
724 if (!ctx || !session)
return -1;
740 new_ctx = hsm_ctx_new();
742 new_session = hsm_session_clone(ctx, ctx->
session[i]);
746 hsm_ctx_close(new_ctx, 0);
749 hsm_ctx_add_session(new_ctx, new_session);
772 if (!key || !key->
module)
return NULL;
773 if (!ctx) ctx = _hsm_ctx;
788 CK_KEY_TYPE key_type;
799 if (hsm_pkcs11_check_error(ctx, rv,
800 "Get attr value algorithm type")) {
808 if ((
CK_LONG)
template[0].ulValueLen < 1) {
848 if (hsm_pkcs11_check_error(ctx, rv,
849 "Get attr value algorithm type")) {
853 if ((
CK_ULONG)
template[0].ulValueLen < 1) {
863 if (hsm_pkcs11_check_error(ctx, rv,
"Could not get the size of the modulus of the private key")) {
868 modulus = (
CK_BYTE_PTR)malloc(template2[0].ulValueLen);
869 template2[0].pValue = modulus;
870 if (modulus == NULL) {
871 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_size_rsa()",
872 "Error allocating memory for modulus");
882 if (hsm_pkcs11_check_error(ctx, rv,
"Could not get the modulus of the private key")) {
888 modulus_bits = template2[0].ulValueLen * 8;
890 for (
int i = 0; modulus_bits && (modulus[i] & mask) == 0; modulus_bits--) {
911 return hsm_get_key_size_rsa(ctx, session, key);
918 static CK_OBJECT_HANDLE
919 hsm_find_object_handle_for_id(
hsm_ctx_t *ctx,
921 CK_OBJECT_CLASS key_class,
926 CK_OBJECT_HANDLE object;
930 {
CKA_CLASS, &key_class,
sizeof(key_class) },
936 if (hsm_pkcs11_check_error(ctx, rv,
"Find objects init")) {
944 if (hsm_pkcs11_check_error(ctx, rv,
"Find object")) {
949 if (hsm_pkcs11_check_error(ctx, rv,
"Find object final")) {
953 if (objectCount > 0) {
965 static unsigned char *
966 hsm_hex_parse(
const char *hex,
size_t *len)
968 unsigned char *bytes;
973 if (!len)
return NULL;
976 if (!hex)
return NULL;
977 hex_len = strlen(hex);
978 if (hex_len % 2 != 0) {
983 bytes = malloc(*len);
984 for (i = 0; i < *len; i++) {
985 bytes[i] = ldns_hexdigit_to_int(hex[2*i]) * 16 +
986 ldns_hexdigit_to_int(hex[2*i+1]);
996 hsm_hex_unparse(
char *dst,
const unsigned char *src,
size_t len)
998 size_t dst_len = len*2 + 1;
1001 for (i = 0; i < len; i++) {
1002 snprintf(dst + (2*i), dst_len,
"%02x", src[i]);
1014 CK_OBJECT_HANDLE
object,
1030 if (hsm_pkcs11_check_error(ctx, rv,
"Get attr value")) {
1035 if ((
CK_LONG)
template[0].ulValueLen < 1) {
1041 template[0].pValue = malloc(
template[0].ulValueLen);
1047 if (hsm_pkcs11_check_error(ctx, rv,
"Get attr value 2")) {
1049 free(
template[0].pValue);
1053 *len =
template[0].ulValueLen;
1054 return template[0].pValue;
1062 hsm_key_new_privkey_object_handle(
hsm_ctx_t *ctx,
1064 CK_OBJECT_HANDLE
object)
1070 id = hsm_get_id_for_object(ctx, session,
object, &len);
1072 if (!
id)
return NULL;
1074 key = hsm_key_new();
1079 key->
public_key = hsm_find_object_handle_for_id(
1100 hsm_list_keys_session_internal(
hsm_ctx_t *ctx,
1110 {
CKA_CLASS, &key_class,
sizeof(key_class) },
1117 CK_OBJECT_HANDLE
object[max_object_count];
1118 CK_OBJECT_HANDLE *key_handles = NULL;
1122 if (hsm_pkcs11_check_error(ctx, rv,
"Find objects init")) {
1127 while (objectCount > 0) {
1132 if (hsm_pkcs11_check_error(ctx, rv,
"Find first object")) {
1138 total_count += objectCount;
1139 if (objectCount > 0 && store) {
1140 key_handles = realloc(key_handles, total_count *
sizeof(CK_OBJECT_HANDLE));
1141 for (i = 0; i < objectCount; i++) {
1142 key_handles[j] =
object[i];
1149 if (hsm_pkcs11_check_error(ctx, rv,
"Find objects final")) {
1156 keys = realloc(keys, total_count *
sizeof(
hsm_key_t *));
1157 for (i = 0; i < total_count; i++) {
1158 key = hsm_key_new_privkey_object_handle(ctx, session,
1166 *count = total_count;
1182 return hsm_list_keys_session_internal(ctx, session, count, 1);
1195 (void) hsm_list_keys_session_internal(ctx, session, &count, 0);
1205 const unsigned char *
id,
size_t len)
1208 CK_OBJECT_HANDLE private_key_handle;
1210 private_key_handle = hsm_find_object_handle_for_id(
1216 if (private_key_handle != 0) {
1217 key = hsm_key_new_privkey_object_handle(ctx, session,
1218 private_key_handle);
1236 const unsigned char *
id,
1242 if (!ctx) ctx = _hsm_ctx;
1243 if (!
id)
return NULL;
1246 key = hsm_find_key_by_id_session(ctx, ctx->
session[i],
id, len);
1247 if (key)
return key;
1259 hsm_find_repository_session(
hsm_ctx_t *ctx,
const char *repository)
1279 "hsm_find_repository_session()",
1280 "Can't find repository: %s", repository);
1294 unsigned long hKey = 0;
1295 unsigned char *data = NULL;
1296 size_t data_size = 0;
1304 if (!session || !session->
module) {
1319 if (hsm_pkcs11_check_error(ctx, rv,
"C_GetAttributeValue")) {
1322 public_exponent_len =
template[0].ulValueLen;
1323 modulus_len =
template[1].ulValueLen;
1325 public_exponent =
template[0].pValue = malloc(public_exponent_len);
1326 if (!public_exponent) {
1327 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_rdata()",
1328 "Error allocating memory for public exponent");
1332 modulus =
template[1].pValue = malloc(modulus_len);
1334 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_rdata()",
1335 "Error allocating memory for modulus");
1336 free(public_exponent);
1345 if (hsm_pkcs11_check_error(ctx, rv,
"get attribute value")) {
1346 free(
template[0].pValue);
1347 free(
template[1].pValue);
1352 hsm_remove_leading_zeroes(public_exponent, &public_exponent_len);
1353 hsm_remove_leading_zeroes(modulus, &modulus_len);
1355 data_size = public_exponent_len + modulus_len + 1;
1356 if (public_exponent_len <= 256) {
1357 data = malloc(data_size);
1359 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_rdata()",
1360 "Error allocating memory for pub key rr data");
1361 free(public_exponent);
1365 data[0] = public_exponent_len;
1366 memcpy(&data[1], public_exponent, public_exponent_len);
1367 memcpy(&data[1 + public_exponent_len], modulus, modulus_len);
1368 }
else if (public_exponent_len <= 65535) {
1370 data = malloc(data_size);
1372 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_rdata()",
1373 "Error allocating memory for pub key rr data");
1374 free(public_exponent);
1379 ldns_write_uint16(&data[1], (uint16_t) public_exponent_len);
1380 memcpy(&data[3], public_exponent, public_exponent_len);
1381 memcpy(&data[3 + public_exponent_len], modulus, modulus_len);
1383 hsm_ctx_set_error(ctx, -1,
"hsm_get_key_rdata()",
1384 "Public exponent too big");
1385 free(public_exponent);
1389 rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, data_size, data);
1390 free(public_exponent);
1400 hsm_create_prefix(
CK_ULONG digest_len,
1401 ldns_algorithm algorithm,
1405 const CK_BYTE RSA_MD5_ID[] = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
1406 const CK_BYTE RSA_SHA1_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 };
1407 const CK_BYTE RSA_SHA256_ID[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
1408 const CK_BYTE RSA_SHA512_ID[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 };
1411 case LDNS_SIGN_RSAMD5:
1412 *data_size =
sizeof(RSA_MD5_ID) + digest_len;
1413 data = malloc(*data_size);
1414 memcpy(data, RSA_MD5_ID,
sizeof(RSA_MD5_ID));
1416 case LDNS_SIGN_RSASHA1:
1417 case LDNS_SIGN_RSASHA1_NSEC3:
1418 *data_size =
sizeof(RSA_SHA1_ID) + digest_len;
1419 data = malloc(*data_size);
1420 memcpy(data, RSA_SHA1_ID,
sizeof(RSA_SHA1_ID));
1422 case LDNS_SIGN_RSASHA256:
1423 *data_size =
sizeof(RSA_SHA256_ID) + digest_len;
1424 data = malloc(*data_size);
1425 memcpy(data, RSA_SHA256_ID,
sizeof(RSA_SHA256_ID));
1427 case LDNS_SIGN_RSASHA512:
1428 *data_size =
sizeof(RSA_SHA512_ID) + digest_len;
1429 data = malloc(*data_size);
1430 memcpy(data, RSA_SHA512_ID,
sizeof(RSA_SHA512_ID));
1441 CK_MECHANISM_TYPE mechanism_type,
1443 ldns_buffer *sign_buf)
1449 digest_mechanism.pParameter = NULL;
1450 digest_mechanism.ulParameterLen = 0;
1451 digest_mechanism.
mechanism = mechanism_type;
1452 digest = malloc(digest_len);
1455 if (hsm_pkcs11_check_error(ctx, rv,
"HSM digest init")) {
1461 ldns_buffer_begin(sign_buf),
1462 ldns_buffer_position(sign_buf),
1465 if (hsm_pkcs11_check_error(ctx, rv,
"HSM digest")) {
1474 ldns_buffer *sign_buf,
1476 ldns_algorithm algorithm)
1494 session = hsm_find_key_session(ctx, key);
1495 if (!session)
return NULL;
1497 signature = malloc(signatureLen);
1498 if (signature == NULL) {
1505 switch (algorithm) {
1506 case LDNS_SIGN_RSAMD5:
1508 digest = hsm_digest_through_hsm(ctx, session,
1513 case LDNS_SIGN_RSASHA1:
1514 case LDNS_SIGN_RSASHA1_NSEC3:
1515 digest_len = LDNS_SHA1_DIGEST_LENGTH;
1516 digest = malloc(digest_len);
1517 digest = ldns_sha1(ldns_buffer_begin(sign_buf),
1518 ldns_buffer_position(sign_buf),
1522 case LDNS_SIGN_RSASHA256:
1523 digest_len = LDNS_SHA256_DIGEST_LENGTH;
1524 digest = malloc(digest_len);
1525 digest = ldns_sha256(ldns_buffer_begin(sign_buf),
1526 ldns_buffer_position(sign_buf),
1530 case LDNS_SIGN_RSASHA512:
1531 digest_len = LDNS_SHA512_DIGEST_LENGTH;
1532 digest = malloc(digest_len);
1533 digest = ldns_sha512(ldns_buffer_begin(sign_buf),
1534 ldns_buffer_position(sign_buf),
1552 data = hsm_create_prefix(digest_len, algorithm, &data_len);
1553 memcpy(data + data_len - digest_len, digest, digest_len);
1555 sign_mechanism.pParameter = NULL;
1556 sign_mechanism.ulParameterLen = 0;
1558 case LDNS_SIGN_RSAMD5:
1559 case LDNS_SIGN_RSASHA1:
1560 case LDNS_SIGN_RSASHA1_NSEC3:
1561 case LDNS_SIGN_RSASHA256:
1562 case LDNS_SIGN_RSASHA512:
1578 if (hsm_pkcs11_check_error(ctx, rv,
"sign init")) {
1588 if (hsm_pkcs11_check_error(ctx, rv,
"sign final")) {
1595 sig_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
1608 hsm_dname_is_wildcard(
const ldns_rdf* dname)
1610 return ( ldns_dname_label_count(dname) > 0 &&
1611 ldns_rdf_data(dname)[0] == 1 &&
1612 ldns_rdf_data(dname)[1] ==
'*');
1616 hsm_create_empty_rrsig(
const ldns_rr_list *rrset,
1621 uint32_t orig_class;
1623 uint8_t label_count;
1625 label_count = ldns_dname_label_count(
1626 ldns_rr_owner(ldns_rr_list_rr(rrset, 0)));
1628 if (hsm_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)))) {
1632 rrsig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
1635 orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
1636 orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
1638 ldns_rr_set_class(rrsig, orig_class);
1639 ldns_rr_set_ttl(rrsig, orig_ttl);
1640 ldns_rr_set_owner(rrsig,
1643 ldns_rr_list_rr(rrset,
1649 (void)ldns_rr_rrsig_set_origttl(
1651 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
1654 (void)ldns_rr_rrsig_set_signame(
1656 ldns_rdf_clone(sign_params->
owner));
1658 (void)ldns_rr_rrsig_set_labels(
1660 ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
1665 (void)ldns_rr_rrsig_set_inception(
1667 ldns_native2rdf_int32(
1671 (void)ldns_rr_rrsig_set_inception(
1673 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
1676 (void)ldns_rr_rrsig_set_expiration(
1678 ldns_native2rdf_int32(
1682 (void)ldns_rr_rrsig_set_expiration(
1684 ldns_native2rdf_int32(
1686 now + LDNS_DEFAULT_EXP_TIME));
1689 (void)ldns_rr_rrsig_set_keytag(
1691 ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
1694 (void)ldns_rr_rrsig_set_algorithm(
1696 ldns_native2rdf_int8(
1700 (void)ldns_rr_rrsig_set_typecovered(
1702 ldns_native2rdf_int16(
1704 ldns_rr_get_type(ldns_rr_list_rr(rrset,
1717 char *(pin_callback)(
const char *repository,
void *),
1721 xmlXPathContextPtr xpath_ctx;
1722 xmlXPathObjectPtr xpath_obj;
1735 int repositories = 0;
1739 _hsm_ctx = hsm_ctx_new();
1742 config_file = strdup(config);
1744 config_file = strdup(HSM_DEFAULT_CONFIG);
1748 doc = xmlParseFile(config_file);
1755 xpath_ctx = xmlXPathNewContext(doc);
1756 if(xpath_ctx == NULL) {
1758 hsm_ctx_free(_hsm_ctx);
1764 xexpr = (xmlChar *)
"//Configuration/RepositoryList/Repository";
1765 xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx);
1766 if(xpath_obj == NULL) {
1767 xmlXPathFreeContext(xpath_ctx);
1769 hsm_ctx_free(_hsm_ctx);
1774 if (xpath_obj->nodesetval) {
1775 for (i = 0; i < xpath_obj->nodesetval->nodeNr; i++) {
1780 hsm_config_default(&module_config);
1782 curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode;
1783 repository = (
char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i],
1784 (
const xmlChar *)
"name");
1787 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"TokenLabel"))
1788 token_label = (
char *) xmlNodeGetContent(curNode);
1789 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Module"))
1790 module_path = (
char *) xmlNodeGetContent(curNode);
1791 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"PIN"))
1792 module_pin = (
char *) xmlNodeGetContent(curNode);
1793 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"SkipPublicKey"))
1795 curNode = curNode->next;
1798 if (repository && token_label && module_path) {
1812 module_pin = pin_callback(repository,
1819 memset(module_pin, 0, strlen(module_pin));
1841 xmlXPathFreeObject(xpath_obj);
1842 xmlXPathFreeContext(xpath_ctx);
1845 if (result ==
HSM_OK && repositories == 0) {
1847 "No repositories found");
1860 prompt = malloc(64);
1861 snprintf(prompt, 64,
"Enter PIN for token %s:", repository);
1862 #ifdef HAVE_GETPASSPHRASE
1863 r = getpassphrase(
"Enter PIN:");
1865 r = getpass(
"Enter PIN:");
1874 hsm_ctx_close(_hsm_ctx, 1);
1881 return hsm_ctx_clone(_hsm_ctx);
1891 CK_SESSION_HANDLE session_handle;
1899 if (session == NULL)
continue;
1905 if (hsm_pkcs11_check_error(ctx, rv,
"get session info")) {
1911 hsm_ctx_set_error(ctx,
HSM_ERROR,
"hsm_check_context()",
1912 "Session not logged in");
1922 if (hsm_pkcs11_check_error(ctx, rv,
"test open session")) {
1926 if (hsm_pkcs11_check_error(ctx, rv,
"test close session")) {
1937 hsm_ctx_close(ctx, 0);
1949 params->
flags = LDNS_KEY_ZONE_KEY;
1953 params->
owner = NULL;
1961 if (params->
owner) ldns_rdf_deep_free(params->
owner);
1970 size_t key_count = 0;
1971 size_t cur_key_count;
1982 keys = realloc(keys,
1983 (key_count + cur_key_count) *
sizeof(
hsm_key_t *));
1984 for (j = 0; j < cur_key_count; j++) {
1985 keys[key_count + j] = session_keys[j];
1987 key_count += cur_key_count;
1999 const char *repository)
2003 if (!repository)
return NULL;
2004 if (!ctx) ctx = _hsm_ctx;
2006 session = hsm_find_repository_session(ctx, repository);
2020 if (!ctx) ctx = _hsm_ctx;
2029 const char *repository)
2033 if (!repository)
return 0;
2034 if (!ctx) ctx = _hsm_ctx;
2036 session = hsm_find_repository_session(ctx, repository);
2046 unsigned char *id_bytes;
2050 id_bytes = hsm_hex_parse(
id, &len);
2052 if (!id_bytes)
return NULL;
2054 key = hsm_find_key_by_id_bin(ctx, id_bytes, len);
2061 const char *repository,
2062 unsigned long keysize)
2067 unsigned char id[16];
2071 CK_OBJECT_HANDLE publicKey, privateKey;
2072 CK_KEY_TYPE keyType =
CKK_RSA;
2076 CK_BYTE publicExponent[] = { 1, 0, 1 };
2081 if (!ctx) ctx = _hsm_ctx;
2082 session = hsm_find_repository_session(ctx, repository);
2083 if (!session)
return NULL;
2088 }
while (hsm_find_key_by_id_bin(ctx,
id, 16));
2091 hsm_hex_unparse(id_str,
id, 16);
2103 {
CKA_WRAP, &cfalse,
sizeof(cfalse) },
2113 {
CKA_SIGN, &ctrue,
sizeof (ctrue) },
2124 publicKeyTemplate, 9,
2125 privateKeyTemplate, 10,
2128 if (hsm_pkcs11_check_error(ctx, rv,
"generate key pair")) {
2132 new_key = hsm_key_new();
2150 if (!ctx) ctx = _hsm_ctx;
2151 if (!key)
return -1;
2153 session = hsm_find_key_session(ctx, key);
2154 if (!session)
return -2;
2158 if (hsm_pkcs11_check_error(ctx, rv,
"Destroy private key")) {
2166 if (hsm_pkcs11_check_error(ctx, rv,
"Destroy public key")) {
2187 for (i = 0; i < count; i++) {
2201 if (!ctx) ctx = _hsm_ctx;
2202 if (!key)
return NULL;
2204 session = hsm_find_key_session(ctx, key);
2205 if (!session)
return NULL;
2207 id = hsm_get_id_for_object(ctx, session, key->
private_key, &len);
2208 if (!
id)
return NULL;
2211 id_str = malloc(len * 2 + 1);
2212 if (!id_str)
return NULL;
2214 hsm_hex_unparse(id_str,
id, len);
2228 if (!ctx) ctx = _hsm_ctx;
2229 session = hsm_find_key_session(ctx, key);
2230 if (!session)
return NULL;
2235 if (key_info->
id == NULL) {
2236 key_info->
id = strdup(
"");
2239 key_info->
algorithm = (
unsigned long) hsm_get_key_algorithm(ctx,
2242 key_info->
keysize = (
unsigned long) hsm_get_key_size(ctx,
2277 const ldns_rr_list* rrset,
2282 ldns_buffer *sign_buf;
2287 if (!key)
return NULL;
2288 if (!sign_params)
return NULL;
2290 signature = hsm_create_empty_rrsig((ldns_rr_list *)rrset,
2296 sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
2298 if (ldns_rrsig2buffer_wire(sign_buf, signature)
2299 != LDNS_STATUS_OK) {
2300 ldns_buffer_free(sign_buf);
2306 for(i = 0; i < ldns_rr_list_rr_count(rrset); i++) {
2307 ldns_rr2canonical(ldns_rr_list_rr(rrset, i));
2311 if (ldns_rr_list2buffer_wire(sign_buf, rrset)
2312 != LDNS_STATUS_OK) {
2313 ldns_buffer_free(sign_buf);
2317 b64_rdf = hsm_sign_buffer(ctx, sign_buf, key, sign_params->
algorithm);
2319 ldns_buffer_free(sign_buf);
2325 ldns_rr_rrsig_set_sig(signature, b64_rdf);
2342 size_t *digest_length)
2350 if (hsm_pkcs11_check_error(ctx, rv,
"digest init")) {
2361 if (hsm_pkcs11_check_error(ctx, rv,
"digest to determine result size")) {
2371 if (hsm_pkcs11_check_error(ctx, rv,
"digest")) {
2385 uint16_t iterations,
2386 uint8_t salt_length,
2389 char *orig_owner_str;
2390 size_t hashed_owner_str_len;
2391 ldns_rdf *hashed_owner;
2392 char *hashed_owner_str;
2393 char *hashed_owner_b32;
2394 int hashed_owner_b32_len;
2397 size_t hash_length = 0;
2407 mechanism.pParameter = NULL;
2408 mechanism.ulParameterLen = 0;
2411 printf(
"unknown algo: %u\n", (
unsigned int)algorithm);
2417 if (!ctx) ctx = _hsm_ctx;
2426 orig_owner_str = ldns_rdf2str(name);
2428 hashed_owner_str_len = salt_length + ldns_rdf_size(name);
2429 hashed_owner_str = LDNS_XMALLOC(
char, hashed_owner_str_len);
2430 memcpy(hashed_owner_str, ldns_rdf_data(name), ldns_rdf_size(name));
2431 memcpy(hashed_owner_str + ldns_rdf_size(name), salt, salt_length);
2433 for (cur_it = iterations + 1; cur_it > 0; cur_it--) {
2434 if (hash != NULL) free(hash);
2435 hash = (
char *) hsm_digest(ctx,
2439 hashed_owner_str_len,
2442 LDNS_FREE(hashed_owner_str);
2443 hashed_owner_str_len = salt_length + hash_length;
2444 hashed_owner_str = LDNS_XMALLOC(
char, hashed_owner_str_len);
2445 if (!hashed_owner_str) {
2446 hsm_ctx_set_error(ctx, -1,
"hsm_nsec3_hash_name()",
2450 memcpy(hashed_owner_str, hash, hash_length);
2451 memcpy(hashed_owner_str + hash_length, salt, salt_length);
2454 LDNS_FREE(hashed_owner_str);
2455 hashed_owner_str = hash;
2456 hashed_owner_str_len = hash_length;
2457 hashed_owner_b32 = LDNS_XMALLOC(
char,
2458 ldns_b32_ntop_calculate_size(
2459 hashed_owner_str_len) + 1);
2460 LDNS_FREE(orig_owner_str);
2461 hashed_owner_b32_len =
2462 (size_t) ldns_b32_ntop_extended_hex((uint8_t *) hashed_owner_str,
2463 hashed_owner_str_len,
2465 ldns_b32_ntop_calculate_size(
2466 hashed_owner_str_len));
2467 if (hashed_owner_b32_len < 1) {
2468 error_name = ldns_rdf2str(name);
2469 hsm_ctx_set_error(ctx, -1,
"hsm_nsec3_hash_name()",
2470 "Error in base32 extended hex encoding "
2471 "of hashed owner name (name: %s, return code: %d)",
2472 error_name, hashed_owner_b32_len);
2473 LDNS_FREE(error_name);
2474 LDNS_FREE(hashed_owner_b32);
2477 hashed_owner_str_len = hashed_owner_b32_len;
2478 hashed_owner_b32[hashed_owner_b32_len] =
'\0';
2480 status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
2481 if (status != LDNS_STATUS_OK) {
2482 hsm_ctx_set_error(ctx, -1,
"hsm_nsec3_hash_name()",
2483 "Error creating rdf from %s", hashed_owner_b32);
2484 LDNS_FREE(hashed_owner_b32);
2489 LDNS_FREE(hashed_owner_b32);
2490 return hashed_owner;
2503 if (!ctx) ctx = _hsm_ctx;
2505 hsm_ctx_set_error(ctx, -1,
"hsm_get_dnskey()",
"Got NULL key");
2509 hsm_ctx_set_error(ctx, -1,
"hsm_get_dnskey()",
"Got NULL sign_params");
2512 session = hsm_find_key_session(ctx, key);
2513 if (!session)
return NULL;
2515 dnskey = ldns_rr_new();
2516 ldns_rr_set_type(dnskey, LDNS_RR_TYPE_DNSKEY);
2518 ldns_rr_set_owner(dnskey, ldns_rdf_clone(sign_params->
owner));
2520 ldns_rr_push_rdf(dnskey,
2521 ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
2522 sign_params->
flags));
2523 ldns_rr_push_rdf(dnskey,
2524 ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
2525 LDNS_DNSSEC_KEYPROTO));
2526 ldns_rr_push_rdf(dnskey,
2527 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
2530 rdata = hsm_get_key_rdata(ctx, session, key);
2531 if (rdata == NULL) {
2534 ldns_rr_push_rdf(dnskey, rdata);
2541 unsigned char *buffer,
2542 unsigned long length)
2547 if (!buffer)
return -1;
2548 if (!ctx) ctx = _hsm_ctx;
2572 unsigned char rnd_buf[4];
2575 memcpy(&rnd, rnd_buf, 4);
2587 unsigned char rnd_buf[8];
2590 memcpy(&rnd, rnd_buf, 8);
2603 const char *token_label,
2611 result = hsm_session_init(_hsm_ctx,
2619 return hsm_ctx_add_session(_hsm_ctx, session);
2633 hsm_session_close(_hsm_ctx, _hsm_ctx->
session[i], 1);
2653 if (!ctx) ctx = _hsm_ctx;
2662 "hsm_token_attached()",
2663 "Can't find repository: %s", repository);
2671 case LDNS_SIGN_RSAMD5:
2672 case LDNS_SIGN_RSASHA1:
2673 case LDNS_SIGN_RSASHA1_NSEC3:
2674 case LDNS_SIGN_RSASHA256:
2675 case LDNS_SIGN_RSASHA512:
2700 if (message == NULL) {
2701 return strdup(
"libhsm memory allocation failed");
2717 printf(
"\t\tmodule at %p (sym %p)\n", (
void *) session->
module, (
void *) session->
module->
sym);
2718 printf(
"\t\tmodule path: %s\n", session->
module->
path);
2719 printf(
"\t\trepository name: %s\n", session->
module->
name);
2721 printf(
"\t\tsess handle: %u\n", (
unsigned int) session->
session);
2733 printf(
"CTX Sessions: %lu\n",
2736 printf(
"\tSession at %p\n", (
void *) ctx->
session[i]);
2748 printf(
"\tmodule: %p\n", (
void *) key->
module);
2749 printf(
"\tprivkey handle: %u\n", (
unsigned int) key->
private_key);
2751 printf(
"\tpubkey handle: %u\n", (
unsigned int) key->
public_key);
2753 printf(
"\tpubkey handle: %s\n",
"NULL");
2755 printf(
"\trepository: %s\n", key->
module->
name);
2757 printf(
"\tsize: %lu\n", key_info->
keysize);
2758 printf(
"\tid: %s\n", key_info->
id);
2761 printf(
"key: hsm_get_key_info() returned NULL\n");
2764 printf(
"key: <void>\n");
2776 fprintf(stderr,
"%s\n", message);
2779 fprintf(stderr,
"Unknown error\n");
2807 if (result !=
HSM_OK)
return;
2810 if (hsm_pkcs11_check_error(ctx, rv,
"C_GetTokenInfo")) {
2814 printf(
"Repository: %s\n",session->
module->
name);
2816 printf(
"\tModule: %s\n", session->
module->
path);
2817 printf(
"\tSlot: %lu\n", slot_id);
2818 printf(
"\tToken Label: %.*s\n",
2819 (
int)
sizeof(token_info.
label), token_info.
label);
2820 printf(
"\tManufacturer: %.*s\n",
2821 (
int)
sizeof(token_info.manufacturerID), token_info.manufacturerID);
2822 printf(
"\tModel: %.*s\n",
2823 (
int)
sizeof(token_info.
model), token_info.
model);
2824 printf(
"\tSerial: %.*s\n",
2825 (
int)
sizeof(token_info.serialNumber), token_info.serialNumber);