73b8029bff2d1115d4f56153907f4cc97737c9a6
[platform/core/security/key-manager.git] / src / manager / crypto / sw-backend / crypto-service.cpp
1 #include <iostream>
2 #include <exception>
3 #include <vector>
4 #include <fstream>
5 #include <string.h>
6 #include <memory>
7
8 #include <openssl/x509_vfy.h>
9 #include <openssl/evp.h>
10 #include <openssl/obj_mac.h>
11 #include <openssl/ec.h>
12 #include <openssl/dsa.h>
13 #include <openssl/dh.h>
14 #include <openssl/rsa.h>
15 #include <openssl/bio.h>
16 #include <openssl/rand.h>
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/obj_mac.h>
21 #include <ckm/ckm-error.h>
22 #include <ckm/ckm-type.h>
23 #include <key-impl.h>
24 #include <sw-backend/crypto-service.h>
25 #include <assert.h>
26 #include <dpl/log/log.h>
27
28 #define OPENSSL_SUCCESS 1       // DO NOTCHANGE THIS VALUE
29 #define OPENSSL_FAIL    0       // DO NOTCHANGE THIS VALUE
30
31 namespace CKM {
32 namespace Crypto {
33 namespace SW {
34
35 CryptoService::CryptoService(){
36 }
37
38 CryptoService::~CryptoService(){
39 }
40
41 int CryptoService::createKeyPairRSA(const int size, // size in bits [1024, 2048, 4096]
42         KeyImpl &createdPrivateKey,  // returned value
43         KeyImpl &createdPublicKey)  // returned value
44 {
45     EVP_PKEY_CTX *ctx = NULL;
46     EVP_PKEY *pkey = NULL;
47     EVP_PKEY *pparam = NULL;
48
49     // check the parameters of functions
50     if(size != 1024 && size !=2048 && size != 4096) {
51         LogError("Error in RSA input size");
52         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in RSA input size");
53     }
54
55     // check the parameters of functions
56     if(&createdPrivateKey == NULL) {
57         LogError("Error in createdPrivateKey value");
58         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
59     }
60
61     // check the parameters of functions
62     if(&createdPublicKey == NULL) {
63         LogError("Error in createdPrivateKey value");
64         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
65     }
66
67     Try {
68         if(!(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL))) {
69             LogError("Error in EVP_PKEY_CTX_new_id function !!");
70             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function !!");
71         }
72
73         if(EVP_PKEY_keygen_init(ctx) <= 0) {
74             LogError("Error in EVP_PKEY_keygen_init function !!");
75             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function !!");
76         }
77
78         if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx,size) <= 0) {
79             LogError("Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
80             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
81         }
82
83         if(!EVP_PKEY_keygen(ctx, &pkey)) {
84             LogError("Error in EVP_PKEY_keygen function !!");
85             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function !!");
86         }
87     } Catch(CryptoService::Exception::opensslError) {
88         if(pkey) {
89             EVP_PKEY_free(pkey);
90         }
91
92         if(pparam) {
93             EVP_PKEY_free(pparam);
94         }
95
96         if(ctx) {
97             EVP_PKEY_CTX_free(ctx);
98         }
99
100         ReThrowMsg(CryptoService::Exception::opensslError,"Error in opensslError function !!");
101     }
102
103     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
104
105     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_RSA_PRIVATE);
106     createdPublicKey = KeyImpl(ptr, KeyType::KEY_RSA_PUBLIC);
107
108     if(pparam) {
109         EVP_PKEY_free(pparam);
110     }
111
112     if(ctx) {
113         EVP_PKEY_CTX_free(ctx);
114     }
115
116     return CKM_CRYPTO_CREATEKEY_SUCCESS;
117 }
118
119
120 int CryptoService::createKeyPairDSA(const int size, // size in bits [1024, 2048, 3072, 4096]
121                 KeyImpl &createdPrivateKey,  // returned value
122                 KeyImpl &createdPublicKey)  // returned value
123 {
124         EVP_PKEY_CTX *pctx = NULL;
125         EVP_PKEY_CTX *kctx = NULL;
126         EVP_PKEY *pkey = NULL;
127         EVP_PKEY *pparam = NULL;
128
129         // check the parameters of functions
130         if(size != 1024 && size !=2048 && size !=3072 && size != 4096) {
131                 LogError("Error in DSA input size");
132                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in DSA input size");
133         }
134
135         // check the parameters of functions
136         if(&createdPrivateKey == NULL) {
137                 LogError("Error in createdPrivateKey value");
138                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
139         }
140
141         // check the parameters of functions
142         if(&createdPublicKey == NULL) {
143                 LogError("Error in createdPrivateKey value");
144                 ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
145         }
146
147         Try {
148                 /* Create the context for generating the parameters */
149                 if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL))) {
150                         LogError("Error in EVP_PKEY_CTX_new_id function");
151                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
152                 }
153
154                 if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
155                         LogError("Error in EVP_PKEY_paramgen_init function");
156                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
157                 }
158
159                 if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, size)) {
160                         LogError("Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
161                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
162                 }
163
164                 /* Generate parameters */
165                 if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
166                         LogError("Error in EVP_PKEY_paramgen function");
167                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
168                 }
169
170                 // Start to generate key
171                 if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
172                         LogError("Error in EVP_PKEY_CTX_new function");
173                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
174                 }
175
176                 if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
177                         LogError("Error in EVP_PKEY_keygen_init function");
178                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
179                 }
180
181                 /* Generate the key */
182                 if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
183                         LogError("Error in EVP_PKEY_keygen function");
184                         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
185                 }
186         }
187         Catch(CryptoService::Exception::opensslError)
188         {
189                 if(pkey) {
190                         EVP_PKEY_free(pkey);
191                 }
192
193                 if(pparam) {
194                         EVP_PKEY_free(pparam);
195                 }
196
197                 if(pctx) {
198                         EVP_PKEY_CTX_free(pctx);
199                 }
200
201                 if(kctx) {
202                         EVP_PKEY_CTX_free(kctx);
203                 }
204
205                 ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
206         }
207
208         KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
209
210         createdPrivateKey = KeyImpl(ptr, KeyType::KEY_DSA_PRIVATE);
211         createdPublicKey = KeyImpl(ptr, KeyType::KEY_DSA_PUBLIC);
212
213         if(pparam) {
214                 EVP_PKEY_free(pparam);
215         }
216
217         if(pctx) {
218                 EVP_PKEY_CTX_free(pctx);
219         }
220
221         if(kctx) {
222                 EVP_PKEY_CTX_free(kctx);
223         }
224
225         return CKM_CRYPTO_CREATEKEY_SUCCESS;
226 }
227
228
229 int CryptoService::createKeyPairECDSA(ElipticCurve type,
230         KeyImpl &createdPrivateKey,  // returned value
231         KeyImpl &createdPublicKey)  // returned value
232 {
233     int ecCurve = NOT_DEFINED;
234     EVP_PKEY_CTX *pctx = NULL;
235     EVP_PKEY_CTX *kctx = NULL;
236     EVP_PKEY *pkey = NULL;
237     EVP_PKEY *pparam = NULL;
238
239     switch(type) {
240     case ElipticCurve::prime192v1:
241         ecCurve = NID_X9_62_prime192v1;
242         break;
243     case ElipticCurve::prime256v1:
244         ecCurve = NID_X9_62_prime256v1;
245         break;
246     case ElipticCurve::secp384r1:
247         ecCurve = NID_secp384r1;
248         break;
249     default:
250         LogError("Error in EC type");
251         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in EC type");
252     }
253
254     // check the parameters of functions
255     if(&createdPrivateKey == NULL) {
256         LogError("Error in createdPrivateKey value");
257         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
258     }
259
260     // check the parameters of functions
261     if(&createdPublicKey == NULL) {
262         LogError("Error in createdPrivateKey value");
263         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
264     }
265
266     Try {
267         /* Create the context for generating the parameters */
268         if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) {
269             LogError("Error in EVP_PKEY_CTX_new_id function");
270             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
271         }
272
273         if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
274             LogError("Error in EVP_PKEY_paramgen_init function");
275             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
276         }
277
278         if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecCurve)) {
279             LogError("Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
280             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
281         }
282
283         /* Generate parameters */
284         if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
285             LogError("Error in EVP_PKEY_paramgen function");
286             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
287         }
288
289         // Start to generate key
290         if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
291             LogError("Error in EVP_PKEY_CTX_new function");
292             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
293         }
294
295         if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
296             LogError("Error in EVP_PKEY_keygen_init function");
297             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
298         }
299
300         /* Generate the key */
301         if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
302             LogError("Error in EVP_PKEY_keygen function");
303             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
304         }
305     } Catch(CryptoService::Exception::opensslError) {
306         if(pkey) {
307             EVP_PKEY_free(pkey);
308         }
309
310         if(pparam) {
311             EVP_PKEY_free(pparam);
312         }
313
314         if(pctx) {
315             EVP_PKEY_CTX_free(pctx);
316         }
317
318         if(kctx) {
319             EVP_PKEY_CTX_free(kctx);
320         }
321
322         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
323     }
324
325     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
326
327     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PRIVATE);
328     createdPublicKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PUBLIC);
329
330     if(pparam) {
331         EVP_PKEY_free(pparam);
332     }
333
334     if(pctx) {
335         EVP_PKEY_CTX_free(pctx);
336     }
337
338     if(kctx) {
339         EVP_PKEY_CTX_free(kctx);
340     }
341
342     return CKM_CRYPTO_CREATEKEY_SUCCESS;
343 }
344
345 } // namespace SW
346 } // namespace Crypto
347 } // namespace CKM