1 : /* -*- mode: C -*-
2 : *
3 : * File: pdf-stm-f-md5.c
4 : * Date: Fri Dec 5 16:40:50 2008
5 : *
6 : * GNU PDF Library - Message-digest 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 <string.h>
29 :
30 : #include <pdf-stm-f-md5.h>
31 :
32 : #define MD5_OUTPUT_SIZE 16
33 :
34 :
35 :
36 : /* Internal state */
37 : struct pdf_stm_f_md5_s
38 : {
39 : pdf_crypt_md_t md;
40 : pdf_buffer_t cache;
41 : };
42 : typedef struct pdf_stm_f_md5_s * pdf_stm_f_md5_t;
43 :
44 :
45 :
46 : pdf_status_t
47 : pdf_stm_f_md5enc_init (pdf_hash_t params, void **state)
48 1 : {
49 : pdf_status_t ret;
50 : pdf_stm_f_md5_t filter_state;
51 :
52 1 : filter_state = pdf_alloc (sizeof (struct pdf_stm_f_md5_s));
53 :
54 1 : if (filter_state == NULL)
55 : {
56 0 : ret = PDF_ENOMEM;
57 : }
58 1 : else if (state == NULL)
59 : {
60 0 : pdf_dealloc (filter_state);
61 0 : ret = PDF_EBADDATA;
62 : }
63 : else
64 : {
65 : pdf_crypt_md_t md;
66 :
67 1 : if (pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md) == PDF_OK)
68 : {
69 1 : filter_state->md = md;
70 1 : filter_state->cache = pdf_buffer_new (MD5_OUTPUT_SIZE);
71 :
72 1 : if (filter_state->cache == NULL)
73 : {
74 0 : pdf_dealloc (filter_state);
75 0 : ret = PDF_ERROR;
76 : }
77 : else
78 : {
79 1 : *state = filter_state;
80 1 : ret = PDF_OK;
81 : }
82 : }
83 : else
84 : {
85 0 : pdf_dealloc (filter_state);
86 0 : ret = PDF_EBADDATA;
87 : }
88 : }
89 1 : return ret;
90 : }
91 :
92 :
93 :
94 : pdf_status_t
95 : pdf_stm_f_md5enc_apply (pdf_hash_t params, void *state, pdf_buffer_t in,
96 : pdf_buffer_t out, pdf_bool_t finish_p)
97 3 : {
98 3 : pdf_stm_f_md5_t filter_state = state;
99 3 : pdf_buffer_t cache = filter_state->cache;
100 : pdf_size_t in_size;
101 : pdf_status_t ret;
102 :
103 3 : in_size = in->wp - in->rp;
104 :
105 3 : pdf_crypt_md_write (filter_state->md, in->data, in_size);
106 3 : in->rp += in_size;
107 3 : ret = PDF_ENINPUT;
108 :
109 3 : if (finish_p == PDF_TRUE)
110 : {
111 : pdf_size_t bytes_to_write;
112 : pdf_size_t cache_size;
113 : pdf_size_t out_size;
114 :
115 1 : if (pdf_buffer_eob_p (cache))
116 : {
117 : /* If we have reached the end, read the hash value in cache */
118 1 : pdf_crypt_md_read (filter_state->md, cache->data, cache->size);
119 1 : cache->wp = cache->size;
120 : }
121 :
122 1 : out_size = out->size - out->wp;
123 1 : cache_size = cache->wp - cache->rp;
124 1 : bytes_to_write = PDF_MIN (out_size, cache_size);
125 :
126 1 : memcpy (out->data, cache->data + cache->rp, bytes_to_write);
127 :
128 1 : cache->rp += bytes_to_write;
129 1 : out->wp += bytes_to_write;
130 :
131 1 : if (out_size < cache_size)
132 0 : ret = PDF_ENOUTPUT;
133 : else
134 1 : ret = PDF_EEOF;
135 : }
136 :
137 3 : return ret;
138 : }
139 :
140 :
141 :
142 : pdf_status_t
143 : pdf_stm_f_md5enc_dealloc_state (void *state)
144 1 : {
145 1 : pdf_stm_f_md5_t filter_state = state;
146 1 : pdf_crypt_md_destroy (filter_state->md);
147 1 : pdf_buffer_destroy (filter_state->cache);
148 1 : pdf_dealloc (state);
149 1 : return PDF_OK;
150 : }
151 :
152 :
153 :
154 : /* End of pdf_stm_f_md5.c */
|