1 : /* -*- mode: C -*-
2 : *
3 : * File: pdf-stm-f-v2.c
4 : * Date: Tue Jul 10 23:44:00 2007
5 : *
6 : * GNU PDF Library - V2 stream filter
7 : *
8 : */
9 :
10 : /* Copyright (C) 2008, 2009 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 <pdf-stm-f-v2.h>
29 : #include <pdf-hash-helper.h>
30 :
31 :
32 : /* Internal state */
33 : struct pdf_stm_f_v2_s
34 : {
35 : pdf_crypt_cipher_t cipher;
36 : };
37 : typedef struct pdf_stm_f_v2_s * pdf_stm_f_v2_t;
38 :
39 :
40 : /* Encryption and decryption */
41 : enum pdf_stm_f_v2_mode_e
42 : {
43 : PDF_STM_F_V2_MODE_ENCODE,
44 : PDF_STM_F_V2_MODE_DECODE
45 : };
46 : typedef enum pdf_stm_f_v2_mode_e pdf_stm_f_v2_mode_t;
47 :
48 :
49 :
50 : static inline pdf_status_t
51 : pdf_stm_f_v2_init (pdf_hash_t params, void **state)
52 3 : {
53 : pdf_status_t ret;
54 : pdf_stm_f_v2_t filter_state;
55 :
56 3 : filter_state = pdf_alloc (sizeof (struct pdf_stm_f_v2_s));
57 :
58 3 : if (filter_state == NULL)
59 : {
60 0 : ret = PDF_ENOMEM;
61 : }
62 3 : else if (state == NULL)
63 : {
64 0 : pdf_dealloc (filter_state);
65 0 : ret = PDF_EBADDATA;
66 : }
67 : else
68 : {
69 : pdf_char_t *key;
70 : pdf_size_t keysize;
71 : pdf_crypt_cipher_t cipher;
72 :
73 : /* We demand all parameters are present */
74 3 : if ((( pdf_hash_key_p (params, "Key") == PDF_TRUE))
75 : && pdf_hash_key_p (params, "KeySize") == PDF_TRUE)
76 : {
77 2 : pdf_hash_get_string (params, "Key", &key);
78 2 : pdf_hash_get_size (params, "KeySize", &keysize);
79 :
80 2 : ret = pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
81 2 : if (ret == PDF_OK)
82 : {
83 4 : ret = pdf_crypt_cipher_setkey (cipher, key, keysize);
84 2 : if (ret == PDF_OK)
85 : {
86 2 : filter_state->cipher = cipher;
87 2 : *state = filter_state;
88 : }
89 : }
90 :
91 2 : if (ret != PDF_OK)
92 : {
93 0 : pdf_dealloc (filter_state);
94 : }
95 : }
96 : else
97 : {
98 1 : pdf_dealloc (filter_state);
99 1 : ret = PDF_EBADDATA;
100 : }
101 : }
102 :
103 3 : return ret;
104 : }
105 :
106 :
107 : static inline pdf_status_t
108 : pdf_stm_f_v2_apply (pdf_stm_f_v2_mode_t mode,
109 : pdf_hash_t params, void *state, pdf_buffer_t in,
110 : pdf_buffer_t out, pdf_bool_t finish_p)
111 8 : {
112 8 : pdf_stm_f_v2_t filter_state = state;
113 :
114 : pdf_size_t in_size;
115 : pdf_size_t out_size;
116 : pdf_size_t bytes_to_copy;
117 : pdf_size_t written;
118 : pdf_status_t ret;
119 :
120 8 : in_size = in->wp - in->rp;
121 8 : out_size = out->size - out->wp;
122 :
123 8 : bytes_to_copy = PDF_MIN(out_size, in_size);
124 :
125 8 : if (bytes_to_copy != 0)
126 : {
127 2 : if (mode == PDF_STM_F_V2_MODE_ENCODE)
128 : {
129 1 : pdf_crypt_cipher_encrypt (filter_state->cipher,
130 : out->data,
131 : out_size,
132 : in->data,
133 : in_size,
134 : &written);
135 : }
136 1 : else if (mode == PDF_STM_F_V2_MODE_DECODE)
137 : {
138 1 : pdf_crypt_cipher_decrypt (filter_state->cipher,
139 : out->data,
140 : out_size,
141 : in->data,
142 : in_size,
143 : &written);
144 : }
145 : else
146 : {
147 : /* This point should not be reached. */
148 : }
149 :
150 2 : in->rp += bytes_to_copy;
151 2 : out->wp += written;
152 : }
153 :
154 8 : if (in_size > out_size)
155 : {
156 : /* We need more room in the output buffer */
157 0 : ret = PDF_ENOUTPUT;
158 : }
159 : else
160 : {
161 : /* We can process more input */
162 8 : ret = PDF_ENINPUT;
163 : }
164 :
165 8 : return ret;
166 : }
167 :
168 :
169 : static inline pdf_status_t
170 : pdf_stm_f_v2_dealloc_state (void *state)
171 2 : {
172 2 : pdf_stm_f_v2_t filter_state = state;
173 2 : pdf_crypt_cipher_destroy (filter_state->cipher);
174 2 : pdf_dealloc (state);
175 2 : return PDF_OK;
176 : }
177 :
178 :
179 :
180 : /* Encode filter */
181 :
182 : pdf_status_t
183 : pdf_stm_f_v2enc_init (pdf_hash_t params, void **state)
184 2 : {
185 2 : return pdf_stm_f_v2_init (params, state);
186 : }
187 :
188 : pdf_status_t
189 : pdf_stm_f_v2enc_apply (pdf_hash_t params, void *state, pdf_buffer_t in,
190 : pdf_buffer_t out, pdf_bool_t finish_p)
191 5 : {
192 5 : return pdf_stm_f_v2_apply (PDF_STM_F_V2_MODE_ENCODE,
193 : params, state, in, out, finish_p);
194 : }
195 :
196 : pdf_status_t
197 : pdf_stm_f_v2enc_dealloc_state (void *state)
198 1 : {
199 1 : return pdf_stm_f_v2_dealloc_state (state);
200 : }
201 :
202 :
203 : /* Decode filter */
204 :
205 : pdf_status_t
206 : pdf_stm_f_v2dec_init (pdf_hash_t params, void **state)
207 1 : {
208 1 : return pdf_stm_f_v2_init (params, state);
209 : }
210 :
211 :
212 : pdf_status_t
213 : pdf_stm_f_v2dec_apply (pdf_hash_t params, void *state, pdf_buffer_t in,
214 : pdf_buffer_t out, pdf_bool_t finish_p)
215 3 : {
216 3 : return pdf_stm_f_v2_apply (PDF_STM_F_V2_MODE_DECODE,
217 : params, state, in, out, finish_p);
218 : }
219 :
220 :
221 : pdf_status_t
222 : pdf_stm_f_v2dec_dealloc_state (void *state)
223 1 : {
224 1 : return pdf_stm_f_v2_dealloc_state (state);
225 : }
226 :
227 :
228 : /* End of pdf_stm_f_v2.c */
|