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