revise logging and coding style
[platform/core/connectivity/nfc-manager-neard.git] / common / net_nfc_util_openssl.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <openssl/evp.h>
19 #include <openssl/engine.h>
20 #include <openssl/pkcs12.h>
21 #include <openssl/pem.h>
22
23 #include "net_nfc_typedef_internal.h"
24 #include "net_nfc_debug_internal.h"
25 #include "net_nfc_util_internal.h"
26 #include "net_nfc_util_openssl_internal.h"
27
28 //static X509 *_load_certificate_from_file(const char *file)
29 //{
30 //      X509 *x509 = NULL;
31 //      BIO *cert = NULL;
32 //
33 //      cert = BIO_new(BIO_s_file());
34 //      if (cert != NULL)
35 //      {
36 //              if (BIO_read_filename(cert, file) > 0)
37 //              {
38 //                      x509 = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
39 //              }
40 //
41 //              BIO_free(cert);
42 //      }
43 //
44 //      return x509;
45 //}
46
47 static X509 *_load_certificate_from_mem(int format, uint8_t *buffer,
48         uint32_t length, char *password)
49 {
50         X509 *x509 = NULL;
51         BIO *mem = NULL;
52
53         mem = BIO_new_mem_buf(buffer, length);
54         if (mem != NULL)
55         {
56                 switch (format)
57                 {
58                 case 0 :
59                         x509 = d2i_X509_bio(mem, NULL);
60                         break;
61
62                 case 1 :
63                         x509 = PEM_read_bio_X509(mem, NULL, NULL, NULL);
64                         break;
65
66                 case 2 :
67                         {
68                                 PKCS12 *p12 = d2i_PKCS12_bio(mem, NULL);
69                                 PKCS12_parse(p12, password, NULL, &x509, NULL);
70                                 PKCS12_free(p12);
71                         }
72                         break;
73                 }
74
75                 BIO_free(mem);
76         }
77         else
78         {
79                 NFC_ERR("X509_LOOKUP_load_file failed");
80         }
81
82         return x509;
83 }
84
85 //int net_nfc_util_openssl_verify_certificate(const char* certfile, const char* CAfile)
86 //{
87 //      int ret = 0;
88 //      X509_STORE *cert_ctx = NULL;
89 //      X509_LOOKUP *lookup = NULL;
90 //
91 //      cert_ctx = X509_STORE_new();
92 //      if (cert_ctx != NULL)
93 //      {
94 //              OpenSSL_add_all_algorithms();
95 //
96 //              lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
97 //              if (lookup != NULL)
98 //              {
99 //                      if (X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM) == true)
100 //                      {
101 //                              lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
102 //                              if (lookup != NULL)
103 //                              {
104 //                                      X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
105 //
106 //                                      ret = _verify_certificate_file(cert_ctx, certfile);
107 //                              }
108 //                              else
109 //                              {
110 //                                      NFC_ERR("X509_STORE_add_lookup failed");
111 //                              }
112 //                      }
113 //                      else
114 //                      {
115 //                              NFC_ERR("X509_LOOKUP_load_file failed");
116 //                      }
117 //              }
118 //              else
119 //              {
120 //                      NFC_ERR("X509_STORE_add_lookup failed");
121 //              }
122 //
123 //              X509_STORE_free(cert_ctx);
124 //      }
125 //      else
126 //      {
127 //              NFC_ERR("X509_STORE_new failed");
128 //      }
129 //
130 //      return ret;
131 //}
132
133 net_nfc_openssl_verify_context_s *net_nfc_util_openssl_init_verify_certificate(void)
134 {
135         net_nfc_openssl_verify_context_s *result = NULL;
136
137         _net_nfc_util_alloc_mem(result, sizeof(net_nfc_openssl_verify_context_s));
138         if (result != NULL)
139         {
140                 result->store = X509_STORE_new();
141                 if (result->store != NULL)
142                         OpenSSL_add_all_algorithms();
143                 else
144                         NFC_ERR("X509_STORE_new failed");
145         }
146         else
147         {
148                 NFC_ERR("alloc failed [%d]", sizeof(net_nfc_openssl_verify_context_s));
149         }
150
151         return result;
152 }
153
154 void net_nfc_util_openssl_release_verify_certificate(
155         net_nfc_openssl_verify_context_s *context)
156 {
157         if (context != NULL)
158         {
159                 if (context->signer_cert != NULL)
160                         X509_free(context->signer_cert);
161
162                 if (context->store != NULL)
163                         X509_STORE_free(context->store);
164
165                 _net_nfc_util_free_mem(context);
166         }
167 }
168
169 bool net_nfc_util_openssl_add_certificate_of_signer(
170         net_nfc_openssl_verify_context_s *context, uint8_t *buffer, uint32_t length)
171 {
172         bool result = false;
173
174         if (context->signer_cert != NULL)
175         {
176                 X509_free(context->signer_cert);
177                 context->signer_cert = NULL;
178         }
179
180         context->signer_cert = _load_certificate_from_mem(1, buffer, length, NULL);
181         if (context->signer_cert != NULL)
182                 result = true;
183
184         return result;
185 }
186
187 bool net_nfc_util_openssl_add_certificate_of_ca(
188         net_nfc_openssl_verify_context_s *context, uint8_t *buffer, uint32_t length)
189 {
190         X509 *x509 = NULL;
191         bool result = false;
192
193         x509 = _load_certificate_from_mem(1, buffer, length, NULL);
194         if (x509 != NULL)
195         {
196                 if (X509_STORE_add_cert(context->store, x509))
197                         result = true;
198         }
199
200         return result;
201 }
202
203 int net_nfc_util_openssl_verify_certificate(
204         net_nfc_openssl_verify_context_s *context)
205 {
206         int result = 0;
207         X509_STORE_CTX *store_ctx = NULL;
208
209         store_ctx = X509_STORE_CTX_new();
210         if (store_ctx != NULL)
211         {
212                 X509_STORE_set_flags(context->store, 0);
213                 if (X509_STORE_CTX_init(store_ctx, context->store, context->signer_cert, 0) == true)
214                         result = X509_verify_cert(store_ctx);
215                 else
216                         NFC_ERR("X509_STORE_CTX_init failed");
217
218                 X509_STORE_CTX_free(store_ctx);
219         }
220         else
221         {
222                 NFC_ERR("X509_STORE_CTX_new failed");
223         }
224
225         return result;
226 }
227
228 int _password_callback(char *buf, int bufsiz, int verify, void *data)
229 {
230         int res = 0;
231         const char *password = (char *)data;
232
233         if (password)
234         {
235                 res = strlen(password);
236                 if (res > bufsiz)
237                         res = bufsiz;
238                 memcpy(buf, password, res);
239                 return res;
240         }
241
242         return res;
243 }
244
245 static int _load_pkcs12(BIO *in, const char *password, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
246 {
247         int ret = 0;
248         PKCS12 *p12 = NULL;
249
250         if ((p12 = d2i_PKCS12_bio(in, NULL)) != NULL)
251         {
252                 if (PKCS12_verify_mac(p12, password, strlen(password)) == true)
253                         ret = PKCS12_parse(p12, password, pkey, cert, ca);
254                 else
255                         NFC_ERR("Mac verify error (wrong password?) in PKCS12 file");
256
257                 PKCS12_free(p12);
258         }
259         else
260         {
261                 NFC_ERR("Error loading PKCS12 file");
262         }
263
264         return ret;
265 }
266
267 EVP_PKEY *_load_key(const char *file, int format, const char *pass, ENGINE *e)
268 {
269         BIO *key = NULL;
270         EVP_PKEY *pkey = NULL;
271
272         if (NULL == file)
273         {
274                 NFC_ERR("no keyfile specified\n");
275                 return pkey;
276         }
277
278         if (OPENSSL_FORMAT_ENGINE == format)
279         {
280                 if (e != NULL)
281                 {
282                         pkey = ENGINE_load_private_key(e, file, NULL/*ui_method*/, (void *)pass);
283                         if (!pkey)
284                                 NFC_ERR("cannot load key from engine");
285                 }
286                 else
287                 {
288                         NFC_ERR("no engine specified");
289                 }
290         }
291         else
292         {
293                 if ((key = BIO_new(BIO_s_file())) != NULL)
294                 {
295                         if (BIO_read_filename(key,file) > 0)
296                         {
297                                 switch (format)
298                                 {
299                                 case OPENSSL_FORMAT_ASN1 :
300                                         pkey = d2i_PrivateKey_bio(key, NULL);
301                                         break;
302
303                                 case OPENSSL_FORMAT_PEM :
304                                         pkey = PEM_read_bio_PrivateKey(key, NULL,
305                                                 (pem_password_cb *)_password_callback, (void *)pass);
306                                         break;
307
308                                 case OPENSSL_FORMAT_PKCS12 :
309                                         if (_load_pkcs12(key, pass, &pkey, NULL, NULL) == false)
310                                                 NFC_ERR("_load_pkcs12 failed");
311                                         break;
312
313                                 case OPENSSL_FORMAT_MSBLOB :
314                                         pkey = b2i_PrivateKey_bio(key);
315                                         break;
316
317                                 case OPENSSL_FORMAT_PVK :
318                                         pkey = b2i_PVK_bio(key, (pem_password_cb *)_password_callback,
319                                                 (void *)pass);
320                                         break;
321
322                                 default :
323                                         NFC_ERR("bad input format specified for key file");
324                                         break;
325                                 }
326                         }
327                         else
328                         {
329                                 NFC_ERR("Error opening %s", file);
330                         }
331
332                         BIO_free(key);
333                 }
334                 else
335                 {
336                         NFC_ERR("BIO_new failed");
337                 }
338         }
339
340         return pkey;
341 }
342
343 EVP_PKEY *_load_pubkey(const char *file, int format,
344         const char *pass, ENGINE *e, const char *key_descrip)
345 {
346         BIO *key = NULL;
347         EVP_PKEY *pkey = NULL;
348
349         if (NULL == file)
350         {
351                 NFC_ERR("no keyfile specified");
352                 return pkey;
353         }
354
355         if (OPENSSL_FORMAT_ENGINE == format)
356         {
357                 if (e != NULL)
358                         pkey = ENGINE_load_public_key(e, file, NULL/*ui_method*/, (void *)pass);
359                 else
360                         NFC_ERR("no engine specified");
361         }
362         else
363         {
364                 if ((key = BIO_new(BIO_s_file())) != NULL)
365                 {
366                         if (BIO_read_filename(key,file) <= 0)
367                         {
368                                 switch (format)
369                                 {
370                                 case OPENSSL_FORMAT_ASN1 :
371                                         pkey = d2i_PUBKEY_bio(key, NULL);
372                                         break;
373
374                                 case OPENSSL_FORMAT_ASN1RSA :
375                                         {
376                                                 RSA *rsa;
377                                                 rsa = d2i_RSAPublicKey_bio(key, NULL);
378                                                 if (rsa)
379                                                 {
380                                                         pkey = EVP_PKEY_new();
381                                                         if (pkey)
382                                                                 EVP_PKEY_set1_RSA(pkey, rsa);
383                                                         RSA_free(rsa);
384                                                 }
385                                                 else
386                                                         pkey = NULL;
387                                         }
388                                         break;
389
390                                 case OPENSSL_FORMAT_PEMRSA :
391                                         {
392                                                 RSA *rsa;
393                                                 rsa = PEM_read_bio_RSAPublicKey(key, NULL,
394                                                         (pem_password_cb *)_password_callback, (void *)pass);
395                                                 if (rsa)
396                                                 {
397                                                         pkey = EVP_PKEY_new();
398                                                         if (pkey)
399                                                                 EVP_PKEY_set1_RSA(pkey, rsa);
400                                                         RSA_free(rsa);
401                                                 }
402                                                 else
403                                                         pkey = NULL;
404                                         }
405                                         break;
406
407                                 case OPENSSL_FORMAT_PEM :
408                                         pkey = PEM_read_bio_PUBKEY(key, NULL,
409                                                 (pem_password_cb *)_password_callback, (void *)pass);
410                                         break;
411
412                                 case OPENSSL_FORMAT_MSBLOB :
413                                         pkey = b2i_PublicKey_bio(key);
414                                         break;
415
416                                 default :
417                                         NFC_ERR("bad input format specified for key file");
418                                         break;
419                                 }
420                         }
421                         else
422                         {
423                                 NFC_ERR("Error opening %s %s", key_descrip, file);
424                         }
425
426                         BIO_free(key);
427                 }
428                 else
429                 {
430                         NFC_ERR("BIO_new failed");
431                 }
432         }
433
434         return pkey;
435 }
436
437 int net_nfc_util_openssl_sign_buffer(uint32_t type, uint8_t *buffer,
438         uint32_t length, char *key_file, char *password, uint8_t *sign, uint32_t *sign_len)
439 {
440         EVP_PKEY *pkey;
441         ENGINE *engine;
442         int result = 0;
443         const EVP_MD *md = NULL;
444
445         OpenSSL_add_all_algorithms();
446
447         /* md context */
448         EVP_MD_CTX ctx = { 0, };
449         EVP_PKEY_CTX *pctx = NULL;
450
451         switch (type)
452         {
453         case 0 :
454                 result = 0;
455                 return result;
456
457                 /* RSASSA-PSS, RSASSA-PKCS1-v1_5 */
458         case 1 :
459         case 2 :
460                 /* md */
461                 md = EVP_get_digestbyname("sha1");
462
463                 /* engine */
464                 engine = ENGINE_get_default_RSA();
465                 break;
466
467                 /* DSA */
468         case 3 :
469                 /* md */
470                 //md = EVP_get_digestbyname("sha1");
471                 /* engine */
472                 engine = ENGINE_get_default_DSA();
473                 break;
474
475                 /* ECDSA */
476         case 4 :
477                 /* md */
478                 md = EVP_get_digestbyname("sha1");
479
480                 /* engine */
481                 engine = ENGINE_get_default_ECDSA();
482                 break;
483
484         default :
485                 result = -1;
486                 return result;
487         }
488
489         /* pkey */
490         pkey = _load_key(key_file, OPENSSL_FORMAT_PKCS12, password, NULL);
491
492         EVP_DigestSignInit(&ctx, &pctx, md, engine, pkey);
493         EVP_DigestSignUpdate(&ctx, buffer, length);
494         EVP_DigestSignFinal(&ctx, sign, sign_len);
495
496         return result;
497 }
498
499 int net_nfc_util_openssl_verify_signature(uint32_t type, uint8_t *buffer,
500         uint32_t length, uint8_t *cert, uint32_t cert_len, uint8_t *sign, uint32_t sign_len)
501 {
502         EVP_PKEY *pkey;
503         int result = 0;
504         ENGINE *engine;
505         const EVP_MD *md = NULL;
506
507         OpenSSL_add_all_algorithms();
508
509         /* md context */
510         EVP_MD_CTX ctx = { 0, };
511         EVP_PKEY_CTX *pctx = NULL;
512
513         switch (type)
514         {
515         case 0 :
516                 result = 0;
517                 return result;
518
519                 /* RSASSA-PSS, RSASSA-PKCS1-v1_5 */
520         case 1 :
521         case 2 :
522                 /* md */
523                 md = EVP_get_digestbyname("sha1");
524
525                 /* engine */
526                 engine = ENGINE_get_default_RSA();
527                 break;
528
529                 /* DSA */
530         case 3 :
531                 /* md */
532                 //md = EVP_get_digestbyname("sha1");
533                 /* engine */
534                 engine = ENGINE_get_default_DSA();
535                 break;
536
537                 /* ECDSA */
538         case 4 :
539                 /* md */
540                 md = EVP_get_digestbyname("sha1");
541
542                 /* engine */
543                 engine = ENGINE_get_default_ECDSA();
544                 break;
545
546         default :
547                 result = -1;
548                 return result;
549         }
550
551         /* pkey */
552         X509 *x509 = _load_certificate_from_mem(0, cert, cert_len, NULL);
553         pkey = X509_PUBKEY_get(X509_get_X509_PUBKEY(x509));
554         X509_free(x509);
555
556         EVP_DigestVerifyInit(&ctx, &pctx, md, engine, pkey);
557         EVP_DigestVerifyUpdate(&ctx, buffer, length);
558         result = EVP_DigestVerifyFinal(&ctx, sign, sign_len);
559
560         NFC_DBG("EVP_DigestVerifyFinal returns %d", result);
561
562         return result;
563 }
564
565 #if 0
566 int net_nfc_util_get_cert_list_from_file(char *file_name, char *password, uint8_t **buffer, uint32_t *length, uint32_t *cert_count)
567 {
568         int result = 0;
569         BIO *bio = NULL;
570
571         bio = BIO_new(BIO_s_file());
572         if (bio != NULL)
573         {
574                 if (BIO_read_filename(bio, file_name) > 0)
575                 {
576                         STACK_OF(X509_INFO) *xis = NULL;
577
578                         if ((xis = PEM_X509_INFO_read_bio(bio, NULL, (pem_password_cb *)_password_callback, password)) != NULL)
579                         {
580                                 X509_INFO *xi;
581                                 int i;
582                                 uint32_t temp_len = 0;
583                                 uint8_t *temp_buf = NULL;
584                                 uint32_t offset = 0;
585                                 uint32_t count = 0;
586
587                                 for (i = 0; i < sk_X509_INFO_num(xis); i++)
588                                 {
589                                         xi = sk_X509_INFO_value(xis, i);
590                                         if (xi->x509)
591                                         {
592                                                 int32_t ret = 0;
593
594                                                 if ((ret = i2d_X509(xi->x509, NULL)) > 0)
595                                                 {
596                                                         temp_len += (ret + 2);
597                                                 }
598                                         }
599                                 }
600
601                                 NFC_DBG("count = %d, length = %d", sk_X509_INFO_num(xis), temp_len);
602                                 *length = temp_len;
603                                 _net_nfc_util_alloc_mem(*buffer, temp_len);
604
605                                 for (i = 0; i < sk_X509_INFO_num(xis); i++)
606                                 {
607                                         xi = sk_X509_INFO_value(xis, i);
608                                         if (xi->x509)
609                                         {
610                                                 temp_buf = NULL;
611
612                                                 if ((temp_len = i2d_X509(xi->x509, &temp_buf)) > 0)
613                                                 {
614                                                         *(uint16_t *)(*buffer + offset) = temp_len;
615                                                         offset += sizeof(uint16_t);
616
617                                                         memcpy(*buffer + offset, temp_buf, temp_len);
618                                                         offset += temp_len;
619
620                                                         count++;
621                                                 }
622                                         }
623                                 }
624
625                                 *cert_count = count;
626
627                                 sk_X509_INFO_pop_free(xis, X509_INFO_free);
628                         }
629                         else
630                         {
631                                 NFC_ERR("PEM_X509_INFO_read_bio failed");
632                         }
633                 }
634
635                 BIO_free(bio);
636         }
637
638         return result;
639 }
640 #endif
641
642 /* TODO : DER?? PEM?? */
643 int net_nfc_util_get_cert_list_from_file(char *file_name, char *password,
644         uint8_t **buffer, uint32_t *length, uint32_t *cert_count)
645 {
646         int result = 0;
647         BIO *bio = NULL;
648
649         bio = BIO_new(BIO_s_file());
650         if (bio != NULL)
651         {
652                 if (BIO_read_filename(bio, file_name) > 0)
653                 {
654                         EVP_PKEY *pkey = NULL;
655                         X509 *x509 = NULL;
656                         STACK_OF(X509) *ca = NULL;
657
658                         if (_load_pkcs12(bio, password, &pkey, &x509, &ca) != 0)
659                         {
660                                 int i;
661                                 int32_t ret = 0;
662                                 X509 *temp_x509;
663                                 uint32_t count = 0;
664                                 uint32_t offset = 0;
665                                 uint32_t temp_len = 0;
666                                 uint8_t *temp_buf = NULL;
667
668                                 if ((ret = i2d_X509(x509, NULL)) > 0)
669                                 {
670                                         temp_len += (ret + 2);
671                                 }
672
673                                 for (i = 0; i < sk_X509_num(ca); i++)
674                                 {
675                                         temp_x509 = sk_X509_value(ca, i);
676                                         if (temp_x509)
677                                         {
678                                                 if ((ret = i2d_X509(temp_x509, NULL)) > 0)
679                                                 {
680                                                         temp_len += (ret + 2);
681                                                 }
682                                         }
683                                 }
684
685                                 NFC_DBG("count = %d, length = %d", sk_X509_num(ca) + 1, temp_len);
686                                 *length = temp_len;
687                                 _net_nfc_util_alloc_mem(*buffer, temp_len);
688
689                                 if ((temp_len = i2d_X509(x509, &temp_buf)) > 0)
690                                 {
691                                         *(uint16_t *)(*buffer + offset) = temp_len;
692                                         offset += sizeof(uint16_t);
693
694                                         memcpy(*buffer + offset, temp_buf, temp_len);
695                                         offset += temp_len;
696
697                                         count++;
698                                 }
699
700                                 for (i = 0; i < sk_X509_num(ca); i++)
701                                 {
702                                         temp_x509 = sk_X509_value(ca, i);
703                                         if (temp_x509)
704                                         {
705                                                 temp_buf = NULL;
706
707                                                 if ((temp_len = i2d_X509(temp_x509, &temp_buf)) > 0)
708                                                 {
709                                                         *(uint16_t *)(*buffer + offset) = temp_len;
710                                                         offset += sizeof(uint16_t);
711
712                                                         memcpy(*buffer + offset, temp_buf, temp_len);
713                                                         offset += temp_len;
714
715                                                         count++;
716                                                 }
717                                         }
718                                 }
719
720                                 *cert_count = count;
721
722                                 sk_X509_pop_free(ca, X509_free);
723                         }
724                         else
725                         {
726                                 NFC_ERR("PEM_X509_INFO_read_bio failed");
727                         }
728                 }
729
730                 BIO_free(bio);
731         }
732
733         return result;
734 }
735
736 bool net_nfc_util_openssl_encode_base64(const uint8_t *buffer,
737         const uint32_t buf_len, char *result, uint32_t max_len, bool new_line_char)
738 {
739         BUF_MEM *bptr;
740         BIO *b64, *bmem;
741         bool ret = false;
742
743         RETV_IF(0 == buf_len, ret);
744         RETV_IF(NULL == buffer, ret);
745
746         b64 = BIO_new(BIO_f_base64());
747         bmem = BIO_new(BIO_s_mem());
748
749         if (false == new_line_char)
750                 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
751
752         b64 = BIO_push(b64, bmem);
753
754         BIO_write(b64, buffer, buf_len);
755         BIO_flush(b64);
756         BIO_get_mem_ptr(b64, &bptr);
757
758         if (max_len >= bptr->length)
759         {
760                 memcpy(result, bptr->data, bptr->length);
761                 result[bptr->length] = 0;
762                 ret = true;
763         }
764         else
765         {
766                 NFC_ERR("not enough result buffer");
767         }
768
769         BIO_free_all(b64);
770
771         return ret;
772 }
773
774 bool net_nfc_util_openssl_decode_base64(const char *buffer, uint8_t *result,
775         uint32_t *out_len, bool new_line_char)
776 {
777         char *temp;
778         bool ret = false;
779         unsigned int length = 0;
780
781         RETV_IF(NULL == buffer, ret);
782         RETV_IF((length = strlen(buffer)) == 0, ret);
783
784         _net_nfc_util_alloc_mem(temp, length);
785         if (temp != NULL)
786         {
787                 BIO *b64, *bmem;
788
789                 b64 = BIO_new(BIO_f_base64());
790                 bmem = BIO_new_mem_buf((void *)buffer, length);
791                 if (false == new_line_char)
792                         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
793                 bmem = BIO_push(b64, bmem);
794
795                 length = BIO_read(bmem, temp, length);
796
797                 BIO_free_all(bmem);
798
799                 if (*out_len > length)
800                 {
801                         *out_len = length;
802                         memcpy(result, temp, *out_len);
803                         ret = true;
804                 }
805                 else
806                 {
807                         NFC_ERR("not enough result buffer");
808                 }
809
810                 _net_nfc_util_free_mem(temp);
811         }
812         else
813         {
814                 NFC_ERR("alloc failed");
815         }
816
817         return ret;
818 }
819
820 bool net_nfc_util_openssl_digest(const char *algorithm, const uint8_t *buffer,
821         const uint32_t buf_len, uint8_t *result, uint32_t *out_len)
822 {
823         const EVP_MD *md;
824         bool ret = false;
825         unsigned char *temp;
826
827         RETV_IF(0 == buf_len, ret);
828         RETV_IF(buffer == NULL, ret);
829         RETV_IF(algorithm == NULL, ret);
830
831         OpenSSL_add_all_digests();
832
833         if ((md = EVP_get_digestbyname(algorithm)) != NULL)
834         {
835                 _net_nfc_util_alloc_mem(temp, EVP_MAX_MD_SIZE);
836                 if (temp != NULL)
837                 {
838                         EVP_MD_CTX mdCtx;
839                         unsigned int resultLen = 0;
840
841                         memset(temp, 0, EVP_MAX_MD_SIZE);
842
843                         EVP_DigestInit(&mdCtx, md);
844                         if (EVP_DigestUpdate(&mdCtx, buffer, buf_len) != 0)
845                                 NFC_ERR("EVP_DigestUpdate failed");
846
847                         EVP_DigestFinal(&mdCtx, temp, &resultLen);
848
849                         if (*out_len >= resultLen)
850                         {
851                                 *out_len = resultLen;
852                                 memcpy(result, temp, *out_len);
853                                 ret = true;
854                         }
855                         else
856                         {
857                                 NFC_ERR("not enough result buffer");
858                         }
859
860                         _net_nfc_util_free_mem(temp);
861                 }
862                 else
863                 {
864                         NFC_ERR("alloc failed");
865                 }
866         }
867         else
868         {
869                 NFC_ERR("EVP_get_digestbyname(\"%s\") returns NULL", algorithm);
870         }
871
872         return ret;
873 }