tizen 2.4 release
[framework/security/key-manager.git] / src / manager / service / CryptoService.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 <CryptoService.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 #define RAND_READ_BYTES 32
32
33 namespace CKM {
34
35 CryptoService::CryptoService(){
36 }
37
38 CryptoService::~CryptoService(){
39 }
40
41
42
43 void CryptoService::initialize() {
44     // try to initialize using ERR_load_crypto_strings and OpenSSL_add_all_algorithms
45     ERR_load_crypto_strings();
46     OpenSSL_add_all_algorithms();
47
48     // initialize entropy
49     std::ifstream ifile(DEV_HW_RANDOM_FILE);
50
51     if (ifile.is_open()
52         && (RAND_READ_BYTES == RAND_load_file(DEV_HW_RANDOM_FILE, RAND_READ_BYTES)))
53         LogDebug("Success to read from [" << DEV_HW_RANDOM_FILE << "]");
54     else if (RAND_READ_BYTES == RAND_load_file(DEV_URANDOM_FILE, RAND_READ_BYTES))
55         LogDebug("Success to read from [" << DEV_URANDOM_FILE << "]");
56     else
57         ThrowMsg(CryptoService::Exception::Crypto_internal,
58             "Error in U_RAND_file_load");
59 }
60
61 const EVP_MD *CryptoService::getMdAlgo(const HashAlgorithm hashAlgo) {
62     const EVP_MD *md_algo=NULL;
63     switch(hashAlgo) {
64     case HashAlgorithm::NONE:
65         md_algo = NULL;
66         break;
67     case HashAlgorithm::SHA1:
68         md_algo = EVP_sha1();
69          break;
70     case HashAlgorithm::SHA256:
71          md_algo = EVP_sha256();
72          break;
73     case HashAlgorithm::SHA384:
74          md_algo = EVP_sha384();
75          break;
76     case HashAlgorithm::SHA512:
77          md_algo = EVP_sha512();
78          break;
79     default:
80         LogError("Error in hashAlgorithm value");
81         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in hashAlgorithm value");
82     }
83     return md_algo;
84 }
85
86 int CryptoService::getRsaPadding(const RSAPaddingAlgorithm padAlgo) {
87     int rsa_padding = -1;
88     switch(padAlgo) {
89     case RSAPaddingAlgorithm::NONE:
90         rsa_padding = RSA_NO_PADDING;
91         break;
92     case RSAPaddingAlgorithm::PKCS1:
93         rsa_padding = RSA_PKCS1_PADDING;
94         break;
95     case RSAPaddingAlgorithm::X931:
96         rsa_padding = RSA_X931_PADDING;
97         break;
98     default:
99         LogError("Error in RSAPaddingAlgorithm value");
100         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in RSAPaddingAlgorithm value");
101     }
102     return rsa_padding;
103 }
104
105 int CryptoService::createKeyPairRSA(const int size, // size in bits [1024, 2048, 4096]
106         KeyImpl &createdPrivateKey,  // returned value
107         KeyImpl &createdPublicKey)  // returned value
108 {
109     EVP_PKEY_CTX *ctx = NULL;
110     EVP_PKEY *pkey = NULL;
111     EVP_PKEY *pparam = NULL;
112
113     // check the parameters of functions
114     if(size != 1024 && size !=2048 && size != 4096) {
115         LogError("Error in RSA input size");
116         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in RSA input size");
117     }
118
119     // check the parameters of functions
120     if(&createdPrivateKey == NULL) {
121         LogError("Error in createdPrivateKey value");
122         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
123     }
124
125     // check the parameters of functions
126     if(&createdPublicKey == NULL) {
127         LogError("Error in createdPrivateKey value");
128         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
129     }
130
131     Try {
132         if(!(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL))) {
133             LogError("Error in EVP_PKEY_CTX_new_id function !!");
134             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function !!");
135         }
136
137         if(EVP_PKEY_keygen_init(ctx) <= 0) {
138             LogError("Error in EVP_PKEY_keygen_init function !!");
139             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function !!");
140         }
141
142         if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx,size) <= 0) {
143             LogError("Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
144             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
145         }
146
147         if(!EVP_PKEY_keygen(ctx, &pkey)) {
148             LogError("Error in EVP_PKEY_keygen function !!");
149             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function !!");
150         }
151     } Catch(CryptoService::Exception::opensslError) {
152         if(pkey) {
153             EVP_PKEY_free(pkey);
154         }
155
156         if(pparam) {
157             EVP_PKEY_free(pparam);
158         }
159
160         if(ctx) {
161             EVP_PKEY_CTX_free(ctx);
162         }
163
164         ReThrowMsg(CryptoService::Exception::opensslError,"Error in opensslError function !!");
165     }
166
167     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
168
169     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_RSA_PRIVATE);
170     createdPublicKey = KeyImpl(ptr, KeyType::KEY_RSA_PUBLIC);
171
172     if(pparam) {
173         EVP_PKEY_free(pparam);
174     }
175
176     if(ctx) {
177         EVP_PKEY_CTX_free(ctx);
178     }
179
180     return CKM_CRYPTO_CREATEKEY_SUCCESS;
181 }
182
183
184 int CryptoService::createKeyPairDSA(const int size, // size in bits [1024, 2048, 3072, 4096]
185         KeyImpl &createdPrivateKey,  // returned value
186         KeyImpl &createdPublicKey)  // returned value
187 {
188     EVP_PKEY_CTX *pctx = NULL;
189     EVP_PKEY_CTX *kctx = NULL;
190     EVP_PKEY *pkey = NULL;
191     EVP_PKEY *pparam = NULL;
192
193     // check the parameters of functions
194     if(size != 1024 && size !=2048 && size !=3072 && size != 4096) {
195         LogError("Error in DSA input size");
196         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in DSA input size");
197     }
198
199     // check the parameters of functions
200     if(&createdPrivateKey == NULL) {
201         LogError("Error in createdPrivateKey value");
202         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
203     }
204
205     // check the parameters of functions
206     if(&createdPublicKey == NULL) {
207         LogError("Error in createdPrivateKey value");
208         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
209     }
210
211     Try {
212         /* Create the context for generating the parameters */
213         if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL))) {
214             LogError("Error in EVP_PKEY_CTX_new_id function");
215             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
216         }
217
218         if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
219             LogError("Error in EVP_PKEY_paramgen_init function");
220             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
221         }
222
223         if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, size)) {
224             LogError("Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
225             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
226         }
227
228         /* Generate parameters */
229         if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
230             LogError("Error in EVP_PKEY_paramgen function");
231             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
232         }
233
234         // Start to generate key
235         if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
236             LogError("Error in EVP_PKEY_CTX_new function");
237             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
238         }
239
240         if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
241             LogError("Error in EVP_PKEY_keygen_init function");
242             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
243         }
244
245         /* Generate the key */
246         if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
247             LogError("Error in EVP_PKEY_keygen function");
248             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
249         }
250     }
251     Catch(CryptoService::Exception::opensslError)
252     {
253         if(pkey) {
254             EVP_PKEY_free(pkey);
255         }
256
257         if(pparam) {
258             EVP_PKEY_free(pparam);
259         }
260
261         if(pctx) {
262             EVP_PKEY_CTX_free(pctx);
263         }
264
265         if(kctx) {
266             EVP_PKEY_CTX_free(kctx);
267         }
268
269         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
270     }
271
272     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
273
274     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_DSA_PRIVATE);
275     createdPublicKey = KeyImpl(ptr, KeyType::KEY_DSA_PUBLIC);
276
277     if(pparam) {
278         EVP_PKEY_free(pparam);
279     }
280
281     if(pctx) {
282         EVP_PKEY_CTX_free(pctx);
283     }
284
285     if(kctx) {
286         EVP_PKEY_CTX_free(kctx);
287     }
288
289     return CKM_CRYPTO_CREATEKEY_SUCCESS;
290 }
291
292
293 int CryptoService::createKeyPairECDSA(ElipticCurve type,
294         KeyImpl &createdPrivateKey,  // returned value
295         KeyImpl &createdPublicKey)  // returned value
296 {
297     int ecCurve = NOT_DEFINED;
298     EVP_PKEY_CTX *pctx = NULL;
299     EVP_PKEY_CTX *kctx = NULL;
300     EVP_PKEY *pkey = NULL;
301     EVP_PKEY *pparam = NULL;
302
303     switch(type) {
304     case ElipticCurve::prime192v1:
305         ecCurve = NID_X9_62_prime192v1;
306         break;
307     case ElipticCurve::prime256v1:
308         ecCurve = NID_X9_62_prime256v1;
309         break;
310     case ElipticCurve::secp384r1:
311         ecCurve = NID_secp384r1;
312         break;
313     default:
314         LogError("Error in EC type");
315         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in EC type");
316     }
317
318     // check the parameters of functions
319     if(&createdPrivateKey == NULL) {
320         LogError("Error in createdPrivateKey value");
321         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
322     }
323
324     // check the parameters of functions
325     if(&createdPublicKey == NULL) {
326         LogError("Error in createdPrivateKey value");
327         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
328     }
329
330     Try {
331         /* Create the context for generating the parameters */
332         if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) {
333             LogError("Error in EVP_PKEY_CTX_new_id function");
334             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
335         }
336
337         if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
338             LogError("Error in EVP_PKEY_paramgen_init function");
339             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
340         }
341
342         if(EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecCurve)) {
343             LogError("Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
344             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
345         }
346
347         /* Generate parameters */
348         if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
349             LogError("Error in EVP_PKEY_paramgen function");
350             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
351         }
352
353         // Start to generate key
354         if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
355             LogError("Error in EVP_PKEY_CTX_new function");
356             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
357         }
358
359         if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
360             LogError("Error in EVP_PKEY_keygen_init function");
361             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
362         }
363
364         /* Generate the key */
365         if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
366             LogError("Error in EVP_PKEY_keygen function");
367             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
368         }
369     } Catch(CryptoService::Exception::opensslError) {
370         if(pkey) {
371             EVP_PKEY_free(pkey);
372         }
373
374         if(pparam) {
375             EVP_PKEY_free(pparam);
376         }
377
378         if(pctx) {
379             EVP_PKEY_CTX_free(pctx);
380         }
381
382         if(kctx) {
383             EVP_PKEY_CTX_free(kctx);
384         }
385
386         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
387     }
388
389     KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
390
391     createdPrivateKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PRIVATE);
392     createdPublicKey = KeyImpl(ptr, KeyType::KEY_ECDSA_PUBLIC);
393
394     if(pparam) {
395         EVP_PKEY_free(pparam);
396     }
397
398     if(pctx) {
399         EVP_PKEY_CTX_free(pctx);
400     }
401
402     if(kctx) {
403         EVP_PKEY_CTX_free(kctx);
404     }
405
406     return CKM_CRYPTO_CREATEKEY_SUCCESS;
407 }
408
409 int CryptoService::createSignature(const KeyImpl &privateKey,
410         const RawBuffer &message,
411         const HashAlgorithm hashAlgo,
412         const RSAPaddingAlgorithm padAlgo,
413         RawBuffer &signature)
414 {
415     int retCode = CKM_API_SUCCESS;
416     int rsa_padding = NOT_DEFINED;
417     const EVP_MD *md_algo = NULL;
418
419     md_algo = getMdAlgo(hashAlgo);
420
421
422     if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) &&
423        (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) &&
424        (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE))
425     {
426         LogError("Error in private key type");
427         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
428     }
429
430     if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) {
431         rsa_padding = getRsaPadding(padAlgo);
432     }
433
434     auto shrPKey = privateKey.getEvpShPtr();
435     if (NULL == shrPKey.get()) {
436         LogError("Error in EVP_PKEY_keygen function");
437         ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
438     }
439
440     if(md_algo == NULL) {
441         retCode = signMessage(shrPKey.get(), message, rsa_padding, signature);
442     }else {
443         retCode = digestSignMessage(shrPKey.get(),message, md_algo, rsa_padding, signature);
444     }
445
446     return retCode;
447 }
448
449 int CryptoService::signMessage(EVP_PKEY *privKey,
450         const RawBuffer &message,
451         const int rsa_padding,
452         RawBuffer &signature)
453 {
454     int retCode = CKM_API_SUCCESS;
455     EVP_PKEY_CTX *pctx = NULL;
456
457     Try {
458         if(!(pctx = EVP_PKEY_CTX_new(privKey, NULL))) {
459             LogError("Error in EVP_PKEY_CTX_new function");
460             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
461         }
462
463         if(EVP_PKEY_sign_init(pctx) != EVP_SUCCESS) {
464             LogError("Error in EVP_PKEY_sign_init function");
465             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_sign_init function");
466         }
467
468         /* Set padding algorithm */
469         if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
470             if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
471                 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
472                 ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
473             }
474         }
475
476         /* Finalize the Sign operation */
477         /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the
478          * signature. Length is returned in slen */
479         size_t slen;
480         if(EVP_SUCCESS != EVP_PKEY_sign(pctx, NULL, &slen, message.data(), message.size())) {
481             LogError("Error in EVP_PKEY_sign function");
482             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_sign function");
483         }
484
485         /* Allocate memory for the signature based on size in slen */
486         unsigned char sig[slen];
487
488         if(EVP_SUCCESS == EVP_PKEY_sign(pctx, sig, &slen, message.data(), message.size())) {
489             // Set value to return RawData
490             signature.assign(sig, sig+slen);
491             retCode = CKM_API_SUCCESS;
492         }else {
493             LogError("Error in EVP_PKEY_sign function: check input parameter");
494             retCode = CKM_API_ERROR_INPUT_PARAM;
495         }
496     } Catch(CryptoService::Exception::opensslError) {
497         if(pctx != NULL) {
498             EVP_PKEY_CTX_free(pctx);
499         }
500         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
501     }
502
503     if(pctx != NULL) {
504         EVP_PKEY_CTX_free(pctx);
505     }
506     return retCode;
507 }
508
509 int CryptoService::digestSignMessage(EVP_PKEY *privKey,
510         const RawBuffer &message,
511         const EVP_MD *md_algo,
512         const int rsa_padding,
513         RawBuffer &signature)
514 {
515     EVP_MD_CTX *mdctx = NULL;
516     EVP_PKEY_CTX *pctx = NULL;
517
518     Try {
519         // Create the Message Digest Context
520         if(!(mdctx = EVP_MD_CTX_create())) {
521             LogError("Error in EVP_MD_CTX_create function");
522             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_MD_CTX_create function");
523         }
524
525         if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, &pctx, md_algo, NULL, privKey)) {
526             LogError("Error in EVP_DigestSignInit function");
527             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignInit function");
528         }
529
530         /* Set padding algorithm */
531         if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) {
532             if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
533                 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
534                 ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
535             }
536         }
537
538         /* Call update with the message */
539         if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx, message.data(), message.size())) {
540             LogError("Error in EVP_DigestSignUpdate function");
541             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignUpdate function");
542         }
543
544         /* Finalize the DigestSign operation */
545         /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
546          * signature. Length is returned in slen */
547         size_t slen;
548         if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, &slen)) {
549             LogError("Error in EVP_DigestSignFinal function");
550             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignFinal function");
551         }
552         /* Allocate memory for the signature based on size in slen */
553         unsigned char sig[slen];
554
555         /* Obtain the signature */
556         if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, sig, &slen)) {
557             LogError("Error in EVP_DigestSignFinal function");
558             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignFinal function");
559         }
560
561         // Set value to return RawData
562         signature.assign(sig, sig+slen);
563     } Catch(CryptoService::Exception::opensslError) {
564         if(mdctx != NULL) {
565             EVP_MD_CTX_destroy(mdctx);
566         }
567
568         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
569     }
570
571     if(mdctx != NULL) {
572         EVP_MD_CTX_destroy(mdctx);
573     }
574
575     return CKM_API_SUCCESS;
576 }
577
578 int CryptoService::verifySignature(const KeyImpl &publicKey,
579         const RawBuffer &message,
580         const RawBuffer &signature,
581         const HashAlgorithm hashAlgo,
582         const RSAPaddingAlgorithm padAlgo)
583 {
584     int rsa_padding = NOT_DEFINED;
585     const EVP_MD *md_algo;
586     int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
587
588     md_algo = getMdAlgo(hashAlgo);
589
590
591     if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) &&
592        (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) &&
593        (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC))
594     {
595         LogError("Error in private key type");
596         ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
597     }
598
599     if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) {
600         rsa_padding = getRsaPadding(padAlgo);
601     }
602
603     auto shrPKey = publicKey.getEvpShPtr();
604     if (NULL == shrPKey.get()) {
605         LogError("Error in getEvpShPtr function");
606         ThrowMsg(CryptoService::Exception::opensslError, "Error in getEvpShPtr function");
607     }
608
609     if(md_algo == NULL) {
610         retCode = verifyMessage(shrPKey.get(), message, signature, rsa_padding);
611     }else {
612         retCode = digestVerifyMessage(shrPKey.get(),message, signature, md_algo, rsa_padding);
613     }
614
615     return retCode;
616 }
617
618 int CryptoService::verifyMessage(EVP_PKEY *pubKey,
619         const RawBuffer &message,
620         const RawBuffer &signature,
621         const int rsa_padding)
622 {
623     int ret = CKM_API_ERROR_VERIFICATION_FAILED;
624     EVP_PKEY_CTX *pctx = NULL;
625
626     Try {
627         if(!(pctx = EVP_PKEY_CTX_new(pubKey, NULL))) {
628             LogError("Error in EVP_PKEY_CTX_new function");
629             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
630         }
631
632         if(EVP_PKEY_verify_init(pctx) != EVP_SUCCESS) {
633             LogError("Error in EVP_PKEY_verify_init function");
634             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_verify_init function");
635         }
636
637         /* Set padding algorithm  */
638         if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
639             if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
640                 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
641                 ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
642             }
643         }
644
645         if(EVP_SUCCESS == EVP_PKEY_verify(pctx, signature.data(), signature.size(), message.data(), message.size())) {
646             ret = CKM_API_SUCCESS;
647         }else {
648             LogError("EVP_PKEY_verify Failed");
649             ret = CKM_API_ERROR_VERIFICATION_FAILED;
650         }
651     } Catch(CryptoService::Exception::opensslError) {
652         if(pctx != NULL) {
653             EVP_PKEY_CTX_free(pctx);
654         }
655         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
656     }
657
658     if(pctx != NULL) {
659         EVP_PKEY_CTX_free(pctx);
660     }
661
662     return ret;
663 }
664
665 int CryptoService::digestVerifyMessage(EVP_PKEY *pubKey,
666         const RawBuffer &message,
667         const RawBuffer &signature,
668         const EVP_MD *md_algo,
669         const int rsa_padding)
670 {
671     int ret = CKM_API_ERROR_VERIFICATION_FAILED;
672     EVP_MD_CTX *mdctx = NULL;
673     EVP_PKEY_CTX *pctx = NULL;
674
675     Try {
676         /* Create the Message Digest Context */
677         if(!(mdctx = EVP_MD_CTX_create())) {
678             LogError("Error in EVP_MD_CTX_create function");
679             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_MD_CTX_create function");
680         }
681
682         if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, &pctx, md_algo, NULL, pubKey)) {
683             LogError("Error in EVP_DigestVerifyInit function");
684             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestVerifyInit function");
685         }
686
687         if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) {
688             if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) {
689                 LogError("Error in EVP_PKEY_CTX_set_rsa_padding function");
690                 ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function");
691             }
692         }
693
694         if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx, message.data(), message.size()) ) {
695             LogError("Error in EVP_DigestVerifyUpdate function");
696             ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestVerifyUpdate function");
697         }
698
699         if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx, const_cast<unsigned char*>(signature.data()), signature.size()) ) {
700             ret = CKM_API_SUCCESS;
701         }else {
702             LogError("EVP_PKEY_verify Failed");
703             ret = CKM_API_ERROR_VERIFICATION_FAILED;
704         }
705     } Catch(CryptoService::Exception::opensslError) {
706         if(mdctx != NULL) {
707             EVP_MD_CTX_destroy(mdctx);
708         }
709         ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
710     }
711
712     if(mdctx != NULL) {
713         EVP_MD_CTX_destroy(mdctx);
714     }
715
716     return ret;
717 }
718 }