diff options
Diffstat (limited to 'SoftHSMv2/src/bin/keyconv')
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/Makefile.am | 27 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/base64.c | 311 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp | 227 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp | 261 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 | 63 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp | 351 | ||||
-rw-r--r-- | SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h | 134 |
7 files changed, 1374 insertions, 0 deletions
diff --git a/SoftHSMv2/src/bin/keyconv/Makefile.am b/SoftHSMv2/src/bin/keyconv/Makefile.am new file mode 100644 index 0000000..5565017 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/Makefile.am @@ -0,0 +1,27 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +AM_CPPFLAGS = -I$(srcdir)/../../lib/crypto \ + @CRYPTO_INCLUDES@ + +dist_man_MANS = softhsm2-keyconv.1 + +bin_PROGRAMS = softhsm2-keyconv + +softhsm2_keyconv_SOURCES = softhsm2-keyconv.cpp \ + base64.c +softhsm2_keyconv_LDADD = @CRYPTO_LIBS@ + +# Compile with OpenSSL support +if WITH_OPENSSL +softhsm2_keyconv_SOURCES += softhsm2-keyconv-ossl.cpp \ + ../../lib/crypto/OSSLComp.cpp +endif + +# Compile with Botan support +if WITH_BOTAN +softhsm2_keyconv_SOURCES += softhsm2-keyconv-botan.cpp +endif + +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ + $(srcdir)/*.cpp diff --git a/SoftHSMv2/src/bin/keyconv/base64.c b/SoftHSMv2/src/bin/keyconv/base64.c new file mode 100644 index 0000000..3eb1201 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/base64.c @@ -0,0 +1,311 @@ +/* $OpenBSD: base64.c,v 1.3 2002/06/09 08:13:07 todd Exp $ */ + +/* + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#if !defined(LINT) && !defined(CODECENTER) +static const char rcsid[] = "$ISC: base64.c,v 8.6 1999/01/08 19:25:18 vixie Exp $"; +#endif /* not lint */ + +#include <sys/types.h> +#ifndef _WIN32 +#include <sys/param.h> +#include <sys/socket.h> +#endif + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(unsigned char const *src, size_t srclength, char *target, size_t targsize) { + size_t datalength = 0; + unsigned char input[3]; + unsigned char output[4]; + size_t i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, unsigned char *target, size_t targsize) { + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp new file mode 100644 index 0000000..cb5700f --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + softhsm2-keyconv-botan.cpp + + Code specific for Botan + *****************************************************************************/ + +#include <config.h> +#define KEYCONV_BOTAN +#include "softhsm2-keyconv.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <fstream> + +#include <botan/init.h> +#include <botan/auto_rng.h> +#include <botan/pkcs8.h> +#include <botan/rsa.h> +#include <botan/dsa.h> +#include <botan/bigint.h> +#include <botan/version.h> + +// Init Botan +void crypto_init() +{ + Botan::LibraryInitializer::initialize(); +} + +// Final Botan +void crypto_final() +{ + Botan::LibraryInitializer::deinitialize(); +} + +// Save the RSA key as a PKCS#8 file +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + int result = 0; + Botan::Private_Key* priv_key = NULL; + Botan::AutoSeeded_RNG* rng = NULL; + Botan::BigInt bigE, bigP, bigQ, bigN, bigD; + + // See if the key material was found. + if + ( + pkey[TAG_MODULUS].size <= 0 || + pkey[TAG_PUBEXP].size <= 0 || + pkey[TAG_PRIVEXP].size <= 0 || + pkey[TAG_PRIME1].size <= 0 || + pkey[TAG_PRIME2].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + bigE = Botan::BigInt((Botan::byte*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size); + bigP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size); + bigQ = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size); + bigN = Botan::BigInt((Botan::byte*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size); + bigD = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size); + + rng = new Botan::AutoSeeded_RNG(); + + try + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) + priv_key = new Botan::RSA_PrivateKey(bigP, bigQ, bigE, bigD, bigN); +#else + priv_key = new Botan::RSA_PrivateKey(*rng, bigP, bigQ, bigE, bigD, bigN); +#endif + } + catch(std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not extract the private key from the file.\n"); + delete rng; + return 1; + } + + std::ofstream priv_file(out_path); + if (!priv_file.is_open()) + { + fprintf(stderr, "ERROR: Could not open file for output.\n"); + delete rng; + delete priv_key; + return 1; + } + + try + { + if (file_pin == NULL) + { + priv_file << Botan::PKCS8::PEM_encode(*priv_key); + } + else + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)"); +#else + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)"); +#endif + } + + printf("The key has been written to %s\n", out_path); + } + catch(std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not write to file.\n"); + result = 1; + } + + delete rng; + delete priv_key; + priv_file.close(); + + return result; +} + +// Save the DSA key as a PKCS#8 file +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + int result = 0; + Botan::Private_Key* priv_key = NULL; + Botan::AutoSeeded_RNG* rng = NULL; + Botan::BigInt bigDP, bigDQ, bigDG, bigDX; + + // See if the key material was found. + if + ( + pkey[TAG_PRIME].size <= 0 || + pkey[TAG_SUBPRIME].size <= 0 || + pkey[TAG_BASE].size <= 0 || + pkey[TAG_PRIVVAL].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + bigDP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME].big, pkey[TAG_PRIME].size); + bigDQ = Botan::BigInt((Botan::byte*)pkey[TAG_SUBPRIME].big, pkey[TAG_SUBPRIME].size); + bigDG = Botan::BigInt((Botan::byte*)pkey[TAG_BASE].big, pkey[TAG_BASE].size); + bigDX = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVVAL].big, pkey[TAG_PRIVVAL].size); + + rng = new Botan::AutoSeeded_RNG(); + + try + { + priv_key = new Botan::DSA_PrivateKey(*rng, Botan::DL_Group(bigDP, bigDQ, bigDG), bigDX); + } + catch (std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not extract the private key from the file.\n"); + delete rng; + return 1; + } + + std::ofstream priv_file(out_path); + if (!priv_file.is_open()) + { + fprintf(stderr, "ERROR: Could not open file for output.\n"); + delete rng; + delete priv_key; + return 1; + } + + try + { + if (file_pin == NULL) + { + priv_file << Botan::PKCS8::PEM_encode(*priv_key); + } + else + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)"); +#else + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)"); +#endif + } + + printf("The key has been written to %s\n", out_path); + } + catch (std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not write to file.\n"); + result = 1; + } + + delete rng; + delete priv_key; + priv_file.close(); + + return result; +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp new file mode 100644 index 0000000..a5cd8eb --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + softhsm2-keyconv-ossl.cpp + + Code specific for OpenSSL + *****************************************************************************/ + +#include <config.h> +#define KEYCONV_OSSL +#include "softhsm2-keyconv.h" +#include "OSSLComp.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <fstream> + +#include <openssl/pem.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/pkcs12.h> +#include <openssl/dsa.h> +#include <openssl/rsa.h> + +// Init OpenSSL +void crypto_init() +{ + OpenSSL_add_all_algorithms(); +#ifdef WITH_FIPS + if (!FIPS_mode_set(1)) + { + fprintf(stderr, "ERROR: can't enter into FIPS mode.\n"); + exit(0); + } +#endif +} + +// Final OpenSSL +void crypto_final() +{ + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +} + +// Save the RSA key as a PKCS#8 file +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + RSA* rsa = NULL; + EVP_PKEY* ossl_pkey = NULL; + PKCS8_PRIV_KEY_INFO* p8inf = NULL; + BIO* out = NULL; + X509_SIG* p8 = NULL; + int result = 0; + + // See if the key material was found. + if + ( + pkey[TAG_MODULUS].size <= 0 || + pkey[TAG_PUBEXP].size <= 0 || + pkey[TAG_PRIVEXP].size <= 0 || + pkey[TAG_PRIME1].size <= 0 || + pkey[TAG_PRIME2].size <= 0 || + pkey[TAG_EXP1].size <= 0 || + pkey[TAG_EXP2].size <= 0 || + pkey[TAG_COEFF].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + rsa = RSA_new(); + BIGNUM* bn_p = BN_bin2bn((unsigned char*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size, NULL); + BIGNUM* bn_q = BN_bin2bn((unsigned char*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size, NULL); + BIGNUM* bn_d = BN_bin2bn((unsigned char*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size, NULL); + BIGNUM* bn_n = BN_bin2bn((unsigned char*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size, NULL); + BIGNUM* bn_e = BN_bin2bn((unsigned char*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size, NULL); + BIGNUM* bn_dmp1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP1].big, pkey[TAG_EXP1].size, NULL); + BIGNUM* bn_dmq1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP2].big, pkey[TAG_EXP2].size, NULL); + BIGNUM* bn_iqmp = BN_bin2bn((unsigned char*)pkey[TAG_COEFF].big, pkey[TAG_COEFF].size, NULL); + RSA_set0_factors(rsa, bn_p, bn_q); + RSA_set0_crt_params(rsa, bn_dmp1, bn_dmq1, bn_iqmp); + RSA_set0_key(rsa, bn_n, bn_e, bn_d); + + ossl_pkey = EVP_PKEY_new(); + + // Convert RSA to EVP_PKEY + if (!EVP_PKEY_set1_RSA(ossl_pkey, rsa)) + { + fprintf(stderr, "ERROR: Could not convert RSA key to EVP_PKEY.\n"); + RSA_free(rsa); + EVP_PKEY_free(ossl_pkey); + return 1; + } + RSA_free(rsa); + + // Convert EVP_PKEY to PKCS#8 + if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey))) + { + fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n"); + EVP_PKEY_free(ossl_pkey); + return 1; + } + EVP_PKEY_free(ossl_pkey); + + // Open output file + if (!(out = BIO_new_file (out_path, "wb"))) + { + fprintf(stderr, "ERROR: Could not open the output file.\n"); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 1; + } + + // Write to disk + if (file_pin == NULL) + { + PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); + printf("The key has been written to %s\n", out_path); + } + else + { + // Encrypt p8 + if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL, + file_pin, strlen(file_pin), NULL, + 0, PKCS12_DEFAULT_ITER, p8inf))) + { + fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n"); + result = 1; + } + else + { + PEM_write_bio_PKCS8(out, p8); + X509_SIG_free(p8); + printf("The key has been written to %s\n", out_path); + } + } + + PKCS8_PRIV_KEY_INFO_free(p8inf); + BIO_free_all(out); + + return result; +} + +// Save the DSA key as a PKCS#8 file +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + DSA* dsa = NULL; + EVP_PKEY* ossl_pkey = NULL; + PKCS8_PRIV_KEY_INFO* p8inf = NULL; + BIO* out = NULL; + X509_SIG* p8 = NULL; + int result = 0; + + // See if the key material was found. + if + ( + pkey[TAG_PRIME].size <= 0 || + pkey[TAG_SUBPRIME].size <= 0 || + pkey[TAG_BASE].size <= 0 || + pkey[TAG_PRIVVAL].size <= 0 || + pkey[TAG_PUBVAL].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + dsa = DSA_new(); + BIGNUM* bn_p = BN_bin2bn((unsigned char*)pkey[TAG_PRIME].big, pkey[TAG_PRIME].size, NULL); + BIGNUM* bn_q = BN_bin2bn((unsigned char*)pkey[TAG_SUBPRIME].big, pkey[TAG_SUBPRIME].size, NULL); + BIGNUM* bn_g = BN_bin2bn((unsigned char*)pkey[TAG_BASE].big, pkey[TAG_BASE].size, NULL); + BIGNUM* bn_priv_key = BN_bin2bn((unsigned char*)pkey[TAG_PRIVVAL].big, pkey[TAG_PRIVVAL].size, NULL); + BIGNUM* bn_pub_key = BN_bin2bn((unsigned char*)pkey[TAG_PUBVAL].big, pkey[TAG_PUBVAL].size, NULL); + + DSA_set0_pqg(dsa, bn_p, bn_q, bn_g); + DSA_set0_key(dsa, bn_pub_key, bn_priv_key); + + ossl_pkey = EVP_PKEY_new(); + + // Convert DSA to EVP_PKEY + if (!EVP_PKEY_set1_DSA(ossl_pkey, dsa)) + { + fprintf(stderr, "ERROR: Could not convert DSA key to EVP_PKEY.\n"); + DSA_free(dsa); + EVP_PKEY_free(ossl_pkey); + return 1; + } + DSA_free(dsa); + + // Convert EVP_PKEY to PKCS#8 + if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey))) + { + fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n"); + EVP_PKEY_free(ossl_pkey); + return 1; + } + EVP_PKEY_free(ossl_pkey); + + // Open output file + if (!(out = BIO_new_file (out_path, "wb"))) + { + fprintf(stderr, "ERROR: Could not open the output file.\n"); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 1; + } + + // Write to disk + if (file_pin == NULL) + { + PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); + printf("The key has been written to %s\n", out_path); + } + else + { + // Encrypt p8 + if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL, + file_pin, strlen(file_pin), NULL, + 0, PKCS12_DEFAULT_ITER, p8inf))) + { + fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n"); + result = 1; + } + else + { + PEM_write_bio_PKCS8(out, p8); + X509_SIG_free(p8); + printf("The key has been written to %s\n", out_path); + } + } + + PKCS8_PRIV_KEY_INFO_free(p8inf); + BIO_free_all(out); + + return result; +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 new file mode 100644 index 0000000..b716bc8 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 @@ -0,0 +1,63 @@ +.TH SOFTHSM2-KEYCONV 1 "20 March 2014" "SoftHSM" +.SH NAME +softhsm2-keyconv \- converting from BIND to PKCS#8 key file format +.SH SYNOPSIS +.B softhsm2-keyconv +.B \-\-in +.I path +.B \-\-out +.I path +.RB [ \-\-pin +.IR PIN ] +.SH DESCRIPTION +.B softhsm2-keyconv +can convert BIND .private-key files to the PKCS#8 file format. +This is so that you can import the PKCS#8 file into +libsofthsm using the command +.BR softhsm2\-util . +If you have another file format, then +.B openssl +probably can help you to convert it into the PKCS#8 file format. +.SH OPTIONS +.B \-\-help\fR, \fB\-h\fR +Shows the help screen. +.TP +.B \-\-in \fIpath\fR +The +.I path +to the input file. +.TP +.B \-\-out \fIpath\fR +The +.I path +to the output file. +.TP +.B \-\-pin \fIPIN\fR +The +.I PIN +will be used to encrypt the PKCS#8 file. +If not given then the PKCS#8 file will be unencrypted. +.TP +.B \-\-version\fR, \fB\-v\fR +Show the version info. +.SH EXAMPLES +The following command can be used to convert a BIND .private-key file to a PKCS#8 file: +.LP +.RS +.nf +softhsm2-keyconv \-\-in Kexample.com.+007+05474.private \\ +.ti +0.7i +\-\-out rsa.pem +.fi +.RE +.LP +.SH AUTHORS +Written by Rickard Bellgrim, Francis Dupont, René Post, and Roland van Rijswijk. +.SH "SEE ALSO" +.IR softhsm2-migrate (1), +.IR softhsm2-util (1), +.IR softhsm2.conf (5), +.IR openssl (1), +.IR named (1), +.IR dnssec-keygen (1), +.IR dnssec-signzone (1) diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp new file mode 100644 index 0000000..aeb75c3 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/************************************************************ +* +* softhsm2-keyconv +* +* This program is for converting from BIND .private-key +* format to PKCS#8 key file format. So that keys can be +* imported from BIND to SoftHSM. +* +* Some of the design/code is from keyconv.c written by +* Hakan Olsson and Jakob Schlyter in 2000 and 2001. +* +************************************************************/ + +#include <config.h> +#include "softhsm2-keyconv.h" + +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#ifndef _WIN32 +#include <unistd.h> +#else +#include <io.h> +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define open _open +#define close _close +#endif +#include <iostream> +#include <fstream> +#include <stdint.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +void usage() +{ + printf("Converting from BIND .private-key format to PKCS#8 key file format.\n"); + printf("Usage: softhsm2-keyconv [OPTIONS]\n"); + printf("Options:\n"); + printf(" -h Shows this help screen.\n"); + printf(" --help Shows this help screen.\n"); + printf(" --in <path> The path to the input file.\n"); + printf(" --out <path> The path to the output file.\n"); + printf(" --pin <PIN> To encrypt PKCS#8 file. Optional.\n"); + printf(" -v Show version info.\n"); + printf(" --version Show version info.\n"); +} + +// Give a number to each option +enum { + OPT_HELP = 0x100, + OPT_IN, + OPT_OUT, + OPT_PIN, + OPT_VERSION +}; + +// Define the options +static const struct option long_options[] = { + { "help", 0, NULL, OPT_HELP }, + { "in", 1, NULL, OPT_IN }, + { "out", 1, NULL, OPT_OUT }, + { "pin", 1, NULL, OPT_PIN }, + { "version", 0, NULL, OPT_VERSION }, + { NULL, 0, NULL, 0 } +}; + +int main(int argc, char* argv[]) +{ + int option_index = 0; + int opt, result; + + char* in_path = NULL; + char* out_path = NULL; + char* file_pin = NULL; + + if (argc == 1) + { + usage(); + exit(0); + } + + while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) + { + switch (opt) + { + case OPT_IN: + in_path = optarg; + break; + case OPT_OUT: + out_path = optarg; + break; + case OPT_PIN: + file_pin = optarg; + break; + case OPT_VERSION: + case 'v': + printf("%s\n", PACKAGE_VERSION); + exit(0); + break; + case OPT_HELP: + case 'h': + default: + usage(); + exit(0); + break; + } + } + + // We should convert to PKCS#8 + result = to_pkcs8(in_path, out_path, file_pin); + + return result; +} + +// Convert from BIND to PKCS#8 +int to_pkcs8(char* in_path, char* out_path, char* file_pin) +{ + FILE* file_pointer = NULL; + char line[MAX_LINE], data[MAX_LINE]; + char* value_pointer = NULL; + int lineno = 0, m, n, error = 0, found, algorithm = DNS_KEYALG_ERROR, data_length; + uint32_t bitfield = 0; + key_material_t pkey[TAG_MAX]; + + if (in_path == NULL) + { + fprintf(stderr, "ERROR: A path to the input file must be supplied. Use --in <path>\n"); + return 1; + } + + if (out_path == NULL) + { + fprintf(stderr, "ERROR: A path to the output file must be supplied. Use --out <path>\n"); + return 1; + } + + file_pointer = fopen(in_path, "r"); + if (file_pointer == NULL) + { + fprintf(stderr, "ERROR: Could not open input file %.100s for reading.\n", in_path); + return 1; + } + + // Loop over all of the lines + while (fgets(line, MAX_LINE, file_pointer) != NULL) + { + lineno++; + + // Find the current text field in the BIND file. + for (m = 0, found = -1; found == -1 && file_tags[m]; m++) + { + if (strncasecmp(line, file_tags[m], strlen(file_tags[m])) == 0) + { + found = m; + } + } + + // The text files is not recognized. + if (found == -1) + { + fprintf(stderr, "ERROR: Unrecognized input line %i\n", lineno); + fprintf(stderr, "ERROR: --> %s", line); + continue; + } + + // Point to the data for this text field. + value_pointer = line + strlen(file_tags[found]) + 1; + + // Continue if we are at the end of the string + if (*value_pointer == 0) + { + continue; + } + + // Check that we do not get duplicates. + if (bitfield & (1 << found)) + { + fprintf(stderr, "ERROR: Duplicate \"%s\" field, line %i - ignored\n", + file_tags[found], lineno); + continue; + } + bitfield |= (1 << found); + + // Handle the data for this text field. + switch (found) + { + case TAG_VERSION: + if (sscanf(value_pointer, "v%i.%i", &m, &n) != 2) + { + fprintf(stderr, "ERROR: Invalid/unknown version string " + "(%.100s).\n", value_pointer); + error = 1; + break; + } + if (m > FILE_MAJOR_VERSION || (m == FILE_MAJOR_VERSION && n > FILE_MINOR_VERSION)) + { + fprintf(stderr, "ERROR: Cannot parse this version of file format, " + "v%i.%i.\n", m, n); + error = 1; + } + break; + case TAG_ALGORITHM: + algorithm = strtol(value_pointer, NULL, 10); + break; + // RSA + case TAG_MODULUS: + case TAG_PUBEXP: + case TAG_PRIVEXP: + case TAG_PRIME1: + case TAG_PRIME2: + case TAG_EXP1: + case TAG_EXP2: + case TAG_COEFF: + // DSA + case TAG_PRIME: + case TAG_SUBPRIME: + case TAG_BASE: + case TAG_PRIVVAL: + case TAG_PUBVAL: + data_length = b64_pton(value_pointer, (unsigned char*)data, MAX_LINE); + if (data_length == -1) + { + error = 1; + fprintf(stderr, "ERROR: Could not parse the base64 string on line %i.\n", lineno); + } + else + { + pkey[found].big = malloc(data_length); + if (!pkey[found].big) + { + fprintf(stderr, "ERROR: Could not allocate memory.\n"); + error = 1; + break; + } + memcpy(pkey[found].big, data, data_length); + pkey[found].size = data_length; + } + break; + // Do not need these + case TAG_CREATED: + case TAG_PUBLISH: + case TAG_ACTIVATE: + default: + break; + } + } + + fclose(file_pointer); + + // Something went wrong. Clean up and quit. + if (error) + { + free_key_material(pkey); + return error; + } + + // Create and set file permissions if the file does not exist. + int fd = open(out_path, O_CREAT, S_IRUSR | S_IWUSR); + if (fd == -1) + { + fprintf(stderr, "ERROR: Could not open the output file: %s (errno %i)\n", + out_path, errno); + free_key_material(pkey); + return 1; + } + ::close(fd); + + crypto_init(); + + // Save the the key to the disk + switch (algorithm) + { + case DNS_KEYALG_ERROR: + fprintf(stderr, "ERROR: The algorithm %i was not given in the file.\n", + algorithm); + error = 1; + break; + case DNS_KEYALG_RSAMD5: + case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_RSASHA1_NSEC3_SHA1: + case DNS_KEYALG_RSASHA256: + case DNS_KEYALG_RSASHA512: + error = save_rsa_pkcs8(out_path, file_pin, pkey); + break; + case DNS_KEYALG_DSA: + case DNS_KEYALG_DSA_NSEC3_SHA1: + error = save_dsa_pkcs8(out_path, file_pin, pkey); + break; + case DNS_KEYALG_ECC: + case DNS_KEYALG_ECC_GOST: + default: + fprintf(stderr, "ERROR: The algorithm %i is not supported.\n", + algorithm); + error = 1; + break; + } + + crypto_final(); + free_key_material(pkey); + + return error; +} + +// Free allocated memory +void free_key_material(key_material_t* pkey) +{ + int i; + + if (!pkey) + { + return; + } + + for (i = 0; i < TAG_MAX; i++) + { + if (pkey[i].big) + { + free(pkey[i].big); + } + } +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h new file mode 100644 index 0000000..fdeb719 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SOFTHSM_V2_SOFTHSM2_KEYCONV_H +#define _SOFTHSM_V2_SOFTHSM2_KEYCONV_H 1 + +#include <stdlib.h> + +typedef struct key_material_t { + unsigned long size; + void* big; + key_material_t() { + size = 0; + big = NULL; + } +} key_material_t; + +// Main functions + +void usage(); +int to_pkcs8(char* in_path, char* out_path, char* file_pin); + +// Support functions + +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey); +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey); +void free_key_material(key_material_t* pkey); +void crypto_init(); +void crypto_final(); + +// base64.c prototypes + +#ifdef __cplusplus +extern "C" { +#endif +int b64_pton(const char* , unsigned char*, size_t); +int b64_ntop(const unsigned char*, size_t, char*, size_t); +#ifdef __cplusplus +} +#endif + +// The BIND file version number. +#define FILE_MAJOR_VERSION 1 +#define FILE_MINOR_VERSION 3 + +// Key algorithm number +#define DNS_KEYALG_ERROR -1 +#define DNS_KEYALG_RSAMD5 1 +#define DNS_KEYALG_DSA 3 +#define DNS_KEYALG_ECC 4 +#define DNS_KEYALG_RSASHA1 5 +#define DNS_KEYALG_DSA_NSEC3_SHA1 6 +#define DNS_KEYALG_RSASHA1_NSEC3_SHA1 7 +#define DNS_KEYALG_RSASHA256 8 +#define DNS_KEYALG_RSASHA512 10 +#define DNS_KEYALG_ECC_GOST 12 + +// Maximum number of lines / line length +#define MAX_LINE 4096 + +// The text fields supported +#if !defined(KEYCONV_BOTAN) && !defined(KEYCONV_OSSL) +static const char* file_tags[] = { + "Private-key-format:", + "Algorithm:", + "Modulus:", + "PublicExponent:", + "PrivateExponent:", + "Prime1:", + "Prime2:", + "Exponent1:", + "Exponent2:", + "Coefficient:", + "Prime(p):", + "Private_value(x):", + "Public_value(y):", + "Subprime(q):", + "Base(g):", + "Created:", + "Publish:", + "Activate:", + NULL +}; +#endif + +// The number of each text field. +// Must match the tags above. +enum FILE_TAGS { + TAG_VERSION = 0, + TAG_ALGORITHM, + TAG_MODULUS, + TAG_PUBEXP, + TAG_PRIVEXP, + TAG_PRIME1, + TAG_PRIME2, + TAG_EXP1, + TAG_EXP2, + TAG_COEFF, + TAG_PRIME, + TAG_PRIVVAL, + TAG_PUBVAL, + TAG_SUBPRIME, + TAG_BASE, + TAG_CREATED, + TAG_PUBLISH, + TAG_ACTIVATE, + // So we know how long this list is + TAG_MAX +}; + +#endif /* _SOFTHSM_V2_SOFTHSM2_KEYCONV_H */ |