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