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