Replace deprecated readdir_r with readdir
[platform/core/security/drm-service-core-tizen.git] / tadcore / TADCInterface / TADC_IF.cpp
1 /*
2  * Copyright (c) 2000-2015 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 //#define _SLP_SIMUL
18 #include "TADC_IF.h"
19 #include "TADC_Util.h"
20 #include "TADC_ErrorCode.h"
21
22 #include "drm_intf_tapps.h"
23
24 #include <openssl/aes.h>
25 #include <openssl/sha.h>
26 #include <openssl/dh.h>
27 #include <openssl/bn.h>
28
29 //2011.03.08 to verify signature
30 #include <openssl/x509.h>
31 #include <openssl/x509_vfy.h>
32 #include <openssl/evp.h>
33 #include <openssl/rsa.h>
34 #include <openssl/err.h>
35 #include <openssl/pem.h>
36
37 #include <dirent.h>
38
39 #include <cerrno>
40 #include <memory>
41
42 #include "DUIDGenerator.h"
43
44
45 int TADC_IF_GetDUID(char *Duid)
46 {
47         if (!Duid) {
48                 DRM_TAPPS_EXCEPTION("Invalid argument.");
49                 return TADC_GETDUID_ERROR;
50         }
51
52         char *duid = NULL;
53
54         if (get_duid(&duid) < 0 || !duid) {
55                 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
56                 return TADC_GETDUID_ERROR;
57         }
58
59         DRM_TAPPS_LOG("DUID is [%s]", duid);
60         memcpy(Duid, duid, strlen(duid) + 1);
61
62         free(duid);
63
64         return TADC_SUCCESS;
65 }
66
67 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
68 {
69         DH *pDH = NULL;
70         TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
71
72         // Debug
73         DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
74
75         //1. dh new
76         if ((pDH = DH_new()) == NULL) {
77                 DRM_TAPPS_EXCEPTION("DH_new() error!");
78                 return -1;
79         }
80
81         // Debug
82         DRM_TAPPS_LOG("After DH_new");
83
84         //2. Set the Prime and Generator Value
85         BYTE prime64[64] = {
86                 0xAE, 0xD9, 0x65, 0x3C, 0x86, 0x3E, 0xD9, 0x6F, 0x31, 0x6E,
87                 0xF6, 0x08, 0x35, 0xD5, 0x01, 0xC1, 0x41, 0x2E, 0xDD, 0x7E,
88                 0xE9, 0x09, 0x99, 0x73, 0xF3, 0xB3, 0xAB, 0x1F, 0x80, 0x85,
89                 0x44, 0x22, 0xDA, 0x07, 0x32, 0x18, 0xC1, 0xF8, 0xC4, 0xED,
90                 0x9F, 0x66, 0x88, 0xCF, 0xD6, 0x18, 0x8B, 0x28, 0x56, 0xA5,
91                 0xB3, 0x6A, 0x8E, 0xBB, 0xC4, 0x2B, 0x2B, 0x3A, 0x9C, 0x20,
92                 0x4E, 0xF7, 0x7F, 0xC3
93         };
94         BYTE generator[1] = {DH_GENERATOR_5};
95
96         pDH->p = BN_bin2bn(prime64, 64, NULL);
97         pDH->g = BN_bin2bn(generator, 1, NULL);
98
99         /* Set a to run with normal modexp and b to use constant time */
100         pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
101
102         // Debug
103         DRM_TAPPS_LOG("After Set the Prime and Generator Value");
104
105         //3. Generate DH Key
106         if (!DH_generate_key(pDH)) {
107                 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
108                 return -1;
109         }
110
111         // Debug
112         DRM_TAPPS_LOG("After DH_generate_key");
113
114         //4. Save DH Infos ( p, g, A, a )
115         TADC_IF_MemCpy(t_dhinfo->p, prime64, 64);
116         t_dhinfo->pSize = 64;
117         t_dhinfo->g = DH_GENERATOR_5;
118         t_dhinfo->ASize = BN_bn2bin(pDH->pub_key, t_dhinfo->A);
119         t_dhinfo->aSize = BN_bn2bin(pDH->priv_key, t_dhinfo->a);
120
121         //5. DH Free
122         DH_free(pDH);
123
124         // Debug
125         DRM_TAPPS_LOG("After DH_free");
126
127         return 0;
128 }
129
130 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
131 {
132         DH *pDH = NULL;
133         BIGNUM *pPubKey = NULL;
134
135         char tempbuf[DHKey_SIZE + 1];
136         int i = 0;
137
138         unsigned char tempG[1];
139
140         TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
141
142         //1. dh new
143         if ((pDH = DH_new()) == NULL) {
144                 DRM_TAPPS_EXCEPTION("DH_new() error!");
145                 return -1;
146         }
147
148         //2.Set DH Info to pDH
149         pDH->p = BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL);
150         tempG[0] = t_dhinfo->g;
151         pDH->g = BN_bin2bn(tempG, 1, NULL);
152         pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
153         pDH->pub_key = BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL);
154         pDH->priv_key = BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL);
155
156         //3. Set Public Key of Server
157         pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
158
159         //4. Compute DH Session Key
160         if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
161                 DRM_TAPPS_EXCEPTION("DH_compute_key() error! \n");
162                 return -1;
163         }
164
165         for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
166                 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
167         }
168
169         //5. DH Free
170         DH_free(pDH);
171         BN_free(pPubKey);
172
173         return 0;
174 }
175
176 /* Only handles 128 bit aes key */
177 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
178                                         int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
179 {
180         AES_KEY stKey;
181         UINT num;
182         TADC_U8 ecount[16];
183         TADC_U8 chain[16];
184
185         AES_set_encrypt_key(pKey, 128, &stKey);
186
187         num = 0;
188
189         TADC_IF_MemSet(ecount, 0, sizeof(ecount));
190         TADC_IF_MemSet(chain, 0, sizeof(chain));
191         TADC_IF_MemCpy(chain, pIV, ivLen);
192
193         AES_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num);
194
195         *pOutLen = inLen;
196
197         return 0;
198 }
199
200 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
201 {
202         SHA_CTX AlgInfo;
203
204         SHA1_Init(&AlgInfo);
205         SHA1_Update(&AlgInfo, in, inLen);
206         SHA1_Final(out, &AlgInfo);
207
208         return 0;
209 }
210
211 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
212                                                         unsigned char *sigData, int sigLen,
213                                                         unsigned char *cert, int certLen)
214 {
215         unsigned char hashValue[20];
216         int iRet = 0;
217
218         X509 *pX509 = NULL;
219         EVP_PKEY *pKey = NULL;
220         RSA *pRsa = NULL;
221
222         //Check parameters
223         if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
224                         sigLen < 1 || certLen < 1) {
225                 DRM_TAPPS_EXCEPTION("Parameter error!");
226                 return -1;
227         }
228
229         iRet = 0;
230
231         //1. Make Hash value of indata by using SHA1
232         TADC_IF_SHA1(inData, inLen, hashValue);
233
234         //2. Get RSA Public Key from cert data ( DER )
235         pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
236
237         if (pX509 == NULL) {
238                 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
239                 return -1;
240         }
241
242         pKey = X509_get_pubkey(pX509);
243
244         if (pKey == NULL) {
245                 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
246                 return -1;
247         }
248
249         pRsa = EVP_PKEY_get1_RSA(pKey);
250
251         if (pRsa == NULL) {
252                 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
253
254                 if (NULL != pKey) {
255                         EVP_PKEY_free(pKey);
256                 }
257
258                 return -1;
259         }
260
261         //3. Verify RSA Sign
262         iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
263
264         if (1 != iRet) {
265                 int err = 0;
266                 char tmpBuf[120] = { 0, };
267
268                 while ((err = ERR_get_error()) != 0)
269                         DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
270
271                 if (NULL != pKey)
272                         EVP_PKEY_free(pKey);
273
274                 return -1;
275         }
276
277         if (NULL != pKey)
278                 EVP_PKEY_free(pKey);
279
280         return 0;
281 }
282
283 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
284                                                   int certLen)
285 {
286         X509 *pstX509 = NULL;
287
288         if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
289                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
290                 return -1;
291         }
292
293         pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
294
295         if (pstX509 == NULL) {
296                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
297                 return -1;
298         }
299
300         sk_X509_push(untrustedCerts, pstX509);
301
302         return 0;
303 }
304
305 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
306 {
307         X509 *pstX509 = NULL;
308         FILE *file = NULL;
309         int ret = 0;
310
311         file = fopen(filePath, "r");
312
313         if (!file) {
314                 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
315                 ret = -1;
316                 goto error;
317         }
318
319         pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
320
321         if (pstX509 == NULL) {
322                 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
323                 ret = -1;
324                 goto error;
325         }
326
327         X509_STORE_add_cert(pstStore, pstX509);
328
329 error:
330
331         if (file != NULL)
332                 fclose(file);
333
334         return ret;
335 }
336
337 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
338 {
339         int ret = 0;
340
341         DIR *dir = NULL;
342         struct dirent *result = nullptr;
343         char file_path_buff[512];
344
345         if (pstStore == NULL || dirPath == NULL) {
346                 DRM_TAPPS_EXCEPTION("Parameter error!");
347                 ret = -1;
348                 goto error;
349         }
350
351         dir = opendir(dirPath);
352
353         if (dir == NULL) {
354                 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
355                 ret = -1;
356                 goto error;
357         }
358
359         while (true) {
360                 errno = 0;
361                 result = readdir(dir);
362                 if (result == NULL) {
363                         if (errno != 0) {
364                                 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
365                                                                         dirPath);
366                                 ret = -1;
367                                 goto error;
368                         } else {
369                                 // end of stream
370                                 break;
371                         }
372                 }
373
374                 if (result->d_type == DT_REG) {
375                         // regular file
376                         memset(file_path_buff, 0, sizeof(file_path_buff));
377                         snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
378                                          result->d_name);
379
380                         if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
381                                 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
382                         } else {
383                                 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
384                         }
385                 }
386         }
387
388 error:
389
390         if (dir != NULL)
391                 closedir(dir);
392
393         return ret;
394 }
395
396 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
397                                                         unsigned char *cert, int certLen)
398 {
399         OpenSSL_add_all_algorithms();
400
401         X509_STORE *pstStore = X509_STORE_new();
402
403         if (pstStore == NULL)
404                 return -1;
405
406         std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
407         _scoped_x509_store(pstStore, X509_STORE_free);
408
409         STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
410
411         if (untrustedCerts == NULL)
412                 return -1;
413
414         std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509) *)>>
415         _scoped_x509_stack(untrustedCerts, [](STACK_OF(X509) *s) {
416                 sk_X509_free(s);
417         });
418
419         //Add RICA Cert to certchain
420         if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
421                 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
422                 return -1;
423         }
424
425         //Add Root CA Cert
426         if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
427                 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
428                 return -1;
429         }
430
431         //Get Cert
432         X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
433
434         if (pstX509 == NULL) {
435                 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
436                 return -1;
437         }
438
439         X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
440         X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
441
442         if (pstStoreCtx == NULL) {
443                 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
444                 return -1;
445         }
446
447         std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
448         _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
449
450         //init
451         X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts);
452
453         //Set Flag
454         X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
455
456         //verify
457         switch (X509_verify_cert(pstStoreCtx)) {
458         case 1:
459                 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
460                 return 0;
461
462         case 0:
463                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
464                                                         X509_verify_cert_error_string(
465                                                                 X509_STORE_CTX_get_error(pstStoreCtx)));
466                 return -1;
467
468         default:
469                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
470                 return -1;
471         }
472 }
473
474 size_t TADC_IF_StrLen(const char *string)
475 {
476         return strlen(string);
477 }
478
479 int TADC_IF_StrCmp(const char *string1, const char *string2)
480 {
481         return strcmp(string1, string2);
482 }
483
484 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
485 {
486         return strncmp(string1, string2, count);
487 }
488
489 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
490 {
491         return strncpy(strDestination, strSource, count);
492 }
493
494 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
495 {
496         return strtoul(nptr, endptr, base);
497 }
498
499 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
500 {
501         return memcmp(buf1, buf2, count);
502 }
503
504 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
505 {
506         memcpy(dest, src, count);
507 }
508
509 void TADC_IF_MemSet(void *dest, int c, size_t count)
510 {
511         memset(dest, c, count);
512 }
513
514 void *TADC_IF_Malloc(size_t size)
515 {
516         return malloc(size);
517 }
518
519 void TADC_IF_Free(void *memblock)
520 {
521         if (memblock != NULL)
522                 free(memblock);
523 }
524
525 int TADC_IF_AtoI(char *str)
526 {
527         return atoi(str);
528 }