From 699a2605bfa39e0bd70fabcfee73887caf533421 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 08 2020 10:13:11 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/configure.ac b/configure.ac index 7c42a97..289c505 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,7 @@ AC_SUBST([OPENLDAP_LIBS]) dnl Define custom variables -lockdir=/run/lock/opencryptoki +lockdir=$localstatedir/lock/opencryptoki AC_SUBST(lockdir) logdir=$localstatedir/log/opencryptoki @@ -189,12 +189,6 @@ AC_ARG_ENABLE([p11sak], [], [enable_p11sak=yes]) -dnl --- pkcstok_migrate -AC_ARG_ENABLE([pkcstok_migrate], - AS_HELP_STRING([--enable-pkcstok_migrate],[build pkcstok_migrate tool @<:@default=enabled@:>@]), - [], - [enable_pkcstok_migrate=yes]) - dnl --- dnl --- Check for external software dnl --- Define what to check based on enabled features @@ -598,9 +592,6 @@ AM_CONDITIONAL([ENABLE_PKCSEP11_SESSION], [test "x$enable_pkcsep11_session" = "x dnl --- enable_p11sak AM_CONDITIONAL([ENABLE_P11SAK], [test "x$enable_p11sak" = "xyes"]) -dnl --- enable_pkcstok_migrate -AM_CONDITIONAL([ENABLE_PKCSTOK_MIGRATE], [test "x$enable_pkcstok_migrate" = "xyes"]) - dnl --- enable_locks if test "x$enable_locks" != "xno"; then enable_locks=yes @@ -634,7 +625,6 @@ AC_CONFIG_FILES([Makefile \ man/man1/p11sak.1 \ man/man1/pkcsep11_migrate.1 \ man/man1/pkcsep11_session.1 \ - man/man1/pkcstok_migrate.1 \ man/man5/opencryptoki.conf.5 \ man/man7/opencryptoki.7 \ man/man8/pkcsslotd.8]) @@ -649,7 +639,6 @@ echo " Library build: $enable_library" echo " Systemd service: $enable_systemd" echo " Build with locks: $enable_locks" echo " Build p11sak tool: $enable_p11sak" -echo " token migrate tool: $enable_pkcstok_migrate" echo echo "Enabled token types:" echo " ICA token: $enable_icatok" diff --git a/man/man1/man1.mk b/man/man1/man1.mk index 6102340..51d23d3 100644 --- a/man/man1/man1.mk +++ b/man/man1/man1.mk @@ -1,9 +1,5 @@ man1_MANS += man/man1/pkcsconf.1 man/man1/pkcsicsf.1 -if ENABLE_PKCSTOK_MIGRATE -man1_MANS += man/man1/pkcstok_migrate.1 -endif - if ENABLE_PKCSEP11_MIGRATE man1_MANS += man/man1/pkcsep11_migrate.1 endif diff --git a/man/man1/pkcstok_migrate.1.in b/man/man1/pkcstok_migrate.1.in deleted file mode 100644 index b17d10b..0000000 --- a/man/man1/pkcstok_migrate.1.in +++ /dev/null @@ -1,69 +0,0 @@ -.\" pkcstok_migrate.1 -.\" -.\" Copyright IBM Corp. 2020 -.\" See LICENSE for details. -.\" -.TH PKCSTOK_MIGRATE 1 "June 2020" "@PACKAGE_VERSION@" "openCryptoki" -.SH NAME -pkcstok_migrate \- utility to migrate an ICA, CCA, Soft, or EP11 token repository -to the FIPS compliant format introduced with openCryptoki 3.12. - -.SH SYNOPSIS -\fBpkcstok_migrate\fP [\fB-h\fP] -.br -\fBpkcstok_migrate\fP \fB--slotid\fP \fIslot-number\fP \fB--datastore\fP \fIdatastore\fP -\fB--confdir\fP \fIconfdir\fP [\fB--sopin\fP \fIsopin\fP] [\fB--userpin\fP -\fIuserpin\fP] [\fB--verbose\fP \fIlevel\fP] - -.SH DESCRIPTION -Convert all objects inside a token repository to the new format introduced with -version 3.12. All encrypted data inside the new format is stored using FIPS -compliant methods. The new format affects the token's master key files (MK_SO -and MK_USER), the NVTOK.DAT, and the token object files in the TOK_OBJ folder. - -While using this tool no process using the token to be migrated must be running. -Especially the pkcsslotd must be stopped before running this tool. - -The tool creates a backup of the token repository to be migrated, and performs -all migration actions on this backup, leaving the original repository folder -completely untouched. The backup folder is located in the same directory as the -original repository and is suffixed with _PKCSTOK_MIGRATE_TMP. - -After a successful migration, the original repository is renamed with a suffix -of _BAK and the backup folder is renamed to the original repository name, so -that the migrated repository can immediately be used. The old folder may be -deleted by the user manually later. - -After a successful migration, the tool adds parameter 'tokversion = 3.12' to the -token's slot configuration in the opencryptoki.conf file. The original config -file is still available as opencryptoki.conf_BAK and may be removed by the user -manually. - -After an unsuccessful migration, the original repository is still available -unchanged. - -.SH "OPTIONS SUMMARY" -.IP "\fB--slotid -s\fP \fISLOT-NUMBER\fP" 10 -specifies the token slot number of the token repository to be migrated -.IP "\fB--datastore -d\fP \fIDATASTORE\fP" 10 -specifies the directory of the token repository to be migrated. -.IP "\fB--confdir -c\fP \fICONFDIR\fP" 10 -specifies the directory where the opencryptoki.conf file is located. -.IP "\fB--sopin -p\fP \fISOPIN\fP" 10 -specifies the SO pin. If not specified, the SO pin is prompted. -.IP "\fB--userpin -u\fP \fIUSERPIN\fP" 10 -specifies the user pin. If not specified, the user pin is prompted. -.IP "\fB--verbose -v\fP \fILEVEL\fP" 10 -specifies the verbose level: \fInone\fP, error, warn, info, devel, debug -.IP "\fB--help -h\fP" 10 -show usage information - -.SH SEE ALSO -.PD 0 -.TP -\fBpkcsconf\fP(1), -.TP -\fBopencryptoki\fP(7), -.TP -\fBpkcsslotd\fP(8). -.PD diff --git a/rpm/opencryptoki.spec b/rpm/opencryptoki.spec index 64142e2..fa4b989 100644 --- a/rpm/opencryptoki.spec +++ b/rpm/opencryptoki.spec @@ -238,11 +238,7 @@ exit 0 %{_unitdir}/pkcsslotd.service %{_sbindir}/pkcsconf %{_sbindir}/pkcsslotd -%{_sbindir}/p11sak -%{_sbindir}/pkcstok_migrate %{_mandir}/man1/pkcsconf.1* -%{_mandir}/man1/p11sak.1* -%{_mandir}/man1/pkcstok_migrate.1* %{_mandir}/man5/%{name}.conf.5* %{_mandir}/man7/%{name}.7* %{_mandir}/man8/pkcsslotd.8* diff --git a/usr/lib/api/shrd_mem.c.in b/usr/lib/api/shrd_mem.c.in index 0cd805b..2f51eda 100644 --- a/usr/lib/api/shrd_mem.c.in +++ b/usr/lib/api/shrd_mem.c.in @@ -55,11 +55,9 @@ void *attach_shared_memory() int shmid; char *shmp; struct stat statbuf; -#if 0 struct group *grp; struct passwd *pw, *epw; uid_t uid, euid; -#endif #if !(MMAP) // Really should fstat the tok_path, since it will be the actual @@ -71,7 +69,6 @@ void *attach_shared_memory() return NULL; } -#if 0 uid = getuid(); euid = geteuid(); // only check group membership if not root user @@ -105,7 +102,6 @@ void *attach_shared_memory() return NULL; } } -#endif Anchor->shm_tok = ftok(TOK_PATH, 'b'); diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c index b76dea9..c30dd1a 100644 --- a/usr/lib/common/loadsave.c +++ b/usr/lib/common/loadsave.c @@ -1701,7 +1701,7 @@ static CK_RV aes_256_gcm_seal(unsigned char *out, || EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) != 1 || EVP_CipherUpdate(ctx, NULL, &outlen, aad, aadlen) != 1 || EVP_CipherUpdate(ctx, out, &outlen, in, inlen) != 1 - || EVP_CipherFinal_ex(ctx, out + outlen, &outlen) != 1 + || EVP_CipherFinal_ex(ctx, out, &outlen) != 1 || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) != 1) { TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); rc = ERR_GENERAL_ERROR; @@ -1741,7 +1741,7 @@ static CK_RV aes_256_gcm_unseal(unsigned char *out, || EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 0) != 1 || EVP_CipherUpdate(ctx, NULL, &outlen, aad, aadlen) != 1 || EVP_CipherUpdate(ctx, out, &outlen, in, inlen) != 1 - || EVP_CipherFinal_ex(ctx, out + outlen, &outlen) != 1) { + || EVP_CipherFinal_ex(ctx, out, &outlen) != 1) { TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); rc = ERR_GENERAL_ERROR; goto done; @@ -1759,7 +1759,6 @@ static CK_RV aes_256_wrap(unsigned char out[40], { CK_RV rc; int outlen; - unsigned char buffer[40 + EVP_MAX_BLOCK_LENGTH]; EVP_CIPHER_CTX *ctx = NULL; @@ -1773,14 +1772,13 @@ static CK_RV aes_256_wrap(unsigned char out[40], EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); if (EVP_CipherInit_ex(ctx, EVP_aes_256_wrap(), NULL, kek, NULL, 1) != 1 - || EVP_CipherUpdate(ctx, buffer, &outlen, in, 32) != 1 - || EVP_CipherFinal_ex(ctx, buffer + outlen, &outlen) != 1) { + || EVP_CipherUpdate(ctx, out, &outlen, in, 32) != 1 + || EVP_CipherFinal_ex(ctx, out, &outlen) != 1) { TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); rc = ERR_GENERAL_ERROR; goto done; } - memcpy(out, buffer, 40); rc = CKR_OK; done: EVP_CIPHER_CTX_free(ctx); @@ -1793,7 +1791,6 @@ static CK_RV aes_256_unwrap(unsigned char key[32], { CK_RV rc; int outlen; - unsigned char buffer[32 + EVP_MAX_BLOCK_LENGTH]; EVP_CIPHER_CTX *ctx = NULL; @@ -1807,14 +1804,13 @@ static CK_RV aes_256_unwrap(unsigned char key[32], EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); if (EVP_CipherInit_ex(ctx, EVP_aes_256_wrap(), NULL, kek, NULL, 0) != 1 - || EVP_CipherUpdate(ctx, buffer, &outlen, in, 40) != 1 - || EVP_CipherFinal_ex(ctx, buffer + outlen, &outlen) != 1) { + || EVP_CipherUpdate(ctx, key, &outlen, in, 40) != 1 + || EVP_CipherFinal_ex(ctx, key, &outlen) != 1) { TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); rc = ERR_GENERAL_ERROR; goto done; } - memcpy(key, buffer, 32); rc = CKR_OK; done: EVP_CIPHER_CTX_free(ctx); @@ -2557,7 +2553,6 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj) CK_ULONG size_64; CK_RV rc; uint32_t len; - uint32_t ver; if (tokdata->version < TOK_NEW_DATA_STORE) return reload_token_object_old(tokdata, obj); @@ -2581,18 +2576,9 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj) goto done; } - memcpy(&ver, header, 4); memcpy(&priv, header + 4, 1); memcpy(&len, header + 60, 4); - - /* - * In OCK 3.12 - 3.14 the version and size was not stored in BE. So if - * version field is in platform endianness, keep size as is also. - */ - if (ver == TOK_NEW_DATA_STORE) - size = len; - else - size = be32toh(len); + size = be32toh(len); buf = (CK_BYTE *) malloc(size); if (buf == NULL) { @@ -2657,9 +2643,8 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj) CK_ULONG clear_len; CK_BBOOL flag = FALSE; CK_RV rc; - CK_ULONG_32 len, be_len; + CK_ULONG_32 len; unsigned char reserved[7] = {0}; - uint32_t tmp; if (tokdata->version < TOK_NEW_DATA_STORE) return save_public_token_object_old(tokdata, obj); @@ -2680,14 +2665,11 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj) goto done; } - tmp = htobe32(tokdata->version); - be_len = htobe32(len); - set_perm(fileno(fp)); - if (fwrite(&tmp, 4, 1, fp) != 1 + if (fwrite(&tokdata->version, 4, 1, fp) != 1 || fwrite(&flag, 1, 1, fp) != 1 || fwrite(reserved, 7, 1, fp) != 1 - || fwrite(&be_len, 4, 1, fp) != 1 + || fwrite(&len, 4, 1, fp) != 1 || fwrite(clear, len, 1, fp) != 1) { rc = CKR_FUNCTION_FAILED; goto done; @@ -2718,7 +2700,6 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata) CK_BBOOL priv; CK_ULONG_32 size; unsigned char header[PUB_HEADER_LEN]; - uint32_t ver; if (tokdata->version < TOK_NEW_DATA_STORE) return load_public_token_objects_old(tokdata); @@ -2746,16 +2727,9 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata) continue; } - memcpy(&ver, header, 4); memcpy(&priv, header + 4, 1); memcpy(&size, header + 12, 4); - - /* - * In OCK 3.12 - 3.14 the version and size was not stored in BE. So if - * version field is in platform endianness, keep size as is also - */ - if (ver != TOK_NEW_DATA_STORE) - size = be32toh(size); + size = be32toh(size); if (priv == TRUE) { fclose(fp2); diff --git a/usr/lib/common/obj_mgr.c b/usr/lib/common/obj_mgr.c index 1bdbe64..3e4ba3b 100644 --- a/usr/lib/common/obj_mgr.c +++ b/usr/lib/common/obj_mgr.c @@ -1751,12 +1751,6 @@ CK_RV object_mgr_set_attribute_values(STDLL_TokData_t *tokdata, save_token_object(tokdata, obj); if (priv_obj) { - if (tokdata->global_shm->num_priv_tok_obj == 0) { - TRACE_DEVEL("%s\n", ock_err(ERR_OBJECT_HANDLE_INVALID)); - rc = CKR_OBJECT_HANDLE_INVALID; - XProcUnLock(tokdata); - goto done; - } rc = object_mgr_search_shm_for_obj(tokdata->global_shm-> priv_tok_objs, 0, tokdata->global_shm-> @@ -1771,12 +1765,6 @@ CK_RV object_mgr_set_attribute_values(STDLL_TokData_t *tokdata, entry = &tokdata->global_shm->priv_tok_objs[index]; } else { - if (tokdata->global_shm->num_publ_tok_obj == 0) { - TRACE_DEVEL("%s\n", ock_err(ERR_OBJECT_HANDLE_INVALID)); - rc = CKR_OBJECT_HANDLE_INVALID; - XProcUnLock(tokdata); - goto done; - } rc = object_mgr_search_shm_for_obj(tokdata->global_shm-> publ_tok_objs, 0, tokdata->global_shm-> @@ -1858,10 +1846,6 @@ CK_RV object_mgr_del_from_shm(OBJECT *obj, LW_SHM_TYPE *global_shm) priv = object_is_private(obj); if (priv) { - if (global_shm->num_priv_tok_obj == 0) { - TRACE_DEVEL("%s\n", ock_err(ERR_OBJECT_HANDLE_INVALID)); - return CKR_OBJECT_HANDLE_INVALID; - } rc = object_mgr_search_shm_for_obj(global_shm->priv_tok_objs, 0, global_shm->num_priv_tok_obj - 1, obj, &index); @@ -1902,10 +1886,6 @@ CK_RV object_mgr_del_from_shm(OBJECT *obj, LW_SHM_TYPE *global_shm) sizeof(TOK_OBJ_ENTRY)); } } else { - if (global_shm->num_publ_tok_obj == 0) { - TRACE_DEVEL("%s\n", ock_err(ERR_OBJECT_HANDLE_INVALID)); - return CKR_OBJECT_HANDLE_INVALID; - } rc = object_mgr_search_shm_for_obj(global_shm->publ_tok_objs, 0, global_shm->num_publ_tok_obj - 1, obj, &index); diff --git a/usr/lib/common/pkcs_utils.c b/usr/lib/common/pkcs_utils.c deleted file mode 100644 index d3074d5..0000000 --- a/usr/lib/common/pkcs_utils.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * COPYRIGHT (c) International Business Machines Corp. 2020 - * - * This program is provided under the terms of the Common Public License, - * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this - * software constitutes recipient's acceptance of CPL-1.0 terms which can be - * found in the file LICENSE file or at - * https://opensource.org/licenses/cpl1.0.php - */ - -/* - * Some routines that are shared between the pkcs utilities in usr/sbin. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "defs.h" -#include "host_defs.h" - -#define OCK_TOOL -#include "pkcs_utils.h" - -extern pkcs_trace_level_t trace_level; - -void pkcs_trace(pkcs_trace_level_t level, const char *file, int line, - const char *fmt, ...) -{ - va_list ap; - const char *fmt_pre; - char buf[1024]; - char *pbuf; - int buflen, len; - - if (level > trace_level) - return; - - pbuf = buf; - buflen = sizeof(buf); - - /* add file line */ - switch (level) { - case TRACE_LEVEL_NONE: - fmt_pre = ""; - break; - case TRACE_LEVEL_ERROR: - fmt_pre = "[%s:%d] ERROR: "; - break; - case TRACE_LEVEL_WARNING: - fmt_pre = "[%s:%d] WARN: "; - break; - case TRACE_LEVEL_INFO: - fmt_pre = "[%s:%d] INFO: "; - break; - case TRACE_LEVEL_DEVEL: - fmt_pre = "[%s:%d] DEVEL: "; - break; - case TRACE_LEVEL_DEBUG: - fmt_pre = "[%s:%d] DEBUG: "; - break; - default: - return; - } - snprintf(pbuf, buflen, fmt_pre, file, line); - - len = strlen(buf); - pbuf = buf + len; - buflen = sizeof(buf) - len; - - va_start(ap, fmt); - vsnprintf(pbuf, buflen, fmt, ap); - va_end(ap); - - printf("%s", buf); -} - -int compute_hash(int hash_type, int buf_size, char *buf, char *digest) -{ - EVP_MD_CTX *md_ctx = NULL; - unsigned int result_size; - int rc; - - md_ctx = EVP_MD_CTX_create(); - - switch (hash_type) { - case HASH_SHA1: - rc = EVP_DigestInit(md_ctx, EVP_sha1()); - break; - case HASH_MD5: - rc = EVP_DigestInit(md_ctx, EVP_md5()); - break; - default: - rc = -1; - goto done; - } - - if (rc != 1) { - TRACE_ERROR("EVP_DigestInit() failed: rc = %d\n", rc); - rc = -1; - goto done; - } - - rc = EVP_DigestUpdate(md_ctx, buf, buf_size); - if (rc != 1) { - TRACE_ERROR("EVP_DigestUpdate() failed: rc = %d\n", rc); - rc = -1; - goto done; - } - - result_size = EVP_MD_CTX_size(md_ctx); - rc = EVP_DigestFinal(md_ctx, (unsigned char *) digest, &result_size); - if (rc != 1) { - TRACE_ERROR("EVP_DigestFinal() failed: rc = %d\n", rc); - rc = -1; - goto done; - } - - rc = 0; - -done: - - EVP_MD_CTX_destroy(md_ctx); - - return rc; -} - -CK_RV local_rng(CK_BYTE *output, CK_ULONG bytes) -{ - int ranfd; - int rlen; - unsigned int totallen = 0; - - ranfd = open("/dev/prandom", 0); - if (ranfd < 0) - ranfd = open("/dev/urandom", 0); - if (ranfd >= 0) { - do { - rlen = read(ranfd, output + totallen, bytes - totallen); - totallen += rlen; - } while (totallen < bytes); - close(ranfd); - return CKR_OK; - } - - return CKR_FUNCTION_FAILED; -} - -CK_RV aes_256_wrap(unsigned char out[40], const unsigned char in[32], - const unsigned char kek[32]) -{ - CK_RV rc; - int outlen; - unsigned char buffer[40 + EVP_MAX_BLOCK_LENGTH]; - - EVP_CIPHER_CTX *ctx = NULL; - - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { - TRACE_ERROR("EVP_CIPHER_CTX_new failed.\n"); - rc = CKR_HOST_MEMORY; - goto done; - } - - EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); - - if (EVP_CipherInit_ex(ctx, EVP_aes_256_wrap(), NULL, kek, NULL, 1) != 1 - || EVP_CipherUpdate(ctx, buffer, &outlen, in, 32) != 1 - || EVP_CipherFinal_ex(ctx, buffer + outlen, &outlen) != 1) { - TRACE_ERROR("EVP_Cipher funcs failed\n"); - rc = CKR_FUNCTION_FAILED; - goto done; - } - - memcpy(out, buffer, 40); - rc = CKR_OK; -done: - EVP_CIPHER_CTX_free(ctx); - return rc; -} - -CK_RV aes_256_unwrap(unsigned char key[32], const unsigned char in[40], - const unsigned char kek[32]) -{ - CK_RV rc; - int outlen; - unsigned char buffer[32 + EVP_MAX_BLOCK_LENGTH]; - - EVP_CIPHER_CTX *ctx = NULL; - - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { - TRACE_ERROR("EVP_CIPHER_CTX_new failed\n"); - rc = CKR_HOST_MEMORY; - goto done; - } - - EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); - - if (EVP_CipherInit_ex(ctx, EVP_aes_256_wrap(), NULL, kek, NULL, 0) != 1 - || EVP_CipherUpdate(ctx, buffer, &outlen, in, 40) != 1 - || EVP_CipherFinal_ex(ctx, buffer + outlen, &outlen) != 1) { - rc = CKR_FUNCTION_FAILED; - goto done; - } - - memcpy(key, buffer, 32); - rc = CKR_OK; -done: - EVP_CIPHER_CTX_free(ctx); - return rc; -} - -CK_RV aes_256_gcm_seal(unsigned char *out, unsigned char tag[16], - const unsigned char *aad, size_t aadlen, - const unsigned char *in, size_t inlen, - const unsigned char key[32], - const unsigned char iv[12]) -{ - CK_RV rc; - int outlen; - - EVP_CIPHER_CTX *ctx = NULL; - - ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { - TRACE_ERROR("EVP_CIPHER_CTX_new failed\n"); - rc = CKR_HOST_MEMORY; - goto done; - } - - if (EVP_CipherInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, -1) != 1 - || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL) != 1 - || EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) != 1 - || EVP_CipherUpdate(ctx, NULL, &outlen, aad, aadlen) != 1 - || EVP_CipherUpdate(ctx, out, &outlen, in, inlen) != 1 - || EVP_CipherFinal_ex(ctx, out + outlen, &outlen) != 1 - || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) != 1) { - TRACE_ERROR("EVP_Cipher funcs failed\n"); - rc = CKR_FUNCTION_FAILED; - goto done; - } - - rc = CKR_OK; -done: - EVP_CIPHER_CTX_free(ctx); - return rc; -} - -int get_pin(char **pin, size_t *pinlen) -{ - struct termios old, new; - int nread; - char *buff = NULL; - size_t buflen; - int rc = 0; - - /* turn echoing off */ - if (tcgetattr(fileno(stdin), &old) != 0) - return -1; - - new = old; - new.c_lflag &= ~ECHO; - if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0) - return -1; - - /* read the pin - * Note: getline will allocate memory for buff. free it when done. - */ - nread = getline(&buff, &buflen, stdin); - if (nread == -1) { - rc = -1; - goto done; - } - - /* Restore terminal */ - (void) tcsetattr(fileno(stdin), TCSAFLUSH, &old); - - /* start a newline */ - printf("\n"); - fflush(stdout); - - /* Allocate PIN. - * Note: nread includes carriage return. - * Replace with terminating NULL. - */ - *pin = (char *) malloc(nread); - if (*pin == NULL) { - rc = -ENOMEM; - goto done; - } - - /* strip the carriage return since not part of pin. */ - buff[nread - 1] = '\0'; - memcpy(*pin, buff, nread); - /* don't include the terminating null in the pinlen */ - *pinlen = nread - 1; - -done: - if (buff) - free(buff); - - return rc; -} - -/** - * Verify that SO PIN and user PIN are correct by comparing their SHA-1 - * values with the stored hashes in NVTOK.DAT. - */ -int verify_pins(char *data_store, char *sopin, unsigned long sopinlen, - char *userpin, unsigned long userpinlen) -{ - TOKEN_DATA td; - char fname[PATH_MAX]; - char pin_sha[SHA1_HASH_SIZE]; - FILE *fp = NULL; - int ret; - int tdnew; - struct stat stbuf; - size_t tdlen; - int fd; - - /* read the NVTOK.DAT */ - snprintf(fname, PATH_MAX, "%s/NVTOK.DAT", data_store); - fp = fopen((char *) fname, "r"); - if (!fp) { - TRACE_ERROR("Cannot not open %s: %s\n", fname, strerror(errno)); - return -1; - } - - fd = fileno(fp); - if ((fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode))) { - ret = -1; - goto done; - } - - if (stbuf.st_size == sizeof(TOKEN_DATA_OLD)) { - /* old data store/pin format */ - tdnew = 0; - tdlen = sizeof(TOKEN_DATA_OLD); - } else if (stbuf.st_size == sizeof(TOKEN_DATA)) { - /* new data store/pin format */ - tdnew = 1; - tdlen = sizeof(TOKEN_DATA); - } else { - TRACE_ERROR("%s has an invalid size of %ld bytes. Neither old nor new token format.\n", - fname, stbuf.st_size); - ret = -1; - goto done; - } - - ret = fread(&td, tdlen, 1, fp); - if (ret != 1) { - TRACE_ERROR("Could not read %s: %s\n", fname, strerror(errno)); - ret = -1; - goto done; - } - - if (tdnew == 0) { - /* Now compute the SHAs for the SO and USER pins entered. - * Compare with the SHAs for SO and USER PINs saved in - * NVTOK.DAT to verify. - */ - - if (sopin != NULL) { - ret = compute_sha1(sopin, sopinlen, pin_sha); - if (ret) { - TRACE_ERROR("Failed to compute sha for SO.\n"); - goto done; - } - - if (memcmp(td.so_pin_sha, pin_sha, SHA1_HASH_SIZE) != 0) { - TRACE_ERROR("SO PIN is incorrect.\n"); - ret = -1; - goto done; - } - } - - if (userpin != NULL) { - ret = compute_sha1(userpin, userpinlen, pin_sha); - if (ret) { - TRACE_ERROR("Failed to compute sha for USER.\n"); - goto done; - } - - if (memcmp(td.user_pin_sha, pin_sha, SHA1_HASH_SIZE) != 0) { - TRACE_ERROR("USER PIN is incorrect.\n"); - ret = -1; - goto done; - } - } - } else if (tdnew == 1) { - if (sopin != NULL) { - unsigned char so_login_key[32]; - - ret = PKCS5_PBKDF2_HMAC(sopin, sopinlen, - td.dat.so_login_salt, 64, - td.dat.so_login_it, EVP_sha512(), - 256 / 8, so_login_key); - if (ret != 1) { - TRACE_ERROR("PBKDF2 failed.\n"); - goto done; - } - - if (CRYPTO_memcmp(td.dat.so_login_key, so_login_key, 32) != 0) { - TRACE_ERROR("USER PIN is incorrect.\n"); - ret = -1; - goto done; - } - } - if (userpin != NULL) { - unsigned char user_login_key[32]; - - ret = PKCS5_PBKDF2_HMAC(userpin, userpinlen, - td.dat.user_login_salt, 64, - td.dat.user_login_it, EVP_sha512(), - 256 / 8, user_login_key); - if (ret != 1) { - TRACE_ERROR("PBKDF2 failed.\n"); - goto done; - } - - if (CRYPTO_memcmp(td.dat.user_login_key, user_login_key, 32) != 0) { - TRACE_ERROR("USER PIN is incorrect.\n"); - ret = -1; - goto done; - } - } - } else { - TRACE_ERROR("Unknown token format.\n"); - ret = -1; - goto done; - } - ret = 0; - -done: - /* clear out the hash */ - memset(pin_sha, 0, SHA1_HASH_SIZE); - if (fp) - fclose(fp); - - return ret; -} - -void set_perm(int file) -{ - struct group *grp; - - // Set absolute permissions or rw-rw---- - fchmod(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - - grp = getgrnam("pkcs11"); // Obtain the group id - if (grp) { - // set ownership to root, and pkcs11 group - if (fchown(file, getuid(), grp->gr_gid) != 0) { - goto error; - } - } else { - goto error; - } - - return; - -error: - TRACE_DEVEL("Unable to set permissions on file.\n"); -} diff --git a/usr/lib/common/pkcs_utils.h b/usr/lib/common/pkcs_utils.h deleted file mode 100644 index 248559c..0000000 --- a/usr/lib/common/pkcs_utils.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * COPYRIGHT (c) International Business Machines Corp. 2020 - * - * This program is provided under the terms of the Common Public License, - * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this - * software constitutes recipient's acceptance of CPL-1.0 terms which can be - * found in the file LICENSE file or at - * https://opensource.org/licenses/cpl1.0.php - */ - -#ifndef PKCS_UTILS_H -#define PKCS_UTILS_H - -#include "pkcs11types.h" - -#define MASTER_KEY_SIZE 24 -#define MASTER_KEY_SIZE_CCA 64 -#define MAX_MASTER_KEY_SIZE MASTER_KEY_SIZE_CCA - -#define MK_FILE_SIZE_00 48 -#define MK_FILE_SIZE_00_CCA 88 - -#define HASH_SHA1 1 -#define HASH_MD5 2 - -#define compute_sha1(a,b,c) compute_hash((HASH_SHA1),(b),(a),(c)) -#define compute_md5(a,b,c) compute_hash(HASH_MD5,(b),(a),(c)) - -int compute_hash(int hash_type, int buf_size, char *buf, char *digest); - -CK_RV local_rng(CK_BYTE *output, CK_ULONG bytes); - -CK_RV aes_256_wrap(unsigned char out[40], const unsigned char in[32], - const unsigned char kek[32]); - -CK_RV aes_256_unwrap(unsigned char key[32], const unsigned char in[40], - const unsigned char kek[32]); - -CK_RV aes_256_gcm_seal(unsigned char *out, unsigned char tag[16], - const unsigned char *aad, size_t aadlen, - const unsigned char *in, size_t inlen, - const unsigned char key[32], - const unsigned char iv[12]); - -int get_pin(char **pin, size_t *pinlen); - -int verify_pins(char *data_store, char *sopin, unsigned long sopinlen, - char *userpin, unsigned long userpinlen); - -void set_perm(int file); - -#ifdef OCK_TOOL -/* Log levels */ -typedef enum { - TRACE_LEVEL_NONE = 0, - TRACE_LEVEL_ERROR, - TRACE_LEVEL_WARNING, - TRACE_LEVEL_INFO, - TRACE_LEVEL_DEVEL, - TRACE_LEVEL_DEBUG -} pkcs_trace_level_t; - -void pkcs_trace(pkcs_trace_level_t level, const char * file, int line, - const char *fmt, ...) - __attribute__ ((format(printf, 4, 5))); - -#define TRACE_NONE(...) \ - pkcs_trace(TRACE_LEVEL_NONE, __FILE__, __LINE__, __VA_ARGS__) -#define TRACE_ERROR(...) \ - pkcs_trace(TRACE_LEVEL_ERROR, __FILE__, __LINE__, __VA_ARGS__) -#define TRACE_WARN(...) \ - pkcs_trace(TRACE_LEVEL_WARNING, __FILE__, __LINE__, __VA_ARGS__) -#define TRACE_INFO(...) \ - pkcs_trace(TRACE_LEVEL_INFO, __FILE__, __LINE__, __VA_ARGS__) -#define TRACE_DEVEL(...) \ - pkcs_trace(TRACE_LEVEL_DEVEL, __FILE__, __LINE__, __VA_ARGS__) -#define TRACE_DEBUG(...) \ - pkcs_trace(TRACE_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__) -#endif /* OCK_TOOL */ - -#endif diff --git a/usr/lib/tpm_stdll/tpm_openssl.c b/usr/lib/tpm_stdll/tpm_openssl.c index ca281da..e1fc080 100644 --- a/usr/lib/tpm_stdll/tpm_openssl.c +++ b/usr/lib/tpm_stdll/tpm_openssl.c @@ -57,7 +57,7 @@ void openssl_print_errors() } #endif -RSA *openssl_gen_key(STDLL_TokData_t *tokdata) +RSA *openssl_gen_key() { RSA *rsa; int rc, counter = 0; @@ -66,7 +66,7 @@ RSA *openssl_gen_key(STDLL_TokData_t *tokdata) BIGNUM *bne; #endif - token_specific_rng(tokdata, (CK_BYTE *) buf, 32); + token_specific_rng(NULL, (CK_BYTE *) buf, 32); RAND_seed(buf, 32); regen_rsa_key: diff --git a/usr/lib/tpm_stdll/tpm_specific.c b/usr/lib/tpm_stdll/tpm_specific.c index 6b0be01..dc5f80f 100644 --- a/usr/lib/tpm_stdll/tpm_specific.c +++ b/usr/lib/tpm_stdll/tpm_specific.c @@ -159,6 +159,8 @@ CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output, TSS_HTPM hTPM; BYTE *random_bytes = NULL; + UNUSED(tokdata); + rc = Tspi_Context_GetTpmObject(tpm_data->tspContext, &hTPM); if (rc) { TRACE_ERROR("Tspi_Context_GetTpmObject: %x\n", rc); @@ -1387,7 +1389,7 @@ CK_RV token_create_private_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, unsigned char n[256], p[256]; /* all sw generated keys are 2048 bits */ - if ((rsa = openssl_gen_key(tokdata)) == NULL) + if ((rsa = openssl_gen_key()) == NULL) return CKR_HOST_MEMORY; if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { @@ -1465,7 +1467,7 @@ CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, unsigned char n[256], p[256]; /* all sw generated keys are 2048 bits */ - if ((rsa = openssl_gen_key(tokdata)) == NULL) + if ((rsa = openssl_gen_key()) == NULL) return CKR_HOST_MEMORY; if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { diff --git a/usr/lib/tpm_stdll/tpm_specific.h b/usr/lib/tpm_stdll/tpm_specific.h index 81af274..541b679 100644 --- a/usr/lib/tpm_stdll/tpm_specific.h +++ b/usr/lib/tpm_stdll/tpm_specific.h @@ -56,7 +56,7 @@ /* retry count for generating software RSA keys */ #define KEYGEN_RETRY 5 -RSA *openssl_gen_key(STDLL_TokData_t *); +RSA *openssl_gen_key(); int openssl_write_key(STDLL_TokData_t *, RSA *, char *, CK_BYTE *); CK_RV openssl_read_key(STDLL_TokData_t *, char *, CK_BYTE *, RSA **); int openssl_get_modulus_and_prime(RSA *, unsigned int *, unsigned char *, diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c deleted file mode 100644 index 46e5e57..0000000 --- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c +++ /dev/null @@ -1,2788 +0,0 @@ -/* - * COPYRIGHT (c) International Business Machines Corp. 2020 - * - * This program is provided under the terms of the Common Public License, - * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this - * software constitutes recipient's acceptance of CPL-1.0 terms which can be - * found in the file LICENSE file or at - * https://opensource.org/licenses/cpl1.0.php - */ - -/* - * pkcstok_migrate - A tool for migrating ICA, CCA, Soft, and EP11 token - * repositories to 3.12 format. - * - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sw_crypt.h" -#include "defs.h" -#include "host_defs.h" -#include "local_types.h" -#include "h_extern.h" - -#define OCK_TOOL -#include "pkcs_utils.h" - - -#define TOKVERSION_00 0x00000000 -#define TOKVERSION_312 0x0003000C - -#define INVALID_TOKEN "unknown/unsupported" - -#define HEADER_LEN 64 -#define FOOTER_LEN 16 - -#define PKCSTOK_MIGRATE_MAX_PATH_LEN (PATH_MAX - 200) - -pkcs_trace_level_t trace_level = TRACE_LEVEL_NONE; - -/** - * Make a 3.12 format OBJECT_PUB: - * - * struct OBJECT_PUB { - * //-------------- <--+ - * u32 tokversion; | 16-byte header - * u8 private_flag; | - * u8 reserved[7]; | - * u32 object_len; | - * //-------------- <--+ - * u8 object[object_len]; | body - * //-------------- <--+ - * }; - */ -static CK_RV make_OBJECT_PUB_312(char **obj_new, unsigned int *obj_new_len, - unsigned char *clear, unsigned int clear_len) -{ - struct { - uint32_t tokversion; - uint8_t private_flag; - uint8_t reserved[7]; - uint32_t object_len; - } header; - uint32_t total_len; - char *object; - CK_RV ret; - - *obj_new = NULL; - *obj_new_len = 0; - - /* Check parms */ - if (!clear || clear_len == 0) { - TRACE_ERROR("Error in parms.\n"); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Allocate memory for new OBJECT_PUB */ - total_len = sizeof(header) + clear_len; - object = malloc(total_len); - if (object == NULL) { - TRACE_ERROR("cannot malloc %d bytes.\n", total_len); - ret = CKR_HOST_MEMORY; - goto done; - } - - /* Setup object */ - memset(&header, 0, sizeof(header)); - header.tokversion = htobe32(0x0003000C); - header.private_flag = 0x00; - header.object_len = htobe32(clear_len); - memcpy(object, &header, sizeof(header)); - memcpy(object + sizeof(header), clear, clear_len); - - *obj_new = object; - *obj_new_len = total_len; - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * This function migrates the public obj to the current format. - */ -static CK_RV migrate_public_token_object(const char *data_store, const char *name, - unsigned char *data, unsigned long len) -{ - const char *tokobj = "TOK_OBJ"; - char fname[PATH_MAX + 1 + strlen(tokobj) + 1 + strlen(name) + 1]; - char *obj_new = NULL; - unsigned int obj_new_len; - FILE *fp = NULL; - CK_RV ret = 0; - - /* Create new public object */ - ret = make_OBJECT_PUB_312(&obj_new, &obj_new_len, data, len); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create an OBJECT_PUB_312, ret=%08lX.\n", ret); - goto done; - } - - /* Setup file name for new object */ - sprintf(fname, "%s/%s/%s", data_store, tokobj, name); - fp = fopen((char *) fname, "w"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp)); - - /* Save new object */ - if (fwrite(obj_new, obj_new_len, 1, fp) != 1) { - TRACE_ERROR("fwrite(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - free(obj_new); - if (fp) - fclose(fp); - - return ret; -} - -/** - * Make a 3.12 format OBJECT_PRIV: - * - * struct OBJECT_PRIV { - * u32 total_len; - * --- auth ------- <--+ - * u32 tokversion | 64-byte header - * u8 private_flag | - * u8 reserved[3] | - * u8 key_wrapped[40] | - * u8 iv[12] | - * u32 object_len | - * --- auth+enc --- <--+ - * u8 object[object_len] | body - * ---------------- <--+ - * u8 tag[16] | 16-byte footer - * ---------------- <--+ - * } - */ -static CK_RV make_OBJECT_PRIV_312(unsigned char **obj_new, unsigned int *obj_new_len, - const char *name, unsigned char *clear, - unsigned int clear_len, const CK_BYTE *masterkey) -{ - struct { - uint32_t tokversion; - uint8_t private_flag; - uint8_t reserved[3]; - uint8_t key_wrapped[40]; - uint8_t iv[12]; - uint32_t object_len; - } header; - unsigned char *object; - CK_BYTE obj_key[32]; - uint32_t total_len; - CK_RV ret; - - *obj_new = NULL; - *obj_new_len = 0; - - /* Check parms */ - if (!name || !clear || clear_len == 0 || !masterkey) { - TRACE_ERROR("Error in parms.\n"); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* An obj name has by definition 8 chars */ - if (strlen(name) != 8) { - TRACE_ERROR("obj name %s does not have 8 chars, OBJ.IDX probably corrupted.\n", - name); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Allocate memory for new OBJECT_PRIV */ - total_len = sizeof(header) + clear_len + FOOTER_LEN; - object = malloc(total_len); - if (object == NULL) { - TRACE_ERROR("cannot malloc %d bytes.\n", total_len); - ret = CKR_HOST_MEMORY; - goto done; - } - - /* Create new object key */ - ret = local_rng(obj_key, 32); - if (ret != CKR_OK) { - TRACE_ERROR("local_rng failed with ret=%08lX.\n", ret); - goto done; - } - - /* Setup header */ - memset(&header, 0, sizeof(header)); - header.tokversion = htobe32(0x0003000C); - header.private_flag = 0x01; - ret = aes_256_wrap(header.key_wrapped, obj_key, masterkey); - if (ret != CKR_OK) { - TRACE_ERROR("aes_256_wrap failed with ret=%08lX.\n", ret); - goto done; - } - - memcpy(header.iv, name, 8); - header.iv[8] = 0; - header.iv[9] = 0; - header.iv[10] = 0; - header.iv[11] = 1; - header.object_len = htobe32(clear_len); - memcpy(object, &header, HEADER_LEN); - - /* Encrypt body */ - ret = aes_256_gcm_seal(object + HEADER_LEN, /* ciphertext */ - object + HEADER_LEN + clear_len, /* tag */ - object, HEADER_LEN, /* aad */ - clear, clear_len, /* plaintext */ - obj_key, /* key */ - header.iv /* iv */); - if (ret != CKR_OK) { - TRACE_ERROR("aes_256_gcm_seal failed with rc=%08lX.\n", ret); - goto done; - } - - *obj_new = object; - *obj_new_len = total_len; - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Decrypts the given version 0.0 private object with given old masterkey. - * - * struct OBJECT_PRIV { - * u32 total_len; - * u8 private_flag; - * //--- enc --- <- enc_old starts here - * u32 object_len; - * u8 object[object_len]; - * u8 sha1[20]; - * u8 padding[padding_len]; - * }; - */ -static CK_RV decrypt_OBJECT_PRIV_00(unsigned char **clear, unsigned int *clear_len, - unsigned char *enc_old, unsigned int enc_len, - const CK_BYTE *masterkey_old) -{ - CK_ULONG_32 obj_data_len_32; - CK_BYTE hash_sha[SHA1_HASH_SIZE]; - CK_BYTE des3_key[MAX_MASTER_KEY_SIZE]; - unsigned char *tmp_clear, *raw_clear; - CK_ULONG tmp_clear_len; - CK_RV ret; - - *clear = NULL; - *clear_len = 0; - - /* Allocate storage for clear output */ - tmp_clear = malloc(enc_len); - if (!tmp_clear) { - TRACE_ERROR("Cannot malloc %d bytes, errno=%s.\n", - enc_len, strerror(errno)); - ret = CKR_HOST_MEMORY; - goto done; - } - - /* Decrypt old object */ - memcpy(des3_key, masterkey_old, MAX_MASTER_KEY_SIZE); - ret = sw_des3_cbc_decrypt(enc_old, enc_len, tmp_clear, &tmp_clear_len, - (CK_BYTE *)"10293847", des3_key); - if (ret) { - TRACE_ERROR("sw_des3_cbc_decrypt failed with ret=%08lX\n", ret); - goto done; - } - - /* Validate the length */ - memcpy(&obj_data_len_32, tmp_clear, sizeof(CK_ULONG_32)); - if (obj_data_len_32 >= enc_len) { - TRACE_ERROR("Decrypted object data length %d inconsistent\n", - obj_data_len_32); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Validate the hash */ - ret = compute_sha1((char *)(tmp_clear + sizeof(CK_ULONG_32)), - obj_data_len_32, (char *)hash_sha); - if (ret != CKR_OK) { - TRACE_ERROR("compute_sha1 failed with ret=%08lX\n", ret); - goto done; - } - - if (memcmp(tmp_clear + sizeof(CK_ULONG_32) + obj_data_len_32, hash_sha, - SHA1_HASH_SIZE) != 0) { - TRACE_ERROR("Stored hash does not match with newly calculated hash.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* At this point, tmp_clear points to the full decrypted obj data: - * | 4 bytes len | clear obj[obj_data_len_32] | 20 bytes sha | padding | - * But the caller only wants clear obj[obj_data_len_32]. - */ - raw_clear = malloc(obj_data_len_32); - if (!raw_clear) { - TRACE_ERROR("Cannot malloc %d bytes, errno=%s.\n", enc_len, strerror(errno)); - ret = CKR_HOST_MEMORY; - goto done; - } - memcpy(raw_clear, tmp_clear + sizeof(CK_ULONG_32), obj_data_len_32); - - *clear = raw_clear; - *clear_len = (unsigned int)obj_data_len_32; - - ret = CKR_OK; - -done: - - free(tmp_clear); - return ret; -} - -/** - * This function migrates the private obj to the current format. - */ -static CK_RV migrate_private_token_object(const char *data_store, const char *name, - unsigned char *data, unsigned long len, - const CK_BYTE *masterkey_old, - const CK_BYTE *masterkey_new) -{ - const char *tokobj = "TOK_OBJ"; - char fname[PATH_MAX + 1 + strlen(tokobj) + 1 + strlen(name) + 1]; - unsigned char *clear = NULL; - unsigned int clear_len; - unsigned char *obj_new = NULL; - unsigned int obj_new_len; - FILE *fp = NULL; - CK_RV ret; - - /* Decrypt old object */ - ret = decrypt_OBJECT_PRIV_00(&clear, &clear_len, data, len, masterkey_old); - if (ret != 0) { - TRACE_ERROR("Cannot decrypt old object with old masterkey, ret=%08lX.\n", ret); - goto done; - } - - /* Create new object */ - ret = make_OBJECT_PRIV_312(&obj_new, &obj_new_len, name, clear, clear_len, - masterkey_new); - if (ret != 0) { - TRACE_ERROR("make_OBJECT_PRIV_312 failed with ret=%08lX.\n", ret); - goto done; - } - - /* Create file name for new object */ - sprintf(fname, "%s/%s/%s", data_store, tokobj, name); - fp = fopen((char *)fname, "w"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp)); - - /* Save new object */ - if (fwrite(obj_new, obj_new_len, 1, fp) != 1) { - TRACE_ERROR("fwrite(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) { - fclose(fp); - fp = NULL; - } - free(clear); - free(obj_new); - - return ret; -} - -/** - * Reads a format 0.0 object: - * - * struct OBJECT { - * u32 total_len; <- indicates old or new format - * u8 private_flag; - * u8 object; <- can be public or private - * }; - * - * The total_len field has been already read to decide whether this - * object is old or new. Its value is passed via the size parm. - */ -static CK_RV read_object_00(FILE *fp, const char *name, unsigned int size, - unsigned char **obj, unsigned int *obj_len, - CK_BBOOL *obj_priv) -{ - CK_BBOOL priv; - size_t read_size; - unsigned char *buf = NULL; - CK_RV ret; - - *obj = NULL; - *obj_len = 0; - - /* Check parms */ - if (!fp || !name) { - TRACE_ERROR("Arguments bad.\n"); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Read 1-char private flag */ - read_size = fread(&priv, sizeof(CK_BBOOL), 1, fp); - if (read_size != 1) { - TRACE_ERROR("Cannot read private flag from old object %s.\n", name); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Allocate buffer for obj */ - size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); - buf = malloc(size); - if (!buf) { - TRACE_ERROR("Cannot malloc %d bytes for object %s.\n", size, name); - ret = CKR_HOST_MEMORY; - goto done; - } - - /* Read obj into buf */ - read_size = fread((char *)buf, 1, size, fp); - if (read_size != size) { - TRACE_ERROR("Cannot read old object %s.\n", name); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - *obj = buf; - *obj_len = size; - *obj_priv = priv; - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Reads the token object given by name from given data_store and returns - * pointers to the object, its length, and indications whether the object - * is in 0.0 or 3.12 format and whether it's private. - */ -static CK_RV read_object(const char *data_store, const char *name, - unsigned char **obj, unsigned int *obj_len, - CK_ULONG *version, CK_BBOOL *obj_priv) -{ - char fname[PATH_MAX]; - unsigned int size = 0; - size_t read_size; - FILE *fp; - CK_RV ret; - - *obj = NULL; - *obj_len = 0; - - /* Open token object file */ - snprintf((char *) fname, sizeof(fname), "%s/TOK_OBJ/", data_store); - strcat((char *) fname, (char *) name); - fp = fopen((char *) fname, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Read 32-bit size field */ - read_size = fread(&size, sizeof(CK_ULONG_32), 1, fp); - if (read_size != 1) { - TRACE_ERROR("Cannot read %ld bytes from %s, read_size = %ld. " - "Object probably empty or corrupted.\n", - sizeof(CK_ULONG_32), name, read_size); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Check if this object is old or current */ - if (size == TOKVERSION_312) { - TRACE_INFO("%s is already in current format, nothing to do.\n", name); - ret = CKR_OK; - *version = TOKVERSION_312; - goto done; - } - - /* Read old object */ - *version = TOKVERSION_00; - ret = read_object_00(fp, name, size, obj, obj_len, obj_priv); - if (ret != 0) { - TRACE_ERROR("Cannot read old object %s.\n", name); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * Migrate the token objects from old to new format. Some of the token objects - * may be in old and some may be in new format if a previous migration run - * was interrupted. - */ -static CK_RV migrate_token_objects(const char *data_store, const CK_BYTE *masterkey_old, - const CK_BYTE *masterkey_new, - const CK_BYTE *so_wrap_key, - const CK_BYTE *user_wrap_key) -{ - const char *tokobj = "TOK_OBJ"; - const char *objidx = "OBJ.IDX"; - FILE *fp = NULL; - unsigned char *obj = NULL; - unsigned int obj_len; - char tmp[PATH_MAX]; - char iname[PATH_MAX + 1 + strlen(tokobj) + 1 + strlen(objidx) + 1]; - CK_BBOOL priv; - CK_ULONG version; - int count = 0, scount = 0; - CK_RV ret; - - /* Check parms */ - if (!data_store || !masterkey_old || !masterkey_new || !so_wrap_key - || !user_wrap_key) { - TRACE_ERROR("Invalid parms.\n"); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Open index file OBJ.IDX */ - sprintf(iname, "%s/%s/%s", data_store, tokobj, objidx); - fp = fopen((char *)iname, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", iname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Migrate items from OBJ.IDX */ - while (fgets(tmp, PATH_MAX, fp)) { - tmp[strlen(tmp) - 1] = 0; - ret = read_object(data_store, tmp, &obj, &obj_len, &version, &priv); - if (ret == 0 && version == TOKVERSION_00) { - if (priv) { - ret = migrate_private_token_object(data_store, tmp, - obj, obj_len, masterkey_old, masterkey_new); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot migrate private object %s, continuing ... \n", tmp); - } else - scount++; - } else { - ret = migrate_public_token_object(data_store, tmp, - obj, obj_len); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot migrate public object %s, continuing ... \n", tmp); - } else - scount++; - } - } - - if (obj) { - free(obj); - obj = NULL; - } - count++; - } - - /* OBJ.IDX must be at eof here */ - if (!feof(fp)) { - TRACE_WARN("OBJ.IDX is not at eof after object %s, should not happen.\n", - tmp); - } - - /* Close OBJ.IDX */ - fclose(fp); - - ret = CKR_OK; - - TRACE_NONE("Migrated %d object(s) out of %d object(s).\n", scount, count); - -done: - - return ret; -} - -/** - * loads the new aes256 masterkey. - * The new format defines the MK to be an AES-256 key. Its unencrypted format - * are just the 32 key bytes. Its encrypted format is a 40 byte key blob - */ -static CK_RV load_masterkey_312(const char *data_store, const char *mkfile, - const char *pin, TOKEN_DATA *tokdata, - CK_BYTE *masterkey) -{ - FILE *fp = NULL; - CK_RV ret; - int rc; - char fname[PATH_MAX]; - unsigned char inbuf[40]; - unsigned char wrap_key[32]; - - /* Open file */ - memset(fname, 0, PATH_MAX); - snprintf(fname, PATH_MAX, "%s/%s", data_store, mkfile); - fp = fopen(fname, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Read wrapped key from file */ - rc = fread(inbuf, sizeof(inbuf), 1, fp); - if (rc != 1) { - TRACE_ERROR("Cannot read %ld bytes from %s.\n", sizeof(inbuf), fname); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Derive wrapping key from pin and public info in TOKEN_DATA */ - if (strstr(mkfile,"MK_SO")) { - rc = PKCS5_PBKDF2_HMAC(pin, strlen(pin), - tokdata->dat.so_wrap_salt, 64, - tokdata->dat.so_wrap_it, EVP_sha512(), - 256 / 8, wrap_key); - } else { - rc = PKCS5_PBKDF2_HMAC(pin, strlen(pin), - tokdata->dat.user_wrap_salt, 64, - tokdata->dat.user_wrap_it, EVP_sha512(), - 256 / 8, wrap_key); - } - if (rc != 1) { - TRACE_INFO("PKCS5_PBKDF2_HMAC returned rc=%08X.\n", rc); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Decrypt buffer with pin-related wrapping key */ - rc = aes_256_unwrap(masterkey, inbuf, wrap_key); - if (rc != CKR_OK) { - TRACE_ERROR("aes_256_unwrap failed with rc=%08X.\n", rc); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * loads the old des3 masterkey from given file with given PIN. - * The format is: - * - * struct MK { - * u8 MK [24 or 64 (cca)]; - * u8 sha1 [20]; - * u8 padding[4]; - * }; - */ -static CK_RV load_masterkey_00(const char *mkfile, const char *pin, - CK_BYTE *masterkey) -{ - CK_BYTE des3_key[3 * DES_KEY_SIZE]; - char hash_sha[SHA1_HASH_SIZE]; - char pin_md5_hash[MD5_HASH_SIZE]; - unsigned char *cipher = NULL; - unsigned char *clear = NULL; - unsigned long cipher_len, clear_len; - CK_ULONG master_key_len = 0L; - int file_size = 0; - - CK_RV ret; - int rc; - FILE *fp = NULL; - - fp = fopen(mkfile, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", mkfile, strerror(errno)); - return CKR_FUNCTION_FAILED; - } - - /* Determine the master key length */ - fseek(fp, 0L, SEEK_END); - file_size = ftell(fp); - switch (file_size) { - case MK_FILE_SIZE_00_CCA: /* CCA token */ - master_key_len = MASTER_KEY_SIZE_CCA; - break; - case MK_FILE_SIZE_00: /* All other tokens */ - master_key_len = MASTER_KEY_SIZE; - break; - default: - /* Unknown MK format, should not occur. */ - TRACE_ERROR("%s has an unknown file size of %d bytes. Should be either 48 or 88 bytes.\n", - mkfile, file_size); - ret = CKR_FUNCTION_FAILED; - goto done; - } - rewind(fp); - - /* Read file contents */ - clear_len = cipher_len = - (master_key_len + SHA1_HASH_SIZE + - (DES_BLOCK_SIZE - 1)) & ~(DES_BLOCK_SIZE - 1); - - cipher = malloc(cipher_len); - clear = malloc(clear_len); - if (cipher == NULL || clear == NULL) { - ret = CKR_HOST_MEMORY; - goto done; - } - - rc = fread(cipher, cipher_len, 1, fp); - if (rc != 1) { - TRACE_ERROR("Cannot read %ld bytes from %s\n", cipher_len, mkfile); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Decrypt the masterkey */ - ret = compute_md5((char *)pin, strlen(pin), pin_md5_hash); - if (ret) { - TRACE_ERROR("Error calculating MD5 of PIN, ret=%08lX\n", ret); - goto done; - } - - memcpy(des3_key, pin_md5_hash, MD5_HASH_SIZE); - memcpy(des3_key + MD5_HASH_SIZE, pin_md5_hash, DES_KEY_SIZE); - - ret = sw_des3_cbc_decrypt(cipher, cipher_len, clear, - &clear_len, (unsigned char *) "12345678", - des3_key); - if (ret != CKR_OK) { - TRACE_ERROR("failed to decrypt master key file after read, ret=%08lX\n", ret); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* compare the hashes to verify integrity */ - ret = compute_sha1((char *)clear, master_key_len, hash_sha); - if (ret) { - TRACE_ERROR("Failed to compute sha1 for masterkey, ret=%08lX\n", ret); - goto done; - } - - if (memcmp(hash_sha, clear + master_key_len, SHA1_HASH_SIZE) != 0) { - TRACE_ERROR("%s appears to be tampered! Cannot migrate.\n", mkfile); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - memcpy(masterkey, clear, master_key_len); - ret = 0; - -done: - if (fp) - fclose(fp); - free(clear); - free(cipher); - - return ret; -} - -/** - * Remove any spaces from given string - */ -static void remove_spaces(char *s) -{ - int i, count = 0; - - for (i = 0; s[i]; i++) { - if (s[i] != ' ') - s[count++] = s[i]; - } - - s[count] = '\0'; -} - -/** - * gets the stdll name from the given opencryptoki.conf file. - */ -static CK_RV get_stdll_name(FILE *fp, char *dll_name) -{ - char line[PATH_MAX]; - - while (fgets(line, sizeof(line), fp)) { - remove_spaces(line); - if (strstr(line, "stdll=")) { - sscanf(line, "stdll=%s", dll_name); - return CKR_OK; - } - } - - return CKR_FUNCTION_FAILED; -} - -/** - * Check if the given conf_dir exists and contains the opencryptoki.conf. - */ -static CK_BBOOL conffile_exists(const char *conf_dir) -{ - char fname[PATH_MAX]; - struct stat statbuf; - DIR *dir; - - TRACE_INFO("Checking if config file exists in %s ...\n", conf_dir); - dir = opendir(conf_dir); - if (dir == NULL) { - TRACE_INFO("Cannot open %s.\n", conf_dir); - return CK_FALSE; - } - - /* Check if opencryptoki.conf exists */ - memset(fname, 0, PATH_MAX); - snprintf(fname, PATH_MAX, "%s/opencryptoki.conf", conf_dir); - if (stat(fname, &statbuf) != 0) { - TRACE_INFO("Cannot find %s.\n", fname); - closedir(dir); - return CK_FALSE; - } - closedir(dir); - - return CK_TRUE; -} - -/** - * Check if the given data_store directory exists. - */ -static CK_BBOOL datastore_exists(const char *data_store) -{ - DIR *dir; - - TRACE_INFO("Checking if datastore %s exists ...\n", data_store); - dir = opendir(data_store); - if (dir == NULL) { - TRACE_INFO("Cannot open %s.\n", data_store); - return CK_FALSE; - } - closedir(dir); - - return CK_TRUE; -} - -/** - * Check if the data store is empty, which is the case when - * there are no entries in OBJ.IDX. - */ -static CK_BBOOL datastore_empty(const char *data_store) -{ - char fname[PATH_MAX]; - struct stat statbuf; - - TRACE_INFO("Checking if data store is empty ...\n"); - - /* Check if OBJ.IDX exists */ - memset(fname, 0, PATH_MAX); - snprintf(fname, PATH_MAX, "%s/TOK_OBJ/OBJ.IDX", data_store); - if (stat(fname, &statbuf) != 0) { - TRACE_INFO("Cannot find %s, data store probably empty.\n", fname); - return CK_TRUE; - } - - /* Check if OBJ.IDX is empty */ - if (statbuf.st_size == 0) { - TRACE_INFO("OBJ.IDX file is empty. Thus no objects to migrate.\n"); - return CK_TRUE; - } - - return CK_FALSE; -} - -/** - * - */ -static CK_RV load_MK_SO_00(const char *data_store, const char *sopin, - CK_BYTE *masterkey) -{ - const char *mkso = "MK_SO"; - char fname[PATH_MAX + 1 + strlen(mkso) + 1]; - CK_RV ret; - - /* Get masterkey from MK_SO. This also verifies SO PIN is correct */ - memset(masterkey, 0, MAX_MASTER_KEY_SIZE); - sprintf(fname, "%s/%s", data_store, mkso); - ret = load_masterkey_00(fname, sopin, masterkey); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load old masterkey from MK_SO, ret=%08lX.\n", ret); - // We cannot do anything more here, even when some objs are still old. - // We would need the old key in order to open an old obj. - } - - return ret; -} - -/** - * - */ -static CK_RV load_MK_USER_00(const char *data_store, const char *userpin, - CK_BYTE *masterkey) -{ - const char *mkuser = "MK_USER"; - char fname[PATH_MAX + 1 + strlen(mkuser) + 1]; - CK_RV ret; - - /* Get masterkey from MK_USER. This also verifies user PIN is correct */ - memset(masterkey, 0, MAX_MASTER_KEY_SIZE); - sprintf(fname, "%s/%s", data_store, mkuser); - ret = load_masterkey_00(fname, userpin, masterkey); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load old masterkey from MK_USER, ret=%08lX.\n", ret); - } - - return ret; -} - -/** - * - */ -static CK_RV load_MK_SO_312(const char *data_store, const char *sopin, - TOKEN_DATA *tokdata, CK_BYTE *masterkey) -{ - CK_RV ret; - - /* Get masterkey from MK_SO_312. This also verifies SO PIN is correct */ - memset(masterkey, 0, MAX_MASTER_KEY_SIZE); - ret = load_masterkey_312(data_store, "MK_SO_312", sopin, tokdata, masterkey); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load masterkey from MK_SO_312, ret=%08lX.\n", ret); - } - - return ret; -} - -/** - * - */ -static CK_RV load_MK_USER_312(const char *data_store, const char *userpin, - TOKEN_DATA *tokdata, CK_BYTE *masterkey) -{ - CK_RV ret; - - /* Get masterkey from MK_USER_312. This also verifies user PIN is correct */ - memset(masterkey, 0, MAX_MASTER_KEY_SIZE); - ret = load_masterkey_312(data_store, "MK_USER_312", userpin, tokdata, masterkey); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load masterkey from MK_USER_312, ret=%08lX.\n", ret); - } - - return ret; -} - -/** - * Loads the NVTOK.DAT and returns the TOKEN_DATA struct. - */ -static CK_RV load_NVTOK_DAT(const char *data_store, const char *nvtok_name, - TOKEN_DATA *td) -{ - char fname[PATH_MAX]; - struct stat stbuf; - int fd; - size_t tdlen; - FILE *fp = NULL; - CK_RV ret; - - /* Check parms */ - if (!data_store || !nvtok_name || !td) { - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Read the NVTOK.DAT */ - snprintf(fname, PATH_MAX, "%s/%s", data_store, nvtok_name); - fp = fopen((char *) fname, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - return CKR_FUNCTION_FAILED; - } - - fd = fileno(fp); - if ((fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode))) { - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Check if this NVTOK.DAT is old or new */ - if (stbuf.st_size == sizeof(TOKEN_DATA_OLD)) { - /* old data store/pin format */ - tdlen = sizeof(TOKEN_DATA_OLD); - } else if (stbuf.st_size == sizeof(TOKEN_DATA)) { - /* new data store/pin format */ - tdlen = sizeof(TOKEN_DATA); - } else { - TRACE_ERROR("%s has an invalid size of %ld bytes. Neither old nor new token format.\n", - fname, stbuf.st_size); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Read TOKEN_DATA */ - ret = fread(td, tdlen, 1, fp); - if (ret != 1) { - TRACE_ERROR("Cannot read %s, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - if (stbuf.st_size == sizeof(TOKEN_DATA)) { - /* The 312 version always uses big endian */ - td->token_info.flags = be32toh(td->token_info.flags); - td->token_info.ulMaxSessionCount - = be32toh(td->token_info.ulMaxSessionCount); - td->token_info.ulSessionCount - = be32toh(td->token_info.ulSessionCount); - td->token_info.ulMaxRwSessionCount - = be32toh(td->token_info.ulMaxRwSessionCount); - td->token_info.ulRwSessionCount - = be32toh(td->token_info.ulRwSessionCount); - td->token_info.ulMaxPinLen = be32toh(td->token_info.ulMaxPinLen); - td->token_info.ulMinPinLen = be32toh(td->token_info.ulMinPinLen); - td->token_info.ulTotalPublicMemory - = be32toh(td->token_info.ulTotalPublicMemory); - td->token_info.ulFreePublicMemory - = be32toh(td->token_info.ulFreePublicMemory); - td->token_info.ulTotalPrivateMemory - = be32toh(td->token_info.ulTotalPrivateMemory); - td->token_info.ulFreePrivateMemory - = be32toh(td->token_info.ulFreePrivateMemory); - td->tweak_vector.allow_weak_des - = be32toh(td->tweak_vector.allow_weak_des); - td->tweak_vector.check_des_parity - = be32toh(td->tweak_vector.check_des_parity); - td->tweak_vector.allow_key_mods - = be32toh(td->tweak_vector.allow_key_mods); - td->tweak_vector.netscape_mods - = be32toh(td->tweak_vector.netscape_mods); - td->dat.version = be32toh(td->dat.version); - td->dat.so_login_it = be64toh(td->dat.so_login_it); - td->dat.user_login_it = be64toh(td->dat.user_login_it); - td->dat.so_wrap_it = be64toh(td->dat.so_wrap_it); - td->dat.user_wrap_it = be64toh(td->dat.user_wrap_it); - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * Strip trailing chars from given string. - */ -static char *strip_trailing_chars(char *s, int slen, char c) -{ - int i; - - if (!s || slen == 0) - return s; - - for (i = slen - 1; i >= 0; i--) { - if (s[i] == c) - s[i] = '\0'; - else - break; - } - - return s; -} - -/** - * Read the token info from NVTOK.DAT. - */ -static CK_RV get_token_info(const char *data_store, CK_TOKEN_INFO_32 *tokinfo) -{ - TOKEN_DATA tokdata; - CK_RV ret; - - TRACE_INFO("Reading token info from NVTOK.DAT ...\n"); - - ret = load_NVTOK_DAT(data_store, "NVTOK.DAT", &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load NVTOK.DAT, datastore inconsistent.\n"); - return ret; - } - - memcpy(tokinfo, &(tokdata.token_info), sizeof(CK_TOKEN_INFO_32)); - - return CKR_OK; -} - -/** - * returns true, if the given string begins with the given char, - * false otherwise. The string may contain leading spaces. - */ -static CK_BBOOL begins_with(const char *str, const char c) -{ - size_t i; - - for (i = 0; i < strlen(str); i++) { - if (str[i] == ' ') - continue; - else if (str[i] == c) - return CK_TRUE; - else - return CK_FALSE; - } - - return CK_FALSE; -} - -/** - * Identify the token that belongs to the given slot ID. - */ -static CK_RV identify_token(CK_SLOT_ID slot_id, char *conf_dir, char *dll_name) -{ - char conf_file[PATH_MAX]; - char line[80], parm[80]; - FILE *fp; - CK_RV ret; - - TRACE_INFO("Identifying the token that belongs to slot %ld ...\n", slot_id); - - /* Open conf file */ - snprintf(conf_file, PATH_MAX, "%s/%s", conf_dir, "opencryptoki.conf"); - fp = fopen(conf_file, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", conf_file, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Get stdll name */ - ret = CKR_FUNCTION_FAILED; - snprintf(parm, sizeof(parm), "slot %ld", slot_id); - while (fgets(line, sizeof(line), fp)) { - if (!begins_with(line, '#') && strstr(line, parm)) { - ret = get_stdll_name(fp, dll_name); - goto done; - } - } - -done: - - fclose(fp); - - return ret; -} - -/** - * derives the SO wrap key from the given SO pin and given public - * info in NVTOK.DAT. - */ -static CK_RV derive_so_wrap_key_312(const char *sopin, TOKEN_DATA *tokdata, - CK_BYTE *so_wrap_key) -{ - CK_RV ret; - - ret = PKCS5_PBKDF2_HMAC(sopin, strlen(sopin), - tokdata->dat.so_wrap_salt, 64, - tokdata->dat.so_wrap_it, EVP_sha512(), - 256 / 8, so_wrap_key); - if (ret != 1) { - TRACE_ERROR("PBKDF2 failed.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * derives the user wrap key from the given user pin and given public - * info in NVTOK.DAT. - */ -static CK_RV derive_user_wrap_key_312(const char *userpin, TOKEN_DATA *tokdata, - CK_BYTE *user_wrap_key) -{ - CK_RV ret; - - ret = PKCS5_PBKDF2_HMAC(userpin, strlen(userpin), - tokdata->dat.user_wrap_salt, 64, - tokdata->dat.user_wrap_it, EVP_sha512(), - 256 / 8, user_wrap_key); - if (ret != 1) { - TRACE_ERROR("PBKDF2 failed.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Activates the new repository by deleting the old MK_USER, MK_SO, and - * NVTOK.DAT, and renaming the new MK_SO_312, MK_USER_312, NVTOK.DAT_312 to - * their normal names. - */ -static CK_RV cleanup_repository_backup(const char *data_store) -{ - static char *names[] = { "MK_SO", "MK_USER", "NVTOK.DAT" }; - int num_names = sizeof(names) / sizeof(char *); - char fname1[PATH_MAX + 9 + 1]; // satisfy compiler warning - char fname2[PATH_MAX + 1 + 1]; // satisfy compiler warning - int i, rc; - CK_RV ret; - - /* Delete old files */ - for (i = 0; i < num_names; i++) { - snprintf(fname1, sizeof(fname1), "%s/%s", data_store, names[i]); - rc = remove(fname1); - if (rc) { - TRACE_ERROR("Cannot delete old file %s.\n", fname1); - ret = CKR_FUNCTION_FAILED; - goto done; - } - } - - /* Rename new files */ - for (i = 0; i < num_names; i++) { - snprintf(fname1, sizeof(fname1), "%s/%s_312", data_store, names[i]); - snprintf(fname2, sizeof(fname2), "%s/%s", data_store, names[i]); - rc = rename(fname1, fname2); - if (rc) { - TRACE_ERROR("Cannot rename new file %s.\n", fname1); - ret = CKR_FUNCTION_FAILED; - goto done; - } - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Migrates the repository. This process may be interrupted at any time and - * must be able to resume until the complete repository is successfully - * migrated. This especially requires to keep the old keys until - * everything is done. - */ -static CK_RV migrate_repository(const char *data_store, const char *sopin, - const char *userpin) -{ - CK_BYTE so_masterkey_old[MAX_MASTER_KEY_SIZE]; - CK_BYTE so_masterkey_new[MAX_MASTER_KEY_SIZE]; - CK_BYTE user_masterkey_old[MAX_MASTER_KEY_SIZE]; - CK_BYTE user_masterkey_new[MAX_MASTER_KEY_SIZE]; - CK_BYTE so_wrap_key[32]; - CK_BYTE user_wrap_key[32]; - CK_RV ret; - TOKEN_DATA tokdata; - - TRACE_INFO("Migrating the repository ...\n"); - - /* Load NVTOK.DAT_312, which was either created before or exists from a - * previous interrupted run. So tokdata definitely contains the 3.12 - * extension. - */ - ret = load_NVTOK_DAT(data_store, "NVTOK.DAT_312", &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load NVTOK.DAT_312, ret=%08lX.\n", ret); - goto done; - } - - ret = load_MK_SO_00(data_store, sopin, so_masterkey_old); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load old masterkey, ret=%08lX.\n", ret); - goto done; - } - - ret = load_MK_USER_00(data_store, userpin, user_masterkey_old); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load old masterkey, ret=%08lX.\n", ret); - goto done; - } - - if (memcmp(so_masterkey_old, user_masterkey_old, MAX_MASTER_KEY_SIZE) != 0) { - TRACE_ERROR("MK_SO and MK_USER are inconsistent, got different MKs.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = load_MK_SO_312(data_store, sopin, &tokdata, so_masterkey_new); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load new masterkey from MK_SO_312, ret=%08lX.\n", ret); - goto done; - } - - ret = load_MK_USER_312(data_store, userpin, &tokdata, user_masterkey_new); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load new masterkey from MK_USER_312, ret=%08lX.\n", ret); - goto done; - } - - if (memcmp(so_masterkey_new, user_masterkey_new, MAX_MASTER_KEY_SIZE) != 0) { - TRACE_ERROR("MK_SO_312 and MK_USER_312 are inconsistent, got different MKs.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* This function needs a new NVTOK.DAT with the public salt and icount */ - ret = derive_so_wrap_key_312(sopin, &tokdata, so_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create new so_wrap_key, ret=%08lX.\n", ret); - goto done; - } - - /* This function needs a new NVTOK.DAT with the public salt and icount */ - ret = derive_user_wrap_key_312(userpin, &tokdata, user_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create new user_wrap_key, ret=%08lX.\n", ret); - goto done; - } - - /* Now do the migration */ - ret = migrate_token_objects(data_store, so_masterkey_old, so_masterkey_new, - so_wrap_key, user_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Migrating token objects failed with ret=%08lX.\n", ret); - goto done; - } - - /* Remove temp files in backup */ - ret = cleanup_repository_backup(data_store); - if (ret != CKR_OK) { - TRACE_ERROR("Cleanup repository backup failed with ret=%08lX.\n", ret); - goto done; - } - -done: - - return ret; -} - -/** - * creates a MK_USER_312 file containing the new user MK. - */ -static CK_RV create_MK_USER_312(const char *data_store, const char *userpin, - const CK_BYTE *masterkey, - TOKEN_DATA *tokdata) -{ - const char *mkuser = "MK_USER_312"; - char fname[PATH_MAX + 1 + strlen(mkuser) + 1]; - CK_BYTE user_wrap_key[32]; - CK_BYTE outbuf[40]; - FILE *fp = NULL; - size_t rv; - CK_RV ret; - - /* Create user wrap key */ - ret = derive_user_wrap_key_312(userpin, tokdata, (unsigned char *)&user_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot derive user wrap key, ret=%08lX.\n", ret); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Wrap user MK with user_wrap_key */ - ret = aes_256_wrap(outbuf, masterkey, user_wrap_key); - if (ret != CKR_OK) - goto done; - - /* Create file MK_USER_312 */ - sprintf(fname, "%s/%s", data_store, mkuser); - fp = fopen(fname, "w"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp)); - - rv = fwrite(outbuf, sizeof(outbuf), 1, fp); - if (rv != 1) { - TRACE_ERROR("fwrite(%s) failed, errno=%s.\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * creates a MK_SO_312 file containing the new SO MK. - */ -static CK_RV create_MK_SO_312(const char *data_store, const char *sopin, - const CK_BYTE *masterkey, - TOKEN_DATA *tokdata) -{ - const char *mkso = "MK_SO_312"; - char fname[PATH_MAX + 1 + strlen(mkso) + 1]; - CK_BYTE outbuf[40]; - CK_BYTE so_wrap_key[32]; - FILE *fp = NULL; - size_t rv; - CK_RV ret; - - /* Derive so wrap key from sopin and tokdata */ - ret = derive_so_wrap_key_312(sopin, tokdata, so_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot derive new so wrap key, ret=%08lX.\n", ret); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Wrap masterkey with SO_wrap_key */ - ret = aes_256_wrap(outbuf, masterkey, so_wrap_key); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot wrap masterkey with so wrap key, ret=%08lX.\n", ret); - goto done; - } - - /* Create file MK_SO_312 */ - sprintf(fname, "%s/%s", data_store, mkso); - fp = fopen(fname, "w"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - rv = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp)); - - rv = fwrite(outbuf, sizeof(outbuf), 1, fp); - if (rv != 1) { - TRACE_ERROR("fwrite(%s) failed, errno=%s.\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * reads the old NVTOK.DAT and returns its contents: - */ -static CK_RV read_NVTOK_DAT_00(const char *data_store, TOKEN_DATA *tokdata) -{ - FILE *fp; - const char *nvtok = "NVTOK.DAT"; - char fname[PATH_MAX + 1 + strlen(nvtok) + 1]; - struct stat stbuf; - int fd; - CK_RV ret; - - /* Check parms */ - if (!data_store || !tokdata) { - return CKR_ARGUMENTS_BAD; - } - - /* Read the old NVTOK.DAT */ - sprintf(fname, "%s/%s", data_store, nvtok); - fp = fopen((char *) fname, "r"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - return CKR_FUNCTION_FAILED; - } - - fd = fileno(fp); - if ((fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode))) { - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Ensure that this NVTOK.DAT is in fact old */ - if (stbuf.st_size != sizeof(TOKEN_DATA_OLD)) { - TRACE_ERROR("%s has an invalid size of %ld bytes.\n", fname, stbuf.st_size); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Read TOKEN_DATA_OLD */ - ret = fread(tokdata, sizeof(TOKEN_DATA_OLD), 1, fp); - if (ret != 1) { - TRACE_ERROR("Cannot read %s, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * creates the additions for new format. - */ -static CK_RV create_TOKEN_DATA_VERSION(const char *sopin, const char *userpin, - TOKEN_DATA *tokdata) -{ - CK_RV ret; - int rc; - - tokdata->dat.version = TOKVERSION_312; - - tokdata->dat.so_login_it = SO_KDF_LOGIN_IT; - memcpy(tokdata->dat.so_login_salt, SO_KDF_LOGIN_PURPOSE, 32); - ret = local_rng(tokdata->dat.so_login_salt + 32, 32); - if (ret != CKR_OK) { - TRACE_ERROR("local_rng returned %lX\n", ret); - goto done; - } - rc = PKCS5_PBKDF2_HMAC(sopin, strlen(sopin), - tokdata->dat.so_login_salt, 64, - tokdata->dat.so_login_it, EVP_sha512(), - 256 / 8, tokdata->dat.so_login_key); - if (rc != 1) { - TRACE_ERROR("Error: PKCS5_PBKDF2_HMAC\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - tokdata->dat.so_wrap_it = SO_KDF_WRAP_IT; - memcpy(tokdata->dat.so_wrap_salt, SO_KDF_WRAP_PURPOSE, 32); - ret = local_rng(tokdata->dat.so_wrap_salt + 32, 32); - if (ret != CKR_OK) { - TRACE_ERROR("local_rng returned %lX\n", ret); - goto done; - } - - tokdata->dat.user_login_it = USER_KDF_LOGIN_IT; - memcpy(tokdata->dat.user_login_salt, USER_KDF_LOGIN_PURPOSE, 32); - ret = local_rng(tokdata->dat.user_login_salt + 32, 32); - if (ret != CKR_OK) { - TRACE_ERROR("local_rng returned %lX\n", ret); - goto done; - } - rc = PKCS5_PBKDF2_HMAC(userpin, strlen(userpin), - tokdata->dat.user_login_salt, 64, - tokdata->dat.user_login_it, EVP_sha512(), - 256 / 8, tokdata->dat.user_login_key); - if (rc != 1) { - TRACE_ERROR("Error: PKCS5_PBKDF2_HMAC\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - tokdata->dat.user_wrap_it = USER_KDF_WRAP_IT; - memcpy(tokdata->dat.user_wrap_salt, USER_KDF_WRAP_PURPOSE, 32); - ret = local_rng(tokdata->dat.user_wrap_salt + 32, 32); - if (ret != CKR_OK) { - TRACE_ERROR("local_rng returned %lX\n", ret); - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Creates the new NVTOK.DAT which now contains the public salt and iteration - * count values that are necessary for re-deriving the pin-related - * wrapping keys. - */ -static CK_RV create_NVTOK_DAT_312(const char *data_store, const char *sopin, - const char *userpin, TOKEN_DATA *tokdata) -{ - const char *nvtok = "NVTOK.DAT_312"; - char fname[PATH_MAX + 1 + strlen(nvtok) + 1]; - TOKEN_DATA be_tokdata; - FILE *fp = NULL; - CK_RV ret; - size_t rc; - - /* Check parms */ - if (!data_store || !sopin || !userpin || !tokdata) { - TRACE_ERROR("invalid parms.\n"); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* Create new file NVTOK.DAT_312 */ - sprintf(fname, "%s/%s", data_store, nvtok); - fp = fopen(fname, "w"); - if (!fp) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp)); - - /* Get contents from old NVTOK.DAT */ - ret = read_NVTOK_DAT_00(data_store, tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot read old NVTOK.DAT, ret=%08lX\n", ret); - goto done; - } - - /* Create additions for new format */ - ret = create_TOKEN_DATA_VERSION(sopin, userpin, tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create TOKEN_DATA_VERSION struct, ret=%08lX\n", ret); - goto done; - } - - /* The 312 version always uses big endian */ - memcpy(&be_tokdata, tokdata, sizeof(TOKEN_DATA)); - be_tokdata.token_info.flags = htobe32(tokdata->token_info.flags); - be_tokdata.token_info.ulMaxSessionCount - = htobe32(tokdata->token_info.ulMaxSessionCount); - be_tokdata.token_info.ulSessionCount - = htobe32(tokdata->token_info.ulSessionCount); - be_tokdata.token_info.ulMaxRwSessionCount - = htobe32(tokdata->token_info.ulMaxRwSessionCount); - be_tokdata.token_info.ulRwSessionCount - = htobe32(tokdata->token_info.ulRwSessionCount); - be_tokdata.token_info.ulMaxPinLen = htobe32(tokdata->token_info.ulMaxPinLen); - be_tokdata.token_info.ulMinPinLen = htobe32(tokdata->token_info.ulMinPinLen); - be_tokdata.token_info.ulTotalPublicMemory - = htobe32(tokdata->token_info.ulTotalPublicMemory); - be_tokdata.token_info.ulFreePublicMemory - = htobe32(tokdata->token_info.ulFreePublicMemory); - be_tokdata.token_info.ulTotalPrivateMemory - = htobe32(tokdata->token_info.ulTotalPrivateMemory); - be_tokdata.token_info.ulFreePrivateMemory - = htobe32(tokdata->token_info.ulFreePrivateMemory); - be_tokdata.tweak_vector.allow_weak_des - = htobe32(tokdata->tweak_vector.allow_weak_des); - be_tokdata.tweak_vector.check_des_parity - = htobe32(tokdata->tweak_vector.check_des_parity); - be_tokdata.tweak_vector.allow_key_mods - = htobe32(tokdata->tweak_vector.allow_key_mods); - be_tokdata.tweak_vector.netscape_mods - = htobe32(tokdata->tweak_vector.netscape_mods); - be_tokdata.dat.version = htobe32(tokdata->dat.version); - be_tokdata.dat.so_login_it = htobe64(tokdata->dat.so_login_it); - be_tokdata.dat.user_login_it = htobe64(tokdata->dat.user_login_it); - be_tokdata.dat.so_wrap_it = htobe64(tokdata->dat.so_wrap_it); - be_tokdata.dat.user_wrap_it = htobe64(tokdata->dat.user_wrap_it); - - /* Write converted token data into NVTOK.DAT_312 */ - rc = fwrite(&be_tokdata, sizeof(TOKEN_DATA), 1, fp); - if (rc != 1) { - TRACE_ERROR("fwrite(%s) failed, errno=%s.\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - if (fp) - fclose(fp); - - return ret; -} - -/** - * Creates new token keys MK_USER_312 and MK_SO_312. The old keys in - * MK_USER and MK_SO are kept until the migration is fully completed. - * Then the old keys are deleted and the new keys are renamed. - */ -static CK_RV create_token_keys_312(const char *data_store, const char *sopin, - const char *userpin) -{ - unsigned char masterkey[32]; - TOKEN_DATA tokdata; - CK_RV ret = CKR_OK; - - TRACE_INFO("Creating new v3.12 MK_SO, MK_USER, and NVTOK.DAT ...\n"); - - /* Create master key */ - ret = local_rng(masterkey, 32); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create master key, ret=%08lX\n", ret); - goto done; - } - - ret = create_NVTOK_DAT_312(data_store, sopin, userpin, &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create NVTOK.DAT_312, ret=%08lX\n", ret); - goto done; - } - - ret = create_MK_SO_312(data_store, sopin, masterkey, &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create MK_SO_312, ret=%08lX\n", ret); - goto done; - } - - ret = create_MK_USER_312(data_store, userpin, masterkey, &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot create MK_USER_312, ret=%08lX\n", ret); - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Count the objs in the data_store and return the number of total objs - * and number of old objs. - */ -static CK_RV count_objects(const char *data_store, unsigned int *num_objs, - unsigned int *num_old_objs) -{ - char tmp[PATH_MAX], iname[PATH_MAX]; - unsigned char *obj = NULL; - unsigned int obj_len; - CK_ULONG version; - CK_BBOOL priv; - FILE *fp; - CK_RV ret; - - *num_objs = 0; - *num_old_objs = 0; - - /* Open index file OBJ.IDX */ - snprintf(iname, sizeof(iname), "%s/TOK_OBJ/OBJ.IDX", data_store); - fp = fopen((char *) iname, "r"); - if (!fp) { - TRACE_INFO("Cannot open %s, datastore probably empty.\n", iname); - ret = CKR_OK; - goto done; - } - - /* Count objects and old objects */ - while (fgets(tmp, PATH_MAX, fp)) { - tmp[strlen(tmp) - 1] = 0; - (*num_objs)++; - ret = read_object(data_store, tmp, &obj, &obj_len, &version, &priv); - if (ret == 0 && version == TOKVERSION_00) - (*num_old_objs)++; - if (obj) { - free(obj); - obj = NULL; - } - } - - /* OBJ.IDX must be at eof here */ - if (!feof(fp)) { - TRACE_WARN("OBJ.IDX is not at eof after object %s, should not happen.\n", - tmp); - } - - fclose(fp); - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Set parameter "*new" to true if the NVTOK.DAT in the given data store - * is on 3.12 level, or false otherwise. - */ -static CK_RV NVTOK_DAT_is_312(const char *data_store, CK_BBOOL *new) -{ - CK_RV ret; - char fname[PATH_MAX]; - struct stat stbuf; - int fd; - FILE *fp = NULL; - - *new = CK_FALSE; - - /* Read the NVTOK.DAT */ - snprintf(fname, PATH_MAX, "%s/NVTOK.DAT", data_store); - fp = fopen((char *)fname, "r"); - if (!fp) { - TRACE_ERROR("Cannot open %s, errno=%s\n", fname, strerror(errno)); - return CKR_FUNCTION_FAILED; - } - - fd = fileno(fp); - if ((fstat(fd, &stbuf) != 0) || (!S_ISREG(stbuf.st_mode))) { - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Check if this NVTOK.DAT is old or new */ - if (stbuf.st_size == sizeof(TOKEN_DATA_OLD)) { - *new = CK_FALSE; - } else if (stbuf.st_size == sizeof(TOKEN_DATA)) { - *new = CK_TRUE; - } else { - TRACE_ERROR("%s has an invalid size of %ld bytes. Neither old nor new token format.\n", - fname, stbuf.st_size); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Check if the data store is in 3.12 format. - */ -static CK_RV datastore_is_312(const char *data_store, const char *sopin, - const char *userpin, CK_BBOOL *new) -{ - CK_RV ret; - CK_BYTE masterkey_so[32]; - CK_BYTE masterkey_user[32]; - unsigned int num_objs = 0, num_old_objs = 0; - TOKEN_DATA tokdata; - - *new = CK_FALSE; - - TRACE_INFO("Checking if data store is already in 3.12 format ...\n"); - - /* Check if NVTOK.DAT is new */ - ret = NVTOK_DAT_is_312(data_store, new); - if (ret != CKR_OK) { - warnx("Cannot determine if NVTOK.DAT has an old or new format."); - warnx("Note that generic token formats cannot be migrated."); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - if (*new == CK_FALSE) { - ret = CKR_OK; - goto done; - } - - /* NVTOK.DAT is already new, now check if we can read the keys */ - ret = load_NVTOK_DAT(data_store, "NVTOK.DAT", &tokdata); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot load NVTOK.DAT, datastore inconsistent, ret=%08lX\n", ret); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = load_masterkey_312(data_store, "MK_SO", sopin, &tokdata, masterkey_so); - if (ret != CKR_OK) { - TRACE_INFO("Cannot load new MK from MK_SO, datastore probably old.\n"); - goto done; - } - - ret = load_masterkey_312(data_store, "MK_USER", userpin, &tokdata, masterkey_user); - if (ret != CKR_OK) { - TRACE_INFO("Cannot load new MK from MK_USER, datastore probably old.\n"); - goto done; - } - - if (memcmp(masterkey_so, masterkey_user, 32) != 0) { - TRACE_ERROR("MKs from MK_SO and MK_USER don't match, datastore inconsistent.\n"); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = count_objects(data_store, &num_objs, &num_old_objs); - if (ret != CKR_OK) { - TRACE_ERROR("cannot count objects in %s.\n", data_store); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - TRACE_INFO("Found %d objects total, %d old objects.\n", num_objs, num_old_objs); - if (num_old_objs > 0) - TRACE_WARN("Note that the old objects are not usable anymore, because " - "we don't have the corresponding old masterkey!\n"); - - if (num_objs > 0 && num_old_objs == 0) - *new = CK_TRUE; - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Switch to new repository by deleting the old repository and renaming - * the backup folder to the original data store name. - */ -static CK_RV switch_to_new_repository(const char *data_store_old, - const char *data_store_new) -{ - char fname1[PATH_MAX]; - CK_RV ret; - int rc = -1; - - TRACE_INFO("Switching to new repository ...\n"); - - /* Rename original repository folder */ - snprintf(fname1, sizeof(fname1), "%s_BAK", data_store_old); - rc = rename(data_store_old, fname1); - if (rc) { - TRACE_ERROR("Cannot rename %s, errno=%s.\n", data_store_old, strerror(rc)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Rename backup folder */ - rc = rename(data_store_new, data_store_old); - if (rc) { - TRACE_ERROR("Cannot rename %s, errno=%s.\n", data_store_new, strerror(rc)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Inserts the new tokversion parm in the token's slot configuration, e.g. - * - * slot 2 - * { - * stdll = libpkcs11_cca.so - * tokversion = 3.12 - * } - */ -static CK_RV update_opencryptoki_conf(CK_SLOT_ID slot_id, char *location) -{ - const char *parm = "tokversion = 3.12\n"; - char dst_file[PATH_MAX], src_file[PATH_MAX], fname[PATH_MAX+20], line[PATH_MAX]; - char slot[32]; - FILE *fp_r = NULL, *fp_w = NULL; - CK_RV ret; - int rc; - - TRACE_INFO("Updating config file ...\n"); - - /* Open current conf file for read */ - snprintf(src_file, PATH_MAX, "%s/%s", location, "opencryptoki.conf"); - fp_r = fopen(src_file, "r"); - if (!fp_r) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", src_file, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Open new conf file for write */ - snprintf(dst_file, PATH_MAX, "%s/%s", location, "opencryptoki.conf_new"); - fp_w = fopen(dst_file, "w"); - if (!fp_w) { - TRACE_ERROR("fopen(%s) failed, errno=%s\n", dst_file, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp_w)); - - /* Insert/replace tokversion parm in new file */ - snprintf(slot, sizeof(slot), "slot %ld", slot_id); - while (fgets(line, sizeof(line), fp_r)) { - if (!begins_with(line, '#') && strstr(line, slot)) { - fputs(line, fp_w); // write "slot n" - /* insert tokversion before '}' */ - while (fgets(line, sizeof(line), fp_r)) { - if (strstr(line, "}")) { - fputs(parm, fp_w); - fputs(line, fp_w); - break; - } - /* Don't write existing tokversion to new file */ - if (!strstr(line, "tokversion")) - fputs(line, fp_w); - } - } else - fputs(line, fp_w); - } - - fclose(fp_r); - fclose(fp_w); - fp_r = NULL; - fp_w = NULL; - - /* Rename old conf file */ - snprintf(fname, sizeof(fname), "%s_BAK", src_file); - rc = rename(src_file, fname); - if (rc) { - TRACE_ERROR("Cannot rename %s\n", src_file); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Rename new file */ - rc = rename(dst_file, src_file); - if (rc) { - TRACE_ERROR("Cannot rename %s.\n", dst_file); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - if (fp_r) - fclose(fp_r); - if (fp_w) - fclose(fp_w); - - return ret; - -} - -/** - * Removes the token_s shared memory from /dev/shm - */ -static CK_RV remove_shared_memory(char *location) -{ - char shm_name[PATH_MAX]; - int i, k, rc; - - i = k = 0; - shm_name[k++] = '/'; - if (location[i] == '/') - i++; - - for (; location[i]; i++, k++) { - if (location[i] == '/') - shm_name[k] = '.'; - else - shm_name[k] = location[i]; - } - shm_name[k] = '\0'; - - rc = shm_unlink(shm_name); - if (rc != 0) { - warnx("shm_unlink(%s) failed, errno=%s", shm_name, strerror(errno)); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} - -/** - * Copy a file given by name from a src folder to a dst folder. - */ -static CK_RV file_copy(char *dst, const char *src, const char *name) -{ - char dst_file[PATH_MAX], src_file[PATH_MAX], buf[4096]; - FILE *fp_r = NULL, *fp_w = NULL; - size_t written; - CK_RV ret; - - snprintf(dst_file, PATH_MAX, "%s/%s", dst, name); - snprintf(src_file, PATH_MAX, "%s/%s", src, name); - - fp_r = fopen(src_file, "r"); - if (!fp_r) { - warnx("fopen(%s) failed, errno=%s", src_file, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - fp_w = fopen(dst_file, "w"); - if (!fp_w) { - warnx("fopen(%s) failed, errno=%s", dst_file, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - set_perm(fileno(fp_w)); - - while (!feof(fp_r)) { - size_t bytes = fread(buf, 1, sizeof(buf), fp_r); - if (bytes) { // can be zero, if file empty - written = fwrite(buf, 1, bytes, fp_w); - if (written != bytes) { - warnx("fwrite(%s) failed, errno=%s", dst_file, - strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - } - } - - ret = CKR_OK; - -done: - - if (fp_r) - fclose(fp_r); - if (fp_w) - fclose(fp_w); - - return ret; -} - -/** - * Change the group owner of the given directory to 'pkcs11'. - */ -static CK_RV change_owner(char *dir) -{ - struct group* grp; - CK_RV ret; - - /* Set group owner */ - grp = getgrnam("pkcs11"); - if (grp) { - if (chown(dir, -1, grp->gr_gid)) { - ret = CKR_FUNCTION_FAILED; - goto done; - } - } else { - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Fix group permissions (see man 2 mkdir for details) */ - if (chmod(dir, 0770)) { - ret = CKR_FUNCTION_FAILED; - goto done; - } - - ret = CKR_OK; - -done: - - return ret; -} - -/** - * Copy the given src folder to the given dst folder including all - * subdirectories and files. - */ -static CK_RV folder_copy(char *dst, const char *src) -{ - char d[PATH_MAX], s[PATH_MAX]; - struct dirent *entry; - CK_RV ret; - DIR *dir; - - /* Open src */ - dir = opendir(src); - if (dir == NULL) { - TRACE_ERROR("Cannot open %s\n", src); - return CKR_FUNCTION_FAILED; - } - - /* Create dst */ - if (mkdir(dst, 0) != 0) { - TRACE_ERROR("Cannot create %s\n", dst); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Change group owner and set permissions */ - ret = change_owner(dst); - if (ret != CKR_OK) { - TRACE_ERROR("Cannot change owner and permissions for %s\n", dst); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Copy folder recursively, skip the "." and ".." entries */ - while ((entry = readdir(dir)) != NULL) { - if (entry->d_type == DT_DIR) { - if (strncmp(entry->d_name, ".", 1) != 0) { - snprintf(d, PATH_MAX, "%s/%s", dst, entry->d_name); - snprintf(s, PATH_MAX, "%s/%s", src, entry->d_name); - ret = folder_copy(d, s); - if (ret != CKR_OK) - goto done; - } - } else { - ret = file_copy(dst, src, entry->d_name); - if (ret != CKR_OK) - goto done; - } - } - - ret = CKR_OK; - -done: - - closedir(dir); - - return ret; -} - -/** - * Remove the given folder and all of its contents. - */ -static CK_RV folder_delete(const char *folder) -{ - DIR *dir; - char fname[PATH_MAX]; - size_t len, path_len; - struct stat statbuf; - struct dirent *ent; - CK_RV ret = CKR_OK; - - dir = opendir(folder); - if (!dir) { - TRACE_INFO("Folder %s doesn't exist.\n", folder); - return CKR_OK; - } - - path_len = strlen(folder); - while (!ret && (ent = readdir(dir))) { - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) - continue; - len = path_len + strlen(ent->d_name) + 2; - snprintf(fname, len, "%s/%s", folder, ent->d_name); - if (!stat(fname, &statbuf)) { - if (S_ISDIR(statbuf.st_mode)) { - ret = folder_delete(fname); - if (ret != CKR_OK) - goto done; - } else { - ret = remove(fname); - if (ret != CKR_OK) - goto done; - } - } else { - /* stat failed */ - TRACE_ERROR("Cannot stat %s, errno=%s.\n", fname, strerror(errno)); - ret = CKR_FUNCTION_FAILED; - goto done; - } - } - - ret = CKR_OK; - -done: - - closedir(dir); - if (ret == CKR_OK) - rmdir(folder); - - return ret; -} - -/** - * Backs up the given data_store to data_store_PKCSTOK_MIGRATE_TMP. - * All folders and files are recursively created and copied. - * Remove the backup if it already exists so that we always have - * a clean backup. - * The calling routine ensures that data_store does not end with a '/' ! - */ -static CK_RV backup_repository(const char *data_store) -{ - char dst[PATH_MAX]; - CK_RV ret = CKR_OK; - - TRACE_INFO("Creating data store backup ...\n"); - - memset(dst, 0, PATH_MAX); - snprintf(dst, PATH_MAX, "%s_PKCSTOK_MIGRATE_TMP", data_store); - ret = folder_delete(dst); - if (ret != CKR_OK) { - warnx("Fatal error: cannot delete old backup: %s", dst); - return CKR_FUNCTION_FAILED; - } - - return folder_copy(dst, data_store); -} - -/** - * Checks if the pkcsslotd is running. - */ -static CK_BBOOL pkcsslotd_running(void) -{ - DIR *dir; - FILE *fp; - struct dirent* ent; - char* endptr; - char buf[PATH_MAX]; - char fname[PATH_MAX]; - - TRACE_INFO("Checking if pkcsslotd is running ...\n"); - if (!(dir = opendir("/proc"))) { - TRACE_WARN("Cannot open /proc, i.e. cannot check if pkcsslotd is running.\n"); - return CK_TRUE; - } - - while ((ent = readdir(dir)) != NULL) { - /* if endptr is not a null character, the directory is not - * entirely numeric, so ignore it */ - long lpid = strtol(ent->d_name, &endptr, 10); - if (*endptr != '\0') { - continue; - } - - /* try to open the cmdline file */ - snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid); - fp = fopen(fname, "r"); - if (!fp) { - warnx("fopen(%s) failed, errno=%s", fname, strerror(errno)); - return CK_TRUE; - } - - /* check the first token in the file: the program pathname */ - if (fgets(buf, sizeof(buf), fp) != NULL) { - char* first = strtok(buf, " "); - if (!first) { - TRACE_WARN("Cannot read program name from %s, i.e. cannot check if pkcsslotd is running.\n", - fname); - return CK_TRUE; - } - if (strstr(first, "pkcsslotd") != NULL) { - fclose(fp); - closedir(dir); - return CK_TRUE; - } - } - fclose(fp); - } - - closedir(dir); - return CK_FALSE; -} - -/** - * - */ -static CK_BBOOL token_invalid(const char *dll) -{ - if (strcmp(dll, INVALID_TOKEN) == 0) - return CK_TRUE; - else - return CK_FALSE; -} - -/** - * returns the token name related to the given stdll name for the - * 4 supported tokens. - */ -static const char *dll2name(const char *dll) -{ - static char *dlls[] = { - "libpkcs11_ica.so", "libpkcs11_cca.so", - "libpkcs11_sw.so", "libpkcs11_ep11.so" - }; - static char *names[] = { - "ICA", "CCA", "Soft", "EP11" - }; - int i, num_tokens = sizeof(names) / sizeof(char *); - - for (i = 0; i < num_tokens; i++) { - if (strcmp(dll, dlls[i]) == 0) - return names[i]; - } - - return INVALID_TOKEN; -} - -/** - * translates the given verbose level string into a numeric verbose level. - * Returns -1 if the string is invalid. - */ -static int verbose_str2level(char *str) -{ - const char *tlevel[] = {"none", "error", "warn", "info", "devel", "debug"}; - const int num = sizeof(tlevel) / sizeof(char *); - int i; - - for (i = 0; i < num; i++) { - if (strcmp(str, tlevel[i]) == 0) { - return i; - } - } - - return -1; -} - -static void usage(char *progname) -{ - printf(" Help:\t\t\t\t%s -h\n", progname); - printf(" -h, --help \t\t\tShow this help\n\n"); - printf(" Options:\n"); - printf(" -s, --slotid SLOTID\t\tPKCS slot number (required)\n"); - printf(" -d, --datastore DATASTORE\ttoken datastore location (required)\n"); - printf(" -c, --confdir CONFDIR\t\tlocation of opencryptoki.conf (required)\n"); - printf(" -u, --userpin USERPIN\t\ttoken user pin (prompted if not specified)\n"); - printf(" -p, --sopin SOPIN\t\ttoken SO pin (prompted if not specified)\n"); - printf(" -v, --verbose LEVEL\t\tset verbose level (optional):\n"); - printf("\t\t\t\tnone (default), error, warn, info, devel, debug\n"); - return; -} - -int main(int argc, char **argv) -{ - CK_RV ret = 0; - int opt = 0, vlevel = -1; - CK_SLOT_ID slot_id = 0; - CK_BBOOL slot_id_specified = CK_FALSE; - size_t sopinlen, userpinlen, buflen = 0; - ssize_t num_chars; - char *data_store = NULL, *data_store_old = NULL, *conf_dir = NULL; - char *sopin = NULL, *userpin = NULL, *verbose = NULL; - char *buff = NULL; - char dll_name[PATH_MAX]; - CK_TOKEN_INFO_32 tokinfo; - CK_BBOOL new; - - static const struct option long_opts[] = { - {"datastore", required_argument, NULL, 'd'}, - {"confdir", required_argument, NULL, 'c'}, - {"slotid", required_argument, NULL, 's'}, - {"userpin", required_argument, NULL, 'u'}, - {"sopin", required_argument, NULL, 'p'}, - {"verbose", required_argument, NULL, 'v'}, - {"help", no_argument, NULL, 'h'}, - {0, 0, 0, 0} - }; - - while ((opt = getopt_long(argc, argv, "d:c:s:u:p:v:h", long_opts, NULL)) != -1) { - switch (opt) { - case 'd': - data_store = strdup(optarg); - break; - case 'c': - conf_dir = strdup(optarg); - break; - case 's': - slot_id = atoi(optarg); - slot_id_specified = CK_TRUE; - break; - case 'u': - userpin = strdup(optarg); - userpinlen = strlen(userpin); - break; - case 'p': - sopin = strdup(optarg); - sopinlen = strlen(sopin); - break; - case 'v': - verbose = strdup(optarg); - vlevel = verbose_str2level(verbose); - if (vlevel < 0) { - warnx("Invalid verbose level '%s' specified.", verbose); - usage(argv[0]); - exit(1); - } - break; - case 'h': - usage(argv[0]); - exit(0); - default: - warnx("pkcstok_migrate: Parameters are required."); - usage(argv[0]); - exit(1); - } - } - - if (argc == 1) { - usage(argv[0]); - exit(1); - } - - printf("\npkcstok_migrate:\n"); - printf("Summary of input parameters:\n"); - if (data_store) { - strip_trailing_chars(data_store, strlen(data_store), '/'); - printf(" datastore = %s \n", data_store); - } - if (conf_dir) { - strip_trailing_chars(conf_dir, strlen(conf_dir), '/'); - printf(" confdir = %s \n", conf_dir); - } - if (slot_id_specified) - printf(" slot ID = %ld\n", slot_id); - if (userpin) - printf(" user PIN specified\n"); - if (sopin) - printf(" SO PIN specified\n"); - if (vlevel >= 0) { - trace_level = vlevel; - printf(" verbose level = %s\n", verbose); - } - printf("\n"); - - /* Slot ID must be given */ - if (!slot_id_specified) { - warnx("Slot ID must be specified."); - goto done; - } - - /* Datastore must be given */ - if (data_store == NULL) { - warnx("Data store path must be specified."); - goto done; - } - - /* Limit datastore path length because of appended suffixes */ - if (strlen(data_store) > PKCSTOK_MIGRATE_MAX_PATH_LEN) { - warnx("Datastore path (%ld characters) is too long (max = %d).\n", - strlen(data_store), PKCSTOK_MIGRATE_MAX_PATH_LEN); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Location of opencryptoki.conf must be specified. */ - if (conf_dir == NULL) { - warnx("Location of opencryptoki.conf must be specified."); - goto done; - } - - /* Limit path to config file because of appended suffixes */ - if (strlen(conf_dir) > PKCSTOK_MIGRATE_MAX_PATH_LEN) { - warnx("Path to config file (%ld characters) is too long (max = %d).\n", - strlen(conf_dir), PKCSTOK_MIGRATE_MAX_PATH_LEN); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Check if given data_store exists */ - if (!datastore_exists(data_store)) { - ret = CKR_FUNCTION_FAILED; - warnx("Datastore %s does not exist.", data_store); - goto done; - } - - /* Check if given conf_dir exists and contains opencryptoki.conf */ - if (!conffile_exists(conf_dir)) { - ret = CKR_FUNCTION_FAILED; - warnx("%s does not exist or does not contain opencryptoki.conf", conf_dir); - goto done; - } - - /* Check if pkcsslotd is running */ - if (pkcsslotd_running()) { - warnx("Please stop pkcsslotd before running this utility."); - ret = CKR_FUNCTION_FAILED; - goto done; - } - - /* Identify token related to given slot ID */ - ret = identify_token(slot_id, conf_dir, dll_name); - if (ret != CKR_OK) { - warnx("Cannot identify a token related to given slot ID %ld", slot_id); - goto done; - } - - /* Check if DLL name from conf file is a known and migratable token */ - printf("Slot ID %ld points to DLL name %s, which is a %s token.\n", - slot_id, dll_name, dll2name(dll_name)); - if (token_invalid(dll2name(dll_name))) { - warnx("Please check your input."); - goto done; - } - - /* Check if there are token objects to migrate */ - if (datastore_empty(data_store)) { - ret = CKR_OK; - warnx("Datastore %s is empty, no objects to migrate.", data_store); - goto done; - } - - /* Get token info from NVTOK.DAT */ - ret = get_token_info(data_store, &tokinfo); - if (ret != CKR_OK) { - warnx("Cannot get the token label from NVTOK.DAT"); - goto done; - } - - /* Check with user if ok to migrate this token, or quit if token not migratable */ - printf("Data store %s points to this token info:\n", data_store); - printf(" label : %.*s\n", 32, tokinfo.label); - printf(" manufacturerID : %.*s\n", 32, tokinfo.manufacturerID); - printf(" model : %.*s\n", 16, tokinfo.model); - printf(" serialNumber : %.*s\n", 16, tokinfo.serialNumber); - printf(" hardwareVersion : %i.%i\n", tokinfo.hardwareVersion.major, tokinfo.hardwareVersion.minor); - printf(" firmwareVersion : %i.%i\n", tokinfo.firmwareVersion.major, tokinfo.firmwareVersion.minor); - printf("Migrate this token with given slot ID? y/n\n"); - num_chars = getline(&buff, &buflen, stdin); - if (num_chars < 0 || strncmp(buff, "y", 1) != 0) { - printf("ok, let's quit.\n"); - goto done; - } - - /* Get the SO pin to authorize migration */ - if (!sopin) { - printf("Enter the SO PIN: "); - fflush(stdout); - ret = get_pin(&sopin, &sopinlen); - if (ret != 0) { - warnx("Could not get SO PIN."); - goto done; - } - } - - /* Get the USER pin to authorize migration */ - if (!userpin) { - printf("Enter the USER PIN: "); - fflush(stdout); - ret = get_pin(&userpin, &userpinlen); - if (ret != 0) { - warnx("Could not get USER PIN."); - goto done; - } - } - - /* Verify the SO and USER PINs entered against NVTOK.DAT. */ - ret = verify_pins(data_store, sopin, sopinlen, userpin, userpinlen); - if (ret) { - warnx("Could not verify pins."); - goto done; - } - - /* Check if data store is already new */ - ret = datastore_is_312(data_store, sopin, userpin, &new); - if (ret == 0 && new) { - printf("Data store %s is already in new format.\n", data_store); - ret = update_opencryptoki_conf(slot_id, conf_dir); - if (ret != CKR_OK) - warnx("Failed to update opencryptoki.conf, you must do this manually."); - goto done; - } - - /* Backup repository if not already done */ - ret = backup_repository(data_store); - if (ret != CKR_OK) { - warnx("Failed to create backup."); - goto done; - } - - /* Perform all actions on the backup */ - char data_store_new[PATH_MAX]; - data_store_old = data_store; - snprintf(data_store_new, PATH_MAX, "%s_PKCSTOK_MIGRATE_TMP", data_store_old); - - /* Create new temp token keys, which exist in parallel to the old ones - * until the migration is fully completed. */ - ret = create_token_keys_312(data_store_new, sopin, userpin); - if (ret != CKR_OK) { - warnx("Failed to create new token keys."); - goto done; - } - - /* Migrate repository */ - ret = migrate_repository(data_store_new, sopin, userpin); - if (ret != CKR_OK) { - warnx("Failed to migrate repository."); - goto done; - } - - /* Switch to new repository */ - ret = switch_to_new_repository(data_store_old, data_store_new); - if (ret != CKR_OK) { - warnx("Switch to new repository failed."); - goto done; - } - - /* Remove the token's shared memory */ - ret = remove_shared_memory(data_store); - if (ret != CKR_OK) { - warnx("Failed to remove token's shared memory."); - goto done; - } - - /* Now insert new 'tokversion=3.12' parm in opencryptoki.conf */ - ret = update_opencryptoki_conf(slot_id, conf_dir); - if (ret != CKR_OK) { - warnx("Failed to update opencryptoki.conf, you must do this manually."); - goto done; - } - - printf("Pre-migration data backed up at '%s_BAK'\n", data_store_old); - printf("Config file backed up at '%s/opencryptoki.conf_BAK'\n", conf_dir); - printf("Remove these backups manually after testing the new repository.\n"); - - ret = CKR_OK; - -done: - - free(buff); - free(sopin); - free(userpin); - free(data_store); - free(conf_dir); - free(verbose); - - if (ret == CKR_OK) { - printf("pkcstok_migrate finished successfully.\n"); - return EXIT_SUCCESS; - } else { - printf("pkcstok_migrate finished with warnings/errors.\n"); - return EXIT_FAILURE; - } -} diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.mk b/usr/sbin/pkcstok_migrate/pkcstok_migrate.mk deleted file mode 100644 index 028a383..0000000 --- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.mk +++ /dev/null @@ -1,22 +0,0 @@ -sbin_PROGRAMS += usr/sbin/pkcstok_migrate/pkcstok_migrate -noinst_HEADERS += misc/mech_types.h -noinst_HEADERS += usr/lib/common/defs.h -noinst_HEADERS += usr/lib/common/host_defs.h -noinst_HEADERS += usr/include/local_types.h -noinst_HEADERS += usr/lib/common/h_extern.h -noinst_HEADERS += usr/lib/common/pkcs_utils.h - -usr_sbin_pkcstok_migrate_pkcstok_migrate_LDFLAGS = -lcrypto -ldl -lrt - -usr_sbin_pkcstok_migrate_pkcstok_migrate_CFLAGS = \ - -DSTDLL_NAME=\"pkcstok_migrate\" \ - -I${srcdir}/usr/include \ - -I${srcdir}/usr/lib/common \ - -I${srcdir}/usr/sbin/pkcstok_migrate - -usr_sbin_pkcstok_migrate_pkcstok_migrate_SOURCES = \ - usr/lib/common/p11util.c \ - usr/lib/common/sw_crypt.c \ - usr/lib/common/trace.c \ - usr/lib/common/pkcs_utils.c \ - usr/sbin/pkcstok_migrate/pkcstok_migrate.c diff --git a/usr/sbin/sbin.mk b/usr/sbin/sbin.mk index 01e152d..640308f 100644 --- a/usr/sbin/sbin.mk +++ b/usr/sbin/sbin.mk @@ -13,9 +13,6 @@ endif if ENABLE_P11SAK include usr/sbin/p11sak/p11sak.mk endif -if ENABLE_PKCSTOK_MIGRATE -include usr/sbin/pkcstok_migrate/pkcstok_migrate.mk -endif include usr/sbin/pkcsslotd/pkcsslotd.mk include usr/sbin/pkcsconf/pkcsconf.mk