2 * Copyright (c) 2000-2015 Samsung Electronics Co., Ltd.
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
8 * http://floralicense.org/license/
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.
22 #include <openssl/bio.h>
23 #include <openssl/evp.h>
24 #include <openssl/buffer.h>
25 #include <openssl/bn.h>
26 #include <openssl/crypto.h>
27 #include <openssl/err.h>
28 #include <openssl/pem.h>
29 #include <openssl/rsa.h>
30 #include <openssl/aes.h>
31 #include <openssl/sha.h>
34 #include <drm-tizen-apps.h>
35 #include <TADC_Util.h>
37 #include "drm_testutil.h"
39 #define _INITIALIZED 0
40 #define _UNINITIALIZED -1
42 static unsigned char g_baSignatureKey[ 32 ] =
44 0x29, 0x2b, 0xf2, 0x29, 0x1f, 0x8b, 0x47, 0x81, 0x95, 0xa, 0x84, 0xf8, 0x91, 0xda, 0x7, 0xd0,
45 0x9c, 0xde, 0x32, 0x3e, 0x9e, 0x46, 0x4a, 0xfc, 0xa4, 0xcc, 0x55, 0x6e, 0xf2, 0x81, 0x61, 0xdb
48 static unsigned char g_baAESKey[ 32 ] =
50 -8, -121, 10, -59, -45, 109, 68, 73, 3, -97, -67, 30, -88, 47, -10,
51 -61, -33, 59, 2, 19, 88, 27, 18, 48, 28, -41, -83, -91, 31, 93, 1, 51
55 int __initialized = _UNINITIALIZED;
59 if(__initialized != _INITIALIZED ) {
60 ERR_load_crypto_strings();
61 OpenSSL_add_all_algorithms();
62 __initialized = _INITIALIZED;
66 int __get_random_bytes(char* output, int random_len)
69 fp = fopen("/dev/urandom", "r");
70 fread(output, 1, random_len, fp);
72 return DRMTEST_SUCCESS;
75 int __file_copy(const char* target_path, const char* source_path)
77 int ret = DRMTEST_SUCCESS;
81 unsigned char buffer[8192];
83 source = fopen(source_path, "r");
89 target = fopen(target_path, "w");
95 while((l1 = fread(buffer, 1, sizeof buffer, source)) > 0) {
96 l2 = fwrite(buffer, 1, l1, target);
113 void _base64_encode(const unsigned char* input, int length, char** output)
115 *output = Base64Encode((unsigned char*)input, length);
118 void _base64_decode(const char* input, unsigned char** output, int* out_len)
120 *output = Base64Decode((char*)input, out_len);
123 char* _replace_all(char *s, const char *olds, const char *news)
125 char *result=NULL, *sr=NULL;
127 size_t oldlen = strlen(olds); if (oldlen < 1) return s;
128 size_t newlen = strlen(news);
130 if (newlen != oldlen) {
131 for (i = 0; s[i] != '\0';) {
132 if (memcmp(&s[i], olds, oldlen) == 0) count++, i += oldlen;
135 } else i = strlen(s);
137 result = (char *) malloc(i + 1 + count * (newlen - oldlen));
138 if (result == NULL) return NULL;
142 if (memcmp(s, olds, oldlen) == 0) {
143 memcpy(sr, news, newlen);
153 int _read_text_file(const char* path, char** output)
155 int ret = DRMTEST_SUCCESS;
158 unsigned long fileLen;
161 file = fopen(path, "rb");
163 ret = DRMTEST_ERR_IO;
168 fseek(file, 0, SEEK_END);
170 fseek(file, 0, SEEK_SET);
173 buffer=(char *)malloc(fileLen+1);
174 if (buffer == NULL) {
175 ret = DRMTEST_ERR_MEMORY;
178 memset(buffer, 0, fileLen+1);
180 //Read file contents into buffer
181 fread(buffer, fileLen, 1, file);
187 if(ret != DRMTEST_SUCCESS && buffer != NULL)
193 int _create_dh_key(const char* dh_key_p_hex, const char* dh_key_g_hex, DH** ppkey)
195 int ret = DRMTEST_SUCCESS;
198 if ((pDH = DH_new()) == NULL) {
199 printf("...FAIL: DH_new() error");
200 ret = DRMTEST_ERR_CRYPTO;
204 BN_hex2bn(&(pDH->p), dh_key_p_hex);
205 BN_hex2bn(&(pDH->g), dh_key_g_hex);
207 /* Set a to run with normal modexp and b to use constant time */
208 pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
211 if (!DH_generate_key(pDH)) {
212 printf("...FAIL: DH_generate_key");
213 ret = DRMTEST_ERR_CRYPTO;
219 if(ret != DRMTEST_SUCCESS && pDH != NULL)
225 int _free_dh_key(DH* pkey)
229 return DRMTEST_SUCCESS;
233 int _get_dh_hex_pubkey(const DH* pkey, char** dh_pubkey)
235 *dh_pubkey = BN_bn2hex(pkey->pub_key);
236 return DRMTEST_SUCCESS;
239 int _get_dh_shared_secret_key(const char* dh_hex_pubkey, DH *pkey,
240 unsigned char** dh_shared_secret_key, int *dh_sec_key_len)
242 int ret = DRMTEST_SUCCESS;
244 BIGNUM *pPubKey = NULL;
245 unsigned char *secret_key_buff = NULL;
246 unsigned char tmp_buff[DH_size(pkey)] = {0,};
249 BN_hex2bn(&pPubKey, dh_hex_pubkey);
251 if(DH_compute_key(tmp_buff, pPubKey, pkey) < 0) {
252 ret = DRMTEST_ERR_CRYPTO;
256 secret_key_buff = (unsigned char *) malloc(DH_size(pkey)/2);
257 if(secret_key_buff == NULL) {
258 ret = DRMTEST_ERR_CRYPTO;
261 memset(secret_key_buff, 0, DH_size(pkey)/2);
263 printf("APP_DRM TEST: shared secret : ");
264 for(int i=0; i<(DH_size(pkey)/2); i++) {
265 secret_key_buff[i] = tmp_buff[i * 2] ^ tmp_buff[(i * 2) + 1];
266 printf("%02x", secret_key_buff[i]);
270 *dh_shared_secret_key = secret_key_buff;
271 *dh_sec_key_len = DH_size(pkey)/2;
275 if(ret != DRMTEST_SUCCESS && secret_key_buff != NULL)
276 free(secret_key_buff);
282 int _create_right_object_without_signature(const char* ro_template_path, const char* cid, const char* duid,
285 int ret = DRMTEST_SUCCESS;
286 char *file_buff = NULL;
287 char *cid_filled = NULL;
288 char *duid_filled = NULL;
290 ret = _read_text_file(ro_template_path, &file_buff);
291 if(ret != DRMTEST_SUCCESS) {
295 cid_filled = _replace_all(file_buff, STR_PLACE_HOLDER_CID, cid);
296 duid_filled = _replace_all(cid_filled, STR_PLACE_HOLDER_DUID, duid);
298 *ro_buff = duid_filled;
300 if(file_buff != NULL)
302 if(cid_filled != NULL)
304 if(ret != DRMTEST_SUCCESS && duid_filled != NULL)
310 int _create_ro_signature(const char* ro_buff, const char* signer_prikey_path, char** signature)
312 int ret = DRMTEST_SUCCESS;
314 EVP_PKEY* pkey = NULL;
316 const char* END_STR = "</CertificateChain>";
317 const char* tmp_end_hash_input = NULL;
318 int hash_input_size = 0;
319 unsigned char hash_value[20];
320 unsigned char sig_value[MAX_CERT_SIZE]; // enough buffer
321 unsigned int sig_len = 0;
322 char* b64_sig_value = NULL;
327 file = fopen(signer_prikey_path, "r");
329 ret = DRMTEST_ERR_IO;
333 pkey = PEM_read_PrivateKey(file, &pkey, NULL, NULL);
335 ret = DRMTEST_ERR_IO;
339 prsa = EVP_PKEY_get1_RSA(pkey);
341 ret = DRMTEST_ERR_CRYPTO;
345 // get hash input size
346 tmp_end_hash_input = strstr(ro_buff, END_STR);
347 hash_input_size = (tmp_end_hash_input - ro_buff) + strlen(END_STR);
352 SHA1_Update(&alginfo, ro_buff, hash_input_size);
353 SHA1_Final(hash_value, &alginfo);
355 // get signature value
356 if( 1 != RSA_sign(NID_sha1, hash_value, 20, sig_value, &sig_len, prsa) ) {
357 ret = DRMTEST_ERR_CRYPTO;
361 // convert to base64 string
362 _base64_encode(sig_value, (int) sig_len, &b64_sig_value);
364 *signature = b64_sig_value;
370 if(ret != DRMTEST_SUCCESS && b64_sig_value != NULL)
376 int _add_signature_to_ro(const char* ro_buff, const char* signature, char** ro_with_signature)
378 int ret = DRMTEST_SUCCESS;
380 buff = _replace_all((char*)ro_buff, STR_PLACE_HOLDER_SIGNATURE, signature);
381 *ro_with_signature = buff;
385 int _encrypt_ro_with_dh_sec_key(const char* ro_with_signature,
386 const unsigned char* dh_secret_key, const int dh_sec_key_len,
389 int ret = DRMTEST_SUCCESS;
390 TADC_U8 key[16] = {0, };
391 TADC_U8 iv[16] = {0, };
392 int encrypted_len = 0;
393 unsigned char encrypted_buff[MAX_CERT_SIZE] = {0, };;
395 (void) dh_sec_key_len; // to prevent unused varialbe error
397 TADC_IF_MemCpy(key, dh_secret_key, 16);
398 TADC_IF_MemCpy(iv, (dh_secret_key+16), 16);
399 ret = TADC_IF_AES_CTR(16, key, 16, iv, strlen(ro_with_signature), (unsigned char*)ro_with_signature,
400 &encrypted_len, (unsigned char*)encrypted_buff);
402 ret = DRMTEST_ERR_CRYPTO;
406 _base64_encode(encrypted_buff, encrypted_len, encrypted_ro);
412 int _create_response_data_in_ro_response(const char* reqid, const char* encrypted_ro, const char* dh_pubkey,
413 char **response_data)
415 int ret = DRMTEST_SUCCESS;
416 char tmp_buff[MAX_CERT_SIZE] = {0,};
417 unsigned char hashed_reqid[20]={0,};
418 char hex_hashed_reqid[256] = {0, };
419 unsigned char hash_value[20]={0,};
421 unsigned char hmac[1024*10] = {0,};
422 char* hmac_base64 = NULL;
423 char* resp_data = NULL;
426 SHA_CTX alginfoForReqId;
427 SHA1_Init(&alginfoForReqId);
428 SHA1_Update(&alginfoForReqId, reqid, strlen(reqid));
429 SHA1_Final(hashed_reqid, &alginfoForReqId);
431 for(int i=0; i<sizeof(hashed_reqid); i++) {
432 sprintf(hex_hashed_reqid + i*2, "%02x", hashed_reqid[i]);
434 sprintf(tmp_buff, "reqid=%s;B=%s;license=%s", hex_hashed_reqid, dh_pubkey, encrypted_ro);
439 SHA1_Update(&alginfo, tmp_buff, strlen(tmp_buff));
440 SHA1_Final(hash_value, &alginfo);
442 // encrypt hash value
443 TADC_U8 key[16] = {0, };
444 TADC_U8 iv[16] = {0, };
446 TADC_IF_MemCpy(key, g_baAESKey, 16);
447 TADC_IF_MemCpy(iv, (g_baAESKey+16), 16);
448 ret = TADC_IF_AES_CTR(16, key, 16, iv, 20, hash_value, &hmac_len, hmac);
450 ret = DRMTEST_ERR_CRYPTO;
455 _base64_encode(hmac, 20, &hmac_base64);
458 strncat(tmp_buff, ";hmac=", strlen(";hmac="));
459 strncat(tmp_buff, hmac_base64, strlen(hmac_base64));
462 resp_data = (char*) malloc(strlen(tmp_buff)+1);
463 if(resp_data == NULL) {
464 ret = DRMTEST_ERR_MEMORY;
467 memset(resp_data, 0, strlen(tmp_buff)+1);
468 strncpy(resp_data, tmp_buff, strlen(tmp_buff));
470 *response_data = resp_data;
473 if(hmac_base64 != NULL)
475 if(ret != DRMTEST_SUCCESS && resp_data != NULL)
480 int _create_time_stamp(const unsigned char* dh_secret_key, char** time_stamp)
482 int ret = DRMTEST_SUCCESS;
484 char tmp_time_buff[128] = {0,};
485 unsigned char enc_time_buff[512] = {0,};
486 char *time_base64 = NULL;
487 int enc_time_buff_len = 0;
488 time_t now = time(NULL);
489 const struct tm* gt = gmtime(&now);
491 sprintf(tmp_time_buff, "%d-%d-%dT%d:%d:00:Z",
492 gt->tm_year+1900, gt->tm_mon+1, gt->tm_mday,
493 gt->tm_hour+1, gt->tm_min+1);
495 // encrypt time_stamp
496 TADC_U8 key[16] = {0, };
497 TADC_U8 iv[16] = {0, };
499 TADC_IF_MemCpy(key, dh_secret_key, 16);
500 TADC_IF_MemCpy(iv, (dh_secret_key+16), 16);
501 ret = TADC_IF_AES_CTR(16, key, 16, iv, strlen(tmp_time_buff), (unsigned char*)tmp_time_buff,
502 &enc_time_buff_len, enc_time_buff);
504 ret = DRMTEST_ERR_CRYPTO;
509 _base64_encode(enc_time_buff, enc_time_buff_len, &time_base64);
511 *time_stamp = time_base64;
513 if(ret != DRMTEST_SUCCESS && time_base64 != NULL)
519 static int req_id_seq = 0;
521 int generate_purchase_response(char** purchase_response_buff, char** req_id)
523 int ret = DRMTEST_SUCCESS;
524 char resp_buff[1024*5] = {0, };
527 char random[64] = {0, };
529 const char *format1 = "<?xml version=\"1.0\">\n";
530 const char *format2 = "<response result=\"0\" message=\"\">\n";
531 const char *format3 = " <DRMType>%d</DRMType>\n";
532 const char *format4 = " <riurl>%s</riurl>\n";
533 const char *format5 = " <reqid>%s</reqid>\n";
534 const char *format6 = "</response>";
536 resp = (char*) malloc(sizeof(resp_buff));
538 ret = DRMTEST_ERR_MEMORY;
541 memset(resp, 0, sizeof(resp_buff));
543 __get_random_bytes(random, sizeof(random));
544 rid = (char*) malloc(1024);
546 ret = DRMTEST_ERR_MEMORY;
549 memset(rid, 0, 1024);
551 for(int i=0; i<sizeof(random); i++) {
552 sprintf(rid + i*2, "%02x", random[i]);
555 strncat(resp_buff, format1, strlen(format1));
556 strncat(resp_buff, format2, strlen(format2));
557 strncat(resp_buff, format3, strlen(format3));
558 strncat(resp_buff, format4, strlen(format4));
559 strncat(resp_buff, format5, strlen(format5));
560 strncat(resp_buff, format6, strlen(format6));
562 sprintf(resp, resp_buff, 1, RIURL, rid);
564 *purchase_response_buff = resp;
568 if(ret != DRMTEST_SUCCESS && resp != NULL)
570 if(ret != DRMTEST_SUCCESS && rid != NULL)
576 int generate_right_object_request(const char* license_response_buff,
577 char** ro_request_buff)
579 int ret = DRMTEST_SUCCESS;
580 unsigned int req_buff_len = 1024*5;
581 char url_buff[1024] = {0, };
582 unsigned int url_buff_len = sizeof(url_buff);
583 char *req_buff = NULL;
585 req_buff = (char *)malloc(1024*5);
586 if(req_buff == NULL) {
587 ret = DRMTEST_ERR_MEMORY;
590 memset(req_buff, 0, req_buff_len);
592 ret = drm_tizen_generate_license_request(license_response_buff, strlen(license_response_buff),
593 req_buff, &req_buff_len, url_buff, &url_buff_len);
595 ret = DRMTEST_ERR_TIZDRM;
600 if(ret != DRMTEST_SUCCESS && req_buff != NULL)
606 int get_dh_key_from_ro_request(const char* ro_request_buff,
607 char** dh_key_p, char** dh_key_g, char** dh_key_a)
609 int ret = DRMTEST_SUCCESS;
611 const char* PFX_P = "p=";
612 const char* PFX_G = ";g=";
613 const char* PFX_A = ";A=";
614 const char* PFX_HMAC = ";hmac=";
616 const char * idx_p = strstr(ro_request_buff, PFX_P);
617 const char * idx_g = strstr(ro_request_buff, PFX_G);
618 const char * idx_a = strstr(ro_request_buff, PFX_A);
619 const char * idx_hmac = strstr(ro_request_buff, PFX_HMAC);
621 int len_p = idx_g - idx_p - strlen(PFX_P);
622 int len_g = idx_a - idx_g - strlen(PFX_G);
623 int len_a = idx_hmac - idx_a - strlen(PFX_A);
629 buff_p = (char *)malloc(len_p + 1);
631 ret = DRMTEST_ERR_MEMORY;
634 memset(buff_p, 0, len_p + 1);
635 strncpy(buff_p, idx_p + strlen(PFX_P), len_p);
638 buff_g = (char *)malloc(len_g + 1);
640 ret = DRMTEST_ERR_MEMORY;
643 memset(buff_g, 0, len_g + 1);
644 strncpy(buff_g, idx_g + strlen(PFX_G), len_g);
647 buff_a = (char *)malloc(len_a + 1);
649 ret = DRMTEST_ERR_MEMORY;
652 memset(buff_a, 0, len_a + 1);
653 strncpy(buff_a, idx_a + strlen(PFX_A), len_a);
657 if(ret != DRMTEST_SUCCESS && buff_p != NULL)
659 if(ret != DRMTEST_SUCCESS && buff_g != NULL)
661 if(ret != DRMTEST_SUCCESS && buff_a != NULL)
667 int generate_right_object_response(const char* dh_key_p, const char* dh_key_g, const char* dh_key_a,
668 const char* req_id, const char* cid, const char* ro_template_path,
669 const char* duid, char** ro_response_buff)
671 int ret = DRMTEST_SUCCESS;
674 char* dh_pubkey = NULL;
675 unsigned char* dh_shared_secret_key = NULL;
676 int dh_sec_key_len = 0;
677 char* ro_buff = NULL;
678 char* ro_signature = NULL;
679 char* ro_with_signature = NULL;
680 char* encrypted_ro = NULL;
681 char* response_data = NULL;
682 char* time_stamp = NULL;
683 char* ro_resp_buff = NULL;
684 int ro_resp_buff_len = 0;
686 const char *format = "<?xml version=\"1.0\">\n"
687 "<response result=\"0\" message=\"\">\n"
688 " <responsedata>%s</responsedata>\n"
689 " <timeStamp>%s</timeStamp>\n"
692 ret = _create_dh_key(dh_key_p, dh_key_g, &pkey);
693 if(ret != DRMTEST_SUCCESS){
697 ret = _get_dh_hex_pubkey(pkey, &dh_pubkey);
698 if(ret != DRMTEST_SUCCESS){
702 ret = _get_dh_shared_secret_key(dh_key_a, pkey, &dh_shared_secret_key, &dh_sec_key_len);
703 if(ret != DRMTEST_SUCCESS){
707 ret = _create_right_object_without_signature(ro_template_path, cid, duid, &ro_buff);
708 if(ret != DRMTEST_SUCCESS){
712 ret = _create_ro_signature(ro_buff, RO_ISSUER_SIGNER_KEY_FILE, &ro_signature);
713 if(ret != DRMTEST_SUCCESS){
717 ret = _add_signature_to_ro(ro_buff, ro_signature, &ro_with_signature);
718 if(ret != DRMTEST_SUCCESS){
721 //printf("...right object:\n%s\n", ro_with_signature);
723 ret = _encrypt_ro_with_dh_sec_key(ro_with_signature, dh_shared_secret_key, dh_sec_key_len,
725 if(ret != DRMTEST_SUCCESS){
729 ret = _create_response_data_in_ro_response(req_id, encrypted_ro, dh_pubkey, &response_data);
730 if(ret != DRMTEST_SUCCESS){
734 ret = _create_time_stamp( dh_shared_secret_key, &time_stamp);
735 if(ret != DRMTEST_SUCCESS){
739 ro_resp_buff_len = strlen(format) + strlen(response_data) + strlen(time_stamp) + 1;
740 ro_resp_buff = (char *) malloc(ro_resp_buff_len);
741 if(ro_resp_buff == NULL) {
742 ret = DRMTEST_ERR_MEMORY;
745 memset(ro_resp_buff, 0, ro_resp_buff_len);
746 sprintf(ro_resp_buff, format, response_data, time_stamp);
748 *ro_response_buff = ro_resp_buff;
753 if(dh_pubkey != NULL)
755 if(dh_shared_secret_key != NULL)
756 free(dh_shared_secret_key);
759 if(ro_signature != NULL)
761 if(ro_with_signature != NULL)
762 free(ro_with_signature);
763 if(encrypted_ro != NULL)
765 if(response_data != NULL)
767 if(time_stamp != NULL)
769 if(ret != DRMTEST_SUCCESS && ro_resp_buff != NULL)
776 int is_identical_files(const char* file1, const char* file2, int* identical)
778 int ret = DRMTEST_SUCCESS;
780 FILE *fp1 = NULL, *fp2 = NULL;
783 fp1 = fopen(file1, "r");
785 ret = DRMTEST_ERR_IO;
789 fp2 = fopen(file2, "r");
791 ret = DRMTEST_ERR_IO;
797 while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2)) {
802 *identical = DRMTEST_IDENTICAL;
804 *identical = DRMTEST_NOTIDENTICAL;