2 * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /*****************************************************************************
28 softhsm2-keyconv-botan.cpp
30 Code specific for Botan
31 *****************************************************************************/
35 #include "softhsm2-keyconv.h"
43 #include <botan/init.h>
44 #include <botan/auto_rng.h>
45 #include <botan/pkcs8.h>
46 #include <botan/rsa.h>
47 #include <botan/dsa.h>
48 #include <botan/bigint.h>
49 #include <botan/version.h>
54 Botan::LibraryInitializer::initialize();
60 Botan::LibraryInitializer::deinitialize();
63 // Save the RSA key as a PKCS#8 file
64 int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey)
67 Botan::Private_Key* priv_key = NULL;
68 Botan::AutoSeeded_RNG* rng = NULL;
69 Botan::BigInt bigE, bigP, bigQ, bigN, bigD;
71 // See if the key material was found.
74 pkey[TAG_MODULUS].size <= 0 ||
75 pkey[TAG_PUBEXP].size <= 0 ||
76 pkey[TAG_PRIVEXP].size <= 0 ||
77 pkey[TAG_PRIME1].size <= 0 ||
78 pkey[TAG_PRIME2].size <= 0
81 fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n");
85 bigE = Botan::BigInt((Botan::byte*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size);
86 bigP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size);
87 bigQ = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size);
88 bigN = Botan::BigInt((Botan::byte*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size);
89 bigD = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size);
91 rng = new Botan::AutoSeeded_RNG();
95 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
96 priv_key = new Botan::RSA_PrivateKey(bigP, bigQ, bigE, bigD, bigN);
98 priv_key = new Botan::RSA_PrivateKey(*rng, bigP, bigQ, bigE, bigD, bigN);
101 catch(std::exception& e)
103 fprintf(stderr, "%s\n", e.what());
104 fprintf(stderr, "ERROR: Could not extract the private key from the file.\n");
109 std::ofstream priv_file(out_path);
110 if (!priv_file.is_open())
112 fprintf(stderr, "ERROR: Could not open file for output.\n");
120 if (file_pin == NULL)
122 priv_file << Botan::PKCS8::PEM_encode(*priv_key);
126 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
127 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)");
129 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)");
133 printf("The key has been written to %s\n", out_path);
135 catch(std::exception& e)
137 fprintf(stderr, "%s\n", e.what());
138 fprintf(stderr, "ERROR: Could not write to file.\n");
149 // Save the DSA key as a PKCS#8 file
150 int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey)
153 Botan::Private_Key* priv_key = NULL;
154 Botan::AutoSeeded_RNG* rng = NULL;
155 Botan::BigInt bigDP, bigDQ, bigDG, bigDX;
157 // See if the key material was found.
160 pkey[TAG_PRIME].size <= 0 ||
161 pkey[TAG_SUBPRIME].size <= 0 ||
162 pkey[TAG_BASE].size <= 0 ||
163 pkey[TAG_PRIVVAL].size <= 0
166 fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n");
170 bigDP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME].big, pkey[TAG_PRIME].size);
171 bigDQ = Botan::BigInt((Botan::byte*)pkey[TAG_SUBPRIME].big, pkey[TAG_SUBPRIME].size);
172 bigDG = Botan::BigInt((Botan::byte*)pkey[TAG_BASE].big, pkey[TAG_BASE].size);
173 bigDX = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVVAL].big, pkey[TAG_PRIVVAL].size);
175 rng = new Botan::AutoSeeded_RNG();
179 priv_key = new Botan::DSA_PrivateKey(*rng, Botan::DL_Group(bigDP, bigDQ, bigDG), bigDX);
181 catch (std::exception& e)
183 fprintf(stderr, "%s\n", e.what());
184 fprintf(stderr, "ERROR: Could not extract the private key from the file.\n");
189 std::ofstream priv_file(out_path);
190 if (!priv_file.is_open())
192 fprintf(stderr, "ERROR: Could not open file for output.\n");
200 if (file_pin == NULL)
202 priv_file << Botan::PKCS8::PEM_encode(*priv_key);
206 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
207 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)");
209 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)");
213 printf("The key has been written to %s\n", out_path);
215 catch (std::exception& e)
217 fprintf(stderr, "%s\n", e.what());
218 fprintf(stderr, "ERROR: Could not write to file.\n");