blob: cb5700f7289b8f7e95668d9034331e60b1399b4b [file] [log] [blame]
NingSun0c89b3c2018-02-08 08:34:03 -08001/*
2 * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
13 *
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.
25 */
26
27/*****************************************************************************
28 softhsm2-keyconv-botan.cpp
29
30 Code specific for Botan
31 *****************************************************************************/
32
33#include <config.h>
34#define KEYCONV_BOTAN
35#include "softhsm2-keyconv.h"
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <iostream>
41#include <fstream>
42
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>
50
51// Init Botan
52void crypto_init()
53{
54 Botan::LibraryInitializer::initialize();
55}
56
57// Final Botan
58void crypto_final()
59{
60 Botan::LibraryInitializer::deinitialize();
61}
62
63// Save the RSA key as a PKCS#8 file
64int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey)
65{
66 int result = 0;
67 Botan::Private_Key* priv_key = NULL;
68 Botan::AutoSeeded_RNG* rng = NULL;
69 Botan::BigInt bigE, bigP, bigQ, bigN, bigD;
70
71 // See if the key material was found.
72 if
73 (
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
79 )
80 {
81 fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n");
82 return 1;
83 }
84
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);
90
91 rng = new Botan::AutoSeeded_RNG();
92
93 try
94 {
95#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
96 priv_key = new Botan::RSA_PrivateKey(bigP, bigQ, bigE, bigD, bigN);
97#else
98 priv_key = new Botan::RSA_PrivateKey(*rng, bigP, bigQ, bigE, bigD, bigN);
99#endif
100 }
101 catch(std::exception& e)
102 {
103 fprintf(stderr, "%s\n", e.what());
104 fprintf(stderr, "ERROR: Could not extract the private key from the file.\n");
105 delete rng;
106 return 1;
107 }
108
109 std::ofstream priv_file(out_path);
110 if (!priv_file.is_open())
111 {
112 fprintf(stderr, "ERROR: Could not open file for output.\n");
113 delete rng;
114 delete priv_key;
115 return 1;
116 }
117
118 try
119 {
120 if (file_pin == NULL)
121 {
122 priv_file << Botan::PKCS8::PEM_encode(*priv_key);
123 }
124 else
125 {
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)");
128#else
129 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)");
130#endif
131 }
132
133 printf("The key has been written to %s\n", out_path);
134 }
135 catch(std::exception& e)
136 {
137 fprintf(stderr, "%s\n", e.what());
138 fprintf(stderr, "ERROR: Could not write to file.\n");
139 result = 1;
140 }
141
142 delete rng;
143 delete priv_key;
144 priv_file.close();
145
146 return result;
147}
148
149// Save the DSA key as a PKCS#8 file
150int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey)
151{
152 int result = 0;
153 Botan::Private_Key* priv_key = NULL;
154 Botan::AutoSeeded_RNG* rng = NULL;
155 Botan::BigInt bigDP, bigDQ, bigDG, bigDX;
156
157 // See if the key material was found.
158 if
159 (
160 pkey[TAG_PRIME].size <= 0 ||
161 pkey[TAG_SUBPRIME].size <= 0 ||
162 pkey[TAG_BASE].size <= 0 ||
163 pkey[TAG_PRIVVAL].size <= 0
164 )
165 {
166 fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n");
167 return 1;
168 }
169
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);
174
175 rng = new Botan::AutoSeeded_RNG();
176
177 try
178 {
179 priv_key = new Botan::DSA_PrivateKey(*rng, Botan::DL_Group(bigDP, bigDQ, bigDG), bigDX);
180 }
181 catch (std::exception& e)
182 {
183 fprintf(stderr, "%s\n", e.what());
184 fprintf(stderr, "ERROR: Could not extract the private key from the file.\n");
185 delete rng;
186 return 1;
187 }
188
189 std::ofstream priv_file(out_path);
190 if (!priv_file.is_open())
191 {
192 fprintf(stderr, "ERROR: Could not open file for output.\n");
193 delete rng;
194 delete priv_key;
195 return 1;
196 }
197
198 try
199 {
200 if (file_pin == NULL)
201 {
202 priv_file << Botan::PKCS8::PEM_encode(*priv_key);
203 }
204 else
205 {
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)");
208#else
209 priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)");
210#endif
211 }
212
213 printf("The key has been written to %s\n", out_path);
214 }
215 catch (std::exception& e)
216 {
217 fprintf(stderr, "%s\n", e.what());
218 fprintf(stderr, "ERROR: Could not write to file.\n");
219 result = 1;
220 }
221
222 delete rng;
223 delete priv_key;
224 priv_file.close();
225
226 return result;
227}