1 /* 2 * Copyright (c) 2009 .SE (The Internet Infrastructure Foundation). 3 * Copyright (c) 2009 NLNet Labs. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 23 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef HSM_H 29 #define HSM_H 1 30 31 #include <stdint.h> 32 #include <ldns/rbtree.h> 33 #include <pthread.h> 34 35 #define HSM_MAX_SESSIONS 100 36 /* 37 * Note that currently the MySQL kasp schema limits the number of HSMs to 38 * 127; so to increase it beyond that requires some database changes similar 39 * to when keypairs(id) was increased, see svn r4465. 40 * 41 * Note that this constant also determines the size of the shared PIN memory. 42 * Increasing this size requires any existing memory to be removed and should 43 * be part of a migration script. 44 */ 45 #define HSM_MAX_SESSIONS 100 46 47 #define HSM_MAX_ALGONAME 16 48 49 #define HSM_ERROR_MSGSIZE 512 50 51 /* TODO: depends on type and key, or just leave it at current 52 * maximum? */ 53 #define HSM_MAX_SIGNATURE_LENGTH 512 54 55 /* Note that this constant also determines the size of the shared PIN memory. 56 * Increasing this size requires any existing memory to be removed and should 57 * be part of a migration script. 58 */ 59 #define HSM_MAX_PIN_LENGTH 255 60 61 /*! Return codes for some of the functions */ 62 /*! These should be different than the list of CKR_ values defined 63 * by pkcs11 (for easier debugging purposes of calling applications) 64 */ 65 #define HSM_OK 0 66 #define HSM_ERROR 0x10000001 67 #define HSM_PIN_INCORRECT 0x10000002 68 #define HSM_CONFIG_FILE_ERROR 0x10000003 69 #define HSM_REPOSITORY_NOT_FOUND 0x10000004 70 #define HSM_NO_REPOSITORIES 0x10000005 71 #define HSM_MODULE_NOT_FOUND 0x10000006 72 73 /*! The mode for the PIN callback functions */ 74 #define HSM_PIN_FIRST 0 /* Used when getting the PIN for the first time. */ 75 #define HSM_PIN_RETRY 1 /* Used when we failed to login the first time. */ 76 #define HSM_PIN_SAVE 2 /* The latest PIN can be saved for future use. Called 77 after a successful login. */ 78 79 /*! HSM configuration */ 80 typedef struct { 81 unsigned int use_pubkey; /*!< Maintain public keys in HSM */ 82 unsigned int allow_extract; /*!< Generate CKA_EXTRACTABLE private keys */ 83 } hsm_config_t; 84 85 /*! Data type to describe an HSM */ 86 typedef struct { 87 unsigned int id; /*!< HSM numerical identifier */ 88 char *name; /*!< name of repository */ 89 char *token_label; /*!< label of the token */ 90 char *path; /*!< path to PKCS#11 library */ 91 void *handle; /*!< handle from dlopen()*/ 92 void *sym; /*!< Function list from dlsym */ 93 hsm_config_t *config; /*!< optional per HSM configuration */ 94 } hsm_module_t; 95 96 /*! HSM Session */ 97 typedef struct { 98 hsm_module_t *module; 99 unsigned long session; 100 } hsm_session_t; 101 102 /*! HSM Key Pair */ 103 typedef struct { 104 char *modulename; /*!< name of the module, as in hsm_session_t.module.name */ 105 unsigned long private_key; /*!< private key within module */ 106 unsigned long public_key; /*!< public key within module */ 107 } libhsm_key_t; 108 109 /*! HSM Key Pair Information */ 110 typedef struct { 111 char *id; /*!< key id */ 112 unsigned long algorithm; /*!< key algorithm (cast from CKK_*)*/ 113 char *algorithm_name; /*!< key algorithm name */ 114 unsigned long keysize; /*!< key size */ 115 } libhsm_key_info_t; 116 117 /*! HSM Repositories */ 118 typedef struct hsm_repository_struct hsm_repository_t; 119 struct hsm_repository_struct { 120 hsm_repository_t* next; /*!< next repository > */ 121 char *name; /*!< name */ 122 char *module; /*!< PKCS#11 module */ 123 char *tokenlabel; /*!< PKCS#11 token label */ 124 char *pin; /*!< PKCS#11 login credentials */ 125 uint8_t require_backup; /*!< require a backup of keys before using new keys */ 126 uint8_t use_pubkey; /*!< use public keys in repository? */ 127 unsigned int allow_extract; /*!< Generate CKA_EXTRACTABLE private keys */ 128 }; 129 130 /*! HSM context to keep track of sessions */ 131 typedef struct { 132 hsm_session_t *session[HSM_MAX_SESSIONS]; /*!< HSM sessions */ 133 size_t session_count; /*!< number of configured HSMs */ 134 135 /*!< non-zero if the last operation failed (only the first error will be set) */ 136 int error; 137 138 /*!< static string describing the action we were trying to do 139 when the first error happened */ 140 const char *error_action; 141 142 /*!< static string describing the first error */ 143 char error_message[HSM_ERROR_MSGSIZE]; 144 145 ldns_rbtree_t* keycache; 146 pthread_mutex_t *keycache_lock; 147 } hsm_ctx_t; 148 149 150 /*! Set HSM Context Error 151 152 If the ctx is given, and it's error value is still 0, the value will be 153 set to 'error', and the error_message and error_action will be set to 154 the given strings. 155 156 \param ctx HSM context 157 \param error error code 158 \param action action for which the error occured 159 \param message error message format string 160 */ 161 extern void 162 hsm_ctx_set_error(hsm_ctx_t *ctx, int error, const char *action, 163 const char *message, ...) 164 #ifdef HAVE___ATTRIBUTE__ 165 __attribute__ ((format (printf, 4, 5))) 166 #endif 167 ; 168 169 /*! Open HSM library 170 171 \param rlist Repository list. 172 \param pin_callback This function will be called for tokens that have 173 no PIN configured. The default hsm_prompt_pin() can 174 be used. If this value is NULL, these tokens will 175 be skipped. 176 \return 0 if successful, !0 if failed 177 178 Attaches all HSMs in the repository list, querying for PINs (using the given 179 callback function) if not known. 180 Also creates initial sessions (not part of any context; every API 181 function that takes a context can be passed NULL, in which case the 182 global context will be used) and log into each HSM. 183 */ 184 extern int 185 hsm_open2(hsm_repository_t* rlist, 186 char *(pin_callback)(unsigned int, const char *, unsigned int)); 187 188 189 /*! Create new repository as specified in conf.xml. 190 191 \param name Repository name. 192 \param module PKCS#11 module. 193 \param tokenlabel PKCS#11 token label. 194 \param pin PKCS#11 login credentials. 195 \param use_pubkey Whether to store the public key in the HSM. 196 \return The created repository. 197 */ 198 hsm_repository_t * 199 hsm_repository_new(char* name, char* module, char* tokenlabel, char* pin, 200 uint8_t use_pubkey, uint8_t allowextract, uint8_t require_backup); 201 202 /*! Free configured repositories. 203 204 \param r Repository list. 205 */ 206 void 207 hsm_repository_free(hsm_repository_t* r); 208 209 /*! Function that queries for a PIN, can be used as callback 210 for hsm_open(). Stores the PIN in the shared memory. 211 212 \param id Used for identifying the repository. Will have a value between zero and 213 HSM_MAX_SESSIONS. 214 \param repository The repository name will be included in the prompt 215 \param mode The type of mode the function should run in. 216 \return The string the user enters 217 */ 218 extern char * 219 hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode); 220 221 222 /*! Function that will check if there is a PIN in the shared memory and returns it. 223 224 \param id Used for identifying the repository. Will have a value between zero and 225 HSM_MAX_SESSIONS. 226 \param repository The repository name will be included in the prompt 227 \param mode The type of mode the function should run in. 228 \return The string the user enters 229 */ 230 extern char * 231 hsm_check_pin(unsigned int id, const char *repository, unsigned int mode); 232 233 234 /*! Logout 235 236 Function that will logout the user by deleting the shared memory and 237 semaphore. Any authenticated process will still be able to interact 238 with the HSM. 239 */ 240 extern int 241 hsm_logout_pin(void); 242 243 244 /*! Close HSM library 245 246 Log out and detach from all configured HSMs 247 This cleans up all data for libhsm, and should be the last function 248 called. 249 */ 250 extern void 251 hsm_close(void); 252 253 254 /*! Create new HSM context 255 256 Creates a new session for each attached HSM. The returned hsm_ctx_t * 257 can be freed with hsm_destroy_context() 258 */ 259 extern hsm_ctx_t * 260 hsm_create_context(void); 261 262 263 /*! Check HSM context 264 265 Check if the associated sessions are still alive. 266 If they are not alive, then try re-open libhsm. 267 268 \param context HSM context 269 \return 0 if successful, !0 if failed 270 */ 271 extern int 272 hsm_check_context(); 273 274 275 /*! Destroy HSM context 276 277 \param context HSM context 278 279 Also destroys any associated sessions. 280 */ 281 extern void 282 hsm_destroy_context(hsm_ctx_t *context); 283 284 extern void 285 libhsm_key_free(libhsm_key_t *key); 286 287 /*! List all known keys in all attached HSMs 288 289 After the function has run, the value at count contains the number 290 of keys found. 291 292 The resulting key list can be freed with libhsm_key_list_free() 293 Alternatively, each individual key structure in the list could be 294 freed with libhsm_key_free() 295 296 \param context HSM context 297 \param count location to store the number of keys found 298 */ 299 extern libhsm_key_t ** 300 hsm_list_keys(hsm_ctx_t *context, size_t *count); 301 302 303 /*! List all known keys in a HSM 304 305 After the function has run, the value at count contains the number 306 of keys found. 307 308 The resulting key list can be freed with libhsm_key_list_free() 309 Alternatively, each individual key structure in the list could be 310 freed with libhsm_key_free() 311 312 \param context HSM context 313 \param count location to store the number of keys found 314 \param repository repository to list the keys in 315 */ 316 extern libhsm_key_t ** 317 hsm_list_keys_repository(hsm_ctx_t *context, 318 size_t *count, 319 const char *repository); 320 321 322 323 /*! Find a key pair by CKA_ID (as hex string) 324 325 The returned key structure can be freed with libhsm_key_free() 326 327 \param context HSM context 328 \param id CKA_ID of key to find (null-terminated 329 string of hex characters) 330 \return key identifier or NULL if not found (or invalid input) 331 */ 332 extern libhsm_key_t * 333 hsm_find_key_by_id(hsm_ctx_t *context, 334 const char *id); 335 336 /*! Generate new key pair in HSM 337 338 Keys generated by libhsm will have a 16-byte identifier set as CKA_ID 339 and the hexadecimal representation of it set as CKA_LABEL. 340 Other stuff, like exponent, may be needed here as well. 341 342 The returned key structure can be freed with libhsm_key_free() 343 344 \param context HSM context 345 \param repository repository in where to create the key 346 \param keysize Size of RSA key 347 \return return key identifier or NULL if key generation failed 348 */ 349 extern libhsm_key_t * 350 hsm_generate_rsa_key(hsm_ctx_t *context, 351 const char *repository, 352 unsigned long keysize); 353 354 /*! Generate new key pair in HSM 355 356 Keys generated by libhsm will have a 16-byte identifier set as CKA_ID 357 and the hexadecimal representation of it set as CKA_LABEL. 358 359 The returned key structure can be freed with libhsm_key_free() 360 361 \param context HSM context 362 \param repository repository in where to create the key 363 \param keysize Size of DSA key 364 \return return key identifier or NULL if key generation failed 365 */ 366 extern libhsm_key_t * 367 hsm_generate_dsa_key(hsm_ctx_t *context, 368 const char *repository, 369 unsigned long keysize); 370 371 /*! Generate new key pair in HSM 372 373 Keys generated by libhsm will have a 16-byte identifier set as CKA_ID 374 and the hexadecimal representation of it set as CKA_LABEL. 375 376 The returned key structure can be freed with libhsm_key_free() 377 378 \param context HSM context 379 \param repository repository in where to create the key 380 \return return key identifier or NULL if key generation failed 381 */ 382 extern libhsm_key_t * 383 hsm_generate_gost_key(hsm_ctx_t *context, 384 const char *repository); 385 386 /*! Generate new key pair in HSM 387 388 Keys generated by libhsm will have a 16-byte identifier set as CKA_ID 389 and the hexadecimal representation of it set as CKA_LABEL. 390 391 The returned key structure can be freed with libhsm_key_free() 392 393 \param context HSM context 394 \param repository repository in where to create the key 395 \param curve which curve to use 396 \return return key identifier or NULL if key generation failed 397 */ 398 extern libhsm_key_t * 399 hsm_generate_ecdsa_key(hsm_ctx_t *context, 400 const char *repository, 401 const char *curve); 402 403 /*! Generate new key pair in HSM 404 405 Keys generated by libhsm will have a 16-byte identifier set as CKA_ID 406 and the hexadecimal representation of it set as CKA_LABEL. 407 408 The returned key structure can be freed with libhsm_key_free() 409 410 \param context HSM context 411 \param repository repository in where to create the key 412 \param curve which curve to use 413 \return return key identifier or NULL if key generation failed 414 */ 415 libhsm_key_t * 416 hsm_generate_eddsa_key(hsm_ctx_t *context, 417 const char *repository, 418 const char *curve); 419 420 /*! Remove a key pair from HSM 421 422 When a key is removed, the module pointer is set to NULL, and 423 the public and private key handles are set to 0. The structure still 424 needs to be freed. 425 426 \param context HSM context 427 \param key Key pair to be removed 428 \return 0 if successful, !0 if failed 429 */ 430 extern int 431 hsm_remove_key(hsm_ctx_t *context, libhsm_key_t *key); 432 433 434 /*! Free the memory of an array of key structures, as returned by 435 hsm_list_keys() 436 437 \param key_list The array of keys to free 438 \param count The number of keys in the array 439 */ 440 extern void 441 libhsm_key_list_free(libhsm_key_t **key_list, size_t count); 442 443 444 /*! Get id as null-terminated hex string using key identifier 445 446 The returned id is allocated data, and must be free()d by the caller 447 448 \param context HSM context 449 \param key Key pair to get the ID from 450 \return id of key pair 451 */ 452 extern char * 453 hsm_get_key_id(hsm_ctx_t *context, 454 const libhsm_key_t *key); 455 456 457 /*! Get extended key information 458 459 The returned id is allocated data, and must be freed by the caller 460 With libhsm_key_info_free() 461 462 \param context HSM context 463 \param key Key pair to get information about 464 \return key information 465 */ 466 extern libhsm_key_info_t * 467 hsm_get_key_info(hsm_ctx_t *context, 468 const libhsm_key_t *key); 469 470 471 /*! Frees the libhsm_key_info_t structure 472 473 \param key_info The structure to free 474 */ 475 extern void 476 libhsm_key_info_free(libhsm_key_info_t *key_info); 477 478 /*! Fill a buffer with random data from any attached HSM 479 480 \param context HSM context 481 \param buffer Buffer to fill with random data 482 \param length Size of random buffer 483 \return 0 if successful, !0 if failed 484 485 */ 486 extern int 487 hsm_random_buffer(hsm_ctx_t *ctx, 488 unsigned char *buffer, 489 unsigned long length); 490 491 492 /*! Return unsigned 32-bit random number from any attached HSM 493 \param context HSM context 494 \return 32-bit random number, or 0 if no HSM with a random generator is 495 attached 496 */ 497 extern uint32_t 498 hsm_random32(hsm_ctx_t *ctx); 499 500 501 /*! Return unsigned 64-bit random number from any attached HSM 502 \param context HSM context 503 \return 64-bit random number, or 0 if no HSM with a random generator is 504 attached 505 */ 506 extern uint64_t 507 hsm_random64(hsm_ctx_t *ctx); 508 509 510 511 /* 512 * Additional functions for debugging, and non-general use-cases. 513 */ 514 515 /*! Attached a named HSM using a PKCS#11 shared library and 516 optional credentials (may be NULL, but then undefined) 517 This function changes the global state, and is not threadsafe 518 519 \param repository the name of the repository 520 \param token_label the name of the token to attach 521 \param path the path of the shared PKCS#11 library 522 \param pin the PIN to log into the token 523 \param config optional configuration 524 \return 0 on success, -1 on error 525 */ 526 extern int 527 hsm_attach(const char *repository, 528 const char *token_name, 529 const char *path, 530 const char *pin, 531 const hsm_config_t *config); 532 533 /*! Check whether a named token has been initialized in this context 534 \param ctx HSM context 535 \param token_name The name of the token 536 \return 1 if the token is attached, 0 if not found 537 */ 538 extern int 539 hsm_token_attached(hsm_ctx_t *ctx, 540 const char *repository); 541 542 /*! Return the current error message 543 544 The returned message is allocated data, and must be free()d by the caller 545 546 \param ctx HSM context 547 \return error message string 548 */ 549 550 extern char * 551 hsm_get_error(hsm_ctx_t *gctx); 552 553 /* a few debug functions for applications */ 554 extern void hsm_print_session(hsm_session_t *session); 555 extern void hsm_print_ctx(hsm_ctx_t *ctx); 556 extern void hsm_print_key(hsm_ctx_t *ctx, libhsm_key_t *key); 557 extern void hsm_print_error(hsm_ctx_t *ctx); 558 extern void hsm_print_tokeninfo(hsm_ctx_t *ctx); 559 560 /* implementation of a key cache per context, needs changing see 561 * OPENDNSSEC-799. 562 */ 563 extern void keycache_create(hsm_ctx_t* ctx); 564 extern void keycache_destroy(hsm_ctx_t* ctx); 565 extern const libhsm_key_t* keycache_lookup(hsm_ctx_t* ctx, const char* locator); 566 567 #endif /* HSM_H */ 568