Fix coding style according to tizen rule
[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
53         if (get_duid(&duid) < 0 || !duid) {
54                 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
55                 return TADC_GETDUID_ERROR;
56         }
57
58         DRM_TAPPS_LOG("DUID is [%s]", duid);
59         memcpy(Duid, duid, strlen(duid) + 1);
60
61         free(duid);
62
63         return TADC_SUCCESS;
64 }
65
66 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
67 {
68         DH *pDH = NULL;
69         TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
70
71         // Debug
72         DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
73
74         //1. dh new
75         if ((pDH = DH_new()) == NULL) {
76                 DRM_TAPPS_EXCEPTION("DH_new() error!");
77                 return -1;
78         }
79
80         // Debug
81         DRM_TAPPS_LOG("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         };
93         BYTE generator[1] = {DH_GENERATOR_5};
94
95         pDH->p = BN_bin2bn(prime64, 64, NULL);
96         pDH->g = BN_bin2bn(generator, 1, NULL);
97
98         /* Set a to run with normal modexp and b to use constant time */
99         pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
100
101         // Debug
102         DRM_TAPPS_LOG("After Set the Prime and Generator Value");
103
104         //3. Generate DH Key
105         if (!DH_generate_key(pDH)) {
106                 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
107                 return -1;
108         }
109
110         // Debug
111         DRM_TAPPS_LOG("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("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                 DRM_TAPPS_EXCEPTION("DH_new() error!");
144                 return -1;
145         }
146
147         //2.Set DH Info to pDH
148         pDH->p = BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL);
149         tempG[0] = t_dhinfo->g;
150         pDH->g = BN_bin2bn(tempG, 1, NULL);
151         pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
152         pDH->pub_key = BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL);
153         pDH->priv_key = BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL);
154
155         //3. Set Public Key of Server
156         pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
157
158         //4. Compute DH Session Key
159         if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
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                 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
166         }
167
168         //5. DH Free
169         DH_free(pDH);
170         BN_free(pPubKey);
171
172         return 0;
173 }
174
175 /* Only handles 128 bit aes key */
176 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
177                                         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 ||
223                         sigLen < 1 || certLen < 1) {
224                 DRM_TAPPS_EXCEPTION("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
236         if (pX509 == NULL) {
237                 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
238                 return -1;
239         }
240
241         pKey = X509_get_pubkey(pX509);
242
243         if (pKey == NULL) {
244                 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
245                 return -1;
246         }
247
248         pRsa = EVP_PKEY_get1_RSA(pKey);
249
250         if (pRsa == NULL) {
251                 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
252
253                 if (NULL != pKey) {
254                         EVP_PKEY_free(pKey);
255                 }
256
257                 return -1;
258         }
259
260         //3. Verify RSA Sign
261         iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
262
263         if (1 != iRet) {
264                 int err = 0;
265                 char tmpBuf[120] = { 0, };
266
267                 while ((err = ERR_get_error()) != 0)
268                         DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
269
270                 if (NULL != pKey)
271                         EVP_PKEY_free(pKey);
272
273                 return -1;
274         }
275
276         if (NULL != pKey)
277                 EVP_PKEY_free(pKey);
278
279         return 0;
280 }
281
282 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
283                                                   int certLen)
284 {
285         X509 *pstX509 = NULL;
286
287         if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
288                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
289                 return -1;
290         }
291
292         pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
293
294         if (pstX509 == NULL) {
295                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
296                 return -1;
297         }
298
299         sk_X509_push(untrustedCerts, pstX509);
300
301         return 0;
302 }
303
304 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
305 {
306         X509 *pstX509 = NULL;
307         FILE *file = NULL;
308         int ret = 0;
309
310         file = fopen(filePath, "r");
311
312         if (!file) {
313                 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
314                 ret = -1;
315                 goto error;
316         }
317
318         pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
319
320         if (pstX509 == NULL) {
321                 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
322                 ret = -1;
323                 goto error;
324         }
325
326         X509_STORE_add_cert(pstStore, pstX509);
327
328 error:
329
330         if (file != NULL)
331                 fclose(file);
332
333         return ret;
334 }
335
336 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
337 {
338         int ret = 0;
339
340         DIR *dir = NULL;
341         struct dirent entry;
342         struct dirent *result;
343         int error;
344         char file_path_buff[512];
345
346         if (pstStore == NULL || dirPath == NULL) {
347                 DRM_TAPPS_EXCEPTION("Parameter error!");
348                 ret = -1;
349                 goto error;
350         }
351
352         dir = opendir(dirPath);
353
354         if (dir == NULL) {
355                 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
356                 ret = -1;
357                 goto error;
358         }
359
360         while (true) {
361                 error = readdir_r(dir, &entry, &result);
362
363                 if (error != 0) {
364                         DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!", dirPath);
365                         ret = -1;
366                         goto error;
367                 }
368
369                 // readdir_r returns NULL in *result if the end
370                 // of the directory stream is reached
371                 if (result == NULL)
372                         break;
373
374                 if (entry.d_type == DT_REG) { // regular file
375                         memset(file_path_buff, 0, sizeof(file_path_buff));
376                         snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
377                                          entry.d_name);
378
379                         if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
380                                 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
381                         } else {
382                                 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
383                         }
384                 }
385         }
386
387 error:
388
389         if (dir != NULL)
390                 closedir(dir);
391
392         return ret;
393 }
394
395 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
396                                                         unsigned char *cert, int certLen)
397 {
398         OpenSSL_add_all_algorithms();
399
400         X509_STORE *pstStore = X509_STORE_new();
401
402         if (pstStore == NULL)
403                 return -1;
404
405         std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
406         _scoped_x509_store(pstStore, X509_STORE_free);
407
408         STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
409
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) {
415                 sk_X509_free(s);
416         });
417
418         //Add RICA Cert to certchain
419         if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
420                 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
421                 return -1;
422         }
423
424         //Add Root CA Cert
425         if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
426                 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
427                 return -1;
428         }
429
430         //Get Cert
431         X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
432
433         if (pstX509 == NULL) {
434                 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
435                 return -1;
436         }
437
438         X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
439         X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
440
441         if (pstStoreCtx == NULL) {
442                 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
443                 return -1;
444         }
445
446         std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
447         _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
448
449         //init
450         X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts);
451
452         //Set Flag
453         X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
454
455         //verify
456         switch (X509_verify_cert(pstStoreCtx)) {
457         case 1:
458                 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
459                 return 0;
460
461         case 0:
462                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
463                                                         X509_verify_cert_error_string(
464                                                                 X509_STORE_CTX_get_error(pstStoreCtx)));
465                 return -1;
466
467         default:
468                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
469                 return -1;
470         }
471 }
472
473 size_t TADC_IF_StrLen(const char *string)
474 {
475         return strlen(string);
476 }
477
478 int TADC_IF_StrCmp(const char *string1, const char *string2)
479 {
480         return strcmp(string1, string2);
481 }
482
483 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
484 {
485         return strncmp(string1, string2, count);
486 }
487
488 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
489 {
490         return strncpy(strDestination, strSource, count);
491 }
492
493 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
494 {
495         return strtoul(nptr, endptr, base);
496 }
497
498 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
499 {
500         return memcmp(buf1, buf2, count);
501 }
502
503 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
504 {
505         memcpy(dest, src, count);
506 }
507
508 void TADC_IF_MemSet(void *dest, int c, size_t count)
509 {
510         memset(dest, c, count);
511 }
512
513 void *TADC_IF_Malloc(size_t size)
514 {
515         return malloc(size);
516 }
517
518 void TADC_IF_Free(void *memblock)
519 {
520         if (memblock != NULL)
521                 free(memblock);
522 }
523
524 int TADC_IF_AtoI(char *str)
525 {
526         return atoi(str);
527 }