Branch data Line data Source code
1 : : /* -*- mode: C -*-
2 : : *
3 : : * File: pdf-crypt.c
4 : : * Date: Fri Feb 22 21:05:05 2008
5 : : *
6 : : * GNU PDF Library - V2 backend encryption module
7 : : *
8 : : */
9 : :
10 : : /* Copyright (C) 2008 Free Software Foundation, Inc. */
11 : :
12 : : /* This program is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU General Public License as published by
14 : : * the Free Software Foundation, either version 3 of the License, or
15 : : * (at your option) any later version.
16 : : *
17 : : * This program is distributed in the hope that it will be useful,
18 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : * GNU General Public License for more details.
21 : : *
22 : : * You should have received a copy of the GNU General Public License
23 : : * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : : */
25 : :
26 : : #include <config.h>
27 : :
28 : : #include <stdlib.h>
29 : : #include <string.h>
30 : : #include <gcrypt.h>
31 : :
32 : : #include <pdf-alloc.h>
33 : : #include <pdf-types.h>
34 : : #include <pdf-error.h>
35 : : #include <pdf-crypt-c-v2.h>
36 : :
37 : : struct pdf_crypt_cipher_v2_s {
38 : : /* Implementation */
39 : : struct pdf_crypt_cipher_s parent;
40 : : /* Implementation-specific private data */
41 : : gcry_cipher_hd_t hd;
42 : : };
43 : :
44 : : static pdf_bool_t
45 : 23 : v2_set_key (pdf_crypt_cipher_t *cipher,
46 : : const pdf_char_t *key,
47 : : pdf_size_t size,
48 : : pdf_error_t **error)
49 : : {
50 : 23 : struct pdf_crypt_cipher_v2_s *v2 = (struct pdf_crypt_cipher_v2_s *)cipher;
51 : : gcry_error_t gcry_error;
52 : :
53 : 23 : gcry_error = gcry_cipher_setkey (v2->hd, key, size);
54 [ - + ]: 23 : if (gcry_error != GPG_ERR_NO_ERROR)
55 : : {
56 : 0 : pdf_set_error (error,
57 : : PDF_EDOMAIN_BASE_ENCRYPTION,
58 : : PDF_EBADV2KEY,
59 : : "cannot set key in V2 cipher: '%s/%s'",
60 : : gcry_strsource (gcry_error),
61 : : gcry_strerror (gcry_error));
62 : 0 : return PDF_FALSE;
63 : : }
64 : 23 : return PDF_TRUE;
65 : : }
66 : :
67 : : static pdf_bool_t
68 : 21 : v2_encrypt (pdf_crypt_cipher_t *cipher,
69 : : pdf_char_t *out,
70 : : pdf_size_t out_size,
71 : : const pdf_char_t *in,
72 : : pdf_size_t in_size,
73 : : pdf_size_t *result_size,
74 : : pdf_error_t **error)
75 : : {
76 : 21 : struct pdf_crypt_cipher_v2_s *v2 = (struct pdf_crypt_cipher_v2_s *)cipher;
77 : : gcry_error_t gcry_error;
78 : :
79 : 21 : gcry_error = gcry_cipher_encrypt (v2->hd, out, out_size, in, in_size);
80 [ - + ]: 21 : if (gcry_error != GPG_ERR_NO_ERROR)
81 : : {
82 : 0 : pdf_set_error (error,
83 : : PDF_EDOMAIN_BASE_ENCRYPTION,
84 : : PDF_ENOMEM,
85 : : "cannot set key in V2 cipher: '%s/%s'",
86 : : gcry_strsource (gcry_error),
87 : : gcry_strerror (gcry_error));
88 : 0 : return PDF_FALSE;
89 : : }
90 : :
91 [ + - ]: 21 : if (result_size)
92 : 21 : *result_size = in_size;
93 : :
94 : 21 : return PDF_TRUE;
95 : : }
96 : :
97 : : static pdf_bool_t
98 : 1 : v2_decrypt (pdf_crypt_cipher_t *cipher,
99 : : pdf_char_t *out,
100 : : pdf_size_t out_size,
101 : : const pdf_char_t *in,
102 : : pdf_size_t in_size,
103 : : pdf_size_t *result_size,
104 : : pdf_error_t **error)
105 : : {
106 : 1 : struct pdf_crypt_cipher_v2_s *v2 = (struct pdf_crypt_cipher_v2_s *)cipher;
107 : : gcry_error_t gcry_error;
108 : :
109 : 1 : gcry_error = gcry_cipher_decrypt (v2->hd, out, out_size, in, in_size);
110 [ - + ]: 1 : if (gcry_error != GPG_ERR_NO_ERROR)
111 : : {
112 : 0 : pdf_set_error (error,
113 : : PDF_EDOMAIN_BASE_ENCRYPTION,
114 : : PDF_ENOMEM,
115 : : "cannot set key in V2 cipher: '%s/%s'",
116 : : gcry_strsource (gcry_error),
117 : : gcry_strerror (gcry_error));
118 : 0 : return PDF_FALSE;
119 : : }
120 : :
121 [ + - ]: 1 : if (result_size)
122 : 1 : *result_size = in_size;
123 : :
124 : 1 : return PDF_TRUE;
125 : : }
126 : :
127 : : static void
128 : 24 : v2_destroy (pdf_crypt_cipher_t *cipher)
129 : : {
130 : 24 : struct pdf_crypt_cipher_v2_s *v2 = (struct pdf_crypt_cipher_v2_s *)cipher;
131 : :
132 : 24 : gcry_cipher_close (v2->hd);
133 : 24 : pdf_dealloc (v2);
134 : 24 : }
135 : :
136 : : /* Implementation of the cipher module */
137 : : static const struct pdf_crypt_cipher_s implementation = {
138 : : .set_key = v2_set_key,
139 : : .encrypt = v2_encrypt,
140 : : .decrypt = v2_decrypt,
141 : : .destroy = v2_destroy
142 : : };
143 : :
144 : : pdf_crypt_cipher_t *
145 : 24 : pdf_crypt_cipher_v2_new (pdf_error_t **error)
146 : : {
147 : : gcry_error_t gcry_error;
148 : : struct pdf_crypt_cipher_v2_s *cipher;
149 : :
150 : 24 : cipher = pdf_alloc (sizeof (struct pdf_crypt_cipher_v2_s));
151 [ - + ]: 24 : if (!cipher)
152 : : {
153 : 0 : pdf_set_error (error,
154 : : PDF_EDOMAIN_BASE_ENCRYPTION,
155 : : PDF_ENOMEM,
156 : : "cannot create new V2 cipher object: "
157 : : "couldn't allocate %lu bytes",
158 : : (unsigned long)sizeof (struct pdf_crypt_cipher_v2_s));
159 : 0 : return NULL;
160 : : }
161 : :
162 : : /* Set implementation API */
163 : 24 : cipher->parent = implementation;
164 : :
165 : : /* Initialize cipher object */
166 : 24 : gcry_error = gcry_cipher_open (&(cipher->hd),
167 : : GCRY_CIPHER_ARCFOUR,
168 : : GCRY_CIPHER_MODE_STREAM,
169 : : 0);
170 [ - + ]: 24 : if (gcry_error != GPG_ERR_NO_ERROR)
171 : : {
172 : 0 : pdf_set_error (error,
173 : : PDF_EDOMAIN_BASE_ENCRYPTION,
174 : : PDF_ENOMEM,
175 : : "cannot initialize V2 cipher: '%s/%s'",
176 : : gcry_strsource (gcry_error),
177 : : gcry_strerror (gcry_error));
178 : 0 : pdf_dealloc (cipher);
179 : 0 : return NULL;
180 : : }
181 : :
182 : 24 : return (pdf_crypt_cipher_t *)cipher;
183 : : }
184 : :
185 : : /* End of pdf-crypt-c-v2.c */
|