Fix build warning and add related gcc options
[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 /* Only handles 128 bit aes key */
177 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV, int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
178 {
179         AES_KEY stKey;
180         UINT num;
181         TADC_U8 ecount[16];
182         TADC_U8 chain[16];
183
184         AES_set_encrypt_key(pKey, 128, &stKey);
185
186         num = 0;
187
188         TADC_IF_MemSet(ecount, 0, sizeof(ecount));
189         TADC_IF_MemSet(chain, 0, sizeof(chain));
190         TADC_IF_MemCpy(chain, pIV, ivLen);
191
192         AES_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num);
193
194         *pOutLen = inLen;
195
196         return 0;
197 }
198
199 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
200 {
201         SHA_CTX AlgInfo;
202
203         SHA1_Init(&AlgInfo);
204         SHA1_Update(&AlgInfo, in, inLen);
205         SHA1_Final(out, &AlgInfo);
206
207         return 0;
208 }
209
210 int TADC_IF_VerifySignature(unsigned char* inData, int inLen,
211                                                         unsigned char* sigData, int sigLen,
212                                                         unsigned char* cert, int certLen)
213 {
214         unsigned char hashValue[20];
215         int iRet = 0;
216
217         X509* pX509 = NULL;
218         EVP_PKEY* pKey = NULL;
219         RSA* pRsa = NULL;
220
221         //Check parameters
222         if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 || sigLen < 1 || certLen < 1)
223         {
224                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : Parameter error!");
225                 return -1;
226         }
227
228         iRet = 0;
229
230         //1. Make Hash value of indata by using SHA1
231         TADC_IF_SHA1(inData, inLen, hashValue);
232
233         //2. Get RSA Public Key from cert data ( DER )
234         pX509 = d2i_X509(NULL, (const unsigned char**)&cert, certLen);
235         if (pX509 == NULL)
236         {
237                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : Get RSA Public Key from cert data!");
238                 return -1;
239         }
240
241         pKey = X509_get_pubkey(pX509);
242         if (pKey == NULL)
243         {
244                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : X509_get_pubkey!");
245                 return -1;
246         }
247
248         pRsa = EVP_PKEY_get1_RSA(pKey);
249         if (pRsa == NULL)
250         {
251                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : EVP_PKEY_get1_RSA!");
252                 if (NULL != pKey)
253                 {
254                         EVP_PKEY_free(pKey);
255                 }
256                 return -1;
257         }
258
259         //3. Verify RSA Sign
260         iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
261         if (1 != iRet)
262         {
263                 int err = 0;
264                 char tmpBuf[120] = {0,};
265
266                 while ((err = ERR_get_error()) != 0)
267                 {
268                         DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
269                 }
270                 //Error
271                 //DRM_TAPPS_EXCEPTION("TADC_IF_VerifySignature Error : RSA_verify error(%s)", ERR_error_string(ERR_get_error(), NULL));
272
273                 if (NULL != pKey)
274                 {
275                         EVP_PKEY_free(pKey);
276                 }
277
278                 return -1;
279         }
280
281         //free
282         if (NULL != pKey)
283         {
284                 EVP_PKEY_free(pKey);
285         }
286
287         return 0;
288 }
289
290 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char* cert, int certLen)
291 {
292         X509* pstX509 = NULL;
293
294         if (untrustedCerts == NULL || cert == NULL || certLen < 1)
295         {
296                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
297                 return -1;
298         }
299
300         pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
301         if (pstX509 == NULL)
302         {
303                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
304                 return -1;
305         }
306
307         sk_X509_push(untrustedCerts, pstX509);
308
309         return 0;
310 }
311
312 int AddCertSTOREFromFile(X509_STORE* pstStore, const char* filePath)
313 {
314         X509* pstX509 = NULL;
315         FILE* file = NULL;
316         int ret = 0;
317
318         file = fopen(filePath, "r");
319         if(!file)
320         {
321                 DRM_TAPPS_EXCEPTION("AddCertSTOREFromFile Error : Parameter error! Fail to open a cert file.");
322                 ret = -1;
323                 goto error;
324         }
325
326         pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
327         if (pstX509 == NULL)
328         {
329                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
330                 ret = -1;
331                 goto error;
332         }
333
334         X509_STORE_add_cert(pstStore, pstX509);
335
336 error:
337         if(file!=NULL)
338                 fclose(file);
339         return ret;
340 }
341
342 int AddCertSTOREFromDir(X509_STORE* pstStore, const char* dirPath)
343 {
344         int ret = 0;
345
346         DIR *dir = NULL;
347         struct dirent entry;
348         struct dirent *result;
349         int error;
350         char file_path_buff[512];
351
352         if (pstStore == NULL || dirPath == NULL)
353         {
354                 DRM_TAPPS_EXCEPTION("AddCertSTOREFromDir Error : Parameter error!");
355                 ret = -1;
356                 goto error;
357         }
358
359         dir = opendir(dirPath);
360         if(dir == NULL) {
361                 DRM_TAPPS_EXCEPTION("AddCertSTOREFromDir Error : cannot open directory!");
362                 ret = -1;
363                 goto error;
364         }
365
366         for(;;) {
367                 error = readdir_r(dir, &entry, &result);
368                 if( error != 0 ) {
369                         DRM_TAPPS_EXCEPTION("AddCertSTOREFromDir Error : fail to read entries from a directory!");
370                         ret = -1;
371                         goto error;
372                 }
373                 // readdir_r returns NULL in *result if the end
374                 // of the directory stream is reached
375                 if(result == NULL)
376                         break;
377
378                 if(entry.d_type == DT_REG) { // regular file
379                         memset(file_path_buff, 0, sizeof(file_path_buff));
380                         snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath, entry.d_name);
381                         if(AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
382                                 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
383                         }else {
384                                 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
385                         }
386                 }
387         }
388
389 error:
390         if(dir!=NULL)
391                 closedir(dir);
392         return ret;
393 }
394
395 int TADC_IF_VerifyCertChain(unsigned char* rica, int ricaLen,
396                                                         unsigned char* cert, int certLen)
397 {
398         X509_STORE_CTX* pstStoreCtx = NULL;
399         X509_STORE* pstStore = NULL;
400         STACK_OF(X509)* untrustedCerts = NULL;
401
402         X509* pstX509 = NULL;
403
404         int iRet = 0;
405         int iErrCode = 0;
406
407         //must call this function.
408         OpenSSL_add_all_algorithms();
409
410         pstStore = X509_STORE_new();
411         if(pstStore == NULL)
412         {
413                 iRet = -1;
414                 goto error;
415         }
416
417         untrustedCerts = sk_X509_new_null();
418         if(untrustedCerts == NULL)
419         {
420                 iRet = -1;
421                 goto error;
422         }
423
424
425         //Add RICA Cert to certchain
426         if ((iRet = AddCertUntrustedCerts(untrustedCerts, rica, ricaLen)) != 0)
427         {
428                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : Add RICA Cert to certchain!");
429                 iRet = -1;
430                 goto error;
431         }
432
433         //Add Root CA Cert
434         if ((iRet = AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR)) != 0)
435         {
436                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : Add Root CA Cert!");
437                 iRet = -1;
438                 goto error;
439         }
440
441         //Get Cert
442         pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
443
444         if (pstX509 == NULL)
445         {
446                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : Get Cert d2i_X509 error!");
447                 iRet = -1;
448                 goto error;
449         }
450
451         X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
452         pstStoreCtx = X509_STORE_CTX_new();
453         if (pstStoreCtx == NULL)
454         {
455                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : 509_STORE_CTX_new error!");
456                 iRet = -1;
457                 goto error;
458         }
459
460         //init
461         X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts);
462
463         //Set Flag
464         X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
465
466         //verify
467         iRet = X509_verify_cert(pstStoreCtx);
468
469         //free
470 error:
471         if (pstStore != NULL)
472                 X509_STORE_free(pstStore);
473         if (pstStoreCtx != NULL)
474                 X509_STORE_CTX_free(pstStoreCtx);
475         if (untrustedCerts != NULL)
476                 sk_X509_free(untrustedCerts);
477
478         if (iRet == 1)
479         {
480                 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success! \n");
481                 return 0;
482         }
483         else if (iRet == 0)
484         {
485                 iErrCode = X509_STORE_CTX_get_error(pstStoreCtx);
486                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : %s \n", X509_verify_cert_error_string(iErrCode));
487                 return -1;
488         }
489         else
490         {
491                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error : 509_verify_cert error! \n");
492                 return -1;
493         }
494 }
495
496 size_t TADC_IF_StrLen(const char *string)
497 {
498         return strlen(string);
499 }
500
501 int TADC_IF_StrCmp(const char *string1, const char *string2)
502 {
503         return strcmp(string1, string2);
504 }
505
506 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
507 {
508         return strncmp(string1, string2, count);
509 }
510
511 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
512 {
513         return strncpy(strDestination, strSource, count);
514 }
515
516 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
517 {
518         return strtoul(nptr, endptr, base);
519 }
520
521 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
522 {
523         return memcmp(buf1, buf2, count);
524 }
525
526 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
527 {
528         memcpy(dest, src, count);
529 }
530
531 void TADC_IF_MemSet(void *dest, int c, size_t count)
532 {
533         memset(dest, c, count);
534 }
535
536 void *TADC_IF_Malloc(size_t size)
537 {
538         return malloc(size);
539 }
540
541 void TADC_IF_Free(void *memblock)
542 {
543         if(memblock != NULL)
544         {
545                 free(memblock);
546         }
547 }
548
549 int TADC_IF_AtoI(char *str)
550 {
551         return atoi(str);
552 }