Fix coding style according to tizen rule
[platform/core/security/drm-service-core-tizen.git] / test / drm_testutil.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 #include <string.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <time.h>
21 #include <vector>
22 #include <fstream>
23 #include <iostream>
24
25 #include <openssl/bio.h>
26 #include <openssl/evp.h>
27 #include <openssl/buffer.h>
28 #include <openssl/bn.h>
29 #include <openssl/crypto.h>
30 #include <openssl/err.h>
31 #include <openssl/pem.h>
32 #include <openssl/rsa.h>
33 #include <openssl/aes.h>
34 #include <openssl/sha.h>
35
36 #include <TADC_IF.h>
37 #include <drm-tizen-apps.h>
38 #include <TADC_Util.h>
39
40 #include "drm_testutil.h"
41
42 #define _INITIALIZED 0
43 #define _UNINITIALIZED -1
44
45 using Binary = std::vector<unsigned char>;
46
47 static unsigned char g_baAESKey[32] = {
48         0xf8, 0x87, 0x0a, 0xc5, 0xd3, 0x6d, 0x44, 0x49,
49         0x03, 0x9f, 0xbd, 0x1e, 0xa8, 0x2f, 0xf6, 0xc3,
50         0xdf, 0x3b, 0x02, 0x13, 0x58, 0x1b, 0x12, 0x30,
51         0x1c, 0xd7, 0xad, 0xa5, 0x1f, 0x5d, 0x01, 0x33
52 };
53
54
55 int __initialized = _UNINITIALIZED;
56
57 void __init_crypto()
58 {
59         if (__initialized != _INITIALIZED) {
60                 ERR_load_crypto_strings();
61                 OpenSSL_add_all_algorithms();
62                 __initialized = _INITIALIZED;
63         }
64 }
65
66 int __get_random_bytes(char *output, int random_len)
67 {
68         FILE *fp = fopen("/dev/urandom", "r");
69         auto size = fread(output, 1, random_len, fp);
70
71         fclose(fp);
72
73         if (size != static_cast<size_t>(random_len))
74                 return DRMTEST_ERR_IO;
75
76         return DRMTEST_SUCCESS;
77 }
78
79 int __file_copy(const char *target_path, const char *source_path)
80 {
81         int ret = DRMTEST_SUCCESS;
82         FILE *source = NULL;
83         FILE *target = NULL;
84         size_t l1, l2;
85         unsigned char buffer[8192];
86
87         source = fopen(source_path, "r");
88
89         if (source == NULL) {
90                 ret = DRMTEST_ERR_IO;
91                 goto error;
92         }
93
94         target = fopen(target_path, "w");
95
96         if (target == NULL) {
97                 ret = DRMTEST_ERR_IO;
98                 goto error;
99         }
100
101         while ((l1 = fread(buffer, 1, sizeof buffer, source)) > 0) {
102                 l2 = fwrite(buffer, 1, l1, target);
103
104                 if (l2 < l1) {
105                         if (ferror(target)) {
106                                 ret = DRMTEST_ERR_IO;
107                                 goto error;
108                         }
109                 }
110         }
111
112 error:
113
114         if (source != NULL)
115                 fclose(source);
116
117         if (target != NULL)
118                 fclose(target);
119
120         return ret;
121 }
122
123 void _base64_encode(const unsigned char *input, int length, char **output)
124 {
125         *output = Base64Encode((unsigned char *)input, length);
126 }
127
128 void _base64_decode(const char *input, unsigned char **output, int *out_len)
129 {
130         *output = Base64Decode((char *)input, out_len);
131 }
132
133 char *_replace_all(char *s, const char *olds, const char *news)
134 {
135         char *result = NULL, *sr = NULL;
136         size_t i, count = 0;
137         size_t oldlen = strlen(olds);
138
139         if (oldlen < 1) return s;
140
141         size_t newlen = strlen(news);
142
143         if (newlen != oldlen) {
144                 for (i = 0; s[i] != '\0';) {
145                         if (memcmp(&s[i], olds, oldlen) == 0) count++, i += oldlen;
146                         else i++;
147                 }
148         } else {
149                 i = strlen(s);
150         }
151
152         result = (char *) malloc(i + 1 + count * (newlen - oldlen));
153
154         if (result == NULL) return NULL;
155
156         sr = result;
157
158         while (*s) {
159                 if (memcmp(s, olds, oldlen) == 0) {
160                         memcpy(sr, news, newlen);
161                         sr += newlen;
162                         s  += oldlen;
163                 } else {
164                         *sr++ = *s++;
165                 }
166         }
167
168         *sr = '\0';
169
170         return result;
171 }
172
173 Binary _read_ro_file(const char *filename)
174 {
175         try {
176                 std::ifstream is(filename, std::ifstream::binary);
177
178                 if (!is || !is.is_open())
179                         return Binary();
180
181                 is.seekg(0, is.end);
182                 int length = is.tellg();
183                 is.seekg(0, is.beg);
184
185                 Binary buffer(length + 1); /* for null-terminated */
186
187                 is.read(reinterpret_cast<char *>(buffer.data()), length);
188
189                 if (!is)
190                         return Binary();
191
192                 return buffer;
193         } catch (...) {
194                 std::cerr << "Failed to read ro file: " << filename << std::endl;
195                 return Binary();
196         }
197 }
198
199 int _create_dh_key(const char *dh_key_p_hex, const char *dh_key_g_hex,
200                                    DH **ppkey)
201 {
202         int ret = DRMTEST_SUCCESS;
203         DH *pDH = NULL;
204
205         if ((pDH = DH_new()) == NULL) {
206                 printf("...FAIL: DH_new() error");
207                 ret = DRMTEST_ERR_CRYPTO;
208                 goto error;
209         }
210
211         BN_hex2bn(&(pDH->p), dh_key_p_hex);
212         BN_hex2bn(&(pDH->g), dh_key_g_hex);
213
214         /* Set a to run with normal modexp and b to use constant time */
215         pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
216
217         // Generate DH Key
218         if (!DH_generate_key(pDH)) {
219                 printf("...FAIL: DH_generate_key");
220                 ret = DRMTEST_ERR_CRYPTO;
221                 goto error;
222         }
223
224         *ppkey = pDH;
225 error:
226
227         if (ret != DRMTEST_SUCCESS && pDH != NULL)
228                 DH_free(pDH);
229
230         return ret;
231 }
232
233 int _free_dh_key(DH *pkey)
234 {
235         if (pkey != NULL)
236                 DH_free(pkey);
237
238         return DRMTEST_SUCCESS;
239 }
240
241
242 int _get_dh_hex_pubkey(const DH *pkey, char **dh_pubkey)
243 {
244         *dh_pubkey = BN_bn2hex(pkey->pub_key);
245         return DRMTEST_SUCCESS;
246 }
247
248 int _get_dh_shared_secret_key(const char *dh_hex_pubkey, DH *pkey,
249                                                           unsigned char **dh_shared_secret_key, int *dh_sec_key_len)
250 {
251         int ret = DRMTEST_SUCCESS;
252
253         BIGNUM  *pPubKey = NULL;
254         unsigned char *secret_key_buff = NULL;
255         unsigned char tmp_buff[DH_size(pkey)] = { 0, };
256
257         BN_hex2bn(&pPubKey, dh_hex_pubkey);
258
259         if (DH_compute_key(tmp_buff, pPubKey, pkey) < 0) {
260                 ret = DRMTEST_ERR_CRYPTO;
261                 goto error;
262         }
263
264         secret_key_buff = (unsigned char *) malloc(DH_size(pkey) / 2);
265
266         if (secret_key_buff == NULL) {
267                 ret = DRMTEST_ERR_CRYPTO;
268                 goto error;
269         }
270
271         memset(secret_key_buff, 0, DH_size(pkey) / 2);
272
273         printf("APP_DRM TEST: shared secret : ");
274
275         for (int i = 0; i < (DH_size(pkey) / 2); i++) {
276                 secret_key_buff[i] = tmp_buff[i * 2] ^ tmp_buff[(i * 2) + 1];
277                 printf("%02x", secret_key_buff[i]);
278         }
279
280         printf("\n");
281
282         *dh_shared_secret_key = secret_key_buff;
283         *dh_sec_key_len = DH_size(pkey) / 2;
284 error:
285
286         if (pPubKey != NULL)
287                 BN_free(pPubKey);
288
289         if (ret != DRMTEST_SUCCESS && secret_key_buff != NULL)
290                 free(secret_key_buff);
291
292         return ret;
293 }
294
295
296 int _create_right_object_without_signature(const char *ro_template_path,
297                 const char *cid, const char *duid,
298                 char **ro_buff)
299 {
300         int ret = DRMTEST_SUCCESS;
301         char *cid_filled = NULL;
302         char *duid_filled = NULL;
303
304         auto buf = _read_ro_file(ro_template_path);
305
306         cid_filled = _replace_all(reinterpret_cast<char *>(buf.data()),
307                                                           STR_PLACE_HOLDER_CID, cid);
308         duid_filled = _replace_all(cid_filled, STR_PLACE_HOLDER_DUID, duid);
309
310         *ro_buff = duid_filled;
311
312         if (cid_filled != NULL)
313                 free(cid_filled);
314
315         if (ret != DRMTEST_SUCCESS && duid_filled != NULL)
316                 free(duid_filled);
317
318         return ret;
319 }
320
321 int _create_ro_signature(const char *ro_buff, const char *signer_prikey_path,
322                                                  char **signature)
323 {
324         int ret = DRMTEST_SUCCESS;
325
326         EVP_PKEY *pkey = NULL;
327         RSA      *prsa = NULL;
328         const char *END_STR = "</CertificateChain>";
329         const char *tmp_end_hash_input = NULL;
330         int hash_input_size = 0;
331         unsigned char hash_value[20];
332         unsigned char sig_value[MAX_CERT_SIZE]; // enough buffer
333         unsigned int sig_len = 0;
334         char *b64_sig_value = NULL;
335
336         FILE *file = NULL;
337
338         // get private key
339         file = fopen(signer_prikey_path, "r");
340
341         if (file == NULL) {
342                 ret = DRMTEST_ERR_IO;
343                 goto error;
344         }
345
346         pkey = PEM_read_PrivateKey(file, &pkey, NULL, NULL);
347
348         if (pkey == NULL) {
349                 ret = DRMTEST_ERR_IO;
350                 goto error;
351         }
352
353         prsa = EVP_PKEY_get1_RSA(pkey);
354
355         if (prsa == NULL) {
356                 ret = DRMTEST_ERR_CRYPTO;
357                 goto error;
358         }
359
360         // get hash input size
361         tmp_end_hash_input = strstr(ro_buff, END_STR);
362         hash_input_size = (tmp_end_hash_input - ro_buff) + strlen(END_STR);
363
364         // get hash value
365         SHA_CTX     alginfo;
366         SHA1_Init(&alginfo);
367         SHA1_Update(&alginfo, ro_buff, hash_input_size);
368         SHA1_Final(hash_value, &alginfo);
369
370         // get signature value
371         if (1 != RSA_sign(NID_sha1, hash_value, 20, sig_value, &sig_len, prsa)) {
372                 ret = DRMTEST_ERR_CRYPTO;
373                 goto error;
374         }
375
376         // convert to base64 string
377         _base64_encode(sig_value, (int) sig_len, &b64_sig_value);
378
379         *signature = b64_sig_value;
380 error:
381
382         if (file != NULL)
383                 fclose(file);
384
385         if (pkey != NULL)
386                 EVP_PKEY_free(pkey);
387
388         if (ret != DRMTEST_SUCCESS && b64_sig_value != NULL)
389                 free(b64_sig_value);
390
391         return ret;
392 }
393
394 int _add_signature_to_ro(const char *ro_buff, const char *signature,
395                                                  char **ro_with_signature)
396 {
397         int ret = DRMTEST_SUCCESS;
398         char *buff = NULL;
399         buff = _replace_all((char *)ro_buff, STR_PLACE_HOLDER_SIGNATURE, signature);
400         *ro_with_signature = buff;
401         return ret;
402 }
403
404 int _encrypt_ro_with_dh_sec_key(const char *ro_with_signature,
405                                                                 const unsigned char *dh_secret_key, const int dh_sec_key_len,
406                                                                 char **encrypted_ro)
407 {
408         int ret = DRMTEST_SUCCESS;
409         TADC_U8     key[16] = {0, };
410         TADC_U8     iv[16] = {0, };
411         int encrypted_len = 0;
412         unsigned char encrypted_buff[MAX_CERT_SIZE] = {0, };;
413
414         (void) dh_sec_key_len; // to prevent unused varialbe error
415
416         TADC_IF_MemCpy(key, dh_secret_key, 16);
417         TADC_IF_MemCpy(iv, (dh_secret_key + 16), 16);
418         ret = TADC_IF_AES_CTR(key, 16, iv, strlen(ro_with_signature),
419                                                   (unsigned char *)ro_with_signature,
420                                                   &encrypted_len, (unsigned char *)encrypted_buff);
421
422         if (ret != 0) {
423                 ret = DRMTEST_ERR_CRYPTO;
424                 goto error;
425         }
426
427         _base64_encode(encrypted_buff, encrypted_len, encrypted_ro);
428
429 error:
430         return ret;
431 }
432
433 int _create_response_data_in_ro_response(const char *reqid,
434                 const char *encrypted_ro, const char *dh_pubkey,
435                 char **response_data)
436 {
437         int ret = DRMTEST_SUCCESS;
438         char tmp_buff[MAX_CERT_SIZE] = { 0, };
439         unsigned char hashed_reqid[20] = { 0, };
440         char hex_hashed_reqid[256] = { 0, };
441         unsigned char hash_value[20] = { 0, };
442         int hmac_len = 0;
443         unsigned char hmac[1024 * 10] = { 0, };
444         char *hmac_base64 = NULL;
445         char *resp_data = NULL;
446
447         // get hashed req_id
448         SHA_CTX alginfoForReqId;
449         SHA1_Init(&alginfoForReqId);
450         SHA1_Update(&alginfoForReqId, reqid, strlen(reqid));
451         SHA1_Final(hashed_reqid, &alginfoForReqId);
452
453         for (size_t i = 0; i < sizeof(hashed_reqid); i++)
454                 sprintf(hex_hashed_reqid + i * 2, "%02x", hashed_reqid[i]);
455
456         sprintf(tmp_buff, "reqid=%s;B=%s;license=%s", hex_hashed_reqid, dh_pubkey,
457                         encrypted_ro);
458
459         // get hash value
460         SHA_CTX     alginfo;
461         SHA1_Init(&alginfo);
462         SHA1_Update(&alginfo, tmp_buff, strlen(tmp_buff));
463         SHA1_Final(hash_value, &alginfo);
464
465         // encrypt hash value
466         TADC_U8     key[16] = {0, };
467         TADC_U8     iv[16] = {0, };
468
469         TADC_IF_MemCpy(key, g_baAESKey, 16);
470         TADC_IF_MemCpy(iv, (g_baAESKey + 16), 16);
471         ret = TADC_IF_AES_CTR(key, 16, iv, 20, hash_value, &hmac_len, hmac);
472
473         if (ret != 0) {
474                 ret = DRMTEST_ERR_CRYPTO;
475                 goto error;
476         }
477
478         // base64 encode
479         _base64_encode(hmac, 20, &hmac_base64);
480
481         // add hmac
482         strncat(tmp_buff, ";hmac=", strlen(";hmac="));
483         strncat(tmp_buff, hmac_base64, strlen(hmac_base64));
484
485         // make return value
486         resp_data = (char *) malloc(strlen(tmp_buff) + 1);
487
488         if (resp_data == NULL) {
489                 ret = DRMTEST_ERR_MEMORY;
490                 goto error;
491         }
492
493         memset(resp_data, 0, strlen(tmp_buff) + 1);
494         strncpy(resp_data, tmp_buff, strlen(tmp_buff));
495
496         *response_data = resp_data;
497
498 error:
499
500         if (hmac_base64 != NULL)
501                 free(hmac_base64);
502
503         if (ret != DRMTEST_SUCCESS && resp_data != NULL)
504                 free(resp_data);
505
506         return ret;
507 }
508
509 int _create_time_stamp(const unsigned char *dh_secret_key, char **time_stamp)
510 {
511         int ret = DRMTEST_SUCCESS;
512
513         char tmp_time_buff[128] = {0, };
514         unsigned char enc_time_buff[512] = {0, };
515         char *time_base64 = NULL;
516         int enc_time_buff_len = 0;
517         time_t now = time(NULL);
518         const struct tm *gt = gmtime(&now);
519
520         sprintf(tmp_time_buff, "%d-%d-%dT%d:%d:00:Z",
521                         gt->tm_year + 1900, gt->tm_mon + 1, gt->tm_mday,
522                         gt->tm_hour + 1, gt->tm_min + 1);
523
524         // encrypt time_stamp
525         TADC_U8 key[16] = {0, };
526         TADC_U8 iv[16] = {0, };
527
528         TADC_IF_MemCpy(key, dh_secret_key, 16);
529         TADC_IF_MemCpy(iv, (dh_secret_key + 16), 16);
530         ret = TADC_IF_AES_CTR(key, 16, iv, strlen(tmp_time_buff),
531                                                   (unsigned char *)tmp_time_buff,
532                                                   &enc_time_buff_len, enc_time_buff);
533
534         if (ret != 0) {
535                 ret = DRMTEST_ERR_CRYPTO;
536                 goto error;
537         }
538
539         // convert to base64
540         _base64_encode(enc_time_buff, enc_time_buff_len, &time_base64);
541
542         *time_stamp = time_base64;
543 error:
544
545         if (ret != DRMTEST_SUCCESS && time_base64 != NULL)
546                 free(time_base64);
547
548         return ret;
549 }
550
551 int generate_purchase_response(char **purchase_response_buff, char **req_id)
552 {
553         int ret = DRMTEST_SUCCESS;
554         char resp_buff[1024 * 5] = {0, };
555         char *resp = NULL;
556         char *rid = NULL;
557         char random[64] = {0, };
558
559         const char *format1 = "<?xml version=\"1.0\">\n";
560         const char *format2 = "<response result=\"0\" message=\"\">\n";
561         const char *format3 = "    <DRMType>%d</DRMType>\n";
562         const char *format4 = "    <riurl>%s</riurl>\n";
563         const char *format5 = "    <reqid>%s</reqid>\n";
564         const char *format6 = "</response>";
565
566         resp = (char *) malloc(sizeof(resp_buff));
567
568         if (resp == NULL) {
569                 ret = DRMTEST_ERR_MEMORY;
570                 goto error;
571         }
572
573         memset(resp, 0, sizeof(resp_buff));
574
575         __get_random_bytes(random, sizeof(random));
576         rid = (char *) malloc(1024);
577
578         if (rid == NULL) {
579                 ret = DRMTEST_ERR_MEMORY;
580                 goto error;
581         }
582
583         memset(rid, 0, 1024);
584
585         for (size_t i = 0; i < sizeof(random); i++)
586                 sprintf(rid + i * 2, "%02x", random[i]);
587
588         strncat(resp_buff, format1, strlen(format1));
589         strncat(resp_buff, format2, strlen(format2));
590         strncat(resp_buff, format3, strlen(format3));
591         strncat(resp_buff, format4, strlen(format4));
592         strncat(resp_buff, format5, strlen(format5));
593         strncat(resp_buff, format6, strlen(format6));
594
595         sprintf(resp, resp_buff, 1, RIURL, rid);
596
597         *purchase_response_buff = resp;
598         *req_id = rid;
599
600 error:
601
602         if (ret != DRMTEST_SUCCESS && resp != NULL)
603                 free(resp);
604
605         if (ret != DRMTEST_SUCCESS && rid != NULL)
606                 free(rid);
607
608         return ret;
609 }
610
611 int generate_right_object_request(const char *license_response_buff)
612 {
613         int ret = DRMTEST_SUCCESS;
614         unsigned int  req_buff_len = 1024 * 5;
615         char url_buff[1024] = {0, };
616         unsigned int  url_buff_len = sizeof(url_buff);
617         char *req_buff = NULL;
618
619         req_buff = (char *)malloc(1024 * 5);
620
621         if (req_buff == NULL) {
622                 ret = DRMTEST_ERR_MEMORY;
623                 goto error;
624         }
625
626         memset(req_buff, 0, req_buff_len);
627
628         ret = drm_tizen_generate_license_request(license_response_buff,
629                         strlen(license_response_buff),
630                         req_buff, &req_buff_len, url_buff, &url_buff_len);
631
632         if (ret != 1) {
633                 ret = DRMTEST_ERR_TIZDRM;
634                 goto error;
635         }
636
637 error:
638
639         if (ret != DRMTEST_SUCCESS && req_buff != NULL)
640                 free(req_buff);
641
642         return ret;
643 }
644
645
646 int get_dh_key_from_ro_request(const char *ro_request_buff,
647                                                            char **dh_key_p, char **dh_key_g, char **dh_key_a)
648 {
649         int ret = DRMTEST_SUCCESS;
650
651         const char *PFX_P = "p=";
652         const char *PFX_G = ";g=";
653         const char *PFX_A = ";A=";
654         const char *PFX_HMAC = ";hmac=";
655
656         const char *idx_p = strstr(ro_request_buff, PFX_P);
657         const char *idx_g = strstr(ro_request_buff, PFX_G);
658         const char *idx_a = strstr(ro_request_buff, PFX_A);
659         const char *idx_hmac = strstr(ro_request_buff, PFX_HMAC);
660
661         int len_p = idx_g - idx_p - strlen(PFX_P);
662         int len_g = idx_a - idx_g - strlen(PFX_G);
663         int len_a = idx_hmac - idx_a - strlen(PFX_A);
664
665         char *buff_p = NULL;
666         char *buff_g = NULL;
667         char *buff_a = NULL;
668
669         buff_p = (char *)malloc(len_p + 1);
670
671         if (buff_p == NULL) {
672                 ret = DRMTEST_ERR_MEMORY;
673                 goto error;
674         }
675
676         memset(buff_p, 0, len_p + 1);
677         strncpy(buff_p, idx_p + strlen(PFX_P), len_p);
678         *dh_key_p = buff_p;
679
680         buff_g = (char *)malloc(len_g + 1);
681
682         if (buff_g == NULL) {
683                 ret = DRMTEST_ERR_MEMORY;
684                 goto error;
685         }
686
687         memset(buff_g, 0, len_g + 1);
688         strncpy(buff_g, idx_g + strlen(PFX_G), len_g);
689         *dh_key_g = buff_g;
690
691         buff_a = (char *)malloc(len_a + 1);
692
693         if (buff_a == NULL) {
694                 ret = DRMTEST_ERR_MEMORY;
695                 goto error;
696         }
697
698         memset(buff_a, 0, len_a + 1);
699         strncpy(buff_a, idx_a + strlen(PFX_A), len_a);
700         *dh_key_a = buff_a;
701
702 error:
703
704         if (ret != DRMTEST_SUCCESS && buff_p != NULL)
705                 free(buff_p);
706
707         if (ret != DRMTEST_SUCCESS && buff_g != NULL)
708                 free(buff_g);
709
710         if (ret != DRMTEST_SUCCESS && buff_a != NULL)
711                 free(buff_a);
712
713         return ret;
714 }
715
716 int generate_right_object_response(const char *dh_key_p, const char *dh_key_g,
717                                                                    const char *dh_key_a,
718                                                                    const char *req_id, const char *cid,
719                                                                    const char *ro_template_path,
720                                                                    const char *duid, char **ro_response_buff)
721 {
722         int ret = DRMTEST_SUCCESS;
723
724         DH *pkey = NULL;
725         char *dh_pubkey = NULL;
726         unsigned char *dh_shared_secret_key = NULL;
727         int   dh_sec_key_len = 0;
728         char *ro_buff = NULL;
729         char *ro_signature = NULL;
730         char *ro_with_signature = NULL;
731         char *encrypted_ro = NULL;
732         char *response_data = NULL;
733         char *time_stamp = NULL;
734         char *ro_resp_buff = NULL;
735         int   ro_resp_buff_len = 0;
736
737         const char *format = "<?xml version=\"1.0\">\n"
738                                                  "<response result=\"0\" message=\"\">\n"
739                                                  "    <responsedata>%s</responsedata>\n"
740                                                  "    <timeStamp>%s</timeStamp>\n"
741                                                  "</response>";
742
743         ret = _create_dh_key(dh_key_p, dh_key_g, &pkey);
744
745         if (ret != DRMTEST_SUCCESS) {
746                 goto error;
747         }
748
749         ret = _get_dh_hex_pubkey(pkey, &dh_pubkey);
750
751         if (ret != DRMTEST_SUCCESS) {
752                 goto error;
753         }
754
755         ret = _get_dh_shared_secret_key(dh_key_a, pkey, &dh_shared_secret_key,
756                                                                         &dh_sec_key_len);
757
758         if (ret != DRMTEST_SUCCESS) {
759                 goto error;
760         }
761
762         ret = _create_right_object_without_signature(ro_template_path, cid, duid,
763                         &ro_buff);
764
765         if (ret != DRMTEST_SUCCESS) {
766                 goto error;
767         }
768
769         ret = _create_ro_signature(ro_buff, RO_ISSUER_SIGNER_KEY_FILE, &ro_signature);
770
771         if (ret != DRMTEST_SUCCESS) {
772                 goto error;
773         }
774
775         ret = _add_signature_to_ro(ro_buff, ro_signature, &ro_with_signature);
776
777         if (ret != DRMTEST_SUCCESS) {
778                 goto error;
779         }
780
781         //printf("...right object:\n%s\n", ro_with_signature);
782
783         ret = _encrypt_ro_with_dh_sec_key(ro_with_signature, dh_shared_secret_key,
784                                                                           dh_sec_key_len,
785                                                                           &encrypted_ro);
786
787         if (ret != DRMTEST_SUCCESS) {
788                 goto error;
789         }
790
791         ret = _create_response_data_in_ro_response(req_id, encrypted_ro, dh_pubkey,
792                         &response_data);
793
794         if (ret != DRMTEST_SUCCESS) {
795                 goto error;
796         }
797
798         ret = _create_time_stamp(dh_shared_secret_key, &time_stamp);
799
800         if (ret != DRMTEST_SUCCESS) {
801                 goto error;
802         }
803
804         ro_resp_buff_len = strlen(format) + strlen(response_data) + strlen(
805                                                    time_stamp) + 1;
806         ro_resp_buff = (char *) malloc(ro_resp_buff_len);
807
808         if (ro_resp_buff == NULL) {
809                 ret = DRMTEST_ERR_MEMORY;
810                 goto error;
811         }
812
813         memset(ro_resp_buff, 0, ro_resp_buff_len);
814         sprintf(ro_resp_buff, format, response_data, time_stamp);
815
816         *ro_response_buff = ro_resp_buff;
817
818 error:
819
820         if (pkey != NULL)
821                 _free_dh_key(pkey);
822
823         if (dh_pubkey != NULL)
824                 free(dh_pubkey);
825
826         if (dh_shared_secret_key != NULL)
827                 free(dh_shared_secret_key);
828
829         if (ro_buff != NULL)
830                 free(ro_buff);
831
832         if (ro_signature != NULL)
833                 free(ro_signature);
834
835         if (ro_with_signature != NULL)
836                 free(ro_with_signature);
837
838         if (encrypted_ro != NULL)
839                 free(encrypted_ro);
840
841         if (response_data != NULL)
842                 free(response_data);
843
844         if (time_stamp != NULL)
845                 free(time_stamp);
846
847         if (ret != DRMTEST_SUCCESS && ro_resp_buff != NULL)
848                 free(ro_resp_buff);
849
850         return ret;
851 }
852
853
854 int is_identical_files(const char *file1, const char *file2, int *identical)
855 {
856         int ret = DRMTEST_SUCCESS;
857
858         FILE *fp1 = NULL, *fp2 = NULL;
859         int ch1, ch2;
860
861         fp1 = fopen(file1, "r");
862
863         if (fp1 == NULL) {
864                 ret = DRMTEST_ERR_IO;
865                 goto error;
866         }
867
868         fp2 = fopen(file2, "r");
869
870         if (fp2 == NULL) {
871                 ret = DRMTEST_ERR_IO;
872                 goto error;
873         }
874
875         ch1 = getc(fp1);
876         ch2 = getc(fp2);
877
878         while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2)) {
879                 ch1 = getc(fp1);
880                 ch2 = getc(fp2);
881         }
882
883         if (ch1 == ch2)
884                 *identical = DRMTEST_IDENTICAL;
885         else
886                 *identical = DRMTEST_NOTIDENTICAL;
887
888 error:
889
890         if (fp1 != NULL)
891                 fclose(fp1);
892
893         if (fp2 != NULL)
894                 fclose(fp2);
895
896         return ret;
897 }
898