aboutsummaryrefslogtreecommitdiffstats
path: root/src/cnki_kdh.c
blob: b13434d721e86b7e35973648ba2344f04267bb68 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright (c) 2020-2021, yzrh <yzrh@noema.org>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "cnki.h"

int
cnki_kdh(cnki_t **param)
{
	if (*param == NULL)
		return 1;

	if ((*param)->stat > 0)
		printf("Begin 'KDH' decryption\n");

	fseek((*param)->fp_i, 0, SEEK_END);

	long size = ftell((*param)->fp_i);

	fseek((*param)->fp_i, ADDRESS_KDH_BODY, SEEK_SET);

	const char key[] = KEY_KDH;
	const int key_len = KEY_KDH_LENGTH;
	long key_cur = 0;

	char buf[(*param)->size_buf];

	FILE *tmp = tmpfile();

	if (tmp == NULL)
		return 1;

	for (;;) {
		fread(buf, (*param)->size_buf, 1, (*param)->fp_i);

		for (int i = 0; i < (*param)->size_buf; i++) {
			buf[i] ^= key[key_cur % key_len];
			key_cur++;
		}

		fwrite(buf, (*param)->size_buf, 1, tmp);

		if (ftell((*param)->fp_i) == size)
			break;
	}

	if ((*param)->stat > 0)
		printf("Decrypted %ld byte(s)\n", ftell(tmp));

	fseek(tmp, 0, SEEK_SET);

	FILE *orig = (*param)->fp_i;
	(*param)->fp_i = tmp;

	cnki_pdf(param);

	(*param)->fp_i = orig;
	fclose(tmp);

	if ((*param)->stat > 0)
		printf("Conversion ended\n");

	return 0;
}