1*ebfedea0SLionel Sambuc /*-
2*ebfedea0SLionel Sambuc * Copyright (c) 2009 The NetBSD Foundation, Inc.
3*ebfedea0SLionel Sambuc * All rights reserved.
4*ebfedea0SLionel Sambuc *
5*ebfedea0SLionel Sambuc * This code is derived from software contributed to The NetBSD Foundation
6*ebfedea0SLionel Sambuc * by Alistair Crooks (agc@NetBSD.org)
7*ebfedea0SLionel Sambuc *
8*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10*ebfedea0SLionel Sambuc * are met:
11*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
12*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
13*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
14*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
15*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
16*ebfedea0SLionel Sambuc *
17*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18*ebfedea0SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*ebfedea0SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20*ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21*ebfedea0SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*ebfedea0SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*ebfedea0SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*ebfedea0SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*ebfedea0SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*ebfedea0SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
28*ebfedea0SLionel Sambuc */
29*ebfedea0SLionel Sambuc /*
30*ebfedea0SLionel Sambuc * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31*ebfedea0SLionel Sambuc * All rights reserved.
32*ebfedea0SLionel Sambuc * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33*ebfedea0SLionel Sambuc * their moral rights under the UK Copyright Design and Patents Act 1988 to
34*ebfedea0SLionel Sambuc * be recorded as the authors of this copyright work.
35*ebfedea0SLionel Sambuc *
36*ebfedea0SLionel Sambuc * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37*ebfedea0SLionel Sambuc * use this file except in compliance with the License.
38*ebfedea0SLionel Sambuc *
39*ebfedea0SLionel Sambuc * You may obtain a copy of the License at
40*ebfedea0SLionel Sambuc * http://www.apache.org/licenses/LICENSE-2.0
41*ebfedea0SLionel Sambuc *
42*ebfedea0SLionel Sambuc * Unless required by applicable law or agreed to in writing, software
43*ebfedea0SLionel Sambuc * distributed under the License is distributed on an "AS IS" BASIS,
44*ebfedea0SLionel Sambuc * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45*ebfedea0SLionel Sambuc *
46*ebfedea0SLionel Sambuc * See the License for the specific language governing permissions and
47*ebfedea0SLionel Sambuc * limitations under the License.
48*ebfedea0SLionel Sambuc */
49*ebfedea0SLionel Sambuc
50*ebfedea0SLionel Sambuc /** \file
51*ebfedea0SLionel Sambuc * \brief Parser for OpenPGP packets
52*ebfedea0SLionel Sambuc */
53*ebfedea0SLionel Sambuc #include "config.h"
54*ebfedea0SLionel Sambuc
55*ebfedea0SLionel Sambuc #ifdef HAVE_SYS_CDEFS_H
56*ebfedea0SLionel Sambuc #include <sys/cdefs.h>
57*ebfedea0SLionel Sambuc #endif
58*ebfedea0SLionel Sambuc
59*ebfedea0SLionel Sambuc #if defined(__NetBSD__)
60*ebfedea0SLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61*ebfedea0SLionel Sambuc __RCSID("$NetBSD: packet-parse.c,v 1.51 2012/03/05 02:20:18 christos Exp $");
62*ebfedea0SLionel Sambuc #endif
63*ebfedea0SLionel Sambuc
64*ebfedea0SLionel Sambuc #include <sys/types.h>
65*ebfedea0SLionel Sambuc #include <sys/param.h>
66*ebfedea0SLionel Sambuc
67*ebfedea0SLionel Sambuc #ifdef HAVE_OPENSSL_CAST_H
68*ebfedea0SLionel Sambuc #include <openssl/cast.h>
69*ebfedea0SLionel Sambuc #endif
70*ebfedea0SLionel Sambuc
71*ebfedea0SLionel Sambuc #include <stdarg.h>
72*ebfedea0SLionel Sambuc #include <stdlib.h>
73*ebfedea0SLionel Sambuc #include <string.h>
74*ebfedea0SLionel Sambuc
75*ebfedea0SLionel Sambuc #ifdef HAVE_UNISTD_H
76*ebfedea0SLionel Sambuc #include <unistd.h>
77*ebfedea0SLionel Sambuc #endif
78*ebfedea0SLionel Sambuc
79*ebfedea0SLionel Sambuc #ifdef HAVE_LIMITS_H
80*ebfedea0SLionel Sambuc #include <limits.h>
81*ebfedea0SLionel Sambuc #endif
82*ebfedea0SLionel Sambuc
83*ebfedea0SLionel Sambuc #include "packet.h"
84*ebfedea0SLionel Sambuc #include "packet-parse.h"
85*ebfedea0SLionel Sambuc #include "keyring.h"
86*ebfedea0SLionel Sambuc #include "errors.h"
87*ebfedea0SLionel Sambuc #include "packet-show.h"
88*ebfedea0SLionel Sambuc #include "create.h"
89*ebfedea0SLionel Sambuc #include "readerwriter.h"
90*ebfedea0SLionel Sambuc #include "netpgpdefs.h"
91*ebfedea0SLionel Sambuc #include "crypto.h"
92*ebfedea0SLionel Sambuc #include "netpgpdigest.h"
93*ebfedea0SLionel Sambuc
94*ebfedea0SLionel Sambuc #define ERRP(cbinfo, cont, err) do { \
95*ebfedea0SLionel Sambuc cont.u.error = err; \
96*ebfedea0SLionel Sambuc CALLBACK(PGP_PARSER_ERROR, cbinfo, &cont); \
97*ebfedea0SLionel Sambuc return 0; \
98*ebfedea0SLionel Sambuc /*NOTREACHED*/ \
99*ebfedea0SLionel Sambuc } while(/*CONSTCOND*/0)
100*ebfedea0SLionel Sambuc
101*ebfedea0SLionel Sambuc /**
102*ebfedea0SLionel Sambuc * limread_data reads the specified amount of the subregion's data
103*ebfedea0SLionel Sambuc * into a data_t structure
104*ebfedea0SLionel Sambuc *
105*ebfedea0SLionel Sambuc * \param data Empty structure which will be filled with data
106*ebfedea0SLionel Sambuc * \param len Number of octets to read
107*ebfedea0SLionel Sambuc * \param subregion
108*ebfedea0SLionel Sambuc * \param stream How to parse
109*ebfedea0SLionel Sambuc *
110*ebfedea0SLionel Sambuc * \return 1 on success, 0 on failure
111*ebfedea0SLionel Sambuc */
112*ebfedea0SLionel Sambuc static int
limread_data(pgp_data_t * data,unsigned len,pgp_region_t * subregion,pgp_stream_t * stream)113*ebfedea0SLionel Sambuc limread_data(pgp_data_t *data, unsigned len,
114*ebfedea0SLionel Sambuc pgp_region_t *subregion, pgp_stream_t *stream)
115*ebfedea0SLionel Sambuc {
116*ebfedea0SLionel Sambuc data->len = len;
117*ebfedea0SLionel Sambuc
118*ebfedea0SLionel Sambuc if (subregion->length - subregion->readc < len) {
119*ebfedea0SLionel Sambuc (void) fprintf(stderr, "limread_data: bad length\n");
120*ebfedea0SLionel Sambuc return 0;
121*ebfedea0SLionel Sambuc }
122*ebfedea0SLionel Sambuc
123*ebfedea0SLionel Sambuc data->contents = calloc(1, data->len);
124*ebfedea0SLionel Sambuc if (!data->contents) {
125*ebfedea0SLionel Sambuc return 0;
126*ebfedea0SLionel Sambuc }
127*ebfedea0SLionel Sambuc
128*ebfedea0SLionel Sambuc return pgp_limited_read(stream, data->contents, data->len, subregion,
129*ebfedea0SLionel Sambuc &stream->errors, &stream->readinfo, &stream->cbinfo);
130*ebfedea0SLionel Sambuc }
131*ebfedea0SLionel Sambuc
132*ebfedea0SLionel Sambuc /**
133*ebfedea0SLionel Sambuc * read_data reads the remainder of the subregion's data
134*ebfedea0SLionel Sambuc * into a data_t structure
135*ebfedea0SLionel Sambuc *
136*ebfedea0SLionel Sambuc * \param data
137*ebfedea0SLionel Sambuc * \param subregion
138*ebfedea0SLionel Sambuc * \param stream
139*ebfedea0SLionel Sambuc *
140*ebfedea0SLionel Sambuc * \return 1 on success, 0 on failure
141*ebfedea0SLionel Sambuc */
142*ebfedea0SLionel Sambuc static int
read_data(pgp_data_t * data,pgp_region_t * region,pgp_stream_t * stream)143*ebfedea0SLionel Sambuc read_data(pgp_data_t *data, pgp_region_t *region, pgp_stream_t *stream)
144*ebfedea0SLionel Sambuc {
145*ebfedea0SLionel Sambuc int cc;
146*ebfedea0SLionel Sambuc
147*ebfedea0SLionel Sambuc cc = region->length - region->readc;
148*ebfedea0SLionel Sambuc return (cc >= 0) ? limread_data(data, (unsigned)cc, region, stream) : 0;
149*ebfedea0SLionel Sambuc }
150*ebfedea0SLionel Sambuc
151*ebfedea0SLionel Sambuc /**
152*ebfedea0SLionel Sambuc * Reads the remainder of the subregion as a string.
153*ebfedea0SLionel Sambuc * It is the user's responsibility to free the memory allocated here.
154*ebfedea0SLionel Sambuc */
155*ebfedea0SLionel Sambuc
156*ebfedea0SLionel Sambuc static int
read_unsig_str(uint8_t ** str,pgp_region_t * subregion,pgp_stream_t * stream)157*ebfedea0SLionel Sambuc read_unsig_str(uint8_t **str, pgp_region_t *subregion,
158*ebfedea0SLionel Sambuc pgp_stream_t *stream)
159*ebfedea0SLionel Sambuc {
160*ebfedea0SLionel Sambuc size_t len;
161*ebfedea0SLionel Sambuc
162*ebfedea0SLionel Sambuc len = subregion->length - subregion->readc;
163*ebfedea0SLionel Sambuc if ((*str = calloc(1, len + 1)) == NULL) {
164*ebfedea0SLionel Sambuc return 0;
165*ebfedea0SLionel Sambuc }
166*ebfedea0SLionel Sambuc if (len &&
167*ebfedea0SLionel Sambuc !pgp_limited_read(stream, *str, len, subregion, &stream->errors,
168*ebfedea0SLionel Sambuc &stream->readinfo, &stream->cbinfo)) {
169*ebfedea0SLionel Sambuc return 0;
170*ebfedea0SLionel Sambuc }
171*ebfedea0SLionel Sambuc (*str)[len] = '\0';
172*ebfedea0SLionel Sambuc return 1;
173*ebfedea0SLionel Sambuc }
174*ebfedea0SLionel Sambuc
175*ebfedea0SLionel Sambuc static int
read_string(char ** str,pgp_region_t * subregion,pgp_stream_t * stream)176*ebfedea0SLionel Sambuc read_string(char **str, pgp_region_t *subregion, pgp_stream_t *stream)
177*ebfedea0SLionel Sambuc {
178*ebfedea0SLionel Sambuc return read_unsig_str((uint8_t **) str, subregion, stream);
179*ebfedea0SLionel Sambuc }
180*ebfedea0SLionel Sambuc
181*ebfedea0SLionel Sambuc void
pgp_init_subregion(pgp_region_t * subregion,pgp_region_t * region)182*ebfedea0SLionel Sambuc pgp_init_subregion(pgp_region_t *subregion, pgp_region_t *region)
183*ebfedea0SLionel Sambuc {
184*ebfedea0SLionel Sambuc (void) memset(subregion, 0x0, sizeof(*subregion));
185*ebfedea0SLionel Sambuc subregion->parent = region;
186*ebfedea0SLionel Sambuc }
187*ebfedea0SLionel Sambuc
188*ebfedea0SLionel Sambuc /*
189*ebfedea0SLionel Sambuc * XXX: replace pgp_ptag_t with something more appropriate for limiting reads
190*ebfedea0SLionel Sambuc */
191*ebfedea0SLionel Sambuc
192*ebfedea0SLionel Sambuc /**
193*ebfedea0SLionel Sambuc * low-level function to read data from reader function
194*ebfedea0SLionel Sambuc *
195*ebfedea0SLionel Sambuc * Use this function, rather than calling the reader directly.
196*ebfedea0SLionel Sambuc *
197*ebfedea0SLionel Sambuc * If the accumulate flag is set in *stream, the function
198*ebfedea0SLionel Sambuc * adds the read data to the accumulated data, and updates
199*ebfedea0SLionel Sambuc * the accumulated length. This is useful if, for example,
200*ebfedea0SLionel Sambuc * the application wants access to the raw data as well as the
201*ebfedea0SLionel Sambuc * parsed data.
202*ebfedea0SLionel Sambuc *
203*ebfedea0SLionel Sambuc * This function will also try to read the entire amount asked for, but not
204*ebfedea0SLionel Sambuc * if it is over INT_MAX. Obviously many callers will know that they
205*ebfedea0SLionel Sambuc * never ask for that much and so can avoid the extra complexity of
206*ebfedea0SLionel Sambuc * dealing with return codes and filled-in lengths.
207*ebfedea0SLionel Sambuc *
208*ebfedea0SLionel Sambuc * \param *dest
209*ebfedea0SLionel Sambuc * \param *plength
210*ebfedea0SLionel Sambuc * \param flags
211*ebfedea0SLionel Sambuc * \param *stream
212*ebfedea0SLionel Sambuc *
213*ebfedea0SLionel Sambuc * \return PGP_R_OK
214*ebfedea0SLionel Sambuc * \return PGP_R_PARTIAL_READ
215*ebfedea0SLionel Sambuc * \return PGP_R_EOF
216*ebfedea0SLionel Sambuc * \return PGP_R_EARLY_EOF
217*ebfedea0SLionel Sambuc *
218*ebfedea0SLionel Sambuc * \sa #pgp_reader_ret_t for details of return codes
219*ebfedea0SLionel Sambuc */
220*ebfedea0SLionel Sambuc
221*ebfedea0SLionel Sambuc static int
sub_base_read(pgp_stream_t * stream,void * dest,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)222*ebfedea0SLionel Sambuc sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
223*ebfedea0SLionel Sambuc pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
224*ebfedea0SLionel Sambuc {
225*ebfedea0SLionel Sambuc size_t n;
226*ebfedea0SLionel Sambuc
227*ebfedea0SLionel Sambuc /* reading more than this would look like an error */
228*ebfedea0SLionel Sambuc if (length > INT_MAX)
229*ebfedea0SLionel Sambuc length = INT_MAX;
230*ebfedea0SLionel Sambuc
231*ebfedea0SLionel Sambuc for (n = 0; n < length;) {
232*ebfedea0SLionel Sambuc int r;
233*ebfedea0SLionel Sambuc
234*ebfedea0SLionel Sambuc r = readinfo->reader(stream, (char *) dest + n, length - n, errors,
235*ebfedea0SLionel Sambuc readinfo, cbinfo);
236*ebfedea0SLionel Sambuc if (r > (int)(length - n)) {
237*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sub_base_read: bad read\n");
238*ebfedea0SLionel Sambuc return 0;
239*ebfedea0SLionel Sambuc }
240*ebfedea0SLionel Sambuc if (r < 0) {
241*ebfedea0SLionel Sambuc return r;
242*ebfedea0SLionel Sambuc }
243*ebfedea0SLionel Sambuc if (r == 0) {
244*ebfedea0SLionel Sambuc break;
245*ebfedea0SLionel Sambuc }
246*ebfedea0SLionel Sambuc n += (unsigned)r;
247*ebfedea0SLionel Sambuc }
248*ebfedea0SLionel Sambuc
249*ebfedea0SLionel Sambuc if (n == 0) {
250*ebfedea0SLionel Sambuc return 0;
251*ebfedea0SLionel Sambuc }
252*ebfedea0SLionel Sambuc if (readinfo->accumulate) {
253*ebfedea0SLionel Sambuc if (readinfo->asize < readinfo->alength) {
254*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sub_base_read: bad size\n");
255*ebfedea0SLionel Sambuc return 0;
256*ebfedea0SLionel Sambuc }
257*ebfedea0SLionel Sambuc if (readinfo->alength + n > readinfo->asize) {
258*ebfedea0SLionel Sambuc uint8_t *temp;
259*ebfedea0SLionel Sambuc
260*ebfedea0SLionel Sambuc readinfo->asize = (readinfo->asize * 2) + (unsigned)n;
261*ebfedea0SLionel Sambuc temp = realloc(readinfo->accumulated, readinfo->asize);
262*ebfedea0SLionel Sambuc if (temp == NULL) {
263*ebfedea0SLionel Sambuc (void) fprintf(stderr,
264*ebfedea0SLionel Sambuc "sub_base_read: bad alloc\n");
265*ebfedea0SLionel Sambuc return 0;
266*ebfedea0SLionel Sambuc }
267*ebfedea0SLionel Sambuc readinfo->accumulated = temp;
268*ebfedea0SLionel Sambuc }
269*ebfedea0SLionel Sambuc if (readinfo->asize < readinfo->alength + n) {
270*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sub_base_read: bad realloc\n");
271*ebfedea0SLionel Sambuc return 0;
272*ebfedea0SLionel Sambuc }
273*ebfedea0SLionel Sambuc (void) memcpy(readinfo->accumulated + readinfo->alength, dest,
274*ebfedea0SLionel Sambuc n);
275*ebfedea0SLionel Sambuc }
276*ebfedea0SLionel Sambuc /* we track length anyway, because it is used for packet offsets */
277*ebfedea0SLionel Sambuc readinfo->alength += (unsigned)n;
278*ebfedea0SLionel Sambuc /* and also the position */
279*ebfedea0SLionel Sambuc readinfo->position += (unsigned)n;
280*ebfedea0SLionel Sambuc
281*ebfedea0SLionel Sambuc return (int)n;
282*ebfedea0SLionel Sambuc }
283*ebfedea0SLionel Sambuc
284*ebfedea0SLionel Sambuc int
pgp_stacked_read(pgp_stream_t * stream,void * dest,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)285*ebfedea0SLionel Sambuc pgp_stacked_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
286*ebfedea0SLionel Sambuc pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
287*ebfedea0SLionel Sambuc {
288*ebfedea0SLionel Sambuc return sub_base_read(stream, dest, length, errors, readinfo->next, cbinfo);
289*ebfedea0SLionel Sambuc }
290*ebfedea0SLionel Sambuc
291*ebfedea0SLionel Sambuc /* This will do a full read so long as length < MAX_INT */
292*ebfedea0SLionel Sambuc static int
base_read(uint8_t * dest,size_t length,pgp_stream_t * stream)293*ebfedea0SLionel Sambuc base_read(uint8_t *dest, size_t length, pgp_stream_t *stream)
294*ebfedea0SLionel Sambuc {
295*ebfedea0SLionel Sambuc return sub_base_read(stream, dest, length, &stream->errors, &stream->readinfo,
296*ebfedea0SLionel Sambuc &stream->cbinfo);
297*ebfedea0SLionel Sambuc }
298*ebfedea0SLionel Sambuc
299*ebfedea0SLionel Sambuc /*
300*ebfedea0SLionel Sambuc * Read a full size_t's worth. If the return is < than length, then
301*ebfedea0SLionel Sambuc * *last_read tells you why - < 0 for an error, == 0 for EOF
302*ebfedea0SLionel Sambuc */
303*ebfedea0SLionel Sambuc
304*ebfedea0SLionel Sambuc static size_t
full_read(pgp_stream_t * stream,uint8_t * dest,size_t length,int * last_read,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)305*ebfedea0SLionel Sambuc full_read(pgp_stream_t *stream, uint8_t *dest,
306*ebfedea0SLionel Sambuc size_t length,
307*ebfedea0SLionel Sambuc int *last_read,
308*ebfedea0SLionel Sambuc pgp_error_t **errors,
309*ebfedea0SLionel Sambuc pgp_reader_t *readinfo,
310*ebfedea0SLionel Sambuc pgp_cbdata_t *cbinfo)
311*ebfedea0SLionel Sambuc {
312*ebfedea0SLionel Sambuc size_t t;
313*ebfedea0SLionel Sambuc int r = 0; /* preset in case some loon calls with length
314*ebfedea0SLionel Sambuc * == 0 */
315*ebfedea0SLionel Sambuc
316*ebfedea0SLionel Sambuc for (t = 0; t < length;) {
317*ebfedea0SLionel Sambuc r = sub_base_read(stream, dest + t, length - t, errors, readinfo,
318*ebfedea0SLionel Sambuc cbinfo);
319*ebfedea0SLionel Sambuc if (r <= 0) {
320*ebfedea0SLionel Sambuc *last_read = r;
321*ebfedea0SLionel Sambuc return t;
322*ebfedea0SLionel Sambuc }
323*ebfedea0SLionel Sambuc t += (size_t)r;
324*ebfedea0SLionel Sambuc }
325*ebfedea0SLionel Sambuc
326*ebfedea0SLionel Sambuc *last_read = r;
327*ebfedea0SLionel Sambuc
328*ebfedea0SLionel Sambuc return t;
329*ebfedea0SLionel Sambuc }
330*ebfedea0SLionel Sambuc
331*ebfedea0SLionel Sambuc
332*ebfedea0SLionel Sambuc
333*ebfedea0SLionel Sambuc /** Read a scalar value of selected length from reader.
334*ebfedea0SLionel Sambuc *
335*ebfedea0SLionel Sambuc * Read an unsigned scalar value from reader in Big Endian representation.
336*ebfedea0SLionel Sambuc *
337*ebfedea0SLionel Sambuc * This function does not know or care about packet boundaries. It
338*ebfedea0SLionel Sambuc * also assumes that an EOF is an error.
339*ebfedea0SLionel Sambuc *
340*ebfedea0SLionel Sambuc * \param *result The scalar value is stored here
341*ebfedea0SLionel Sambuc * \param *reader Our reader
342*ebfedea0SLionel Sambuc * \param length How many bytes to read
343*ebfedea0SLionel Sambuc * \return 1 on success, 0 on failure
344*ebfedea0SLionel Sambuc */
345*ebfedea0SLionel Sambuc static unsigned
_read_scalar(unsigned * result,unsigned length,pgp_stream_t * stream)346*ebfedea0SLionel Sambuc _read_scalar(unsigned *result, unsigned length,
347*ebfedea0SLionel Sambuc pgp_stream_t *stream)
348*ebfedea0SLionel Sambuc {
349*ebfedea0SLionel Sambuc unsigned t = 0;
350*ebfedea0SLionel Sambuc
351*ebfedea0SLionel Sambuc if (length > sizeof(*result)) {
352*ebfedea0SLionel Sambuc (void) fprintf(stderr, "_read_scalar: bad length\n");
353*ebfedea0SLionel Sambuc return 0;
354*ebfedea0SLionel Sambuc }
355*ebfedea0SLionel Sambuc
356*ebfedea0SLionel Sambuc while (length--) {
357*ebfedea0SLionel Sambuc uint8_t c;
358*ebfedea0SLionel Sambuc int r;
359*ebfedea0SLionel Sambuc
360*ebfedea0SLionel Sambuc r = base_read(&c, 1, stream);
361*ebfedea0SLionel Sambuc if (r != 1)
362*ebfedea0SLionel Sambuc return 0;
363*ebfedea0SLionel Sambuc t = (t << 8) + c;
364*ebfedea0SLionel Sambuc }
365*ebfedea0SLionel Sambuc
366*ebfedea0SLionel Sambuc *result = t;
367*ebfedea0SLionel Sambuc return 1;
368*ebfedea0SLionel Sambuc }
369*ebfedea0SLionel Sambuc
370*ebfedea0SLionel Sambuc /**
371*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
372*ebfedea0SLionel Sambuc * \brief Read bytes from a region within the packet.
373*ebfedea0SLionel Sambuc *
374*ebfedea0SLionel Sambuc * Read length bytes into the buffer pointed to by *dest.
375*ebfedea0SLionel Sambuc * Make sure we do not read over the packet boundary.
376*ebfedea0SLionel Sambuc * Updates the Packet Tag's pgp_ptag_t::readc.
377*ebfedea0SLionel Sambuc *
378*ebfedea0SLionel Sambuc * If length would make us read over the packet boundary, or if
379*ebfedea0SLionel Sambuc * reading fails, we call the callback with an error.
380*ebfedea0SLionel Sambuc *
381*ebfedea0SLionel Sambuc * Note that if the region is indeterminate, this can return a short
382*ebfedea0SLionel Sambuc * read - check region->last_read for the length. EOF is indicated by
383*ebfedea0SLionel Sambuc * a success return and region->last_read == 0 in this case (for a
384*ebfedea0SLionel Sambuc * region of known length, EOF is an error).
385*ebfedea0SLionel Sambuc *
386*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
387*ebfedea0SLionel Sambuc *
388*ebfedea0SLionel Sambuc * \param dest The destination buffer
389*ebfedea0SLionel Sambuc * \param length How many bytes to read
390*ebfedea0SLionel Sambuc * \param region Pointer to packet region
391*ebfedea0SLionel Sambuc * \param errors Error stack
392*ebfedea0SLionel Sambuc * \param readinfo Reader info
393*ebfedea0SLionel Sambuc * \param cbinfo Callback info
394*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
395*ebfedea0SLionel Sambuc */
396*ebfedea0SLionel Sambuc unsigned
pgp_limited_read(pgp_stream_t * stream,uint8_t * dest,size_t length,pgp_region_t * region,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)397*ebfedea0SLionel Sambuc pgp_limited_read(pgp_stream_t *stream, uint8_t *dest,
398*ebfedea0SLionel Sambuc size_t length,
399*ebfedea0SLionel Sambuc pgp_region_t *region,
400*ebfedea0SLionel Sambuc pgp_error_t **errors,
401*ebfedea0SLionel Sambuc pgp_reader_t *readinfo,
402*ebfedea0SLionel Sambuc pgp_cbdata_t *cbinfo)
403*ebfedea0SLionel Sambuc {
404*ebfedea0SLionel Sambuc size_t r;
405*ebfedea0SLionel Sambuc int lr;
406*ebfedea0SLionel Sambuc
407*ebfedea0SLionel Sambuc if (!region->indeterminate &&
408*ebfedea0SLionel Sambuc region->readc + length > region->length) {
409*ebfedea0SLionel Sambuc PGP_ERROR_1(errors, PGP_E_P_NOT_ENOUGH_DATA, "%s",
410*ebfedea0SLionel Sambuc "Not enough data");
411*ebfedea0SLionel Sambuc return 0;
412*ebfedea0SLionel Sambuc }
413*ebfedea0SLionel Sambuc r = full_read(stream, dest, length, &lr, errors, readinfo, cbinfo);
414*ebfedea0SLionel Sambuc if (lr < 0) {
415*ebfedea0SLionel Sambuc PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed");
416*ebfedea0SLionel Sambuc return 0;
417*ebfedea0SLionel Sambuc }
418*ebfedea0SLionel Sambuc if (!region->indeterminate && r != length) {
419*ebfedea0SLionel Sambuc PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed");
420*ebfedea0SLionel Sambuc return 0;
421*ebfedea0SLionel Sambuc }
422*ebfedea0SLionel Sambuc region->last_read = (unsigned)r;
423*ebfedea0SLionel Sambuc do {
424*ebfedea0SLionel Sambuc region->readc += (unsigned)r;
425*ebfedea0SLionel Sambuc if (region->parent && region->length > region->parent->length) {
426*ebfedea0SLionel Sambuc (void) fprintf(stderr,
427*ebfedea0SLionel Sambuc "ops_limited_read: bad length\n");
428*ebfedea0SLionel Sambuc return 0;
429*ebfedea0SLionel Sambuc }
430*ebfedea0SLionel Sambuc } while ((region = region->parent) != NULL);
431*ebfedea0SLionel Sambuc return 1;
432*ebfedea0SLionel Sambuc }
433*ebfedea0SLionel Sambuc
434*ebfedea0SLionel Sambuc /**
435*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
436*ebfedea0SLionel Sambuc \brief Call pgp_limited_read on next in stack
437*ebfedea0SLionel Sambuc */
438*ebfedea0SLionel Sambuc unsigned
pgp_stacked_limited_read(pgp_stream_t * stream,uint8_t * dest,unsigned length,pgp_region_t * region,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)439*ebfedea0SLionel Sambuc pgp_stacked_limited_read(pgp_stream_t *stream, uint8_t *dest, unsigned length,
440*ebfedea0SLionel Sambuc pgp_region_t *region,
441*ebfedea0SLionel Sambuc pgp_error_t **errors,
442*ebfedea0SLionel Sambuc pgp_reader_t *readinfo,
443*ebfedea0SLionel Sambuc pgp_cbdata_t *cbinfo)
444*ebfedea0SLionel Sambuc {
445*ebfedea0SLionel Sambuc return pgp_limited_read(stream, dest, length, region, errors,
446*ebfedea0SLionel Sambuc readinfo->next, cbinfo);
447*ebfedea0SLionel Sambuc }
448*ebfedea0SLionel Sambuc
449*ebfedea0SLionel Sambuc static unsigned
limread(uint8_t * dest,unsigned length,pgp_region_t * region,pgp_stream_t * info)450*ebfedea0SLionel Sambuc limread(uint8_t *dest, unsigned length,
451*ebfedea0SLionel Sambuc pgp_region_t *region, pgp_stream_t *info)
452*ebfedea0SLionel Sambuc {
453*ebfedea0SLionel Sambuc return pgp_limited_read(info, dest, length, region, &info->errors,
454*ebfedea0SLionel Sambuc &info->readinfo, &info->cbinfo);
455*ebfedea0SLionel Sambuc }
456*ebfedea0SLionel Sambuc
457*ebfedea0SLionel Sambuc static unsigned
exact_limread(uint8_t * dest,unsigned len,pgp_region_t * region,pgp_stream_t * stream)458*ebfedea0SLionel Sambuc exact_limread(uint8_t *dest, unsigned len,
459*ebfedea0SLionel Sambuc pgp_region_t *region,
460*ebfedea0SLionel Sambuc pgp_stream_t *stream)
461*ebfedea0SLionel Sambuc {
462*ebfedea0SLionel Sambuc unsigned ret;
463*ebfedea0SLionel Sambuc
464*ebfedea0SLionel Sambuc stream->exact_read = 1;
465*ebfedea0SLionel Sambuc ret = limread(dest, len, region, stream);
466*ebfedea0SLionel Sambuc stream->exact_read = 0;
467*ebfedea0SLionel Sambuc return ret;
468*ebfedea0SLionel Sambuc }
469*ebfedea0SLionel Sambuc
470*ebfedea0SLionel Sambuc /** Skip over length bytes of this packet.
471*ebfedea0SLionel Sambuc *
472*ebfedea0SLionel Sambuc * Calls limread() to skip over some data.
473*ebfedea0SLionel Sambuc *
474*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
475*ebfedea0SLionel Sambuc *
476*ebfedea0SLionel Sambuc * \param length How many bytes to skip
477*ebfedea0SLionel Sambuc * \param *region Pointer to packet region
478*ebfedea0SLionel Sambuc * \param *stream How to parse
479*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
480*ebfedea0SLionel Sambuc */
481*ebfedea0SLionel Sambuc static int
limskip(unsigned length,pgp_region_t * region,pgp_stream_t * stream)482*ebfedea0SLionel Sambuc limskip(unsigned length, pgp_region_t *region, pgp_stream_t *stream)
483*ebfedea0SLionel Sambuc {
484*ebfedea0SLionel Sambuc uint8_t buf[NETPGP_BUFSIZ];
485*ebfedea0SLionel Sambuc
486*ebfedea0SLionel Sambuc while (length > 0) {
487*ebfedea0SLionel Sambuc unsigned n = length % NETPGP_BUFSIZ;
488*ebfedea0SLionel Sambuc
489*ebfedea0SLionel Sambuc if (!limread(buf, n, region, stream)) {
490*ebfedea0SLionel Sambuc return 0;
491*ebfedea0SLionel Sambuc }
492*ebfedea0SLionel Sambuc length -= n;
493*ebfedea0SLionel Sambuc }
494*ebfedea0SLionel Sambuc return 1;
495*ebfedea0SLionel Sambuc }
496*ebfedea0SLionel Sambuc
497*ebfedea0SLionel Sambuc /** Read a scalar.
498*ebfedea0SLionel Sambuc *
499*ebfedea0SLionel Sambuc * Read a big-endian scalar of length bytes, respecting packet
500*ebfedea0SLionel Sambuc * boundaries (by calling limread() to read the raw data).
501*ebfedea0SLionel Sambuc *
502*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
503*ebfedea0SLionel Sambuc *
504*ebfedea0SLionel Sambuc * \param *dest The scalar value is stored here
505*ebfedea0SLionel Sambuc * \param length How many bytes make up this scalar (at most 4)
506*ebfedea0SLionel Sambuc * \param *region Pointer to current packet region
507*ebfedea0SLionel Sambuc * \param *stream How to parse
508*ebfedea0SLionel Sambuc * \param *cb The callback
509*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
510*ebfedea0SLionel Sambuc *
511*ebfedea0SLionel Sambuc * \see RFC4880 3.1
512*ebfedea0SLionel Sambuc */
513*ebfedea0SLionel Sambuc static int
limread_scalar(unsigned * dest,unsigned len,pgp_region_t * region,pgp_stream_t * stream)514*ebfedea0SLionel Sambuc limread_scalar(unsigned *dest,
515*ebfedea0SLionel Sambuc unsigned len,
516*ebfedea0SLionel Sambuc pgp_region_t *region,
517*ebfedea0SLionel Sambuc pgp_stream_t *stream)
518*ebfedea0SLionel Sambuc {
519*ebfedea0SLionel Sambuc uint8_t c[4] = "";
520*ebfedea0SLionel Sambuc unsigned t;
521*ebfedea0SLionel Sambuc unsigned n;
522*ebfedea0SLionel Sambuc
523*ebfedea0SLionel Sambuc if (len > 4) {
524*ebfedea0SLionel Sambuc (void) fprintf(stderr, "limread_scalar: bad length\n");
525*ebfedea0SLionel Sambuc return 0;
526*ebfedea0SLionel Sambuc }
527*ebfedea0SLionel Sambuc /*LINTED*/
528*ebfedea0SLionel Sambuc if (/*CONSTCOND*/sizeof(*dest) < 4) {
529*ebfedea0SLionel Sambuc (void) fprintf(stderr, "limread_scalar: bad dest\n");
530*ebfedea0SLionel Sambuc return 0;
531*ebfedea0SLionel Sambuc }
532*ebfedea0SLionel Sambuc if (!limread(c, len, region, stream)) {
533*ebfedea0SLionel Sambuc return 0;
534*ebfedea0SLionel Sambuc }
535*ebfedea0SLionel Sambuc for (t = 0, n = 0; n < len; ++n) {
536*ebfedea0SLionel Sambuc t = (t << 8) + c[n];
537*ebfedea0SLionel Sambuc }
538*ebfedea0SLionel Sambuc *dest = t;
539*ebfedea0SLionel Sambuc return 1;
540*ebfedea0SLionel Sambuc }
541*ebfedea0SLionel Sambuc
542*ebfedea0SLionel Sambuc /** Read a scalar.
543*ebfedea0SLionel Sambuc *
544*ebfedea0SLionel Sambuc * Read a big-endian scalar of length bytes, respecting packet
545*ebfedea0SLionel Sambuc * boundaries (by calling limread() to read the raw data).
546*ebfedea0SLionel Sambuc *
547*ebfedea0SLionel Sambuc * The value read is stored in a size_t, which is a different size
548*ebfedea0SLionel Sambuc * from an unsigned on some platforms.
549*ebfedea0SLionel Sambuc *
550*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
551*ebfedea0SLionel Sambuc *
552*ebfedea0SLionel Sambuc * \param *dest The scalar value is stored here
553*ebfedea0SLionel Sambuc * \param length How many bytes make up this scalar (at most 4)
554*ebfedea0SLionel Sambuc * \param *region Pointer to current packet region
555*ebfedea0SLionel Sambuc * \param *stream How to parse
556*ebfedea0SLionel Sambuc * \param *cb The callback
557*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
558*ebfedea0SLionel Sambuc *
559*ebfedea0SLionel Sambuc * \see RFC4880 3.1
560*ebfedea0SLionel Sambuc */
561*ebfedea0SLionel Sambuc static int
limread_size_t(size_t * dest,unsigned length,pgp_region_t * region,pgp_stream_t * stream)562*ebfedea0SLionel Sambuc limread_size_t(size_t *dest,
563*ebfedea0SLionel Sambuc unsigned length,
564*ebfedea0SLionel Sambuc pgp_region_t *region,
565*ebfedea0SLionel Sambuc pgp_stream_t *stream)
566*ebfedea0SLionel Sambuc {
567*ebfedea0SLionel Sambuc unsigned tmp;
568*ebfedea0SLionel Sambuc
569*ebfedea0SLionel Sambuc /*
570*ebfedea0SLionel Sambuc * Note that because the scalar is at most 4 bytes, we don't care if
571*ebfedea0SLionel Sambuc * size_t is bigger than usigned
572*ebfedea0SLionel Sambuc */
573*ebfedea0SLionel Sambuc if (!limread_scalar(&tmp, length, region, stream))
574*ebfedea0SLionel Sambuc return 0;
575*ebfedea0SLionel Sambuc
576*ebfedea0SLionel Sambuc *dest = tmp;
577*ebfedea0SLionel Sambuc return 1;
578*ebfedea0SLionel Sambuc }
579*ebfedea0SLionel Sambuc
580*ebfedea0SLionel Sambuc /** Read a timestamp.
581*ebfedea0SLionel Sambuc *
582*ebfedea0SLionel Sambuc * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970). They are stored in an unsigned scalar
583*ebfedea0SLionel Sambuc * of 4 bytes.
584*ebfedea0SLionel Sambuc *
585*ebfedea0SLionel Sambuc * This function reads the timestamp using limread_scalar().
586*ebfedea0SLionel Sambuc *
587*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
588*ebfedea0SLionel Sambuc *
589*ebfedea0SLionel Sambuc * \param *dest The timestamp is stored here
590*ebfedea0SLionel Sambuc * \param *ptag Pointer to current packet's Packet Tag.
591*ebfedea0SLionel Sambuc * \param *reader Our reader
592*ebfedea0SLionel Sambuc * \param *cb The callback
593*ebfedea0SLionel Sambuc * \return see limread_scalar()
594*ebfedea0SLionel Sambuc *
595*ebfedea0SLionel Sambuc * \see RFC4880 3.5
596*ebfedea0SLionel Sambuc */
597*ebfedea0SLionel Sambuc static int
limited_read_time(time_t * dest,pgp_region_t * region,pgp_stream_t * stream)598*ebfedea0SLionel Sambuc limited_read_time(time_t *dest, pgp_region_t *region,
599*ebfedea0SLionel Sambuc pgp_stream_t *stream)
600*ebfedea0SLionel Sambuc {
601*ebfedea0SLionel Sambuc uint8_t c;
602*ebfedea0SLionel Sambuc time_t mytime = 0;
603*ebfedea0SLionel Sambuc int i;
604*ebfedea0SLionel Sambuc
605*ebfedea0SLionel Sambuc /*
606*ebfedea0SLionel Sambuc * Cannot assume that time_t is 4 octets long -
607*ebfedea0SLionel Sambuc * SunOS 5.10 and NetBSD both have 64-bit time_ts.
608*ebfedea0SLionel Sambuc */
609*ebfedea0SLionel Sambuc if (/* CONSTCOND */sizeof(time_t) == 4) {
610*ebfedea0SLionel Sambuc return limread_scalar((unsigned *)(void *)dest, 4, region, stream);
611*ebfedea0SLionel Sambuc }
612*ebfedea0SLionel Sambuc for (i = 0; i < 4; i++) {
613*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
614*ebfedea0SLionel Sambuc return 0;
615*ebfedea0SLionel Sambuc }
616*ebfedea0SLionel Sambuc mytime = (mytime << 8) + c;
617*ebfedea0SLionel Sambuc }
618*ebfedea0SLionel Sambuc *dest = mytime;
619*ebfedea0SLionel Sambuc return 1;
620*ebfedea0SLionel Sambuc }
621*ebfedea0SLionel Sambuc
622*ebfedea0SLionel Sambuc /**
623*ebfedea0SLionel Sambuc * \ingroup Core_MPI
624*ebfedea0SLionel Sambuc * Read a multiprecision integer.
625*ebfedea0SLionel Sambuc *
626*ebfedea0SLionel Sambuc * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts. First there is a 2 byte scalar
627*ebfedea0SLionel Sambuc * indicating the length of the following MPI in Bits. Then follow the bits that make up the actual number, most
628*ebfedea0SLionel Sambuc * significant bits first (Big Endian). The most significant bit in the MPI is supposed to be 1 (unless the MPI is
629*ebfedea0SLionel Sambuc * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted).
630*ebfedea0SLionel Sambuc *
631*ebfedea0SLionel Sambuc * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are
632*ebfedea0SLionel Sambuc * supposed to be cleared - I guess. XXX - does anything actually say so?
633*ebfedea0SLionel Sambuc *
634*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
635*ebfedea0SLionel Sambuc *
636*ebfedea0SLionel Sambuc * \param **pgn return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed
637*ebfedea0SLionel Sambuc * by the caller XXX right ben?
638*ebfedea0SLionel Sambuc * \param *ptag Pointer to current packet's Packet Tag.
639*ebfedea0SLionel Sambuc * \param *reader Our reader
640*ebfedea0SLionel Sambuc * \param *cb The callback
641*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
642*ebfedea0SLionel Sambuc * see comment below - the callback is called with a PGP_PARSER_ERROR in case of an error)
643*ebfedea0SLionel Sambuc *
644*ebfedea0SLionel Sambuc * \see RFC4880 3.2
645*ebfedea0SLionel Sambuc */
646*ebfedea0SLionel Sambuc static int
limread_mpi(BIGNUM ** pbn,pgp_region_t * region,pgp_stream_t * stream)647*ebfedea0SLionel Sambuc limread_mpi(BIGNUM **pbn, pgp_region_t *region, pgp_stream_t *stream)
648*ebfedea0SLionel Sambuc {
649*ebfedea0SLionel Sambuc uint8_t buf[NETPGP_BUFSIZ] = "";
650*ebfedea0SLionel Sambuc /* an MPI has a 2 byte length part.
651*ebfedea0SLionel Sambuc * Length is given in bits, so the
652*ebfedea0SLionel Sambuc * largest we should ever need for
653*ebfedea0SLionel Sambuc * the buffer is NETPGP_BUFSIZ bytes. */
654*ebfedea0SLionel Sambuc unsigned length;
655*ebfedea0SLionel Sambuc unsigned nonzero;
656*ebfedea0SLionel Sambuc unsigned ret;
657*ebfedea0SLionel Sambuc
658*ebfedea0SLionel Sambuc stream->reading_mpi_len = 1;
659*ebfedea0SLionel Sambuc ret = (unsigned)limread_scalar(&length, 2, region, stream);
660*ebfedea0SLionel Sambuc
661*ebfedea0SLionel Sambuc stream->reading_mpi_len = 0;
662*ebfedea0SLionel Sambuc if (!ret)
663*ebfedea0SLionel Sambuc return 0;
664*ebfedea0SLionel Sambuc
665*ebfedea0SLionel Sambuc nonzero = length & 7; /* there should be this many zero bits in the
666*ebfedea0SLionel Sambuc * MS byte */
667*ebfedea0SLionel Sambuc if (!nonzero)
668*ebfedea0SLionel Sambuc nonzero = 8;
669*ebfedea0SLionel Sambuc length = (length + 7) / 8;
670*ebfedea0SLionel Sambuc
671*ebfedea0SLionel Sambuc if (length == 0) {
672*ebfedea0SLionel Sambuc /* if we try to read a length of 0, then fail */
673*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
674*ebfedea0SLionel Sambuc (void) fprintf(stderr, "limread_mpi: 0 length\n");
675*ebfedea0SLionel Sambuc }
676*ebfedea0SLionel Sambuc return 0;
677*ebfedea0SLionel Sambuc }
678*ebfedea0SLionel Sambuc if (length > NETPGP_BUFSIZ) {
679*ebfedea0SLionel Sambuc (void) fprintf(stderr, "limread_mpi: bad length\n");
680*ebfedea0SLionel Sambuc return 0;
681*ebfedea0SLionel Sambuc }
682*ebfedea0SLionel Sambuc if (!limread(buf, length, region, stream)) {
683*ebfedea0SLionel Sambuc return 0;
684*ebfedea0SLionel Sambuc }
685*ebfedea0SLionel Sambuc if (((unsigned)buf[0] >> nonzero) != 0 ||
686*ebfedea0SLionel Sambuc !((unsigned)buf[0] & (1U << (nonzero - 1U)))) {
687*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_P_MPI_FORMAT_ERROR,
688*ebfedea0SLionel Sambuc "%s", "MPI Format error");
689*ebfedea0SLionel Sambuc /* XXX: Ben, one part of
690*ebfedea0SLionel Sambuc * this constraint does
691*ebfedea0SLionel Sambuc * not apply to
692*ebfedea0SLionel Sambuc * encrypted MPIs the
693*ebfedea0SLionel Sambuc * draft says. -- peter */
694*ebfedea0SLionel Sambuc return 0;
695*ebfedea0SLionel Sambuc }
696*ebfedea0SLionel Sambuc *pbn = BN_bin2bn(buf, (int)length, NULL);
697*ebfedea0SLionel Sambuc return 1;
698*ebfedea0SLionel Sambuc }
699*ebfedea0SLionel Sambuc
700*ebfedea0SLionel Sambuc static unsigned read_new_length(unsigned *, pgp_stream_t *);
701*ebfedea0SLionel Sambuc
702*ebfedea0SLionel Sambuc /* allocate space, read, and stash data away in a virtual pkt */
703*ebfedea0SLionel Sambuc static void
streamread(pgp_stream_t * stream,unsigned c)704*ebfedea0SLionel Sambuc streamread(pgp_stream_t *stream, unsigned c)
705*ebfedea0SLionel Sambuc {
706*ebfedea0SLionel Sambuc int cc;
707*ebfedea0SLionel Sambuc
708*ebfedea0SLionel Sambuc stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
709*ebfedea0SLionel Sambuc cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
710*ebfedea0SLionel Sambuc c, &stream->errors, &stream->readinfo, &stream->cbinfo);
711*ebfedea0SLionel Sambuc stream->virtualc += cc;
712*ebfedea0SLionel Sambuc }
713*ebfedea0SLionel Sambuc
714*ebfedea0SLionel Sambuc /* coalesce all the partial blocks together */
715*ebfedea0SLionel Sambuc static int
coalesce_blocks(pgp_stream_t * stream,unsigned length)716*ebfedea0SLionel Sambuc coalesce_blocks(pgp_stream_t *stream, unsigned length)
717*ebfedea0SLionel Sambuc {
718*ebfedea0SLionel Sambuc unsigned c;
719*ebfedea0SLionel Sambuc
720*ebfedea0SLionel Sambuc stream->coalescing = 1;
721*ebfedea0SLionel Sambuc /* already read a partial block length - prime the array */
722*ebfedea0SLionel Sambuc streamread(stream, length);
723*ebfedea0SLionel Sambuc while (read_new_length(&c, stream) && stream->partial_read) {
724*ebfedea0SLionel Sambuc /* length we read is partial - add to end of array */
725*ebfedea0SLionel Sambuc streamread(stream, c);
726*ebfedea0SLionel Sambuc }
727*ebfedea0SLionel Sambuc /* not partial - add the last extent to the end of the array */
728*ebfedea0SLionel Sambuc streamread(stream, c);
729*ebfedea0SLionel Sambuc stream->coalescing = 0;
730*ebfedea0SLionel Sambuc return 1;
731*ebfedea0SLionel Sambuc }
732*ebfedea0SLionel Sambuc
733*ebfedea0SLionel Sambuc /** Read some data with a New-Format length from reader.
734*ebfedea0SLionel Sambuc *
735*ebfedea0SLionel Sambuc * \sa Internet-Draft RFC4880.txt Section 4.2.2
736*ebfedea0SLionel Sambuc *
737*ebfedea0SLionel Sambuc * \param *length Where the decoded length will be put
738*ebfedea0SLionel Sambuc * \param *stream How to parse
739*ebfedea0SLionel Sambuc * \return 1 if OK, else 0
740*ebfedea0SLionel Sambuc *
741*ebfedea0SLionel Sambuc */
742*ebfedea0SLionel Sambuc
743*ebfedea0SLionel Sambuc static unsigned
read_new_length(unsigned * length,pgp_stream_t * stream)744*ebfedea0SLionel Sambuc read_new_length(unsigned *length, pgp_stream_t *stream)
745*ebfedea0SLionel Sambuc {
746*ebfedea0SLionel Sambuc uint8_t c;
747*ebfedea0SLionel Sambuc
748*ebfedea0SLionel Sambuc stream->partial_read = 0;
749*ebfedea0SLionel Sambuc if (base_read(&c, 1, stream) != 1) {
750*ebfedea0SLionel Sambuc return 0;
751*ebfedea0SLionel Sambuc }
752*ebfedea0SLionel Sambuc if (c < 192) {
753*ebfedea0SLionel Sambuc /* 1. One-octet packet */
754*ebfedea0SLionel Sambuc *length = c;
755*ebfedea0SLionel Sambuc return 1;
756*ebfedea0SLionel Sambuc }
757*ebfedea0SLionel Sambuc if (c < 224) {
758*ebfedea0SLionel Sambuc /* 2. Two-octet packet */
759*ebfedea0SLionel Sambuc unsigned t = (c - 192) << 8;
760*ebfedea0SLionel Sambuc
761*ebfedea0SLionel Sambuc if (base_read(&c, 1, stream) != 1) {
762*ebfedea0SLionel Sambuc return 0;
763*ebfedea0SLionel Sambuc }
764*ebfedea0SLionel Sambuc *length = t + c + 192;
765*ebfedea0SLionel Sambuc return 1;
766*ebfedea0SLionel Sambuc }
767*ebfedea0SLionel Sambuc if (c < 255) {
768*ebfedea0SLionel Sambuc /* 3. Partial Body Length */
769*ebfedea0SLionel Sambuc stream->partial_read = 1;
770*ebfedea0SLionel Sambuc *length = 1 << (c & 0x1f);
771*ebfedea0SLionel Sambuc if (!stream->coalescing) {
772*ebfedea0SLionel Sambuc /* we have been called from coalesce_blocks -
773*ebfedea0SLionel Sambuc * just return with the partial length */
774*ebfedea0SLionel Sambuc coalesce_blocks(stream, *length);
775*ebfedea0SLionel Sambuc *length = stream->virtualc;
776*ebfedea0SLionel Sambuc }
777*ebfedea0SLionel Sambuc return 1;
778*ebfedea0SLionel Sambuc }
779*ebfedea0SLionel Sambuc /* 4. Five-Octet packet */
780*ebfedea0SLionel Sambuc return _read_scalar(length, 4, stream);
781*ebfedea0SLionel Sambuc }
782*ebfedea0SLionel Sambuc
783*ebfedea0SLionel Sambuc /** Read the length information for a new format Packet Tag.
784*ebfedea0SLionel Sambuc *
785*ebfedea0SLionel Sambuc * New style Packet Tags encode the length in one to five octets. This function reads the right amount of bytes and
786*ebfedea0SLionel Sambuc * decodes it to the proper length information.
787*ebfedea0SLionel Sambuc *
788*ebfedea0SLionel Sambuc * This function makes sure to respect packet boundaries.
789*ebfedea0SLionel Sambuc *
790*ebfedea0SLionel Sambuc * \param *length return the length here
791*ebfedea0SLionel Sambuc * \param *ptag Pointer to current packet's Packet Tag.
792*ebfedea0SLionel Sambuc * \param *reader Our reader
793*ebfedea0SLionel Sambuc * \param *cb The callback
794*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
795*ebfedea0SLionel Sambuc * see comment below)
796*ebfedea0SLionel Sambuc *
797*ebfedea0SLionel Sambuc * \see RFC4880 4.2.2
798*ebfedea0SLionel Sambuc * \see pgp_ptag_t
799*ebfedea0SLionel Sambuc */
800*ebfedea0SLionel Sambuc static int
limited_read_new_length(unsigned * length,pgp_region_t * region,pgp_stream_t * stream)801*ebfedea0SLionel Sambuc limited_read_new_length(unsigned *length, pgp_region_t *region,
802*ebfedea0SLionel Sambuc pgp_stream_t *stream)
803*ebfedea0SLionel Sambuc {
804*ebfedea0SLionel Sambuc uint8_t c = 0x0;
805*ebfedea0SLionel Sambuc
806*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
807*ebfedea0SLionel Sambuc return 0;
808*ebfedea0SLionel Sambuc }
809*ebfedea0SLionel Sambuc if (c < 192) {
810*ebfedea0SLionel Sambuc *length = c;
811*ebfedea0SLionel Sambuc return 1;
812*ebfedea0SLionel Sambuc }
813*ebfedea0SLionel Sambuc if (c < 224) {
814*ebfedea0SLionel Sambuc unsigned t = (c - 192) << 8;
815*ebfedea0SLionel Sambuc
816*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
817*ebfedea0SLionel Sambuc return 0;
818*ebfedea0SLionel Sambuc }
819*ebfedea0SLionel Sambuc *length = t + c + 192;
820*ebfedea0SLionel Sambuc return 1;
821*ebfedea0SLionel Sambuc }
822*ebfedea0SLionel Sambuc if (c < 255) {
823*ebfedea0SLionel Sambuc stream->partial_read = 1;
824*ebfedea0SLionel Sambuc *length = 1 << (c & 0x1f);
825*ebfedea0SLionel Sambuc if (!stream->coalescing) {
826*ebfedea0SLionel Sambuc /* we have been called from coalesce_blocks -
827*ebfedea0SLionel Sambuc * just return with the partial length */
828*ebfedea0SLionel Sambuc coalesce_blocks(stream, *length);
829*ebfedea0SLionel Sambuc *length = stream->virtualc;
830*ebfedea0SLionel Sambuc }
831*ebfedea0SLionel Sambuc return 1;
832*ebfedea0SLionel Sambuc }
833*ebfedea0SLionel Sambuc return limread_scalar(length, 4, region, stream);
834*ebfedea0SLionel Sambuc }
835*ebfedea0SLionel Sambuc
836*ebfedea0SLionel Sambuc /**
837*ebfedea0SLionel Sambuc \ingroup Core_Create
838*ebfedea0SLionel Sambuc \brief Free allocated memory
839*ebfedea0SLionel Sambuc */
840*ebfedea0SLionel Sambuc void
pgp_data_free(pgp_data_t * data)841*ebfedea0SLionel Sambuc pgp_data_free(pgp_data_t *data)
842*ebfedea0SLionel Sambuc {
843*ebfedea0SLionel Sambuc free(data->contents);
844*ebfedea0SLionel Sambuc data->contents = NULL;
845*ebfedea0SLionel Sambuc data->len = 0;
846*ebfedea0SLionel Sambuc }
847*ebfedea0SLionel Sambuc
848*ebfedea0SLionel Sambuc /**
849*ebfedea0SLionel Sambuc \ingroup Core_Create
850*ebfedea0SLionel Sambuc \brief Free allocated memory
851*ebfedea0SLionel Sambuc */
852*ebfedea0SLionel Sambuc static void
string_free(char ** str)853*ebfedea0SLionel Sambuc string_free(char **str)
854*ebfedea0SLionel Sambuc {
855*ebfedea0SLionel Sambuc free(*str);
856*ebfedea0SLionel Sambuc *str = NULL;
857*ebfedea0SLionel Sambuc }
858*ebfedea0SLionel Sambuc
859*ebfedea0SLionel Sambuc /**
860*ebfedea0SLionel Sambuc \ingroup Core_Create
861*ebfedea0SLionel Sambuc \brief Free allocated memory
862*ebfedea0SLionel Sambuc */
863*ebfedea0SLionel Sambuc /* ! Free packet memory, set pointer to NULL */
864*ebfedea0SLionel Sambuc void
pgp_subpacket_free(pgp_subpacket_t * packet)865*ebfedea0SLionel Sambuc pgp_subpacket_free(pgp_subpacket_t *packet)
866*ebfedea0SLionel Sambuc {
867*ebfedea0SLionel Sambuc free(packet->raw);
868*ebfedea0SLionel Sambuc packet->raw = NULL;
869*ebfedea0SLionel Sambuc }
870*ebfedea0SLionel Sambuc
871*ebfedea0SLionel Sambuc /**
872*ebfedea0SLionel Sambuc \ingroup Core_Create
873*ebfedea0SLionel Sambuc \brief Free allocated memory
874*ebfedea0SLionel Sambuc */
875*ebfedea0SLionel Sambuc static void
headers_free(pgp_headers_t * headers)876*ebfedea0SLionel Sambuc headers_free(pgp_headers_t *headers)
877*ebfedea0SLionel Sambuc {
878*ebfedea0SLionel Sambuc unsigned n;
879*ebfedea0SLionel Sambuc
880*ebfedea0SLionel Sambuc for (n = 0; n < headers->headerc; ++n) {
881*ebfedea0SLionel Sambuc free(headers->headers[n].key);
882*ebfedea0SLionel Sambuc free(headers->headers[n].value);
883*ebfedea0SLionel Sambuc }
884*ebfedea0SLionel Sambuc free(headers->headers);
885*ebfedea0SLionel Sambuc headers->headers = NULL;
886*ebfedea0SLionel Sambuc }
887*ebfedea0SLionel Sambuc
888*ebfedea0SLionel Sambuc /**
889*ebfedea0SLionel Sambuc \ingroup Core_Create
890*ebfedea0SLionel Sambuc \brief Free allocated memory
891*ebfedea0SLionel Sambuc */
892*ebfedea0SLionel Sambuc static void
cleartext_trailer_free(struct pgp_hash_t ** trailer)893*ebfedea0SLionel Sambuc cleartext_trailer_free(struct pgp_hash_t **trailer)
894*ebfedea0SLionel Sambuc {
895*ebfedea0SLionel Sambuc free(*trailer);
896*ebfedea0SLionel Sambuc *trailer = NULL;
897*ebfedea0SLionel Sambuc }
898*ebfedea0SLionel Sambuc
899*ebfedea0SLionel Sambuc /**
900*ebfedea0SLionel Sambuc \ingroup Core_Create
901*ebfedea0SLionel Sambuc \brief Free allocated memory
902*ebfedea0SLionel Sambuc */
903*ebfedea0SLionel Sambuc static void
cmd_get_passphrase_free(pgp_seckey_passphrase_t * skp)904*ebfedea0SLionel Sambuc cmd_get_passphrase_free(pgp_seckey_passphrase_t *skp)
905*ebfedea0SLionel Sambuc {
906*ebfedea0SLionel Sambuc if (skp->passphrase && *skp->passphrase) {
907*ebfedea0SLionel Sambuc free(*skp->passphrase);
908*ebfedea0SLionel Sambuc *skp->passphrase = NULL;
909*ebfedea0SLionel Sambuc }
910*ebfedea0SLionel Sambuc }
911*ebfedea0SLionel Sambuc
912*ebfedea0SLionel Sambuc /**
913*ebfedea0SLionel Sambuc \ingroup Core_Create
914*ebfedea0SLionel Sambuc \brief Free allocated memory
915*ebfedea0SLionel Sambuc */
916*ebfedea0SLionel Sambuc static void
free_BN(BIGNUM ** pp)917*ebfedea0SLionel Sambuc free_BN(BIGNUM **pp)
918*ebfedea0SLionel Sambuc {
919*ebfedea0SLionel Sambuc BN_free(*pp);
920*ebfedea0SLionel Sambuc *pp = NULL;
921*ebfedea0SLionel Sambuc }
922*ebfedea0SLionel Sambuc
923*ebfedea0SLionel Sambuc /**
924*ebfedea0SLionel Sambuc * \ingroup Core_Create
925*ebfedea0SLionel Sambuc * \brief Free the memory used when parsing a signature
926*ebfedea0SLionel Sambuc * \param sig
927*ebfedea0SLionel Sambuc */
928*ebfedea0SLionel Sambuc static void
sig_free(pgp_sig_t * sig)929*ebfedea0SLionel Sambuc sig_free(pgp_sig_t *sig)
930*ebfedea0SLionel Sambuc {
931*ebfedea0SLionel Sambuc switch (sig->info.key_alg) {
932*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
933*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
934*ebfedea0SLionel Sambuc free_BN(&sig->info.sig.rsa.sig);
935*ebfedea0SLionel Sambuc break;
936*ebfedea0SLionel Sambuc
937*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
938*ebfedea0SLionel Sambuc free_BN(&sig->info.sig.dsa.r);
939*ebfedea0SLionel Sambuc free_BN(&sig->info.sig.dsa.s);
940*ebfedea0SLionel Sambuc break;
941*ebfedea0SLionel Sambuc
942*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
943*ebfedea0SLionel Sambuc free_BN(&sig->info.sig.elgamal.r);
944*ebfedea0SLionel Sambuc free_BN(&sig->info.sig.elgamal.s);
945*ebfedea0SLionel Sambuc break;
946*ebfedea0SLionel Sambuc
947*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE00:
948*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE01:
949*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE02:
950*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE03:
951*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE04:
952*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE05:
953*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE06:
954*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE07:
955*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE08:
956*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE09:
957*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE10:
958*ebfedea0SLionel Sambuc pgp_data_free(&sig->info.sig.unknown);
959*ebfedea0SLionel Sambuc break;
960*ebfedea0SLionel Sambuc
961*ebfedea0SLionel Sambuc default:
962*ebfedea0SLionel Sambuc (void) fprintf(stderr, "sig_free: bad sig type\n");
963*ebfedea0SLionel Sambuc }
964*ebfedea0SLionel Sambuc }
965*ebfedea0SLionel Sambuc
966*ebfedea0SLionel Sambuc /**
967*ebfedea0SLionel Sambuc \ingroup Core_Create
968*ebfedea0SLionel Sambuc \brief Free allocated memory
969*ebfedea0SLionel Sambuc */
970*ebfedea0SLionel Sambuc /* ! Free any memory allocated when parsing the packet content */
971*ebfedea0SLionel Sambuc void
pgp_parser_content_free(pgp_packet_t * c)972*ebfedea0SLionel Sambuc pgp_parser_content_free(pgp_packet_t *c)
973*ebfedea0SLionel Sambuc {
974*ebfedea0SLionel Sambuc switch (c->tag) {
975*ebfedea0SLionel Sambuc case PGP_PARSER_PTAG:
976*ebfedea0SLionel Sambuc case PGP_PTAG_CT_COMPRESSED:
977*ebfedea0SLionel Sambuc case PGP_PTAG_SS_CREATION_TIME:
978*ebfedea0SLionel Sambuc case PGP_PTAG_SS_EXPIRATION_TIME:
979*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEY_EXPIRY:
980*ebfedea0SLionel Sambuc case PGP_PTAG_SS_TRUST:
981*ebfedea0SLionel Sambuc case PGP_PTAG_SS_ISSUER_KEY_ID:
982*ebfedea0SLionel Sambuc case PGP_PTAG_CT_1_PASS_SIG:
983*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PRIMARY_USER_ID:
984*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCABLE:
985*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCATION_KEY:
986*ebfedea0SLionel Sambuc case PGP_PTAG_CT_LITDATA_HEADER:
987*ebfedea0SLionel Sambuc case PGP_PTAG_CT_LITDATA_BODY:
988*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
989*ebfedea0SLionel Sambuc case PGP_PTAG_CT_UNARMOURED_TEXT:
990*ebfedea0SLionel Sambuc case PGP_PTAG_CT_ARMOUR_TRAILER:
991*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNATURE_HEADER:
992*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SE_DATA_HEADER:
993*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SE_IP_DATA_HEADER:
994*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SE_IP_DATA_BODY:
995*ebfedea0SLionel Sambuc case PGP_PTAG_CT_MDC:
996*ebfedea0SLionel Sambuc case PGP_GET_SECKEY:
997*ebfedea0SLionel Sambuc break;
998*ebfedea0SLionel Sambuc
999*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1000*ebfedea0SLionel Sambuc headers_free(&c->u.cleartext_head);
1001*ebfedea0SLionel Sambuc break;
1002*ebfedea0SLionel Sambuc
1003*ebfedea0SLionel Sambuc case PGP_PTAG_CT_ARMOUR_HEADER:
1004*ebfedea0SLionel Sambuc headers_free(&c->u.armour_header.headers);
1005*ebfedea0SLionel Sambuc break;
1006*ebfedea0SLionel Sambuc
1007*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1008*ebfedea0SLionel Sambuc cleartext_trailer_free(&c->u.cleartext_trailer);
1009*ebfedea0SLionel Sambuc break;
1010*ebfedea0SLionel Sambuc
1011*ebfedea0SLionel Sambuc case PGP_PTAG_CT_TRUST:
1012*ebfedea0SLionel Sambuc pgp_data_free(&c->u.trust);
1013*ebfedea0SLionel Sambuc break;
1014*ebfedea0SLionel Sambuc
1015*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNATURE:
1016*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNATURE_FOOTER:
1017*ebfedea0SLionel Sambuc sig_free(&c->u.sig);
1018*ebfedea0SLionel Sambuc break;
1019*ebfedea0SLionel Sambuc
1020*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PUBLIC_KEY:
1021*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PUBLIC_SUBKEY:
1022*ebfedea0SLionel Sambuc pgp_pubkey_free(&c->u.pubkey);
1023*ebfedea0SLionel Sambuc break;
1024*ebfedea0SLionel Sambuc
1025*ebfedea0SLionel Sambuc case PGP_PTAG_CT_USER_ID:
1026*ebfedea0SLionel Sambuc pgp_userid_free(&c->u.userid);
1027*ebfedea0SLionel Sambuc break;
1028*ebfedea0SLionel Sambuc
1029*ebfedea0SLionel Sambuc case PGP_PTAG_SS_SIGNERS_USER_ID:
1030*ebfedea0SLionel Sambuc pgp_userid_free(&c->u.ss_signer);
1031*ebfedea0SLionel Sambuc break;
1032*ebfedea0SLionel Sambuc
1033*ebfedea0SLionel Sambuc case PGP_PTAG_CT_USER_ATTR:
1034*ebfedea0SLionel Sambuc pgp_data_free(&c->u.userattr);
1035*ebfedea0SLionel Sambuc break;
1036*ebfedea0SLionel Sambuc
1037*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREFERRED_SKA:
1038*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_skapref);
1039*ebfedea0SLionel Sambuc break;
1040*ebfedea0SLionel Sambuc
1041*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREFERRED_HASH:
1042*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_hashpref);
1043*ebfedea0SLionel Sambuc break;
1044*ebfedea0SLionel Sambuc
1045*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREF_COMPRESS:
1046*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_zpref);
1047*ebfedea0SLionel Sambuc break;
1048*ebfedea0SLionel Sambuc
1049*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEY_FLAGS:
1050*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_key_flags);
1051*ebfedea0SLionel Sambuc break;
1052*ebfedea0SLionel Sambuc
1053*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEYSERV_PREFS:
1054*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_key_server_prefs);
1055*ebfedea0SLionel Sambuc break;
1056*ebfedea0SLionel Sambuc
1057*ebfedea0SLionel Sambuc case PGP_PTAG_SS_FEATURES:
1058*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_features);
1059*ebfedea0SLionel Sambuc break;
1060*ebfedea0SLionel Sambuc
1061*ebfedea0SLionel Sambuc case PGP_PTAG_SS_NOTATION_DATA:
1062*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_notation.name);
1063*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_notation.value);
1064*ebfedea0SLionel Sambuc break;
1065*ebfedea0SLionel Sambuc
1066*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REGEXP:
1067*ebfedea0SLionel Sambuc string_free(&c->u.ss_regexp);
1068*ebfedea0SLionel Sambuc break;
1069*ebfedea0SLionel Sambuc
1070*ebfedea0SLionel Sambuc case PGP_PTAG_SS_POLICY_URI:
1071*ebfedea0SLionel Sambuc string_free(&c->u.ss_policy);
1072*ebfedea0SLionel Sambuc break;
1073*ebfedea0SLionel Sambuc
1074*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREF_KEYSERV:
1075*ebfedea0SLionel Sambuc string_free(&c->u.ss_keyserv);
1076*ebfedea0SLionel Sambuc break;
1077*ebfedea0SLionel Sambuc
1078*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED00:
1079*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED01:
1080*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED02:
1081*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED03:
1082*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED04:
1083*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED05:
1084*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED06:
1085*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED07:
1086*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED08:
1087*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED09:
1088*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED10:
1089*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_userdef);
1090*ebfedea0SLionel Sambuc break;
1091*ebfedea0SLionel Sambuc
1092*ebfedea0SLionel Sambuc case PGP_PTAG_SS_RESERVED:
1093*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_unknown);
1094*ebfedea0SLionel Sambuc break;
1095*ebfedea0SLionel Sambuc
1096*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCATION_REASON:
1097*ebfedea0SLionel Sambuc string_free(&c->u.ss_revocation.reason);
1098*ebfedea0SLionel Sambuc break;
1099*ebfedea0SLionel Sambuc
1100*ebfedea0SLionel Sambuc case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
1101*ebfedea0SLionel Sambuc pgp_data_free(&c->u.ss_embedded_sig);
1102*ebfedea0SLionel Sambuc break;
1103*ebfedea0SLionel Sambuc
1104*ebfedea0SLionel Sambuc case PGP_PARSER_PACKET_END:
1105*ebfedea0SLionel Sambuc pgp_subpacket_free(&c->u.packet);
1106*ebfedea0SLionel Sambuc break;
1107*ebfedea0SLionel Sambuc
1108*ebfedea0SLionel Sambuc case PGP_PARSER_ERROR:
1109*ebfedea0SLionel Sambuc case PGP_PARSER_ERRCODE:
1110*ebfedea0SLionel Sambuc break;
1111*ebfedea0SLionel Sambuc
1112*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SECRET_KEY:
1113*ebfedea0SLionel Sambuc case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
1114*ebfedea0SLionel Sambuc pgp_seckey_free(&c->u.seckey);
1115*ebfedea0SLionel Sambuc break;
1116*ebfedea0SLionel Sambuc
1117*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PK_SESSION_KEY:
1118*ebfedea0SLionel Sambuc case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1119*ebfedea0SLionel Sambuc pgp_pk_sesskey_free(&c->u.pk_sesskey);
1120*ebfedea0SLionel Sambuc break;
1121*ebfedea0SLionel Sambuc
1122*ebfedea0SLionel Sambuc case PGP_GET_PASSPHRASE:
1123*ebfedea0SLionel Sambuc cmd_get_passphrase_free(&c->u.skey_passphrase);
1124*ebfedea0SLionel Sambuc break;
1125*ebfedea0SLionel Sambuc
1126*ebfedea0SLionel Sambuc default:
1127*ebfedea0SLionel Sambuc fprintf(stderr, "Can't free %d (0x%x)\n", c->tag, c->tag);
1128*ebfedea0SLionel Sambuc }
1129*ebfedea0SLionel Sambuc }
1130*ebfedea0SLionel Sambuc
1131*ebfedea0SLionel Sambuc /**
1132*ebfedea0SLionel Sambuc \ingroup Core_Create
1133*ebfedea0SLionel Sambuc \brief Free allocated memory
1134*ebfedea0SLionel Sambuc */
1135*ebfedea0SLionel Sambuc void
pgp_pk_sesskey_free(pgp_pk_sesskey_t * sk)1136*ebfedea0SLionel Sambuc pgp_pk_sesskey_free(pgp_pk_sesskey_t *sk)
1137*ebfedea0SLionel Sambuc {
1138*ebfedea0SLionel Sambuc switch (sk->alg) {
1139*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
1140*ebfedea0SLionel Sambuc free_BN(&sk->params.rsa.encrypted_m);
1141*ebfedea0SLionel Sambuc break;
1142*ebfedea0SLionel Sambuc
1143*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
1144*ebfedea0SLionel Sambuc free_BN(&sk->params.elgamal.g_to_k);
1145*ebfedea0SLionel Sambuc free_BN(&sk->params.elgamal.encrypted_m);
1146*ebfedea0SLionel Sambuc break;
1147*ebfedea0SLionel Sambuc
1148*ebfedea0SLionel Sambuc default:
1149*ebfedea0SLionel Sambuc (void) fprintf(stderr, "pgp_pk_sesskey_free: bad alg\n");
1150*ebfedea0SLionel Sambuc break;
1151*ebfedea0SLionel Sambuc }
1152*ebfedea0SLionel Sambuc }
1153*ebfedea0SLionel Sambuc
1154*ebfedea0SLionel Sambuc /**
1155*ebfedea0SLionel Sambuc \ingroup Core_Create
1156*ebfedea0SLionel Sambuc \brief Free allocated memory
1157*ebfedea0SLionel Sambuc */
1158*ebfedea0SLionel Sambuc /* ! Free the memory used when parsing a public key */
1159*ebfedea0SLionel Sambuc void
pgp_pubkey_free(pgp_pubkey_t * p)1160*ebfedea0SLionel Sambuc pgp_pubkey_free(pgp_pubkey_t *p)
1161*ebfedea0SLionel Sambuc {
1162*ebfedea0SLionel Sambuc switch (p->alg) {
1163*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
1164*ebfedea0SLionel Sambuc case PGP_PKA_RSA_ENCRYPT_ONLY:
1165*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
1166*ebfedea0SLionel Sambuc free_BN(&p->key.rsa.n);
1167*ebfedea0SLionel Sambuc free_BN(&p->key.rsa.e);
1168*ebfedea0SLionel Sambuc break;
1169*ebfedea0SLionel Sambuc
1170*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
1171*ebfedea0SLionel Sambuc free_BN(&p->key.dsa.p);
1172*ebfedea0SLionel Sambuc free_BN(&p->key.dsa.q);
1173*ebfedea0SLionel Sambuc free_BN(&p->key.dsa.g);
1174*ebfedea0SLionel Sambuc free_BN(&p->key.dsa.y);
1175*ebfedea0SLionel Sambuc break;
1176*ebfedea0SLionel Sambuc
1177*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
1178*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1179*ebfedea0SLionel Sambuc free_BN(&p->key.elgamal.p);
1180*ebfedea0SLionel Sambuc free_BN(&p->key.elgamal.g);
1181*ebfedea0SLionel Sambuc free_BN(&p->key.elgamal.y);
1182*ebfedea0SLionel Sambuc break;
1183*ebfedea0SLionel Sambuc
1184*ebfedea0SLionel Sambuc case PGP_PKA_NOTHING:
1185*ebfedea0SLionel Sambuc /* nothing to free */
1186*ebfedea0SLionel Sambuc break;
1187*ebfedea0SLionel Sambuc
1188*ebfedea0SLionel Sambuc default:
1189*ebfedea0SLionel Sambuc (void) fprintf(stderr, "pgp_pubkey_free: bad alg\n");
1190*ebfedea0SLionel Sambuc }
1191*ebfedea0SLionel Sambuc }
1192*ebfedea0SLionel Sambuc
1193*ebfedea0SLionel Sambuc /**
1194*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
1195*ebfedea0SLionel Sambuc */
1196*ebfedea0SLionel Sambuc static int
parse_pubkey_data(pgp_pubkey_t * key,pgp_region_t * region,pgp_stream_t * stream)1197*ebfedea0SLionel Sambuc parse_pubkey_data(pgp_pubkey_t *key, pgp_region_t *region,
1198*ebfedea0SLionel Sambuc pgp_stream_t *stream)
1199*ebfedea0SLionel Sambuc {
1200*ebfedea0SLionel Sambuc uint8_t c = 0x0;
1201*ebfedea0SLionel Sambuc
1202*ebfedea0SLionel Sambuc if (region->readc != 0) {
1203*ebfedea0SLionel Sambuc /* We should not have read anything so far */
1204*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_pubkey_data: bad length\n");
1205*ebfedea0SLionel Sambuc return 0;
1206*ebfedea0SLionel Sambuc }
1207*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1208*ebfedea0SLionel Sambuc return 0;
1209*ebfedea0SLionel Sambuc }
1210*ebfedea0SLionel Sambuc key->version = (pgp_version_t)c;
1211*ebfedea0SLionel Sambuc switch (key->version) {
1212*ebfedea0SLionel Sambuc case PGP_V2:
1213*ebfedea0SLionel Sambuc case PGP_V3:
1214*ebfedea0SLionel Sambuc case PGP_V4:
1215*ebfedea0SLionel Sambuc break;
1216*ebfedea0SLionel Sambuc default:
1217*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN,
1218*ebfedea0SLionel Sambuc "Bad public key version (0x%02x)", key->version);
1219*ebfedea0SLionel Sambuc return 0;
1220*ebfedea0SLionel Sambuc }
1221*ebfedea0SLionel Sambuc if (!limited_read_time(&key->birthtime, region, stream)) {
1222*ebfedea0SLionel Sambuc return 0;
1223*ebfedea0SLionel Sambuc }
1224*ebfedea0SLionel Sambuc
1225*ebfedea0SLionel Sambuc key->days_valid = 0;
1226*ebfedea0SLionel Sambuc if ((key->version == 2 || key->version == 3) &&
1227*ebfedea0SLionel Sambuc !limread_scalar(&key->days_valid, 2, region, stream)) {
1228*ebfedea0SLionel Sambuc return 0;
1229*ebfedea0SLionel Sambuc }
1230*ebfedea0SLionel Sambuc
1231*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1232*ebfedea0SLionel Sambuc return 0;
1233*ebfedea0SLionel Sambuc }
1234*ebfedea0SLionel Sambuc key->alg = c;
1235*ebfedea0SLionel Sambuc
1236*ebfedea0SLionel Sambuc switch (key->alg) {
1237*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
1238*ebfedea0SLionel Sambuc if (!limread_mpi(&key->key.dsa.p, region, stream) ||
1239*ebfedea0SLionel Sambuc !limread_mpi(&key->key.dsa.q, region, stream) ||
1240*ebfedea0SLionel Sambuc !limread_mpi(&key->key.dsa.g, region, stream) ||
1241*ebfedea0SLionel Sambuc !limread_mpi(&key->key.dsa.y, region, stream)) {
1242*ebfedea0SLionel Sambuc return 0;
1243*ebfedea0SLionel Sambuc }
1244*ebfedea0SLionel Sambuc break;
1245*ebfedea0SLionel Sambuc
1246*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
1247*ebfedea0SLionel Sambuc case PGP_PKA_RSA_ENCRYPT_ONLY:
1248*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
1249*ebfedea0SLionel Sambuc if (!limread_mpi(&key->key.rsa.n, region, stream) ||
1250*ebfedea0SLionel Sambuc !limread_mpi(&key->key.rsa.e, region, stream)) {
1251*ebfedea0SLionel Sambuc return 0;
1252*ebfedea0SLionel Sambuc }
1253*ebfedea0SLionel Sambuc break;
1254*ebfedea0SLionel Sambuc
1255*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
1256*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1257*ebfedea0SLionel Sambuc if (!limread_mpi(&key->key.elgamal.p, region, stream) ||
1258*ebfedea0SLionel Sambuc !limread_mpi(&key->key.elgamal.g, region, stream) ||
1259*ebfedea0SLionel Sambuc !limread_mpi(&key->key.elgamal.y, region, stream)) {
1260*ebfedea0SLionel Sambuc return 0;
1261*ebfedea0SLionel Sambuc }
1262*ebfedea0SLionel Sambuc break;
1263*ebfedea0SLionel Sambuc
1264*ebfedea0SLionel Sambuc default:
1265*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors,
1266*ebfedea0SLionel Sambuc PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
1267*ebfedea0SLionel Sambuc "Unsupported Public Key algorithm (%s)",
1268*ebfedea0SLionel Sambuc pgp_show_pka(key->alg));
1269*ebfedea0SLionel Sambuc return 0;
1270*ebfedea0SLionel Sambuc }
1271*ebfedea0SLionel Sambuc
1272*ebfedea0SLionel Sambuc return 1;
1273*ebfedea0SLionel Sambuc }
1274*ebfedea0SLionel Sambuc
1275*ebfedea0SLionel Sambuc
1276*ebfedea0SLionel Sambuc /**
1277*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1278*ebfedea0SLionel Sambuc * \brief Parse a public key packet.
1279*ebfedea0SLionel Sambuc *
1280*ebfedea0SLionel Sambuc * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys.
1281*ebfedea0SLionel Sambuc *
1282*ebfedea0SLionel Sambuc * Once the key has been parsed successfully, it is passed to the callback.
1283*ebfedea0SLionel Sambuc *
1284*ebfedea0SLionel Sambuc * \param *ptag Pointer to the current Packet Tag. This function should consume the entire packet.
1285*ebfedea0SLionel Sambuc * \param *reader Our reader
1286*ebfedea0SLionel Sambuc * \param *cb The callback
1287*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1288*ebfedea0SLionel Sambuc *
1289*ebfedea0SLionel Sambuc * \see RFC4880 5.5.2
1290*ebfedea0SLionel Sambuc */
1291*ebfedea0SLionel Sambuc static int
parse_pubkey(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)1292*ebfedea0SLionel Sambuc parse_pubkey(pgp_content_enum tag, pgp_region_t *region,
1293*ebfedea0SLionel Sambuc pgp_stream_t *stream)
1294*ebfedea0SLionel Sambuc {
1295*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1296*ebfedea0SLionel Sambuc
1297*ebfedea0SLionel Sambuc if (!parse_pubkey_data(&pkt.u.pubkey, region, stream)) {
1298*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_pubkey: parse_pubkey_data failed\n");
1299*ebfedea0SLionel Sambuc return 0;
1300*ebfedea0SLionel Sambuc }
1301*ebfedea0SLionel Sambuc
1302*ebfedea0SLionel Sambuc /* XXX: this test should be done for all packets, surely? */
1303*ebfedea0SLionel Sambuc if (region->readc != region->length) {
1304*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
1305*ebfedea0SLionel Sambuc "Unconsumed data (%d)", region->length - region->readc);
1306*ebfedea0SLionel Sambuc return 0;
1307*ebfedea0SLionel Sambuc }
1308*ebfedea0SLionel Sambuc CALLBACK(tag, &stream->cbinfo, &pkt);
1309*ebfedea0SLionel Sambuc
1310*ebfedea0SLionel Sambuc return 1;
1311*ebfedea0SLionel Sambuc }
1312*ebfedea0SLionel Sambuc
1313*ebfedea0SLionel Sambuc /**
1314*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1315*ebfedea0SLionel Sambuc * \brief Parse one user attribute packet.
1316*ebfedea0SLionel Sambuc *
1317*ebfedea0SLionel Sambuc * User attribute packets contain one or more attribute subpackets.
1318*ebfedea0SLionel Sambuc * For now, handle the whole packet as raw data.
1319*ebfedea0SLionel Sambuc */
1320*ebfedea0SLionel Sambuc
1321*ebfedea0SLionel Sambuc static int
parse_userattr(pgp_region_t * region,pgp_stream_t * stream)1322*ebfedea0SLionel Sambuc parse_userattr(pgp_region_t *region, pgp_stream_t *stream)
1323*ebfedea0SLionel Sambuc {
1324*ebfedea0SLionel Sambuc
1325*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1326*ebfedea0SLionel Sambuc
1327*ebfedea0SLionel Sambuc /*
1328*ebfedea0SLionel Sambuc * xxx- treat as raw data for now. Could break down further into
1329*ebfedea0SLionel Sambuc * attribute sub-packets later - rachel
1330*ebfedea0SLionel Sambuc */
1331*ebfedea0SLionel Sambuc if (region->readc != 0) {
1332*ebfedea0SLionel Sambuc /* We should not have read anything so far */
1333*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_userattr: bad length\n");
1334*ebfedea0SLionel Sambuc return 0;
1335*ebfedea0SLionel Sambuc }
1336*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.userattr, region, stream)) {
1337*ebfedea0SLionel Sambuc return 0;
1338*ebfedea0SLionel Sambuc }
1339*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_USER_ATTR, &stream->cbinfo, &pkt);
1340*ebfedea0SLionel Sambuc return 1;
1341*ebfedea0SLionel Sambuc }
1342*ebfedea0SLionel Sambuc
1343*ebfedea0SLionel Sambuc /**
1344*ebfedea0SLionel Sambuc \ingroup Core_Create
1345*ebfedea0SLionel Sambuc \brief Free allocated memory
1346*ebfedea0SLionel Sambuc */
1347*ebfedea0SLionel Sambuc /* ! Free the memory used when parsing this packet type */
1348*ebfedea0SLionel Sambuc void
pgp_userid_free(uint8_t ** id)1349*ebfedea0SLionel Sambuc pgp_userid_free(uint8_t **id)
1350*ebfedea0SLionel Sambuc {
1351*ebfedea0SLionel Sambuc free(*id);
1352*ebfedea0SLionel Sambuc *id = NULL;
1353*ebfedea0SLionel Sambuc }
1354*ebfedea0SLionel Sambuc
1355*ebfedea0SLionel Sambuc /**
1356*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1357*ebfedea0SLionel Sambuc * \brief Parse a user id.
1358*ebfedea0SLionel Sambuc *
1359*ebfedea0SLionel Sambuc * This function parses an user id packet, which is basically just a char array the size of the packet.
1360*ebfedea0SLionel Sambuc *
1361*ebfedea0SLionel Sambuc * The char array is to be treated as an UTF-8 string.
1362*ebfedea0SLionel Sambuc *
1363*ebfedea0SLionel Sambuc * The userid gets null terminated by this function. Freeing it is the responsibility of the caller.
1364*ebfedea0SLionel Sambuc *
1365*ebfedea0SLionel Sambuc * Once the userid has been parsed successfully, it is passed to the callback.
1366*ebfedea0SLionel Sambuc *
1367*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
1368*ebfedea0SLionel Sambuc * \param *reader Our reader
1369*ebfedea0SLionel Sambuc * \param *cb The callback
1370*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1371*ebfedea0SLionel Sambuc *
1372*ebfedea0SLionel Sambuc * \see RFC4880 5.11
1373*ebfedea0SLionel Sambuc */
1374*ebfedea0SLionel Sambuc static int
parse_userid(pgp_region_t * region,pgp_stream_t * stream)1375*ebfedea0SLionel Sambuc parse_userid(pgp_region_t *region, pgp_stream_t *stream)
1376*ebfedea0SLionel Sambuc {
1377*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1378*ebfedea0SLionel Sambuc
1379*ebfedea0SLionel Sambuc if (region->readc != 0) {
1380*ebfedea0SLionel Sambuc /* We should not have read anything so far */
1381*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_userid: bad length\n");
1382*ebfedea0SLionel Sambuc return 0;
1383*ebfedea0SLionel Sambuc }
1384*ebfedea0SLionel Sambuc
1385*ebfedea0SLionel Sambuc if ((pkt.u.userid = calloc(1, region->length + 1)) == NULL) {
1386*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_userid: bad alloc\n");
1387*ebfedea0SLionel Sambuc return 0;
1388*ebfedea0SLionel Sambuc }
1389*ebfedea0SLionel Sambuc
1390*ebfedea0SLionel Sambuc if (region->length &&
1391*ebfedea0SLionel Sambuc !limread(pkt.u.userid, region->length, region,
1392*ebfedea0SLionel Sambuc stream)) {
1393*ebfedea0SLionel Sambuc return 0;
1394*ebfedea0SLionel Sambuc }
1395*ebfedea0SLionel Sambuc pkt.u.userid[region->length] = 0x0;
1396*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_USER_ID, &stream->cbinfo, &pkt);
1397*ebfedea0SLionel Sambuc return 1;
1398*ebfedea0SLionel Sambuc }
1399*ebfedea0SLionel Sambuc
1400*ebfedea0SLionel Sambuc static pgp_hash_t *
parse_hash_find(pgp_stream_t * stream,const uint8_t * keyid)1401*ebfedea0SLionel Sambuc parse_hash_find(pgp_stream_t *stream, const uint8_t *keyid)
1402*ebfedea0SLionel Sambuc {
1403*ebfedea0SLionel Sambuc pgp_hashtype_t *hp;
1404*ebfedea0SLionel Sambuc size_t n;
1405*ebfedea0SLionel Sambuc
1406*ebfedea0SLionel Sambuc for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) {
1407*ebfedea0SLionel Sambuc if (memcmp(hp->keyid, keyid, PGP_KEY_ID_SIZE) == 0) {
1408*ebfedea0SLionel Sambuc return &hp->hash;
1409*ebfedea0SLionel Sambuc }
1410*ebfedea0SLionel Sambuc }
1411*ebfedea0SLionel Sambuc return NULL;
1412*ebfedea0SLionel Sambuc }
1413*ebfedea0SLionel Sambuc
1414*ebfedea0SLionel Sambuc /**
1415*ebfedea0SLionel Sambuc * \ingroup Core_Parse
1416*ebfedea0SLionel Sambuc * \brief Parse a version 3 signature.
1417*ebfedea0SLionel Sambuc *
1418*ebfedea0SLionel Sambuc * This function parses an version 3 signature packet, handling RSA and DSA signatures.
1419*ebfedea0SLionel Sambuc *
1420*ebfedea0SLionel Sambuc * Once the signature has been parsed successfully, it is passed to the callback.
1421*ebfedea0SLionel Sambuc *
1422*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
1423*ebfedea0SLionel Sambuc * \param *reader Our reader
1424*ebfedea0SLionel Sambuc * \param *cb The callback
1425*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1426*ebfedea0SLionel Sambuc *
1427*ebfedea0SLionel Sambuc * \see RFC4880 5.2.2
1428*ebfedea0SLionel Sambuc */
1429*ebfedea0SLionel Sambuc static int
parse_v3_sig(pgp_region_t * region,pgp_stream_t * stream)1430*ebfedea0SLionel Sambuc parse_v3_sig(pgp_region_t *region,
1431*ebfedea0SLionel Sambuc pgp_stream_t *stream)
1432*ebfedea0SLionel Sambuc {
1433*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1434*ebfedea0SLionel Sambuc uint8_t c = 0x0;
1435*ebfedea0SLionel Sambuc
1436*ebfedea0SLionel Sambuc /* clear signature */
1437*ebfedea0SLionel Sambuc (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
1438*ebfedea0SLionel Sambuc
1439*ebfedea0SLionel Sambuc pkt.u.sig.info.version = PGP_V3;
1440*ebfedea0SLionel Sambuc
1441*ebfedea0SLionel Sambuc /* hash info length */
1442*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1443*ebfedea0SLionel Sambuc return 0;
1444*ebfedea0SLionel Sambuc }
1445*ebfedea0SLionel Sambuc if (c != 5) {
1446*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt, "bad hash info length");
1447*ebfedea0SLionel Sambuc }
1448*ebfedea0SLionel Sambuc
1449*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1450*ebfedea0SLionel Sambuc return 0;
1451*ebfedea0SLionel Sambuc }
1452*ebfedea0SLionel Sambuc pkt.u.sig.info.type = (pgp_sig_type_t)c;
1453*ebfedea0SLionel Sambuc /* XXX: check signature type */
1454*ebfedea0SLionel Sambuc
1455*ebfedea0SLionel Sambuc if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) {
1456*ebfedea0SLionel Sambuc return 0;
1457*ebfedea0SLionel Sambuc }
1458*ebfedea0SLionel Sambuc pkt.u.sig.info.birthtime_set = 1;
1459*ebfedea0SLionel Sambuc
1460*ebfedea0SLionel Sambuc if (!limread(pkt.u.sig.info.signer_id, PGP_KEY_ID_SIZE, region,
1461*ebfedea0SLionel Sambuc stream)) {
1462*ebfedea0SLionel Sambuc return 0;
1463*ebfedea0SLionel Sambuc }
1464*ebfedea0SLionel Sambuc pkt.u.sig.info.signer_id_set = 1;
1465*ebfedea0SLionel Sambuc
1466*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1467*ebfedea0SLionel Sambuc return 0;
1468*ebfedea0SLionel Sambuc }
1469*ebfedea0SLionel Sambuc pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c;
1470*ebfedea0SLionel Sambuc /* XXX: check algorithm */
1471*ebfedea0SLionel Sambuc
1472*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1473*ebfedea0SLionel Sambuc return 0;
1474*ebfedea0SLionel Sambuc }
1475*ebfedea0SLionel Sambuc pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c;
1476*ebfedea0SLionel Sambuc /* XXX: check algorithm */
1477*ebfedea0SLionel Sambuc
1478*ebfedea0SLionel Sambuc if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
1479*ebfedea0SLionel Sambuc return 0;
1480*ebfedea0SLionel Sambuc }
1481*ebfedea0SLionel Sambuc
1482*ebfedea0SLionel Sambuc switch (pkt.u.sig.info.key_alg) {
1483*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
1484*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
1485*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
1486*ebfedea0SLionel Sambuc return 0;
1487*ebfedea0SLionel Sambuc }
1488*ebfedea0SLionel Sambuc break;
1489*ebfedea0SLionel Sambuc
1490*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
1491*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream) ||
1492*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
1493*ebfedea0SLionel Sambuc return 0;
1494*ebfedea0SLionel Sambuc }
1495*ebfedea0SLionel Sambuc break;
1496*ebfedea0SLionel Sambuc
1497*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1498*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
1499*ebfedea0SLionel Sambuc stream) ||
1500*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
1501*ebfedea0SLionel Sambuc stream)) {
1502*ebfedea0SLionel Sambuc return 0;
1503*ebfedea0SLionel Sambuc }
1504*ebfedea0SLionel Sambuc break;
1505*ebfedea0SLionel Sambuc
1506*ebfedea0SLionel Sambuc default:
1507*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors,
1508*ebfedea0SLionel Sambuc PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
1509*ebfedea0SLionel Sambuc "Unsupported signature key algorithm (%s)",
1510*ebfedea0SLionel Sambuc pgp_show_pka(pkt.u.sig.info.key_alg));
1511*ebfedea0SLionel Sambuc return 0;
1512*ebfedea0SLionel Sambuc }
1513*ebfedea0SLionel Sambuc
1514*ebfedea0SLionel Sambuc if (region->readc != region->length) {
1515*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
1516*ebfedea0SLionel Sambuc "Unconsumed data (%d)",
1517*ebfedea0SLionel Sambuc region->length - region->readc);
1518*ebfedea0SLionel Sambuc return 0;
1519*ebfedea0SLionel Sambuc }
1520*ebfedea0SLionel Sambuc if (pkt.u.sig.info.signer_id_set) {
1521*ebfedea0SLionel Sambuc pkt.u.sig.hash = parse_hash_find(stream,
1522*ebfedea0SLionel Sambuc pkt.u.sig.info.signer_id);
1523*ebfedea0SLionel Sambuc }
1524*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_SIGNATURE, &stream->cbinfo, &pkt);
1525*ebfedea0SLionel Sambuc return 1;
1526*ebfedea0SLionel Sambuc }
1527*ebfedea0SLionel Sambuc
1528*ebfedea0SLionel Sambuc /**
1529*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1530*ebfedea0SLionel Sambuc * \brief Parse one signature sub-packet.
1531*ebfedea0SLionel Sambuc *
1532*ebfedea0SLionel Sambuc * Version 4 signatures can have an arbitrary amount of (hashed and
1533*ebfedea0SLionel Sambuc * unhashed) subpackets. Subpackets are used to hold optional
1534*ebfedea0SLionel Sambuc * attributes of subpackets.
1535*ebfedea0SLionel Sambuc *
1536*ebfedea0SLionel Sambuc * This function parses one such signature subpacket.
1537*ebfedea0SLionel Sambuc *
1538*ebfedea0SLionel Sambuc * Once the subpacket has been parsed successfully, it is passed to the callback.
1539*ebfedea0SLionel Sambuc *
1540*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag. This function should consume the entire subpacket.
1541*ebfedea0SLionel Sambuc * \param *reader Our reader
1542*ebfedea0SLionel Sambuc * \param *cb The callback
1543*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1544*ebfedea0SLionel Sambuc *
1545*ebfedea0SLionel Sambuc * \see RFC4880 5.2.3
1546*ebfedea0SLionel Sambuc */
1547*ebfedea0SLionel Sambuc static int
parse_one_sig_subpacket(pgp_sig_t * sig,pgp_region_t * region,pgp_stream_t * stream)1548*ebfedea0SLionel Sambuc parse_one_sig_subpacket(pgp_sig_t *sig,
1549*ebfedea0SLionel Sambuc pgp_region_t *region,
1550*ebfedea0SLionel Sambuc pgp_stream_t *stream)
1551*ebfedea0SLionel Sambuc {
1552*ebfedea0SLionel Sambuc pgp_region_t subregion;
1553*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1554*ebfedea0SLionel Sambuc uint8_t bools = 0x0;
1555*ebfedea0SLionel Sambuc uint8_t c = 0x0;
1556*ebfedea0SLionel Sambuc unsigned doread = 1;
1557*ebfedea0SLionel Sambuc unsigned t8;
1558*ebfedea0SLionel Sambuc unsigned t7;
1559*ebfedea0SLionel Sambuc
1560*ebfedea0SLionel Sambuc pgp_init_subregion(&subregion, region);
1561*ebfedea0SLionel Sambuc if (!limited_read_new_length(&subregion.length, region, stream)) {
1562*ebfedea0SLionel Sambuc return 0;
1563*ebfedea0SLionel Sambuc }
1564*ebfedea0SLionel Sambuc
1565*ebfedea0SLionel Sambuc if (subregion.length > region->length) {
1566*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt, "Subpacket too long");
1567*ebfedea0SLionel Sambuc }
1568*ebfedea0SLionel Sambuc
1569*ebfedea0SLionel Sambuc if (!limread(&c, 1, &subregion, stream)) {
1570*ebfedea0SLionel Sambuc return 0;
1571*ebfedea0SLionel Sambuc }
1572*ebfedea0SLionel Sambuc
1573*ebfedea0SLionel Sambuc t8 = (c & 0x7f) / 8;
1574*ebfedea0SLionel Sambuc t7 = 1 << (c & 7);
1575*ebfedea0SLionel Sambuc
1576*ebfedea0SLionel Sambuc pkt.critical = (unsigned)c >> 7;
1577*ebfedea0SLionel Sambuc pkt.tag = (pgp_content_enum)(PGP_PTAG_SIG_SUBPKT_BASE + (c & 0x7f));
1578*ebfedea0SLionel Sambuc
1579*ebfedea0SLionel Sambuc /* Application wants it delivered raw */
1580*ebfedea0SLionel Sambuc if (stream->ss_raw[t8] & t7) {
1581*ebfedea0SLionel Sambuc pkt.u.ss_raw.tag = pkt.tag;
1582*ebfedea0SLionel Sambuc pkt.u.ss_raw.length = subregion.length - 1;
1583*ebfedea0SLionel Sambuc pkt.u.ss_raw.raw = calloc(1, pkt.u.ss_raw.length);
1584*ebfedea0SLionel Sambuc if (pkt.u.ss_raw.raw == NULL) {
1585*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_one_sig_subpacket: bad alloc\n");
1586*ebfedea0SLionel Sambuc return 0;
1587*ebfedea0SLionel Sambuc }
1588*ebfedea0SLionel Sambuc if (!limread(pkt.u.ss_raw.raw, (unsigned)pkt.u.ss_raw.length,
1589*ebfedea0SLionel Sambuc &subregion, stream)) {
1590*ebfedea0SLionel Sambuc return 0;
1591*ebfedea0SLionel Sambuc }
1592*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_RAW_SS, &stream->cbinfo, &pkt);
1593*ebfedea0SLionel Sambuc return 1;
1594*ebfedea0SLionel Sambuc }
1595*ebfedea0SLionel Sambuc switch (pkt.tag) {
1596*ebfedea0SLionel Sambuc case PGP_PTAG_SS_CREATION_TIME:
1597*ebfedea0SLionel Sambuc case PGP_PTAG_SS_EXPIRATION_TIME:
1598*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEY_EXPIRY:
1599*ebfedea0SLionel Sambuc if (!limited_read_time(&pkt.u.ss_time, &subregion, stream))
1600*ebfedea0SLionel Sambuc return 0;
1601*ebfedea0SLionel Sambuc if (pkt.tag == PGP_PTAG_SS_CREATION_TIME) {
1602*ebfedea0SLionel Sambuc sig->info.birthtime = pkt.u.ss_time;
1603*ebfedea0SLionel Sambuc sig->info.birthtime_set = 1;
1604*ebfedea0SLionel Sambuc }
1605*ebfedea0SLionel Sambuc if (pkt.tag == PGP_PTAG_SS_EXPIRATION_TIME) {
1606*ebfedea0SLionel Sambuc sig->info.duration = pkt.u.ss_time;
1607*ebfedea0SLionel Sambuc sig->info.duration_set = 1;
1608*ebfedea0SLionel Sambuc }
1609*ebfedea0SLionel Sambuc break;
1610*ebfedea0SLionel Sambuc
1611*ebfedea0SLionel Sambuc case PGP_PTAG_SS_TRUST:
1612*ebfedea0SLionel Sambuc if (!limread(&pkt.u.ss_trust.level, 1, &subregion, stream) ||
1613*ebfedea0SLionel Sambuc !limread(&pkt.u.ss_trust.amount, 1, &subregion, stream)) {
1614*ebfedea0SLionel Sambuc return 0;
1615*ebfedea0SLionel Sambuc }
1616*ebfedea0SLionel Sambuc break;
1617*ebfedea0SLionel Sambuc
1618*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCABLE:
1619*ebfedea0SLionel Sambuc if (!limread(&bools, 1, &subregion, stream)) {
1620*ebfedea0SLionel Sambuc return 0;
1621*ebfedea0SLionel Sambuc }
1622*ebfedea0SLionel Sambuc pkt.u.ss_revocable = !!bools;
1623*ebfedea0SLionel Sambuc break;
1624*ebfedea0SLionel Sambuc
1625*ebfedea0SLionel Sambuc case PGP_PTAG_SS_ISSUER_KEY_ID:
1626*ebfedea0SLionel Sambuc if (!limread(pkt.u.ss_issuer, PGP_KEY_ID_SIZE, &subregion, stream)) {
1627*ebfedea0SLionel Sambuc return 0;
1628*ebfedea0SLionel Sambuc }
1629*ebfedea0SLionel Sambuc (void) memcpy(sig->info.signer_id, pkt.u.ss_issuer, PGP_KEY_ID_SIZE);
1630*ebfedea0SLionel Sambuc sig->info.signer_id_set = 1;
1631*ebfedea0SLionel Sambuc break;
1632*ebfedea0SLionel Sambuc
1633*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREFERRED_SKA:
1634*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_skapref, &subregion, stream)) {
1635*ebfedea0SLionel Sambuc return 0;
1636*ebfedea0SLionel Sambuc }
1637*ebfedea0SLionel Sambuc break;
1638*ebfedea0SLionel Sambuc
1639*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREFERRED_HASH:
1640*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_hashpref, &subregion, stream)) {
1641*ebfedea0SLionel Sambuc return 0;
1642*ebfedea0SLionel Sambuc }
1643*ebfedea0SLionel Sambuc break;
1644*ebfedea0SLionel Sambuc
1645*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREF_COMPRESS:
1646*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_zpref, &subregion, stream)) {
1647*ebfedea0SLionel Sambuc return 0;
1648*ebfedea0SLionel Sambuc }
1649*ebfedea0SLionel Sambuc break;
1650*ebfedea0SLionel Sambuc
1651*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PRIMARY_USER_ID:
1652*ebfedea0SLionel Sambuc if (!limread(&bools, 1, &subregion, stream)) {
1653*ebfedea0SLionel Sambuc return 0;
1654*ebfedea0SLionel Sambuc }
1655*ebfedea0SLionel Sambuc pkt.u.ss_primary_userid = !!bools;
1656*ebfedea0SLionel Sambuc break;
1657*ebfedea0SLionel Sambuc
1658*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEY_FLAGS:
1659*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
1660*ebfedea0SLionel Sambuc return 0;
1661*ebfedea0SLionel Sambuc }
1662*ebfedea0SLionel Sambuc break;
1663*ebfedea0SLionel Sambuc
1664*ebfedea0SLionel Sambuc case PGP_PTAG_SS_KEYSERV_PREFS:
1665*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_key_server_prefs, &subregion, stream)) {
1666*ebfedea0SLionel Sambuc return 0;
1667*ebfedea0SLionel Sambuc }
1668*ebfedea0SLionel Sambuc break;
1669*ebfedea0SLionel Sambuc
1670*ebfedea0SLionel Sambuc case PGP_PTAG_SS_FEATURES:
1671*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_features, &subregion, stream)) {
1672*ebfedea0SLionel Sambuc return 0;
1673*ebfedea0SLionel Sambuc }
1674*ebfedea0SLionel Sambuc break;
1675*ebfedea0SLionel Sambuc
1676*ebfedea0SLionel Sambuc case PGP_PTAG_SS_SIGNERS_USER_ID:
1677*ebfedea0SLionel Sambuc if (!read_unsig_str(&pkt.u.ss_signer, &subregion, stream)) {
1678*ebfedea0SLionel Sambuc return 0;
1679*ebfedea0SLionel Sambuc }
1680*ebfedea0SLionel Sambuc break;
1681*ebfedea0SLionel Sambuc
1682*ebfedea0SLionel Sambuc case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
1683*ebfedea0SLionel Sambuc /* \todo should do something with this sig? */
1684*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_embedded_sig, &subregion, stream)) {
1685*ebfedea0SLionel Sambuc return 0;
1686*ebfedea0SLionel Sambuc }
1687*ebfedea0SLionel Sambuc break;
1688*ebfedea0SLionel Sambuc
1689*ebfedea0SLionel Sambuc case PGP_PTAG_SS_NOTATION_DATA:
1690*ebfedea0SLionel Sambuc if (!limread_data(&pkt.u.ss_notation.flags, 4,
1691*ebfedea0SLionel Sambuc &subregion, stream)) {
1692*ebfedea0SLionel Sambuc return 0;
1693*ebfedea0SLionel Sambuc }
1694*ebfedea0SLionel Sambuc if (!limread_size_t(&pkt.u.ss_notation.name.len, 2,
1695*ebfedea0SLionel Sambuc &subregion, stream)) {
1696*ebfedea0SLionel Sambuc return 0;
1697*ebfedea0SLionel Sambuc }
1698*ebfedea0SLionel Sambuc if (!limread_size_t(&pkt.u.ss_notation.value.len, 2,
1699*ebfedea0SLionel Sambuc &subregion, stream)) {
1700*ebfedea0SLionel Sambuc return 0;
1701*ebfedea0SLionel Sambuc }
1702*ebfedea0SLionel Sambuc if (!limread_data(&pkt.u.ss_notation.name,
1703*ebfedea0SLionel Sambuc (unsigned)pkt.u.ss_notation.name.len,
1704*ebfedea0SLionel Sambuc &subregion, stream)) {
1705*ebfedea0SLionel Sambuc return 0;
1706*ebfedea0SLionel Sambuc }
1707*ebfedea0SLionel Sambuc if (!limread_data(&pkt.u.ss_notation.value,
1708*ebfedea0SLionel Sambuc (unsigned)pkt.u.ss_notation.value.len,
1709*ebfedea0SLionel Sambuc &subregion, stream)) {
1710*ebfedea0SLionel Sambuc return 0;
1711*ebfedea0SLionel Sambuc }
1712*ebfedea0SLionel Sambuc break;
1713*ebfedea0SLionel Sambuc
1714*ebfedea0SLionel Sambuc case PGP_PTAG_SS_POLICY_URI:
1715*ebfedea0SLionel Sambuc if (!read_string(&pkt.u.ss_policy, &subregion, stream)) {
1716*ebfedea0SLionel Sambuc return 0;
1717*ebfedea0SLionel Sambuc }
1718*ebfedea0SLionel Sambuc break;
1719*ebfedea0SLionel Sambuc
1720*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REGEXP:
1721*ebfedea0SLionel Sambuc if (!read_string(&pkt.u.ss_regexp, &subregion, stream)) {
1722*ebfedea0SLionel Sambuc return 0;
1723*ebfedea0SLionel Sambuc }
1724*ebfedea0SLionel Sambuc break;
1725*ebfedea0SLionel Sambuc
1726*ebfedea0SLionel Sambuc case PGP_PTAG_SS_PREF_KEYSERV:
1727*ebfedea0SLionel Sambuc if (!read_string(&pkt.u.ss_keyserv, &subregion, stream)) {
1728*ebfedea0SLionel Sambuc return 0;
1729*ebfedea0SLionel Sambuc }
1730*ebfedea0SLionel Sambuc break;
1731*ebfedea0SLionel Sambuc
1732*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED00:
1733*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED01:
1734*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED02:
1735*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED03:
1736*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED04:
1737*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED05:
1738*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED06:
1739*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED07:
1740*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED08:
1741*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED09:
1742*ebfedea0SLionel Sambuc case PGP_PTAG_SS_USERDEFINED10:
1743*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_userdef, &subregion, stream)) {
1744*ebfedea0SLionel Sambuc return 0;
1745*ebfedea0SLionel Sambuc }
1746*ebfedea0SLionel Sambuc break;
1747*ebfedea0SLionel Sambuc
1748*ebfedea0SLionel Sambuc case PGP_PTAG_SS_RESERVED:
1749*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.ss_unknown, &subregion, stream)) {
1750*ebfedea0SLionel Sambuc return 0;
1751*ebfedea0SLionel Sambuc }
1752*ebfedea0SLionel Sambuc break;
1753*ebfedea0SLionel Sambuc
1754*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCATION_REASON:
1755*ebfedea0SLionel Sambuc /* first byte is the machine-readable code */
1756*ebfedea0SLionel Sambuc if (!limread(&pkt.u.ss_revocation.code, 1, &subregion, stream)) {
1757*ebfedea0SLionel Sambuc return 0;
1758*ebfedea0SLionel Sambuc }
1759*ebfedea0SLionel Sambuc /* the rest is a human-readable UTF-8 string */
1760*ebfedea0SLionel Sambuc if (!read_string(&pkt.u.ss_revocation.reason, &subregion,
1761*ebfedea0SLionel Sambuc stream)) {
1762*ebfedea0SLionel Sambuc return 0;
1763*ebfedea0SLionel Sambuc }
1764*ebfedea0SLionel Sambuc break;
1765*ebfedea0SLionel Sambuc
1766*ebfedea0SLionel Sambuc case PGP_PTAG_SS_REVOCATION_KEY:
1767*ebfedea0SLionel Sambuc /* octet 0 = class. Bit 0x80 must be set */
1768*ebfedea0SLionel Sambuc if (!limread(&pkt.u.ss_revocation_key.class, 1,
1769*ebfedea0SLionel Sambuc &subregion, stream)) {
1770*ebfedea0SLionel Sambuc return 0;
1771*ebfedea0SLionel Sambuc }
1772*ebfedea0SLionel Sambuc if (!(pkt.u.ss_revocation_key.class & 0x80)) {
1773*ebfedea0SLionel Sambuc printf("Warning: PGP_PTAG_SS_REVOCATION_KEY class: "
1774*ebfedea0SLionel Sambuc "Bit 0x80 should be set\n");
1775*ebfedea0SLionel Sambuc return 0;
1776*ebfedea0SLionel Sambuc }
1777*ebfedea0SLionel Sambuc /* octet 1 = algid */
1778*ebfedea0SLionel Sambuc if (!limread(&pkt.u.ss_revocation_key.algid, 1,
1779*ebfedea0SLionel Sambuc &subregion, stream)) {
1780*ebfedea0SLionel Sambuc return 0;
1781*ebfedea0SLionel Sambuc }
1782*ebfedea0SLionel Sambuc /* octets 2-21 = fingerprint */
1783*ebfedea0SLionel Sambuc if (!limread(&pkt.u.ss_revocation_key.fingerprint[0],
1784*ebfedea0SLionel Sambuc PGP_FINGERPRINT_SIZE, &subregion, stream)) {
1785*ebfedea0SLionel Sambuc return 0;
1786*ebfedea0SLionel Sambuc }
1787*ebfedea0SLionel Sambuc break;
1788*ebfedea0SLionel Sambuc
1789*ebfedea0SLionel Sambuc default:
1790*ebfedea0SLionel Sambuc if (stream->ss_parsed[t8] & t7) {
1791*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_PROTO_UNKNOWN_SS,
1792*ebfedea0SLionel Sambuc "Unknown signature subpacket type (%d)",
1793*ebfedea0SLionel Sambuc c & 0x7f);
1794*ebfedea0SLionel Sambuc }
1795*ebfedea0SLionel Sambuc doread = 0;
1796*ebfedea0SLionel Sambuc break;
1797*ebfedea0SLionel Sambuc }
1798*ebfedea0SLionel Sambuc
1799*ebfedea0SLionel Sambuc /* Application doesn't want it delivered parsed */
1800*ebfedea0SLionel Sambuc if (!(stream->ss_parsed[t8] & t7)) {
1801*ebfedea0SLionel Sambuc if (pkt.critical) {
1802*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors,
1803*ebfedea0SLionel Sambuc PGP_E_PROTO_CRITICAL_SS_IGNORED,
1804*ebfedea0SLionel Sambuc "Critical signature subpacket ignored (%d)",
1805*ebfedea0SLionel Sambuc c & 0x7f);
1806*ebfedea0SLionel Sambuc }
1807*ebfedea0SLionel Sambuc if (!doread &&
1808*ebfedea0SLionel Sambuc !limskip(subregion.length - 1, &subregion, stream)) {
1809*ebfedea0SLionel Sambuc return 0;
1810*ebfedea0SLionel Sambuc }
1811*ebfedea0SLionel Sambuc if (doread) {
1812*ebfedea0SLionel Sambuc pgp_parser_content_free(&pkt);
1813*ebfedea0SLionel Sambuc }
1814*ebfedea0SLionel Sambuc return 1;
1815*ebfedea0SLionel Sambuc }
1816*ebfedea0SLionel Sambuc if (doread && subregion.readc != subregion.length) {
1817*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
1818*ebfedea0SLionel Sambuc "Unconsumed data (%d)",
1819*ebfedea0SLionel Sambuc subregion.length - subregion.readc);
1820*ebfedea0SLionel Sambuc return 0;
1821*ebfedea0SLionel Sambuc }
1822*ebfedea0SLionel Sambuc CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
1823*ebfedea0SLionel Sambuc return 1;
1824*ebfedea0SLionel Sambuc }
1825*ebfedea0SLionel Sambuc
1826*ebfedea0SLionel Sambuc /**
1827*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1828*ebfedea0SLionel Sambuc * \brief Parse several signature subpackets.
1829*ebfedea0SLionel Sambuc *
1830*ebfedea0SLionel Sambuc * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set.
1831*ebfedea0SLionel Sambuc * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the
1832*ebfedea0SLionel Sambuc * entire set is consumed.
1833*ebfedea0SLionel Sambuc *
1834*ebfedea0SLionel Sambuc * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket.
1835*ebfedea0SLionel Sambuc *
1836*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag.
1837*ebfedea0SLionel Sambuc * \param *reader Our reader
1838*ebfedea0SLionel Sambuc * \param *cb The callback
1839*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1840*ebfedea0SLionel Sambuc *
1841*ebfedea0SLionel Sambuc * \see RFC4880 5.2.3
1842*ebfedea0SLionel Sambuc */
1843*ebfedea0SLionel Sambuc static int
parse_sig_subpkts(pgp_sig_t * sig,pgp_region_t * region,pgp_stream_t * stream)1844*ebfedea0SLionel Sambuc parse_sig_subpkts(pgp_sig_t *sig,
1845*ebfedea0SLionel Sambuc pgp_region_t *region,
1846*ebfedea0SLionel Sambuc pgp_stream_t *stream)
1847*ebfedea0SLionel Sambuc {
1848*ebfedea0SLionel Sambuc pgp_region_t subregion;
1849*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1850*ebfedea0SLionel Sambuc
1851*ebfedea0SLionel Sambuc pgp_init_subregion(&subregion, region);
1852*ebfedea0SLionel Sambuc if (!limread_scalar(&subregion.length, 2, region, stream)) {
1853*ebfedea0SLionel Sambuc return 0;
1854*ebfedea0SLionel Sambuc }
1855*ebfedea0SLionel Sambuc
1856*ebfedea0SLionel Sambuc if (subregion.length > region->length) {
1857*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt, "Subpacket set too long");
1858*ebfedea0SLionel Sambuc }
1859*ebfedea0SLionel Sambuc
1860*ebfedea0SLionel Sambuc while (subregion.readc < subregion.length) {
1861*ebfedea0SLionel Sambuc if (!parse_one_sig_subpacket(sig, &subregion, stream)) {
1862*ebfedea0SLionel Sambuc return 0;
1863*ebfedea0SLionel Sambuc }
1864*ebfedea0SLionel Sambuc }
1865*ebfedea0SLionel Sambuc
1866*ebfedea0SLionel Sambuc if (subregion.readc != subregion.length) {
1867*ebfedea0SLionel Sambuc if (!limskip(subregion.length - subregion.readc,
1868*ebfedea0SLionel Sambuc &subregion, stream)) {
1869*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt,
1870*ebfedea0SLionel Sambuc "parse_sig_subpkts: subpacket length read mismatch");
1871*ebfedea0SLionel Sambuc }
1872*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt, "Subpacket length mismatch");
1873*ebfedea0SLionel Sambuc }
1874*ebfedea0SLionel Sambuc return 1;
1875*ebfedea0SLionel Sambuc }
1876*ebfedea0SLionel Sambuc
1877*ebfedea0SLionel Sambuc /**
1878*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
1879*ebfedea0SLionel Sambuc * \brief Parse a version 4 signature.
1880*ebfedea0SLionel Sambuc *
1881*ebfedea0SLionel Sambuc * This function parses a version 4 signature including all its hashed and unhashed subpackets.
1882*ebfedea0SLionel Sambuc *
1883*ebfedea0SLionel Sambuc * Once the signature packet has been parsed successfully, it is passed to the callback.
1884*ebfedea0SLionel Sambuc *
1885*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag.
1886*ebfedea0SLionel Sambuc * \param *reader Our reader
1887*ebfedea0SLionel Sambuc * \param *cb The callback
1888*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
1889*ebfedea0SLionel Sambuc *
1890*ebfedea0SLionel Sambuc * \see RFC4880 5.2.3
1891*ebfedea0SLionel Sambuc */
1892*ebfedea0SLionel Sambuc static int
parse_v4_sig(pgp_region_t * region,pgp_stream_t * stream)1893*ebfedea0SLionel Sambuc parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
1894*ebfedea0SLionel Sambuc {
1895*ebfedea0SLionel Sambuc pgp_packet_t pkt;
1896*ebfedea0SLionel Sambuc uint8_t c = 0x0;
1897*ebfedea0SLionel Sambuc
1898*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1899*ebfedea0SLionel Sambuc fprintf(stderr, "\nparse_v4_sig\n");
1900*ebfedea0SLionel Sambuc }
1901*ebfedea0SLionel Sambuc /* clear signature */
1902*ebfedea0SLionel Sambuc (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
1903*ebfedea0SLionel Sambuc
1904*ebfedea0SLionel Sambuc /*
1905*ebfedea0SLionel Sambuc * We need to hash the packet data from version through the hashed
1906*ebfedea0SLionel Sambuc * subpacket data
1907*ebfedea0SLionel Sambuc */
1908*ebfedea0SLionel Sambuc
1909*ebfedea0SLionel Sambuc pkt.u.sig.v4_hashstart = stream->readinfo.alength - 1;
1910*ebfedea0SLionel Sambuc
1911*ebfedea0SLionel Sambuc /* Set version,type,algorithms */
1912*ebfedea0SLionel Sambuc
1913*ebfedea0SLionel Sambuc pkt.u.sig.info.version = PGP_V4;
1914*ebfedea0SLionel Sambuc
1915*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1916*ebfedea0SLionel Sambuc return 0;
1917*ebfedea0SLionel Sambuc }
1918*ebfedea0SLionel Sambuc pkt.u.sig.info.type = (pgp_sig_type_t)c;
1919*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1920*ebfedea0SLionel Sambuc fprintf(stderr, "signature type=%d (%s)\n",
1921*ebfedea0SLionel Sambuc pkt.u.sig.info.type,
1922*ebfedea0SLionel Sambuc pgp_show_sig_type(pkt.u.sig.info.type));
1923*ebfedea0SLionel Sambuc }
1924*ebfedea0SLionel Sambuc /* XXX: check signature type */
1925*ebfedea0SLionel Sambuc
1926*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1927*ebfedea0SLionel Sambuc return 0;
1928*ebfedea0SLionel Sambuc }
1929*ebfedea0SLionel Sambuc pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c;
1930*ebfedea0SLionel Sambuc /* XXX: check key algorithm */
1931*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1932*ebfedea0SLionel Sambuc (void) fprintf(stderr, "key_alg=%d (%s)\n",
1933*ebfedea0SLionel Sambuc pkt.u.sig.info.key_alg,
1934*ebfedea0SLionel Sambuc pgp_show_pka(pkt.u.sig.info.key_alg));
1935*ebfedea0SLionel Sambuc }
1936*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
1937*ebfedea0SLionel Sambuc return 0;
1938*ebfedea0SLionel Sambuc }
1939*ebfedea0SLionel Sambuc pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c;
1940*ebfedea0SLionel Sambuc /* XXX: check hash algorithm */
1941*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1942*ebfedea0SLionel Sambuc fprintf(stderr, "hash_alg=%d %s\n",
1943*ebfedea0SLionel Sambuc pkt.u.sig.info.hash_alg,
1944*ebfedea0SLionel Sambuc pgp_show_hash_alg(pkt.u.sig.info.hash_alg));
1945*ebfedea0SLionel Sambuc }
1946*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_SIGNATURE_HEADER, &stream->cbinfo, &pkt);
1947*ebfedea0SLionel Sambuc
1948*ebfedea0SLionel Sambuc if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
1949*ebfedea0SLionel Sambuc return 0;
1950*ebfedea0SLionel Sambuc }
1951*ebfedea0SLionel Sambuc
1952*ebfedea0SLionel Sambuc pkt.u.sig.info.v4_hashlen = stream->readinfo.alength
1953*ebfedea0SLionel Sambuc - pkt.u.sig.v4_hashstart;
1954*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1955*ebfedea0SLionel Sambuc fprintf(stderr, "v4_hashlen=%zd\n", pkt.u.sig.info.v4_hashlen);
1956*ebfedea0SLionel Sambuc }
1957*ebfedea0SLionel Sambuc
1958*ebfedea0SLionel Sambuc /* copy hashed subpackets */
1959*ebfedea0SLionel Sambuc if (pkt.u.sig.info.v4_hashed) {
1960*ebfedea0SLionel Sambuc free(pkt.u.sig.info.v4_hashed);
1961*ebfedea0SLionel Sambuc }
1962*ebfedea0SLionel Sambuc pkt.u.sig.info.v4_hashed = calloc(1, pkt.u.sig.info.v4_hashlen);
1963*ebfedea0SLionel Sambuc if (pkt.u.sig.info.v4_hashed == NULL) {
1964*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_v4_sig: bad alloc\n");
1965*ebfedea0SLionel Sambuc return 0;
1966*ebfedea0SLionel Sambuc }
1967*ebfedea0SLionel Sambuc
1968*ebfedea0SLionel Sambuc if (!stream->readinfo.accumulate) {
1969*ebfedea0SLionel Sambuc /* We must accumulate, else we can't check the signature */
1970*ebfedea0SLionel Sambuc fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
1971*ebfedea0SLionel Sambuc return 0;
1972*ebfedea0SLionel Sambuc }
1973*ebfedea0SLionel Sambuc (void) memcpy(pkt.u.sig.info.v4_hashed,
1974*ebfedea0SLionel Sambuc stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
1975*ebfedea0SLionel Sambuc pkt.u.sig.info.v4_hashlen);
1976*ebfedea0SLionel Sambuc
1977*ebfedea0SLionel Sambuc if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
1978*ebfedea0SLionel Sambuc return 0;
1979*ebfedea0SLionel Sambuc }
1980*ebfedea0SLionel Sambuc
1981*ebfedea0SLionel Sambuc if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
1982*ebfedea0SLionel Sambuc return 0;
1983*ebfedea0SLionel Sambuc }
1984*ebfedea0SLionel Sambuc
1985*ebfedea0SLionel Sambuc switch (pkt.u.sig.info.key_alg) {
1986*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
1987*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
1988*ebfedea0SLionel Sambuc return 0;
1989*ebfedea0SLionel Sambuc }
1990*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
1991*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n");
1992*ebfedea0SLionel Sambuc BN_print_fp(stderr, pkt.u.sig.info.sig.rsa.sig);
1993*ebfedea0SLionel Sambuc (void) fprintf(stderr, "\n");
1994*ebfedea0SLionel Sambuc }
1995*ebfedea0SLionel Sambuc break;
1996*ebfedea0SLionel Sambuc
1997*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
1998*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream)) {
1999*ebfedea0SLionel Sambuc /*
2000*ebfedea0SLionel Sambuc * usually if this fails, it just means we've reached
2001*ebfedea0SLionel Sambuc * the end of the keyring
2002*ebfedea0SLionel Sambuc */
2003*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2004*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2005*ebfedea0SLionel Sambuc "Error reading DSA r field in signature");
2006*ebfedea0SLionel Sambuc }
2007*ebfedea0SLionel Sambuc return 0;
2008*ebfedea0SLionel Sambuc }
2009*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
2010*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt,
2011*ebfedea0SLionel Sambuc "Error reading DSA s field in signature");
2012*ebfedea0SLionel Sambuc }
2013*ebfedea0SLionel Sambuc break;
2014*ebfedea0SLionel Sambuc
2015*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
2016*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
2017*ebfedea0SLionel Sambuc stream) ||
2018*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
2019*ebfedea0SLionel Sambuc stream)) {
2020*ebfedea0SLionel Sambuc return 0;
2021*ebfedea0SLionel Sambuc }
2022*ebfedea0SLionel Sambuc break;
2023*ebfedea0SLionel Sambuc
2024*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE00:
2025*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE01:
2026*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE02:
2027*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE03:
2028*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE04:
2029*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE05:
2030*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE06:
2031*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE07:
2032*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE08:
2033*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE09:
2034*ebfedea0SLionel Sambuc case PGP_PKA_PRIVATE10:
2035*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
2036*ebfedea0SLionel Sambuc return 0;
2037*ebfedea0SLionel Sambuc }
2038*ebfedea0SLionel Sambuc break;
2039*ebfedea0SLionel Sambuc
2040*ebfedea0SLionel Sambuc default:
2041*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
2042*ebfedea0SLionel Sambuc "Bad v4 signature key algorithm (%s)",
2043*ebfedea0SLionel Sambuc pgp_show_pka(pkt.u.sig.info.key_alg));
2044*ebfedea0SLionel Sambuc return 0;
2045*ebfedea0SLionel Sambuc }
2046*ebfedea0SLionel Sambuc if (region->readc != region->length) {
2047*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
2048*ebfedea0SLionel Sambuc "Unconsumed data (%d)",
2049*ebfedea0SLionel Sambuc region->length - region->readc);
2050*ebfedea0SLionel Sambuc return 0;
2051*ebfedea0SLionel Sambuc }
2052*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
2053*ebfedea0SLionel Sambuc return 1;
2054*ebfedea0SLionel Sambuc }
2055*ebfedea0SLionel Sambuc
2056*ebfedea0SLionel Sambuc /**
2057*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
2058*ebfedea0SLionel Sambuc * \brief Parse a signature subpacket.
2059*ebfedea0SLionel Sambuc *
2060*ebfedea0SLionel Sambuc * This function calls the appropriate function to handle v3 or v4 signatures.
2061*ebfedea0SLionel Sambuc *
2062*ebfedea0SLionel Sambuc * Once the signature packet has been parsed successfully, it is passed to the callback.
2063*ebfedea0SLionel Sambuc *
2064*ebfedea0SLionel Sambuc * \param *ptag Pointer to the Packet Tag.
2065*ebfedea0SLionel Sambuc * \param *reader Our reader
2066*ebfedea0SLionel Sambuc * \param *cb The callback
2067*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error
2068*ebfedea0SLionel Sambuc */
2069*ebfedea0SLionel Sambuc static int
parse_sig(pgp_region_t * region,pgp_stream_t * stream)2070*ebfedea0SLionel Sambuc parse_sig(pgp_region_t *region, pgp_stream_t *stream)
2071*ebfedea0SLionel Sambuc {
2072*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2073*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2074*ebfedea0SLionel Sambuc
2075*ebfedea0SLionel Sambuc if (region->readc != 0) {
2076*ebfedea0SLionel Sambuc /* We should not have read anything so far */
2077*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_sig: bad length\n");
2078*ebfedea0SLionel Sambuc return 0;
2079*ebfedea0SLionel Sambuc }
2080*ebfedea0SLionel Sambuc
2081*ebfedea0SLionel Sambuc (void) memset(&pkt, 0x0, sizeof(pkt));
2082*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2083*ebfedea0SLionel Sambuc return 0;
2084*ebfedea0SLionel Sambuc }
2085*ebfedea0SLionel Sambuc if (c == 2 || c == 3) {
2086*ebfedea0SLionel Sambuc return parse_v3_sig(region, stream);
2087*ebfedea0SLionel Sambuc }
2088*ebfedea0SLionel Sambuc if (c == 4) {
2089*ebfedea0SLionel Sambuc return parse_v4_sig(region, stream);
2090*ebfedea0SLionel Sambuc }
2091*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_SIGNATURE_VRSN,
2092*ebfedea0SLionel Sambuc "Bad signature version (%d)", c);
2093*ebfedea0SLionel Sambuc return 0;
2094*ebfedea0SLionel Sambuc }
2095*ebfedea0SLionel Sambuc
2096*ebfedea0SLionel Sambuc /**
2097*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2098*ebfedea0SLionel Sambuc \brief Parse Compressed packet
2099*ebfedea0SLionel Sambuc */
2100*ebfedea0SLionel Sambuc static int
parse_compressed(pgp_region_t * region,pgp_stream_t * stream)2101*ebfedea0SLionel Sambuc parse_compressed(pgp_region_t *region, pgp_stream_t *stream)
2102*ebfedea0SLionel Sambuc {
2103*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2104*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2105*ebfedea0SLionel Sambuc
2106*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2107*ebfedea0SLionel Sambuc return 0;
2108*ebfedea0SLionel Sambuc }
2109*ebfedea0SLionel Sambuc
2110*ebfedea0SLionel Sambuc pkt.u.compressed = (pgp_compression_type_t)c;
2111*ebfedea0SLionel Sambuc
2112*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_COMPRESSED, &stream->cbinfo, &pkt);
2113*ebfedea0SLionel Sambuc
2114*ebfedea0SLionel Sambuc /*
2115*ebfedea0SLionel Sambuc * The content of a compressed data packet is more OpenPGP packets
2116*ebfedea0SLionel Sambuc * once decompressed, so recursively handle them
2117*ebfedea0SLionel Sambuc */
2118*ebfedea0SLionel Sambuc
2119*ebfedea0SLionel Sambuc return pgp_decompress(region, stream, pkt.u.compressed);
2120*ebfedea0SLionel Sambuc }
2121*ebfedea0SLionel Sambuc
2122*ebfedea0SLionel Sambuc /* XXX: this could be improved by sharing all hashes that are the */
2123*ebfedea0SLionel Sambuc /* same, then duping them just before checking the signature. */
2124*ebfedea0SLionel Sambuc static void
parse_hash_init(pgp_stream_t * stream,pgp_hash_alg_t type,const uint8_t * keyid)2125*ebfedea0SLionel Sambuc parse_hash_init(pgp_stream_t *stream, pgp_hash_alg_t type,
2126*ebfedea0SLionel Sambuc const uint8_t *keyid)
2127*ebfedea0SLionel Sambuc {
2128*ebfedea0SLionel Sambuc pgp_hashtype_t *hash;
2129*ebfedea0SLionel Sambuc
2130*ebfedea0SLionel Sambuc hash = realloc(stream->hashes,
2131*ebfedea0SLionel Sambuc (stream->hashc + 1) * sizeof(*stream->hashes));
2132*ebfedea0SLionel Sambuc if (hash == NULL) {
2133*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_hash_init: bad alloc 0\n");
2134*ebfedea0SLionel Sambuc /* just continue and die here */
2135*ebfedea0SLionel Sambuc /* XXX - agc - no way to return failure */
2136*ebfedea0SLionel Sambuc } else {
2137*ebfedea0SLionel Sambuc stream->hashes = hash;
2138*ebfedea0SLionel Sambuc }
2139*ebfedea0SLionel Sambuc hash = &stream->hashes[stream->hashc++];
2140*ebfedea0SLionel Sambuc
2141*ebfedea0SLionel Sambuc pgp_hash_any(&hash->hash, type);
2142*ebfedea0SLionel Sambuc if (!hash->hash.init(&hash->hash)) {
2143*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_hash_init: bad alloc\n");
2144*ebfedea0SLionel Sambuc /* just continue and die here */
2145*ebfedea0SLionel Sambuc /* XXX - agc - no way to return failure */
2146*ebfedea0SLionel Sambuc }
2147*ebfedea0SLionel Sambuc (void) memcpy(hash->keyid, keyid, sizeof(hash->keyid));
2148*ebfedea0SLionel Sambuc }
2149*ebfedea0SLionel Sambuc
2150*ebfedea0SLionel Sambuc /**
2151*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2152*ebfedea0SLionel Sambuc \brief Parse a One Pass Signature packet
2153*ebfedea0SLionel Sambuc */
2154*ebfedea0SLionel Sambuc static int
parse_one_pass(pgp_region_t * region,pgp_stream_t * stream)2155*ebfedea0SLionel Sambuc parse_one_pass(pgp_region_t * region, pgp_stream_t * stream)
2156*ebfedea0SLionel Sambuc {
2157*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2158*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2159*ebfedea0SLionel Sambuc
2160*ebfedea0SLionel Sambuc if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) {
2161*ebfedea0SLionel Sambuc return 0;
2162*ebfedea0SLionel Sambuc }
2163*ebfedea0SLionel Sambuc if (pkt.u.one_pass_sig.version != 3) {
2164*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN,
2165*ebfedea0SLionel Sambuc "Bad one-pass signature version (%d)",
2166*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.version);
2167*ebfedea0SLionel Sambuc return 0;
2168*ebfedea0SLionel Sambuc }
2169*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2170*ebfedea0SLionel Sambuc return 0;
2171*ebfedea0SLionel Sambuc }
2172*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.sig_type = (pgp_sig_type_t)c;
2173*ebfedea0SLionel Sambuc
2174*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2175*ebfedea0SLionel Sambuc return 0;
2176*ebfedea0SLionel Sambuc }
2177*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.hash_alg = (pgp_hash_alg_t)c;
2178*ebfedea0SLionel Sambuc
2179*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2180*ebfedea0SLionel Sambuc return 0;
2181*ebfedea0SLionel Sambuc }
2182*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.key_alg = (pgp_pubkey_alg_t)c;
2183*ebfedea0SLionel Sambuc
2184*ebfedea0SLionel Sambuc if (!limread(pkt.u.one_pass_sig.keyid,
2185*ebfedea0SLionel Sambuc (unsigned)sizeof(pkt.u.one_pass_sig.keyid),
2186*ebfedea0SLionel Sambuc region, stream)) {
2187*ebfedea0SLionel Sambuc return 0;
2188*ebfedea0SLionel Sambuc }
2189*ebfedea0SLionel Sambuc
2190*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2191*ebfedea0SLionel Sambuc return 0;
2192*ebfedea0SLionel Sambuc }
2193*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.nested = !!c;
2194*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_1_PASS_SIG, &stream->cbinfo, &pkt);
2195*ebfedea0SLionel Sambuc /* XXX: we should, perhaps, let the app choose whether to hash or not */
2196*ebfedea0SLionel Sambuc parse_hash_init(stream, pkt.u.one_pass_sig.hash_alg,
2197*ebfedea0SLionel Sambuc pkt.u.one_pass_sig.keyid);
2198*ebfedea0SLionel Sambuc return 1;
2199*ebfedea0SLionel Sambuc }
2200*ebfedea0SLionel Sambuc
2201*ebfedea0SLionel Sambuc /**
2202*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2203*ebfedea0SLionel Sambuc \brief Parse a Trust packet
2204*ebfedea0SLionel Sambuc */
2205*ebfedea0SLionel Sambuc static int
parse_trust(pgp_region_t * region,pgp_stream_t * stream)2206*ebfedea0SLionel Sambuc parse_trust(pgp_region_t *region, pgp_stream_t *stream)
2207*ebfedea0SLionel Sambuc {
2208*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2209*ebfedea0SLionel Sambuc
2210*ebfedea0SLionel Sambuc if (!read_data(&pkt.u.trust, region, stream)) {
2211*ebfedea0SLionel Sambuc return 0;
2212*ebfedea0SLionel Sambuc }
2213*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_TRUST, &stream->cbinfo, &pkt);
2214*ebfedea0SLionel Sambuc return 1;
2215*ebfedea0SLionel Sambuc }
2216*ebfedea0SLionel Sambuc
2217*ebfedea0SLionel Sambuc static void
parse_hash_data(pgp_stream_t * stream,const void * data,size_t length)2218*ebfedea0SLionel Sambuc parse_hash_data(pgp_stream_t *stream, const void *data,
2219*ebfedea0SLionel Sambuc size_t length)
2220*ebfedea0SLionel Sambuc {
2221*ebfedea0SLionel Sambuc size_t n;
2222*ebfedea0SLionel Sambuc
2223*ebfedea0SLionel Sambuc for (n = 0; n < stream->hashc; ++n) {
2224*ebfedea0SLionel Sambuc stream->hashes[n].hash.add(&stream->hashes[n].hash, data, (unsigned)length);
2225*ebfedea0SLionel Sambuc }
2226*ebfedea0SLionel Sambuc }
2227*ebfedea0SLionel Sambuc
2228*ebfedea0SLionel Sambuc /**
2229*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2230*ebfedea0SLionel Sambuc \brief Parse a Literal Data packet
2231*ebfedea0SLionel Sambuc */
2232*ebfedea0SLionel Sambuc static int
parse_litdata(pgp_region_t * region,pgp_stream_t * stream)2233*ebfedea0SLionel Sambuc parse_litdata(pgp_region_t *region, pgp_stream_t *stream)
2234*ebfedea0SLionel Sambuc {
2235*ebfedea0SLionel Sambuc pgp_memory_t *mem;
2236*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2237*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2238*ebfedea0SLionel Sambuc
2239*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2240*ebfedea0SLionel Sambuc return 0;
2241*ebfedea0SLionel Sambuc }
2242*ebfedea0SLionel Sambuc pkt.u.litdata_header.format = (pgp_litdata_enum)c;
2243*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2244*ebfedea0SLionel Sambuc return 0;
2245*ebfedea0SLionel Sambuc }
2246*ebfedea0SLionel Sambuc if (!limread((uint8_t *)pkt.u.litdata_header.filename,
2247*ebfedea0SLionel Sambuc (unsigned)c, region, stream)) {
2248*ebfedea0SLionel Sambuc return 0;
2249*ebfedea0SLionel Sambuc }
2250*ebfedea0SLionel Sambuc pkt.u.litdata_header.filename[c] = '\0';
2251*ebfedea0SLionel Sambuc if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) {
2252*ebfedea0SLionel Sambuc return 0;
2253*ebfedea0SLionel Sambuc }
2254*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_LITDATA_HEADER, &stream->cbinfo, &pkt);
2255*ebfedea0SLionel Sambuc mem = pkt.u.litdata_body.mem = pgp_memory_new();
2256*ebfedea0SLionel Sambuc pgp_memory_init(pkt.u.litdata_body.mem,
2257*ebfedea0SLionel Sambuc (unsigned)((region->length * 101) / 100) + 12);
2258*ebfedea0SLionel Sambuc pkt.u.litdata_body.data = mem->buf;
2259*ebfedea0SLionel Sambuc
2260*ebfedea0SLionel Sambuc while (region->readc < region->length) {
2261*ebfedea0SLionel Sambuc unsigned readc = region->length - region->readc;
2262*ebfedea0SLionel Sambuc
2263*ebfedea0SLionel Sambuc if (!limread(mem->buf, readc, region, stream)) {
2264*ebfedea0SLionel Sambuc return 0;
2265*ebfedea0SLionel Sambuc }
2266*ebfedea0SLionel Sambuc pkt.u.litdata_body.length = readc;
2267*ebfedea0SLionel Sambuc parse_hash_data(stream, pkt.u.litdata_body.data, region->length);
2268*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_LITDATA_BODY, &stream->cbinfo, &pkt);
2269*ebfedea0SLionel Sambuc }
2270*ebfedea0SLionel Sambuc
2271*ebfedea0SLionel Sambuc /* XXX - get rid of mem here? */
2272*ebfedea0SLionel Sambuc
2273*ebfedea0SLionel Sambuc return 1;
2274*ebfedea0SLionel Sambuc }
2275*ebfedea0SLionel Sambuc
2276*ebfedea0SLionel Sambuc /**
2277*ebfedea0SLionel Sambuc * \ingroup Core_Create
2278*ebfedea0SLionel Sambuc *
2279*ebfedea0SLionel Sambuc * pgp_seckey_free() frees the memory associated with "key". Note that
2280*ebfedea0SLionel Sambuc * the key itself is not freed.
2281*ebfedea0SLionel Sambuc *
2282*ebfedea0SLionel Sambuc * \param key
2283*ebfedea0SLionel Sambuc */
2284*ebfedea0SLionel Sambuc
2285*ebfedea0SLionel Sambuc void
pgp_seckey_free(pgp_seckey_t * key)2286*ebfedea0SLionel Sambuc pgp_seckey_free(pgp_seckey_t *key)
2287*ebfedea0SLionel Sambuc {
2288*ebfedea0SLionel Sambuc switch (key->pubkey.alg) {
2289*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
2290*ebfedea0SLionel Sambuc case PGP_PKA_RSA_ENCRYPT_ONLY:
2291*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
2292*ebfedea0SLionel Sambuc free_BN(&key->key.rsa.d);
2293*ebfedea0SLionel Sambuc free_BN(&key->key.rsa.p);
2294*ebfedea0SLionel Sambuc free_BN(&key->key.rsa.q);
2295*ebfedea0SLionel Sambuc free_BN(&key->key.rsa.u);
2296*ebfedea0SLionel Sambuc break;
2297*ebfedea0SLionel Sambuc
2298*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
2299*ebfedea0SLionel Sambuc free_BN(&key->key.dsa.x);
2300*ebfedea0SLionel Sambuc break;
2301*ebfedea0SLionel Sambuc
2302*ebfedea0SLionel Sambuc default:
2303*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2304*ebfedea0SLionel Sambuc "pgp_seckey_free: Unknown algorithm: %d (%s)\n",
2305*ebfedea0SLionel Sambuc key->pubkey.alg,
2306*ebfedea0SLionel Sambuc pgp_show_pka(key->pubkey.alg));
2307*ebfedea0SLionel Sambuc }
2308*ebfedea0SLionel Sambuc free(key->checkhash);
2309*ebfedea0SLionel Sambuc }
2310*ebfedea0SLionel Sambuc
2311*ebfedea0SLionel Sambuc static int
consume_packet(pgp_region_t * region,pgp_stream_t * stream,unsigned warn)2312*ebfedea0SLionel Sambuc consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn)
2313*ebfedea0SLionel Sambuc {
2314*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2315*ebfedea0SLionel Sambuc pgp_data_t remainder;
2316*ebfedea0SLionel Sambuc
2317*ebfedea0SLionel Sambuc if (region->indeterminate) {
2318*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt,
2319*ebfedea0SLionel Sambuc "Can't consume indeterminate packets");
2320*ebfedea0SLionel Sambuc }
2321*ebfedea0SLionel Sambuc
2322*ebfedea0SLionel Sambuc if (read_data(&remainder, region, stream)) {
2323*ebfedea0SLionel Sambuc /* now throw it away */
2324*ebfedea0SLionel Sambuc pgp_data_free(&remainder);
2325*ebfedea0SLionel Sambuc if (warn) {
2326*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_CONSUMED,
2327*ebfedea0SLionel Sambuc "%s", "Warning: packet consumer");
2328*ebfedea0SLionel Sambuc }
2329*ebfedea0SLionel Sambuc return 1;
2330*ebfedea0SLionel Sambuc }
2331*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_NOT_CONSUMED,
2332*ebfedea0SLionel Sambuc "%s", (warn) ? "Warning: Packet was not consumed" :
2333*ebfedea0SLionel Sambuc "Packet was not consumed");
2334*ebfedea0SLionel Sambuc return warn;
2335*ebfedea0SLionel Sambuc }
2336*ebfedea0SLionel Sambuc
2337*ebfedea0SLionel Sambuc /**
2338*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
2339*ebfedea0SLionel Sambuc * \brief Parse a secret key
2340*ebfedea0SLionel Sambuc */
2341*ebfedea0SLionel Sambuc static int
parse_seckey(pgp_region_t * region,pgp_stream_t * stream)2342*ebfedea0SLionel Sambuc parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
2343*ebfedea0SLionel Sambuc {
2344*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2345*ebfedea0SLionel Sambuc pgp_region_t encregion;
2346*ebfedea0SLionel Sambuc pgp_region_t *saved_region = NULL;
2347*ebfedea0SLionel Sambuc pgp_crypt_t decrypt;
2348*ebfedea0SLionel Sambuc pgp_hash_t checkhash;
2349*ebfedea0SLionel Sambuc unsigned blocksize;
2350*ebfedea0SLionel Sambuc unsigned crypted;
2351*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2352*ebfedea0SLionel Sambuc int ret = 1;
2353*ebfedea0SLionel Sambuc
2354*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2355*ebfedea0SLionel Sambuc fprintf(stderr, "\n---------\nparse_seckey:\n");
2356*ebfedea0SLionel Sambuc fprintf(stderr,
2357*ebfedea0SLionel Sambuc "region length=%u, readc=%u, remainder=%u\n",
2358*ebfedea0SLionel Sambuc region->length, region->readc,
2359*ebfedea0SLionel Sambuc region->length - region->readc);
2360*ebfedea0SLionel Sambuc }
2361*ebfedea0SLionel Sambuc (void) memset(&pkt, 0x0, sizeof(pkt));
2362*ebfedea0SLionel Sambuc if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) {
2363*ebfedea0SLionel Sambuc return 0;
2364*ebfedea0SLionel Sambuc }
2365*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2366*ebfedea0SLionel Sambuc fprintf(stderr, "parse_seckey: public key parsed\n");
2367*ebfedea0SLionel Sambuc pgp_print_pubkey(&pkt.u.seckey.pubkey);
2368*ebfedea0SLionel Sambuc }
2369*ebfedea0SLionel Sambuc stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4);
2370*ebfedea0SLionel Sambuc
2371*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2372*ebfedea0SLionel Sambuc return 0;
2373*ebfedea0SLionel Sambuc }
2374*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_usage = (pgp_s2k_usage_t)c;
2375*ebfedea0SLionel Sambuc
2376*ebfedea0SLionel Sambuc if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED ||
2377*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
2378*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2379*ebfedea0SLionel Sambuc return 0;
2380*ebfedea0SLionel Sambuc }
2381*ebfedea0SLionel Sambuc pkt.u.seckey.alg = (pgp_symm_alg_t)c;
2382*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2383*ebfedea0SLionel Sambuc return 0;
2384*ebfedea0SLionel Sambuc }
2385*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_specifier = (pgp_s2k_specifier_t)c;
2386*ebfedea0SLionel Sambuc switch (pkt.u.seckey.s2k_specifier) {
2387*ebfedea0SLionel Sambuc case PGP_S2KS_SIMPLE:
2388*ebfedea0SLionel Sambuc case PGP_S2KS_SALTED:
2389*ebfedea0SLionel Sambuc case PGP_S2KS_ITERATED_AND_SALTED:
2390*ebfedea0SLionel Sambuc break;
2391*ebfedea0SLionel Sambuc default:
2392*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2393*ebfedea0SLionel Sambuc "parse_seckey: bad seckey\n");
2394*ebfedea0SLionel Sambuc return 0;
2395*ebfedea0SLionel Sambuc }
2396*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2397*ebfedea0SLionel Sambuc return 0;
2398*ebfedea0SLionel Sambuc }
2399*ebfedea0SLionel Sambuc pkt.u.seckey.hash_alg = (pgp_hash_alg_t)c;
2400*ebfedea0SLionel Sambuc if (pkt.u.seckey.s2k_specifier != PGP_S2KS_SIMPLE &&
2401*ebfedea0SLionel Sambuc !limread(pkt.u.seckey.salt, 8, region, stream)) {
2402*ebfedea0SLionel Sambuc return 0;
2403*ebfedea0SLionel Sambuc }
2404*ebfedea0SLionel Sambuc if (pkt.u.seckey.s2k_specifier ==
2405*ebfedea0SLionel Sambuc PGP_S2KS_ITERATED_AND_SALTED) {
2406*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2407*ebfedea0SLionel Sambuc return 0;
2408*ebfedea0SLionel Sambuc }
2409*ebfedea0SLionel Sambuc pkt.u.seckey.octetc =
2410*ebfedea0SLionel Sambuc (16 + ((unsigned)c & 15)) <<
2411*ebfedea0SLionel Sambuc (((unsigned)c >> 4) + 6);
2412*ebfedea0SLionel Sambuc }
2413*ebfedea0SLionel Sambuc } else if (pkt.u.seckey.s2k_usage != PGP_S2KU_NONE) {
2414*ebfedea0SLionel Sambuc /* this is V3 style, looks just like a V4 simple hash */
2415*ebfedea0SLionel Sambuc pkt.u.seckey.alg = (pgp_symm_alg_t)c;
2416*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_usage = PGP_S2KU_ENCRYPTED;
2417*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_specifier = PGP_S2KS_SIMPLE;
2418*ebfedea0SLionel Sambuc pkt.u.seckey.hash_alg = PGP_HASH_MD5;
2419*ebfedea0SLionel Sambuc }
2420*ebfedea0SLionel Sambuc crypted = pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED ||
2421*ebfedea0SLionel Sambuc pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED;
2422*ebfedea0SLionel Sambuc
2423*ebfedea0SLionel Sambuc if (crypted) {
2424*ebfedea0SLionel Sambuc pgp_packet_t seckey;
2425*ebfedea0SLionel Sambuc pgp_hash_t hashes[(PGP_MAX_KEY_SIZE + PGP_MIN_HASH_SIZE - 1) / PGP_MIN_HASH_SIZE];
2426*ebfedea0SLionel Sambuc unsigned passlen;
2427*ebfedea0SLionel Sambuc uint8_t key[PGP_MAX_KEY_SIZE + PGP_MAX_HASH_SIZE];
2428*ebfedea0SLionel Sambuc char *passphrase;
2429*ebfedea0SLionel Sambuc int hashsize;
2430*ebfedea0SLionel Sambuc int keysize;
2431*ebfedea0SLionel Sambuc int n;
2432*ebfedea0SLionel Sambuc
2433*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2434*ebfedea0SLionel Sambuc (void) fprintf(stderr, "crypted seckey\n");
2435*ebfedea0SLionel Sambuc }
2436*ebfedea0SLionel Sambuc blocksize = pgp_block_size(pkt.u.seckey.alg);
2437*ebfedea0SLionel Sambuc if (blocksize == 0 || blocksize > PGP_MAX_BLOCK_SIZE) {
2438*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2439*ebfedea0SLionel Sambuc "parse_seckey: bad blocksize\n");
2440*ebfedea0SLionel Sambuc return 0;
2441*ebfedea0SLionel Sambuc }
2442*ebfedea0SLionel Sambuc
2443*ebfedea0SLionel Sambuc if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) {
2444*ebfedea0SLionel Sambuc return 0;
2445*ebfedea0SLionel Sambuc }
2446*ebfedea0SLionel Sambuc (void) memset(&seckey, 0x0, sizeof(seckey));
2447*ebfedea0SLionel Sambuc passphrase = NULL;
2448*ebfedea0SLionel Sambuc seckey.u.skey_passphrase.passphrase = &passphrase;
2449*ebfedea0SLionel Sambuc seckey.u.skey_passphrase.seckey = &pkt.u.seckey;
2450*ebfedea0SLionel Sambuc CALLBACK(PGP_GET_PASSPHRASE, &stream->cbinfo, &seckey);
2451*ebfedea0SLionel Sambuc if (!passphrase) {
2452*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2453*ebfedea0SLionel Sambuc /* \todo make into proper error */
2454*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2455*ebfedea0SLionel Sambuc "parse_seckey: can't get passphrase\n");
2456*ebfedea0SLionel Sambuc }
2457*ebfedea0SLionel Sambuc if (!consume_packet(region, stream, 0)) {
2458*ebfedea0SLionel Sambuc return 0;
2459*ebfedea0SLionel Sambuc }
2460*ebfedea0SLionel Sambuc
2461*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_ENCRYPTED_SECRET_KEY,
2462*ebfedea0SLionel Sambuc &stream->cbinfo, &pkt);
2463*ebfedea0SLionel Sambuc
2464*ebfedea0SLionel Sambuc return 1;
2465*ebfedea0SLionel Sambuc }
2466*ebfedea0SLionel Sambuc keysize = pgp_key_size(pkt.u.seckey.alg);
2467*ebfedea0SLionel Sambuc if (keysize == 0 || keysize > PGP_MAX_KEY_SIZE) {
2468*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2469*ebfedea0SLionel Sambuc "parse_seckey: bad keysize\n");
2470*ebfedea0SLionel Sambuc return 0;
2471*ebfedea0SLionel Sambuc }
2472*ebfedea0SLionel Sambuc
2473*ebfedea0SLionel Sambuc /* Hardcoded SHA1 for just now */
2474*ebfedea0SLionel Sambuc pkt.u.seckey.hash_alg = PGP_HASH_SHA1;
2475*ebfedea0SLionel Sambuc hashsize = pgp_hash_size(pkt.u.seckey.hash_alg);
2476*ebfedea0SLionel Sambuc if (hashsize == 0 || hashsize > PGP_MAX_HASH_SIZE) {
2477*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2478*ebfedea0SLionel Sambuc "parse_seckey: bad hashsize\n");
2479*ebfedea0SLionel Sambuc return 0;
2480*ebfedea0SLionel Sambuc }
2481*ebfedea0SLionel Sambuc
2482*ebfedea0SLionel Sambuc for (n = 0; n * hashsize < keysize; ++n) {
2483*ebfedea0SLionel Sambuc int i;
2484*ebfedea0SLionel Sambuc
2485*ebfedea0SLionel Sambuc pgp_hash_any(&hashes[n],
2486*ebfedea0SLionel Sambuc pkt.u.seckey.hash_alg);
2487*ebfedea0SLionel Sambuc if (!hashes[n].init(&hashes[n])) {
2488*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2489*ebfedea0SLionel Sambuc "parse_seckey: bad alloc\n");
2490*ebfedea0SLionel Sambuc return 0;
2491*ebfedea0SLionel Sambuc }
2492*ebfedea0SLionel Sambuc /* preload hashes with zeroes... */
2493*ebfedea0SLionel Sambuc for (i = 0; i < n; ++i) {
2494*ebfedea0SLionel Sambuc hashes[n].add(&hashes[n],
2495*ebfedea0SLionel Sambuc (const uint8_t *) "", 1);
2496*ebfedea0SLionel Sambuc }
2497*ebfedea0SLionel Sambuc }
2498*ebfedea0SLionel Sambuc passlen = (unsigned)strlen(passphrase);
2499*ebfedea0SLionel Sambuc for (n = 0; n * hashsize < keysize; ++n) {
2500*ebfedea0SLionel Sambuc unsigned i;
2501*ebfedea0SLionel Sambuc
2502*ebfedea0SLionel Sambuc switch (pkt.u.seckey.s2k_specifier) {
2503*ebfedea0SLionel Sambuc case PGP_S2KS_SALTED:
2504*ebfedea0SLionel Sambuc hashes[n].add(&hashes[n],
2505*ebfedea0SLionel Sambuc pkt.u.seckey.salt,
2506*ebfedea0SLionel Sambuc PGP_SALT_SIZE);
2507*ebfedea0SLionel Sambuc /* FALLTHROUGH */
2508*ebfedea0SLionel Sambuc case PGP_S2KS_SIMPLE:
2509*ebfedea0SLionel Sambuc hashes[n].add(&hashes[n],
2510*ebfedea0SLionel Sambuc (uint8_t *)passphrase, (unsigned)passlen);
2511*ebfedea0SLionel Sambuc break;
2512*ebfedea0SLionel Sambuc
2513*ebfedea0SLionel Sambuc case PGP_S2KS_ITERATED_AND_SALTED:
2514*ebfedea0SLionel Sambuc for (i = 0; i < pkt.u.seckey.octetc;
2515*ebfedea0SLionel Sambuc i += passlen + PGP_SALT_SIZE) {
2516*ebfedea0SLionel Sambuc unsigned j;
2517*ebfedea0SLionel Sambuc
2518*ebfedea0SLionel Sambuc j = passlen + PGP_SALT_SIZE;
2519*ebfedea0SLionel Sambuc if (i + j > pkt.u.seckey.octetc && i != 0) {
2520*ebfedea0SLionel Sambuc j = pkt.u.seckey.octetc - i;
2521*ebfedea0SLionel Sambuc }
2522*ebfedea0SLionel Sambuc hashes[n].add(&hashes[n],
2523*ebfedea0SLionel Sambuc pkt.u.seckey.salt,
2524*ebfedea0SLionel Sambuc (unsigned)(j > PGP_SALT_SIZE) ?
2525*ebfedea0SLionel Sambuc PGP_SALT_SIZE : j);
2526*ebfedea0SLionel Sambuc if (j > PGP_SALT_SIZE) {
2527*ebfedea0SLionel Sambuc hashes[n].add(&hashes[n],
2528*ebfedea0SLionel Sambuc (uint8_t *) passphrase,
2529*ebfedea0SLionel Sambuc j - PGP_SALT_SIZE);
2530*ebfedea0SLionel Sambuc }
2531*ebfedea0SLionel Sambuc }
2532*ebfedea0SLionel Sambuc break;
2533*ebfedea0SLionel Sambuc default:
2534*ebfedea0SLionel Sambuc break;
2535*ebfedea0SLionel Sambuc }
2536*ebfedea0SLionel Sambuc }
2537*ebfedea0SLionel Sambuc
2538*ebfedea0SLionel Sambuc for (n = 0; n * hashsize < keysize; ++n) {
2539*ebfedea0SLionel Sambuc int r;
2540*ebfedea0SLionel Sambuc
2541*ebfedea0SLionel Sambuc r = hashes[n].finish(&hashes[n], key + n * hashsize);
2542*ebfedea0SLionel Sambuc if (r != hashsize) {
2543*ebfedea0SLionel Sambuc (void) fprintf(stderr,
2544*ebfedea0SLionel Sambuc "parse_seckey: bad r\n");
2545*ebfedea0SLionel Sambuc return 0;
2546*ebfedea0SLionel Sambuc }
2547*ebfedea0SLionel Sambuc }
2548*ebfedea0SLionel Sambuc
2549*ebfedea0SLionel Sambuc pgp_forget(passphrase, passlen);
2550*ebfedea0SLionel Sambuc
2551*ebfedea0SLionel Sambuc pgp_crypt_any(&decrypt, pkt.u.seckey.alg);
2552*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2553*ebfedea0SLionel Sambuc hexdump(stderr, "input iv", pkt.u.seckey.iv, pgp_block_size(pkt.u.seckey.alg));
2554*ebfedea0SLionel Sambuc hexdump(stderr, "key", key, CAST_KEY_LENGTH);
2555*ebfedea0SLionel Sambuc }
2556*ebfedea0SLionel Sambuc decrypt.set_iv(&decrypt, pkt.u.seckey.iv);
2557*ebfedea0SLionel Sambuc decrypt.set_crypt_key(&decrypt, key);
2558*ebfedea0SLionel Sambuc
2559*ebfedea0SLionel Sambuc /* now read encrypted data */
2560*ebfedea0SLionel Sambuc
2561*ebfedea0SLionel Sambuc pgp_reader_push_decrypt(stream, &decrypt, region);
2562*ebfedea0SLionel Sambuc
2563*ebfedea0SLionel Sambuc /*
2564*ebfedea0SLionel Sambuc * Since all known encryption for PGP doesn't compress, we
2565*ebfedea0SLionel Sambuc * can limit to the same length as the current region (for
2566*ebfedea0SLionel Sambuc * now).
2567*ebfedea0SLionel Sambuc */
2568*ebfedea0SLionel Sambuc pgp_init_subregion(&encregion, NULL);
2569*ebfedea0SLionel Sambuc encregion.length = region->length - region->readc;
2570*ebfedea0SLionel Sambuc if (pkt.u.seckey.pubkey.version != PGP_V4) {
2571*ebfedea0SLionel Sambuc encregion.length -= 2;
2572*ebfedea0SLionel Sambuc }
2573*ebfedea0SLionel Sambuc saved_region = region;
2574*ebfedea0SLionel Sambuc region = &encregion;
2575*ebfedea0SLionel Sambuc }
2576*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2577*ebfedea0SLionel Sambuc fprintf(stderr, "parse_seckey: end of crypted passphrase\n");
2578*ebfedea0SLionel Sambuc }
2579*ebfedea0SLionel Sambuc if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
2580*ebfedea0SLionel Sambuc /* XXX - Hard-coded SHA1 here ?? Check */
2581*ebfedea0SLionel Sambuc pkt.u.seckey.checkhash = calloc(1, PGP_SHA1_HASH_SIZE);
2582*ebfedea0SLionel Sambuc if (pkt.u.seckey.checkhash == NULL) {
2583*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_seckey: bad alloc\n");
2584*ebfedea0SLionel Sambuc return 0;
2585*ebfedea0SLionel Sambuc }
2586*ebfedea0SLionel Sambuc pgp_hash_sha1(&checkhash);
2587*ebfedea0SLionel Sambuc pgp_reader_push_hash(stream, &checkhash);
2588*ebfedea0SLionel Sambuc } else {
2589*ebfedea0SLionel Sambuc pgp_reader_push_sum16(stream);
2590*ebfedea0SLionel Sambuc }
2591*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2592*ebfedea0SLionel Sambuc fprintf(stderr, "parse_seckey: checkhash, reading MPIs\n");
2593*ebfedea0SLionel Sambuc }
2594*ebfedea0SLionel Sambuc switch (pkt.u.seckey.pubkey.alg) {
2595*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
2596*ebfedea0SLionel Sambuc case PGP_PKA_RSA_ENCRYPT_ONLY:
2597*ebfedea0SLionel Sambuc case PGP_PKA_RSA_SIGN_ONLY:
2598*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.seckey.key.rsa.d, region, stream) ||
2599*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.seckey.key.rsa.p, region, stream) ||
2600*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.seckey.key.rsa.q, region, stream) ||
2601*ebfedea0SLionel Sambuc !limread_mpi(&pkt.u.seckey.key.rsa.u, region, stream)) {
2602*ebfedea0SLionel Sambuc ret = 0;
2603*ebfedea0SLionel Sambuc }
2604*ebfedea0SLionel Sambuc break;
2605*ebfedea0SLionel Sambuc
2606*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
2607*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) {
2608*ebfedea0SLionel Sambuc ret = 0;
2609*ebfedea0SLionel Sambuc }
2610*ebfedea0SLionel Sambuc break;
2611*ebfedea0SLionel Sambuc
2612*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
2613*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.seckey.key.elgamal.x, region, stream)) {
2614*ebfedea0SLionel Sambuc ret = 0;
2615*ebfedea0SLionel Sambuc }
2616*ebfedea0SLionel Sambuc break;
2617*ebfedea0SLionel Sambuc
2618*ebfedea0SLionel Sambuc default:
2619*ebfedea0SLionel Sambuc PGP_ERROR_2(&stream->errors,
2620*ebfedea0SLionel Sambuc PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2621*ebfedea0SLionel Sambuc "Unsupported Public Key algorithm %d (%s)",
2622*ebfedea0SLionel Sambuc pkt.u.seckey.pubkey.alg,
2623*ebfedea0SLionel Sambuc pgp_show_pka(pkt.u.seckey.pubkey.alg));
2624*ebfedea0SLionel Sambuc ret = 0;
2625*ebfedea0SLionel Sambuc }
2626*ebfedea0SLionel Sambuc
2627*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2628*ebfedea0SLionel Sambuc (void) fprintf(stderr, "4 MPIs read\n");
2629*ebfedea0SLionel Sambuc }
2630*ebfedea0SLionel Sambuc stream->reading_v3_secret = 0;
2631*ebfedea0SLionel Sambuc
2632*ebfedea0SLionel Sambuc if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
2633*ebfedea0SLionel Sambuc uint8_t hash[PGP_CHECKHASH_SIZE];
2634*ebfedea0SLionel Sambuc
2635*ebfedea0SLionel Sambuc pgp_reader_pop_hash(stream);
2636*ebfedea0SLionel Sambuc checkhash.finish(&checkhash, hash);
2637*ebfedea0SLionel Sambuc
2638*ebfedea0SLionel Sambuc if (crypted &&
2639*ebfedea0SLionel Sambuc pkt.u.seckey.pubkey.version != PGP_V4) {
2640*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2641*ebfedea0SLionel Sambuc region = saved_region;
2642*ebfedea0SLionel Sambuc }
2643*ebfedea0SLionel Sambuc if (ret) {
2644*ebfedea0SLionel Sambuc if (!limread(pkt.u.seckey.checkhash,
2645*ebfedea0SLionel Sambuc PGP_CHECKHASH_SIZE, region, stream)) {
2646*ebfedea0SLionel Sambuc return 0;
2647*ebfedea0SLionel Sambuc }
2648*ebfedea0SLionel Sambuc
2649*ebfedea0SLionel Sambuc if (memcmp(hash, pkt.u.seckey.checkhash,
2650*ebfedea0SLionel Sambuc PGP_CHECKHASH_SIZE) != 0) {
2651*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt,
2652*ebfedea0SLionel Sambuc "Hash mismatch in secret key");
2653*ebfedea0SLionel Sambuc }
2654*ebfedea0SLionel Sambuc }
2655*ebfedea0SLionel Sambuc } else {
2656*ebfedea0SLionel Sambuc uint16_t sum;
2657*ebfedea0SLionel Sambuc
2658*ebfedea0SLionel Sambuc sum = pgp_reader_pop_sum16(stream);
2659*ebfedea0SLionel Sambuc if (crypted &&
2660*ebfedea0SLionel Sambuc pkt.u.seckey.pubkey.version != PGP_V4) {
2661*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2662*ebfedea0SLionel Sambuc region = saved_region;
2663*ebfedea0SLionel Sambuc }
2664*ebfedea0SLionel Sambuc if (ret) {
2665*ebfedea0SLionel Sambuc if (!limread_scalar(&pkt.u.seckey.checksum, 2,
2666*ebfedea0SLionel Sambuc region, stream))
2667*ebfedea0SLionel Sambuc return 0;
2668*ebfedea0SLionel Sambuc
2669*ebfedea0SLionel Sambuc if (sum != pkt.u.seckey.checksum) {
2670*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt,
2671*ebfedea0SLionel Sambuc "Checksum mismatch in secret key");
2672*ebfedea0SLionel Sambuc }
2673*ebfedea0SLionel Sambuc }
2674*ebfedea0SLionel Sambuc }
2675*ebfedea0SLionel Sambuc
2676*ebfedea0SLionel Sambuc if (crypted && pkt.u.seckey.pubkey.version == PGP_V4) {
2677*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2678*ebfedea0SLionel Sambuc }
2679*ebfedea0SLionel Sambuc if (region == NULL) {
2680*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_seckey: NULL region\n");
2681*ebfedea0SLionel Sambuc return 0;
2682*ebfedea0SLionel Sambuc }
2683*ebfedea0SLionel Sambuc if (ret && region->readc != region->length) {
2684*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_seckey: bad length\n");
2685*ebfedea0SLionel Sambuc return 0;
2686*ebfedea0SLionel Sambuc }
2687*ebfedea0SLionel Sambuc if (!ret) {
2688*ebfedea0SLionel Sambuc return 0;
2689*ebfedea0SLionel Sambuc }
2690*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
2691*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2692*ebfedea0SLionel Sambuc (void) fprintf(stderr, "--- end of parse_seckey\n\n");
2693*ebfedea0SLionel Sambuc }
2694*ebfedea0SLionel Sambuc return 1;
2695*ebfedea0SLionel Sambuc }
2696*ebfedea0SLionel Sambuc
2697*ebfedea0SLionel Sambuc /**
2698*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2699*ebfedea0SLionel Sambuc \brief Parse a Public Key Session Key packet
2700*ebfedea0SLionel Sambuc */
2701*ebfedea0SLionel Sambuc static int
parse_pk_sesskey(pgp_region_t * region,pgp_stream_t * stream)2702*ebfedea0SLionel Sambuc parse_pk_sesskey(pgp_region_t *region,
2703*ebfedea0SLionel Sambuc pgp_stream_t *stream)
2704*ebfedea0SLionel Sambuc {
2705*ebfedea0SLionel Sambuc const pgp_seckey_t *secret;
2706*ebfedea0SLionel Sambuc pgp_packet_t sesskey;
2707*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2708*ebfedea0SLionel Sambuc uint8_t *iv;
2709*ebfedea0SLionel Sambuc uint8_t c = 0x0;
2710*ebfedea0SLionel Sambuc uint8_t cs[2];
2711*ebfedea0SLionel Sambuc unsigned k;
2712*ebfedea0SLionel Sambuc BIGNUM *g_to_k;
2713*ebfedea0SLionel Sambuc BIGNUM *enc_m;
2714*ebfedea0SLionel Sambuc int n;
2715*ebfedea0SLionel Sambuc uint8_t unencoded_m_buf[1024];
2716*ebfedea0SLionel Sambuc
2717*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2718*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_pk_sesskey - can't read char in region\n");
2719*ebfedea0SLionel Sambuc return 0;
2720*ebfedea0SLionel Sambuc }
2721*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.version = c;
2722*ebfedea0SLionel Sambuc if (pkt.u.pk_sesskey.version != 3) {
2723*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PKSK_VRSN,
2724*ebfedea0SLionel Sambuc "Bad public-key encrypted session key version (%d)",
2725*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.version);
2726*ebfedea0SLionel Sambuc return 0;
2727*ebfedea0SLionel Sambuc }
2728*ebfedea0SLionel Sambuc if (!limread(pkt.u.pk_sesskey.key_id,
2729*ebfedea0SLionel Sambuc (unsigned)sizeof(pkt.u.pk_sesskey.key_id), region, stream)) {
2730*ebfedea0SLionel Sambuc return 0;
2731*ebfedea0SLionel Sambuc }
2732*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2733*ebfedea0SLionel Sambuc hexdump(stderr, "sesskey: pubkey id", pkt.u.pk_sesskey.key_id, sizeof(pkt.u.pk_sesskey.key_id));
2734*ebfedea0SLionel Sambuc }
2735*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
2736*ebfedea0SLionel Sambuc return 0;
2737*ebfedea0SLionel Sambuc }
2738*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.alg = (pgp_pubkey_alg_t)c;
2739*ebfedea0SLionel Sambuc switch (pkt.u.pk_sesskey.alg) {
2740*ebfedea0SLionel Sambuc case PGP_PKA_RSA:
2741*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m,
2742*ebfedea0SLionel Sambuc region, stream)) {
2743*ebfedea0SLionel Sambuc return 0;
2744*ebfedea0SLionel Sambuc }
2745*ebfedea0SLionel Sambuc enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m;
2746*ebfedea0SLionel Sambuc g_to_k = NULL;
2747*ebfedea0SLionel Sambuc break;
2748*ebfedea0SLionel Sambuc
2749*ebfedea0SLionel Sambuc case PGP_PKA_DSA:
2750*ebfedea0SLionel Sambuc case PGP_PKA_ELGAMAL:
2751*ebfedea0SLionel Sambuc if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k,
2752*ebfedea0SLionel Sambuc region, stream) ||
2753*ebfedea0SLionel Sambuc !limread_mpi(
2754*ebfedea0SLionel Sambuc &pkt.u.pk_sesskey.params.elgamal.encrypted_m,
2755*ebfedea0SLionel Sambuc region, stream)) {
2756*ebfedea0SLionel Sambuc return 0;
2757*ebfedea0SLionel Sambuc }
2758*ebfedea0SLionel Sambuc g_to_k = pkt.u.pk_sesskey.params.elgamal.g_to_k;
2759*ebfedea0SLionel Sambuc enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m;
2760*ebfedea0SLionel Sambuc break;
2761*ebfedea0SLionel Sambuc
2762*ebfedea0SLionel Sambuc default:
2763*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors,
2764*ebfedea0SLionel Sambuc PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2765*ebfedea0SLionel Sambuc "Unknown public key algorithm in session key (%s)",
2766*ebfedea0SLionel Sambuc pgp_show_pka(pkt.u.pk_sesskey.alg));
2767*ebfedea0SLionel Sambuc return 0;
2768*ebfedea0SLionel Sambuc }
2769*ebfedea0SLionel Sambuc
2770*ebfedea0SLionel Sambuc (void) memset(&sesskey, 0x0, sizeof(sesskey));
2771*ebfedea0SLionel Sambuc secret = NULL;
2772*ebfedea0SLionel Sambuc sesskey.u.get_seckey.seckey = &secret;
2773*ebfedea0SLionel Sambuc sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey;
2774*ebfedea0SLionel Sambuc
2775*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2776*ebfedea0SLionel Sambuc (void) fprintf(stderr, "getting secret key via callback\n");
2777*ebfedea0SLionel Sambuc }
2778*ebfedea0SLionel Sambuc
2779*ebfedea0SLionel Sambuc CALLBACK(PGP_GET_SECKEY, &stream->cbinfo, &sesskey);
2780*ebfedea0SLionel Sambuc
2781*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2782*ebfedea0SLionel Sambuc (void) fprintf(stderr, "got secret key via callback\n");
2783*ebfedea0SLionel Sambuc }
2784*ebfedea0SLionel Sambuc if (!secret) {
2785*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo,
2786*ebfedea0SLionel Sambuc &pkt);
2787*ebfedea0SLionel Sambuc return 1;
2788*ebfedea0SLionel Sambuc }
2789*ebfedea0SLionel Sambuc n = pgp_decrypt_decode_mpi(unencoded_m_buf,
2790*ebfedea0SLionel Sambuc (unsigned)sizeof(unencoded_m_buf), g_to_k, enc_m, secret);
2791*ebfedea0SLionel Sambuc
2792*ebfedea0SLionel Sambuc if (n < 1) {
2793*ebfedea0SLionel Sambuc ERRP(&stream->cbinfo, pkt, "decrypted message too short");
2794*ebfedea0SLionel Sambuc return 0;
2795*ebfedea0SLionel Sambuc }
2796*ebfedea0SLionel Sambuc
2797*ebfedea0SLionel Sambuc /* PKA */
2798*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.symm_alg = (pgp_symm_alg_t)unencoded_m_buf[0];
2799*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2800*ebfedea0SLionel Sambuc (void) fprintf(stderr, "symm alg %d\n", pkt.u.pk_sesskey.symm_alg);
2801*ebfedea0SLionel Sambuc }
2802*ebfedea0SLionel Sambuc
2803*ebfedea0SLionel Sambuc if (!pgp_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
2804*ebfedea0SLionel Sambuc /* ERR1P */
2805*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG,
2806*ebfedea0SLionel Sambuc "Symmetric algorithm %s not supported",
2807*ebfedea0SLionel Sambuc pgp_show_symm_alg(
2808*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.symm_alg));
2809*ebfedea0SLionel Sambuc return 0;
2810*ebfedea0SLionel Sambuc }
2811*ebfedea0SLionel Sambuc k = pgp_key_size(pkt.u.pk_sesskey.symm_alg);
2812*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2813*ebfedea0SLionel Sambuc (void) fprintf(stderr, "key size %d\n", k);
2814*ebfedea0SLionel Sambuc }
2815*ebfedea0SLionel Sambuc
2816*ebfedea0SLionel Sambuc if ((unsigned) n != k + 3) {
2817*ebfedea0SLionel Sambuc PGP_ERROR_2(&stream->errors, PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN,
2818*ebfedea0SLionel Sambuc "decrypted message wrong length (got %d expected %d)",
2819*ebfedea0SLionel Sambuc n, k + 3);
2820*ebfedea0SLionel Sambuc return 0;
2821*ebfedea0SLionel Sambuc }
2822*ebfedea0SLionel Sambuc if (k > sizeof(pkt.u.pk_sesskey.key)) {
2823*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_pk_sesskey: bad keylength\n");
2824*ebfedea0SLionel Sambuc return 0;
2825*ebfedea0SLionel Sambuc }
2826*ebfedea0SLionel Sambuc
2827*ebfedea0SLionel Sambuc (void) memcpy(pkt.u.pk_sesskey.key, unencoded_m_buf + 1, k);
2828*ebfedea0SLionel Sambuc
2829*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2830*ebfedea0SLionel Sambuc hexdump(stderr, "recovered sesskey", pkt.u.pk_sesskey.key, k);
2831*ebfedea0SLionel Sambuc }
2832*ebfedea0SLionel Sambuc pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] +
2833*ebfedea0SLionel Sambuc (unencoded_m_buf[k + 2] << 8);
2834*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2835*ebfedea0SLionel Sambuc (void) fprintf(stderr, "session key checksum: %2x %2x\n",
2836*ebfedea0SLionel Sambuc unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]);
2837*ebfedea0SLionel Sambuc }
2838*ebfedea0SLionel Sambuc
2839*ebfedea0SLionel Sambuc /* Check checksum */
2840*ebfedea0SLionel Sambuc pgp_calc_sesskey_checksum(&pkt.u.pk_sesskey, &cs[0]);
2841*ebfedea0SLionel Sambuc if (unencoded_m_buf[k + 1] != cs[0] ||
2842*ebfedea0SLionel Sambuc unencoded_m_buf[k + 2] != cs[1]) {
2843*ebfedea0SLionel Sambuc PGP_ERROR_4(&stream->errors, PGP_E_PROTO_BAD_SK_CHECKSUM,
2844*ebfedea0SLionel Sambuc "Session key checksum wrong: expected %2x %2x, got %2x %2x",
2845*ebfedea0SLionel Sambuc cs[0], cs[1], unencoded_m_buf[k + 1],
2846*ebfedea0SLionel Sambuc unencoded_m_buf[k + 2]);
2847*ebfedea0SLionel Sambuc return 0;
2848*ebfedea0SLionel Sambuc }
2849*ebfedea0SLionel Sambuc
2850*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2851*ebfedea0SLionel Sambuc (void) fprintf(stderr, "getting pk session key via callback\n");
2852*ebfedea0SLionel Sambuc }
2853*ebfedea0SLionel Sambuc /* all is well */
2854*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt);
2855*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2856*ebfedea0SLionel Sambuc (void) fprintf(stderr, "got pk session key via callback\n");
2857*ebfedea0SLionel Sambuc }
2858*ebfedea0SLionel Sambuc
2859*ebfedea0SLionel Sambuc pgp_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg);
2860*ebfedea0SLionel Sambuc iv = calloc(1, stream->decrypt.blocksize);
2861*ebfedea0SLionel Sambuc if (iv == NULL) {
2862*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_pk_sesskey: bad alloc\n");
2863*ebfedea0SLionel Sambuc return 0;
2864*ebfedea0SLionel Sambuc }
2865*ebfedea0SLionel Sambuc stream->decrypt.set_iv(&stream->decrypt, iv);
2866*ebfedea0SLionel Sambuc stream->decrypt.set_crypt_key(&stream->decrypt, pkt.u.pk_sesskey.key);
2867*ebfedea0SLionel Sambuc pgp_encrypt_init(&stream->decrypt);
2868*ebfedea0SLionel Sambuc free(iv);
2869*ebfedea0SLionel Sambuc return 1;
2870*ebfedea0SLionel Sambuc }
2871*ebfedea0SLionel Sambuc
2872*ebfedea0SLionel Sambuc static int
decrypt_se_data(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)2873*ebfedea0SLionel Sambuc decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
2874*ebfedea0SLionel Sambuc pgp_stream_t *stream)
2875*ebfedea0SLionel Sambuc {
2876*ebfedea0SLionel Sambuc pgp_crypt_t *decrypt;
2877*ebfedea0SLionel Sambuc const int printerrors = 1;
2878*ebfedea0SLionel Sambuc int r = 1;
2879*ebfedea0SLionel Sambuc
2880*ebfedea0SLionel Sambuc decrypt = pgp_get_decrypt(stream);
2881*ebfedea0SLionel Sambuc if (decrypt) {
2882*ebfedea0SLionel Sambuc pgp_region_t encregion;
2883*ebfedea0SLionel Sambuc unsigned b = (unsigned)decrypt->blocksize;
2884*ebfedea0SLionel Sambuc uint8_t buf[PGP_MAX_BLOCK_SIZE + 2] = "";
2885*ebfedea0SLionel Sambuc
2886*ebfedea0SLionel Sambuc pgp_reader_push_decrypt(stream, decrypt, region);
2887*ebfedea0SLionel Sambuc
2888*ebfedea0SLionel Sambuc pgp_init_subregion(&encregion, NULL);
2889*ebfedea0SLionel Sambuc encregion.length = b + 2;
2890*ebfedea0SLionel Sambuc
2891*ebfedea0SLionel Sambuc if (!exact_limread(buf, b + 2, &encregion, stream)) {
2892*ebfedea0SLionel Sambuc return 0;
2893*ebfedea0SLionel Sambuc }
2894*ebfedea0SLionel Sambuc if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
2895*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2896*ebfedea0SLionel Sambuc PGP_ERROR_4(&stream->errors,
2897*ebfedea0SLionel Sambuc PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT,
2898*ebfedea0SLionel Sambuc "Bad symmetric decrypt (%02x%02x vs %02x%02x)",
2899*ebfedea0SLionel Sambuc buf[b - 2], buf[b - 1], buf[b], buf[b + 1]);
2900*ebfedea0SLionel Sambuc return 0;
2901*ebfedea0SLionel Sambuc }
2902*ebfedea0SLionel Sambuc if (tag == PGP_PTAG_CT_SE_DATA_BODY) {
2903*ebfedea0SLionel Sambuc decrypt->decrypt_resync(decrypt);
2904*ebfedea0SLionel Sambuc decrypt->block_encrypt(decrypt, decrypt->civ,
2905*ebfedea0SLionel Sambuc decrypt->civ);
2906*ebfedea0SLionel Sambuc }
2907*ebfedea0SLionel Sambuc r = pgp_parse(stream, !printerrors);
2908*ebfedea0SLionel Sambuc
2909*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2910*ebfedea0SLionel Sambuc } else {
2911*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2912*ebfedea0SLionel Sambuc
2913*ebfedea0SLionel Sambuc while (region->readc < region->length) {
2914*ebfedea0SLionel Sambuc unsigned len;
2915*ebfedea0SLionel Sambuc
2916*ebfedea0SLionel Sambuc len = region->length - region->readc;
2917*ebfedea0SLionel Sambuc if (len > sizeof(pkt.u.se_data_body.data))
2918*ebfedea0SLionel Sambuc len = sizeof(pkt.u.se_data_body.data);
2919*ebfedea0SLionel Sambuc
2920*ebfedea0SLionel Sambuc if (!limread(pkt.u.se_data_body.data, len,
2921*ebfedea0SLionel Sambuc region, stream)) {
2922*ebfedea0SLionel Sambuc return 0;
2923*ebfedea0SLionel Sambuc }
2924*ebfedea0SLionel Sambuc pkt.u.se_data_body.length = len;
2925*ebfedea0SLionel Sambuc CALLBACK(tag, &stream->cbinfo, &pkt);
2926*ebfedea0SLionel Sambuc }
2927*ebfedea0SLionel Sambuc }
2928*ebfedea0SLionel Sambuc
2929*ebfedea0SLionel Sambuc return r;
2930*ebfedea0SLionel Sambuc }
2931*ebfedea0SLionel Sambuc
2932*ebfedea0SLionel Sambuc static int
decrypt_se_ip_data(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)2933*ebfedea0SLionel Sambuc decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
2934*ebfedea0SLionel Sambuc pgp_stream_t *stream)
2935*ebfedea0SLionel Sambuc {
2936*ebfedea0SLionel Sambuc pgp_crypt_t *decrypt;
2937*ebfedea0SLionel Sambuc const int printerrors = 1;
2938*ebfedea0SLionel Sambuc int r = 1;
2939*ebfedea0SLionel Sambuc
2940*ebfedea0SLionel Sambuc decrypt = pgp_get_decrypt(stream);
2941*ebfedea0SLionel Sambuc if (decrypt) {
2942*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2943*ebfedea0SLionel Sambuc (void) fprintf(stderr, "decrypt_se_ip_data: decrypt\n");
2944*ebfedea0SLionel Sambuc }
2945*ebfedea0SLionel Sambuc pgp_reader_push_decrypt(stream, decrypt, region);
2946*ebfedea0SLionel Sambuc pgp_reader_push_se_ip_data(stream, decrypt, region);
2947*ebfedea0SLionel Sambuc
2948*ebfedea0SLionel Sambuc r = pgp_parse(stream, !printerrors);
2949*ebfedea0SLionel Sambuc
2950*ebfedea0SLionel Sambuc pgp_reader_pop_se_ip_data(stream);
2951*ebfedea0SLionel Sambuc pgp_reader_pop_decrypt(stream);
2952*ebfedea0SLionel Sambuc } else {
2953*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2954*ebfedea0SLionel Sambuc
2955*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
2956*ebfedea0SLionel Sambuc (void) fprintf(stderr, "decrypt_se_ip_data: no decrypt\n");
2957*ebfedea0SLionel Sambuc }
2958*ebfedea0SLionel Sambuc while (region->readc < region->length) {
2959*ebfedea0SLionel Sambuc unsigned len;
2960*ebfedea0SLionel Sambuc
2961*ebfedea0SLionel Sambuc len = region->length - region->readc;
2962*ebfedea0SLionel Sambuc if (len > sizeof(pkt.u.se_data_body.data)) {
2963*ebfedea0SLionel Sambuc len = sizeof(pkt.u.se_data_body.data);
2964*ebfedea0SLionel Sambuc }
2965*ebfedea0SLionel Sambuc
2966*ebfedea0SLionel Sambuc if (!limread(pkt.u.se_data_body.data,
2967*ebfedea0SLionel Sambuc len, region, stream)) {
2968*ebfedea0SLionel Sambuc return 0;
2969*ebfedea0SLionel Sambuc }
2970*ebfedea0SLionel Sambuc
2971*ebfedea0SLionel Sambuc pkt.u.se_data_body.length = len;
2972*ebfedea0SLionel Sambuc
2973*ebfedea0SLionel Sambuc CALLBACK(tag, &stream->cbinfo, &pkt);
2974*ebfedea0SLionel Sambuc }
2975*ebfedea0SLionel Sambuc }
2976*ebfedea0SLionel Sambuc
2977*ebfedea0SLionel Sambuc return r;
2978*ebfedea0SLionel Sambuc }
2979*ebfedea0SLionel Sambuc
2980*ebfedea0SLionel Sambuc /**
2981*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
2982*ebfedea0SLionel Sambuc \brief Read a Symmetrically Encrypted packet
2983*ebfedea0SLionel Sambuc */
2984*ebfedea0SLionel Sambuc static int
parse_se_data(pgp_region_t * region,pgp_stream_t * stream)2985*ebfedea0SLionel Sambuc parse_se_data(pgp_region_t *region, pgp_stream_t *stream)
2986*ebfedea0SLionel Sambuc {
2987*ebfedea0SLionel Sambuc pgp_packet_t pkt;
2988*ebfedea0SLionel Sambuc
2989*ebfedea0SLionel Sambuc /* there's no info to go with this, so just announce it */
2990*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_SE_DATA_HEADER, &stream->cbinfo, &pkt);
2991*ebfedea0SLionel Sambuc
2992*ebfedea0SLionel Sambuc /*
2993*ebfedea0SLionel Sambuc * The content of an encrypted data packet is more OpenPGP packets
2994*ebfedea0SLionel Sambuc * once decrypted, so recursively handle them
2995*ebfedea0SLionel Sambuc */
2996*ebfedea0SLionel Sambuc return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream);
2997*ebfedea0SLionel Sambuc }
2998*ebfedea0SLionel Sambuc
2999*ebfedea0SLionel Sambuc /**
3000*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3001*ebfedea0SLionel Sambuc \brief Read a Symmetrically Encrypted Integrity Protected packet
3002*ebfedea0SLionel Sambuc */
3003*ebfedea0SLionel Sambuc static int
parse_se_ip_data(pgp_region_t * region,pgp_stream_t * stream)3004*ebfedea0SLionel Sambuc parse_se_ip_data(pgp_region_t *region, pgp_stream_t *stream)
3005*ebfedea0SLionel Sambuc {
3006*ebfedea0SLionel Sambuc pgp_packet_t pkt;
3007*ebfedea0SLionel Sambuc uint8_t c = 0x0;
3008*ebfedea0SLionel Sambuc
3009*ebfedea0SLionel Sambuc if (!limread(&c, 1, region, stream)) {
3010*ebfedea0SLionel Sambuc return 0;
3011*ebfedea0SLionel Sambuc }
3012*ebfedea0SLionel Sambuc pkt.u.se_ip_data_header = c;
3013*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
3014*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_se_ip_data: data header %d\n", c);
3015*ebfedea0SLionel Sambuc }
3016*ebfedea0SLionel Sambuc if (pkt.u.se_ip_data_header != PGP_SE_IP_DATA_VERSION) {
3017*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_se_ip_data: bad version\n");
3018*ebfedea0SLionel Sambuc return 0;
3019*ebfedea0SLionel Sambuc }
3020*ebfedea0SLionel Sambuc
3021*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
3022*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
3023*ebfedea0SLionel Sambuc region->readc, region->length);
3024*ebfedea0SLionel Sambuc hexdump(stderr, "compressed region", stream->virtualpkt, stream->virtualc);
3025*ebfedea0SLionel Sambuc }
3026*ebfedea0SLionel Sambuc /*
3027*ebfedea0SLionel Sambuc * The content of an encrypted data packet is more OpenPGP packets
3028*ebfedea0SLionel Sambuc * once decrypted, so recursively handle them
3029*ebfedea0SLionel Sambuc */
3030*ebfedea0SLionel Sambuc return decrypt_se_ip_data(PGP_PTAG_CT_SE_IP_DATA_BODY, region, stream);
3031*ebfedea0SLionel Sambuc }
3032*ebfedea0SLionel Sambuc
3033*ebfedea0SLionel Sambuc /**
3034*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3035*ebfedea0SLionel Sambuc \brief Read a MDC packet
3036*ebfedea0SLionel Sambuc */
3037*ebfedea0SLionel Sambuc static int
parse_mdc(pgp_region_t * region,pgp_stream_t * stream)3038*ebfedea0SLionel Sambuc parse_mdc(pgp_region_t *region, pgp_stream_t *stream)
3039*ebfedea0SLionel Sambuc {
3040*ebfedea0SLionel Sambuc pgp_packet_t pkt;
3041*ebfedea0SLionel Sambuc
3042*ebfedea0SLionel Sambuc pkt.u.mdc.length = PGP_SHA1_HASH_SIZE;
3043*ebfedea0SLionel Sambuc if ((pkt.u.mdc.data = calloc(1, PGP_SHA1_HASH_SIZE)) == NULL) {
3044*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_mdc: bad alloc\n");
3045*ebfedea0SLionel Sambuc return 0;
3046*ebfedea0SLionel Sambuc }
3047*ebfedea0SLionel Sambuc if (!limread(pkt.u.mdc.data, PGP_SHA1_HASH_SIZE, region, stream)) {
3048*ebfedea0SLionel Sambuc return 0;
3049*ebfedea0SLionel Sambuc }
3050*ebfedea0SLionel Sambuc CALLBACK(PGP_PTAG_CT_MDC, &stream->cbinfo, &pkt);
3051*ebfedea0SLionel Sambuc free(pkt.u.mdc.data);
3052*ebfedea0SLionel Sambuc return 1;
3053*ebfedea0SLionel Sambuc }
3054*ebfedea0SLionel Sambuc
3055*ebfedea0SLionel Sambuc /**
3056*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
3057*ebfedea0SLionel Sambuc * \brief Parse one packet.
3058*ebfedea0SLionel Sambuc *
3059*ebfedea0SLionel Sambuc * This function parses the packet tag. It computes the value of the
3060*ebfedea0SLionel Sambuc * content tag and then calls the appropriate function to handle the
3061*ebfedea0SLionel Sambuc * content.
3062*ebfedea0SLionel Sambuc *
3063*ebfedea0SLionel Sambuc * \param *stream How to parse
3064*ebfedea0SLionel Sambuc * \param *pktlen On return, will contain number of bytes in packet
3065*ebfedea0SLionel Sambuc * \return 1 on success, 0 on error, -1 on EOF */
3066*ebfedea0SLionel Sambuc static int
parse_packet(pgp_stream_t * stream,uint32_t * pktlen)3067*ebfedea0SLionel Sambuc parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
3068*ebfedea0SLionel Sambuc {
3069*ebfedea0SLionel Sambuc pgp_packet_t pkt;
3070*ebfedea0SLionel Sambuc pgp_region_t region;
3071*ebfedea0SLionel Sambuc uint8_t ptag;
3072*ebfedea0SLionel Sambuc unsigned indeterminate = 0;
3073*ebfedea0SLionel Sambuc int ret;
3074*ebfedea0SLionel Sambuc
3075*ebfedea0SLionel Sambuc pkt.u.ptag.position = stream->readinfo.position;
3076*ebfedea0SLionel Sambuc
3077*ebfedea0SLionel Sambuc ret = base_read(&ptag, 1, stream);
3078*ebfedea0SLionel Sambuc
3079*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
3080*ebfedea0SLionel Sambuc (void) fprintf(stderr,
3081*ebfedea0SLionel Sambuc "parse_packet: base_read returned %d, ptag %d\n",
3082*ebfedea0SLionel Sambuc ret, ptag);
3083*ebfedea0SLionel Sambuc }
3084*ebfedea0SLionel Sambuc
3085*ebfedea0SLionel Sambuc /* errors in the base read are effectively EOF. */
3086*ebfedea0SLionel Sambuc if (ret <= 0) {
3087*ebfedea0SLionel Sambuc return -1;
3088*ebfedea0SLionel Sambuc }
3089*ebfedea0SLionel Sambuc
3090*ebfedea0SLionel Sambuc *pktlen = 0;
3091*ebfedea0SLionel Sambuc
3092*ebfedea0SLionel Sambuc if (!(ptag & PGP_PTAG_ALWAYS_SET)) {
3093*ebfedea0SLionel Sambuc pkt.u.error = "Format error (ptag bit not set)";
3094*ebfedea0SLionel Sambuc CALLBACK(PGP_PARSER_ERROR, &stream->cbinfo, &pkt);
3095*ebfedea0SLionel Sambuc return 0;
3096*ebfedea0SLionel Sambuc }
3097*ebfedea0SLionel Sambuc pkt.u.ptag.new_format = !!(ptag & PGP_PTAG_NEW_FORMAT);
3098*ebfedea0SLionel Sambuc if (pkt.u.ptag.new_format) {
3099*ebfedea0SLionel Sambuc pkt.u.ptag.type = (ptag & PGP_PTAG_NF_CONTENT_TAG_MASK);
3100*ebfedea0SLionel Sambuc pkt.u.ptag.length_type = 0;
3101*ebfedea0SLionel Sambuc if (!read_new_length(&pkt.u.ptag.length, stream)) {
3102*ebfedea0SLionel Sambuc return 0;
3103*ebfedea0SLionel Sambuc }
3104*ebfedea0SLionel Sambuc } else {
3105*ebfedea0SLionel Sambuc unsigned rb;
3106*ebfedea0SLionel Sambuc
3107*ebfedea0SLionel Sambuc rb = 0;
3108*ebfedea0SLionel Sambuc pkt.u.ptag.type = ((unsigned)ptag &
3109*ebfedea0SLionel Sambuc PGP_PTAG_OF_CONTENT_TAG_MASK)
3110*ebfedea0SLionel Sambuc >> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
3111*ebfedea0SLionel Sambuc pkt.u.ptag.length_type = ptag & PGP_PTAG_OF_LENGTH_TYPE_MASK;
3112*ebfedea0SLionel Sambuc switch (pkt.u.ptag.length_type) {
3113*ebfedea0SLionel Sambuc case PGP_PTAG_OLD_LEN_1:
3114*ebfedea0SLionel Sambuc rb = _read_scalar(&pkt.u.ptag.length, 1, stream);
3115*ebfedea0SLionel Sambuc break;
3116*ebfedea0SLionel Sambuc
3117*ebfedea0SLionel Sambuc case PGP_PTAG_OLD_LEN_2:
3118*ebfedea0SLionel Sambuc rb = _read_scalar(&pkt.u.ptag.length, 2, stream);
3119*ebfedea0SLionel Sambuc break;
3120*ebfedea0SLionel Sambuc
3121*ebfedea0SLionel Sambuc case PGP_PTAG_OLD_LEN_4:
3122*ebfedea0SLionel Sambuc rb = _read_scalar(&pkt.u.ptag.length, 4, stream);
3123*ebfedea0SLionel Sambuc break;
3124*ebfedea0SLionel Sambuc
3125*ebfedea0SLionel Sambuc case PGP_PTAG_OLD_LEN_INDETERMINATE:
3126*ebfedea0SLionel Sambuc pkt.u.ptag.length = 0;
3127*ebfedea0SLionel Sambuc indeterminate = 1;
3128*ebfedea0SLionel Sambuc rb = 1;
3129*ebfedea0SLionel Sambuc break;
3130*ebfedea0SLionel Sambuc }
3131*ebfedea0SLionel Sambuc if (!rb) {
3132*ebfedea0SLionel Sambuc return 0;
3133*ebfedea0SLionel Sambuc }
3134*ebfedea0SLionel Sambuc }
3135*ebfedea0SLionel Sambuc
3136*ebfedea0SLionel Sambuc CALLBACK(PGP_PARSER_PTAG, &stream->cbinfo, &pkt);
3137*ebfedea0SLionel Sambuc
3138*ebfedea0SLionel Sambuc pgp_init_subregion(®ion, NULL);
3139*ebfedea0SLionel Sambuc region.length = pkt.u.ptag.length;
3140*ebfedea0SLionel Sambuc region.indeterminate = indeterminate;
3141*ebfedea0SLionel Sambuc if (pgp_get_debug_level(__FILE__)) {
3142*ebfedea0SLionel Sambuc (void) fprintf(stderr, "parse_packet: type %u\n",
3143*ebfedea0SLionel Sambuc pkt.u.ptag.type);
3144*ebfedea0SLionel Sambuc }
3145*ebfedea0SLionel Sambuc switch (pkt.u.ptag.type) {
3146*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SIGNATURE:
3147*ebfedea0SLionel Sambuc ret = parse_sig(®ion, stream);
3148*ebfedea0SLionel Sambuc break;
3149*ebfedea0SLionel Sambuc
3150*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PUBLIC_KEY:
3151*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PUBLIC_SUBKEY:
3152*ebfedea0SLionel Sambuc ret = parse_pubkey((pgp_content_enum)pkt.u.ptag.type, ®ion, stream);
3153*ebfedea0SLionel Sambuc break;
3154*ebfedea0SLionel Sambuc
3155*ebfedea0SLionel Sambuc case PGP_PTAG_CT_TRUST:
3156*ebfedea0SLionel Sambuc ret = parse_trust(®ion, stream);
3157*ebfedea0SLionel Sambuc break;
3158*ebfedea0SLionel Sambuc
3159*ebfedea0SLionel Sambuc case PGP_PTAG_CT_USER_ID:
3160*ebfedea0SLionel Sambuc ret = parse_userid(®ion, stream);
3161*ebfedea0SLionel Sambuc break;
3162*ebfedea0SLionel Sambuc
3163*ebfedea0SLionel Sambuc case PGP_PTAG_CT_COMPRESSED:
3164*ebfedea0SLionel Sambuc ret = parse_compressed(®ion, stream);
3165*ebfedea0SLionel Sambuc break;
3166*ebfedea0SLionel Sambuc
3167*ebfedea0SLionel Sambuc case PGP_PTAG_CT_1_PASS_SIG:
3168*ebfedea0SLionel Sambuc ret = parse_one_pass(®ion, stream);
3169*ebfedea0SLionel Sambuc break;
3170*ebfedea0SLionel Sambuc
3171*ebfedea0SLionel Sambuc case PGP_PTAG_CT_LITDATA:
3172*ebfedea0SLionel Sambuc ret = parse_litdata(®ion, stream);
3173*ebfedea0SLionel Sambuc break;
3174*ebfedea0SLionel Sambuc
3175*ebfedea0SLionel Sambuc case PGP_PTAG_CT_USER_ATTR:
3176*ebfedea0SLionel Sambuc ret = parse_userattr(®ion, stream);
3177*ebfedea0SLionel Sambuc break;
3178*ebfedea0SLionel Sambuc
3179*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SECRET_KEY:
3180*ebfedea0SLionel Sambuc ret = parse_seckey(®ion, stream);
3181*ebfedea0SLionel Sambuc break;
3182*ebfedea0SLionel Sambuc
3183*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SECRET_SUBKEY:
3184*ebfedea0SLionel Sambuc ret = parse_seckey(®ion, stream);
3185*ebfedea0SLionel Sambuc break;
3186*ebfedea0SLionel Sambuc
3187*ebfedea0SLionel Sambuc case PGP_PTAG_CT_PK_SESSION_KEY:
3188*ebfedea0SLionel Sambuc ret = parse_pk_sesskey(®ion, stream);
3189*ebfedea0SLionel Sambuc break;
3190*ebfedea0SLionel Sambuc
3191*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SE_DATA:
3192*ebfedea0SLionel Sambuc ret = parse_se_data(®ion, stream);
3193*ebfedea0SLionel Sambuc break;
3194*ebfedea0SLionel Sambuc
3195*ebfedea0SLionel Sambuc case PGP_PTAG_CT_SE_IP_DATA:
3196*ebfedea0SLionel Sambuc ret = parse_se_ip_data(®ion, stream);
3197*ebfedea0SLionel Sambuc break;
3198*ebfedea0SLionel Sambuc
3199*ebfedea0SLionel Sambuc case PGP_PTAG_CT_MDC:
3200*ebfedea0SLionel Sambuc ret = parse_mdc(®ion, stream);
3201*ebfedea0SLionel Sambuc break;
3202*ebfedea0SLionel Sambuc
3203*ebfedea0SLionel Sambuc default:
3204*ebfedea0SLionel Sambuc PGP_ERROR_1(&stream->errors, PGP_E_P_UNKNOWN_TAG,
3205*ebfedea0SLionel Sambuc "Unknown content tag 0x%x",
3206*ebfedea0SLionel Sambuc pkt.u.ptag.type);
3207*ebfedea0SLionel Sambuc ret = 0;
3208*ebfedea0SLionel Sambuc }
3209*ebfedea0SLionel Sambuc
3210*ebfedea0SLionel Sambuc /* Ensure that the entire packet has been consumed */
3211*ebfedea0SLionel Sambuc
3212*ebfedea0SLionel Sambuc if (region.length != region.readc && !region.indeterminate) {
3213*ebfedea0SLionel Sambuc if (!consume_packet(®ion, stream, 0)) {
3214*ebfedea0SLionel Sambuc ret = -1;
3215*ebfedea0SLionel Sambuc }
3216*ebfedea0SLionel Sambuc }
3217*ebfedea0SLionel Sambuc
3218*ebfedea0SLionel Sambuc /* also consume it if there's been an error? */
3219*ebfedea0SLionel Sambuc /* \todo decide what to do about an error on an */
3220*ebfedea0SLionel Sambuc /* indeterminate packet */
3221*ebfedea0SLionel Sambuc if (ret == 0) {
3222*ebfedea0SLionel Sambuc if (!consume_packet(®ion, stream, 0)) {
3223*ebfedea0SLionel Sambuc ret = -1;
3224*ebfedea0SLionel Sambuc }
3225*ebfedea0SLionel Sambuc }
3226*ebfedea0SLionel Sambuc /* set pktlen */
3227*ebfedea0SLionel Sambuc
3228*ebfedea0SLionel Sambuc *pktlen = stream->readinfo.alength;
3229*ebfedea0SLionel Sambuc
3230*ebfedea0SLionel Sambuc /* do callback on entire packet, if desired and there was no error */
3231*ebfedea0SLionel Sambuc
3232*ebfedea0SLionel Sambuc if (ret > 0 && stream->readinfo.accumulate) {
3233*ebfedea0SLionel Sambuc pkt.u.packet.length = stream->readinfo.alength;
3234*ebfedea0SLionel Sambuc pkt.u.packet.raw = stream->readinfo.accumulated;
3235*ebfedea0SLionel Sambuc stream->readinfo.accumulated = NULL;
3236*ebfedea0SLionel Sambuc stream->readinfo.asize = 0;
3237*ebfedea0SLionel Sambuc CALLBACK(PGP_PARSER_PACKET_END, &stream->cbinfo, &pkt);
3238*ebfedea0SLionel Sambuc }
3239*ebfedea0SLionel Sambuc stream->readinfo.alength = 0;
3240*ebfedea0SLionel Sambuc
3241*ebfedea0SLionel Sambuc return (ret < 0) ? -1 : (ret) ? 1 : 0;
3242*ebfedea0SLionel Sambuc }
3243*ebfedea0SLionel Sambuc
3244*ebfedea0SLionel Sambuc /**
3245*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
3246*ebfedea0SLionel Sambuc *
3247*ebfedea0SLionel Sambuc * \brief Parse packets from an input stream until EOF or error.
3248*ebfedea0SLionel Sambuc *
3249*ebfedea0SLionel Sambuc * \details Setup the necessary parsing configuration in "stream"
3250*ebfedea0SLionel Sambuc * before calling pgp_parse().
3251*ebfedea0SLionel Sambuc *
3252*ebfedea0SLionel Sambuc * That information includes :
3253*ebfedea0SLionel Sambuc *
3254*ebfedea0SLionel Sambuc * - a "reader" function to be used to get the data to be parsed
3255*ebfedea0SLionel Sambuc *
3256*ebfedea0SLionel Sambuc * - a "callback" function to be called when this library has identified
3257*ebfedea0SLionel Sambuc * a parseable object within the data
3258*ebfedea0SLionel Sambuc *
3259*ebfedea0SLionel Sambuc * - whether the calling function wants the signature subpackets
3260*ebfedea0SLionel Sambuc * returned raw, parsed or not at all.
3261*ebfedea0SLionel Sambuc *
3262*ebfedea0SLionel Sambuc * After returning, stream->errors holds any errors encountered while parsing.
3263*ebfedea0SLionel Sambuc *
3264*ebfedea0SLionel Sambuc * \param stream Parsing configuration
3265*ebfedea0SLionel Sambuc * \return 1 on success in all packets, 0 on error in any packet
3266*ebfedea0SLionel Sambuc *
3267*ebfedea0SLionel Sambuc * \sa CoreAPI Overview
3268*ebfedea0SLionel Sambuc *
3269*ebfedea0SLionel Sambuc * \sa pgp_print_errors()
3270*ebfedea0SLionel Sambuc *
3271*ebfedea0SLionel Sambuc */
3272*ebfedea0SLionel Sambuc
3273*ebfedea0SLionel Sambuc int
pgp_parse(pgp_stream_t * stream,const int perrors)3274*ebfedea0SLionel Sambuc pgp_parse(pgp_stream_t *stream, const int perrors)
3275*ebfedea0SLionel Sambuc {
3276*ebfedea0SLionel Sambuc uint32_t pktlen;
3277*ebfedea0SLionel Sambuc int r;
3278*ebfedea0SLionel Sambuc
3279*ebfedea0SLionel Sambuc do {
3280*ebfedea0SLionel Sambuc r = parse_packet(stream, &pktlen);
3281*ebfedea0SLionel Sambuc } while (r != -1);
3282*ebfedea0SLionel Sambuc if (perrors) {
3283*ebfedea0SLionel Sambuc pgp_print_errors(stream->errors);
3284*ebfedea0SLionel Sambuc }
3285*ebfedea0SLionel Sambuc return (stream->errors == NULL);
3286*ebfedea0SLionel Sambuc }
3287*ebfedea0SLionel Sambuc
3288*ebfedea0SLionel Sambuc /**
3289*ebfedea0SLionel Sambuc * \ingroup Core_ReadPackets
3290*ebfedea0SLionel Sambuc *
3291*ebfedea0SLionel Sambuc * \brief Specifies whether one or more signature
3292*ebfedea0SLionel Sambuc * subpacket types should be returned parsed; or raw; or ignored.
3293*ebfedea0SLionel Sambuc *
3294*ebfedea0SLionel Sambuc * \param stream Pointer to previously allocated structure
3295*ebfedea0SLionel Sambuc * \param tag Packet tag. PGP_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag
3296*ebfedea0SLionel Sambuc * \param type Parse type
3297*ebfedea0SLionel Sambuc * \todo Make all packet types optional, not just subpackets */
3298*ebfedea0SLionel Sambuc void
pgp_parse_options(pgp_stream_t * stream,pgp_content_enum tag,pgp_parse_type_t type)3299*ebfedea0SLionel Sambuc pgp_parse_options(pgp_stream_t *stream,
3300*ebfedea0SLionel Sambuc pgp_content_enum tag,
3301*ebfedea0SLionel Sambuc pgp_parse_type_t type)
3302*ebfedea0SLionel Sambuc {
3303*ebfedea0SLionel Sambuc unsigned t7;
3304*ebfedea0SLionel Sambuc unsigned t8;
3305*ebfedea0SLionel Sambuc
3306*ebfedea0SLionel Sambuc if (tag == PGP_PTAG_SS_ALL) {
3307*ebfedea0SLionel Sambuc int n;
3308*ebfedea0SLionel Sambuc
3309*ebfedea0SLionel Sambuc for (n = 0; n < 256; ++n) {
3310*ebfedea0SLionel Sambuc pgp_parse_options(stream,
3311*ebfedea0SLionel Sambuc PGP_PTAG_SIG_SUBPKT_BASE + n,
3312*ebfedea0SLionel Sambuc type);
3313*ebfedea0SLionel Sambuc }
3314*ebfedea0SLionel Sambuc return;
3315*ebfedea0SLionel Sambuc }
3316*ebfedea0SLionel Sambuc if (tag < PGP_PTAG_SIG_SUBPKT_BASE ||
3317*ebfedea0SLionel Sambuc tag > PGP_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) {
3318*ebfedea0SLionel Sambuc (void) fprintf(stderr, "pgp_parse_options: bad tag\n");
3319*ebfedea0SLionel Sambuc return;
3320*ebfedea0SLionel Sambuc }
3321*ebfedea0SLionel Sambuc t8 = (tag - PGP_PTAG_SIG_SUBPKT_BASE) / 8;
3322*ebfedea0SLionel Sambuc t7 = 1 << ((tag - PGP_PTAG_SIG_SUBPKT_BASE) & 7);
3323*ebfedea0SLionel Sambuc switch (type) {
3324*ebfedea0SLionel Sambuc case PGP_PARSE_RAW:
3325*ebfedea0SLionel Sambuc stream->ss_raw[t8] |= t7;
3326*ebfedea0SLionel Sambuc stream->ss_parsed[t8] &= ~t7;
3327*ebfedea0SLionel Sambuc break;
3328*ebfedea0SLionel Sambuc
3329*ebfedea0SLionel Sambuc case PGP_PARSE_PARSED:
3330*ebfedea0SLionel Sambuc stream->ss_raw[t8] &= ~t7;
3331*ebfedea0SLionel Sambuc stream->ss_parsed[t8] |= t7;
3332*ebfedea0SLionel Sambuc break;
3333*ebfedea0SLionel Sambuc
3334*ebfedea0SLionel Sambuc case PGP_PARSE_IGNORE:
3335*ebfedea0SLionel Sambuc stream->ss_raw[t8] &= ~t7;
3336*ebfedea0SLionel Sambuc stream->ss_parsed[t8] &= ~t7;
3337*ebfedea0SLionel Sambuc break;
3338*ebfedea0SLionel Sambuc }
3339*ebfedea0SLionel Sambuc }
3340*ebfedea0SLionel Sambuc
3341*ebfedea0SLionel Sambuc /**
3342*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3343*ebfedea0SLionel Sambuc \brief Free pgp_stream_t struct and its contents
3344*ebfedea0SLionel Sambuc */
3345*ebfedea0SLionel Sambuc void
pgp_stream_delete(pgp_stream_t * stream)3346*ebfedea0SLionel Sambuc pgp_stream_delete(pgp_stream_t *stream)
3347*ebfedea0SLionel Sambuc {
3348*ebfedea0SLionel Sambuc pgp_cbdata_t *cbinfo;
3349*ebfedea0SLionel Sambuc pgp_cbdata_t *next;
3350*ebfedea0SLionel Sambuc
3351*ebfedea0SLionel Sambuc for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
3352*ebfedea0SLionel Sambuc next = cbinfo->next;
3353*ebfedea0SLionel Sambuc free(cbinfo);
3354*ebfedea0SLionel Sambuc }
3355*ebfedea0SLionel Sambuc if (stream->readinfo.destroyer) {
3356*ebfedea0SLionel Sambuc stream->readinfo.destroyer(&stream->readinfo);
3357*ebfedea0SLionel Sambuc }
3358*ebfedea0SLionel Sambuc pgp_free_errors(stream->errors);
3359*ebfedea0SLionel Sambuc if (stream->readinfo.accumulated) {
3360*ebfedea0SLionel Sambuc free(stream->readinfo.accumulated);
3361*ebfedea0SLionel Sambuc }
3362*ebfedea0SLionel Sambuc free(stream);
3363*ebfedea0SLionel Sambuc }
3364*ebfedea0SLionel Sambuc
3365*ebfedea0SLionel Sambuc /**
3366*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3367*ebfedea0SLionel Sambuc \brief Returns the parse_info's reader_info
3368*ebfedea0SLionel Sambuc \return Pointer to the reader_info inside the parse_info
3369*ebfedea0SLionel Sambuc */
3370*ebfedea0SLionel Sambuc pgp_reader_t *
pgp_readinfo(pgp_stream_t * stream)3371*ebfedea0SLionel Sambuc pgp_readinfo(pgp_stream_t *stream)
3372*ebfedea0SLionel Sambuc {
3373*ebfedea0SLionel Sambuc return &stream->readinfo;
3374*ebfedea0SLionel Sambuc }
3375*ebfedea0SLionel Sambuc
3376*ebfedea0SLionel Sambuc /**
3377*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3378*ebfedea0SLionel Sambuc \brief Sets the parse_info's callback
3379*ebfedea0SLionel Sambuc This is used when adding the first callback in a stack of callbacks.
3380*ebfedea0SLionel Sambuc \sa pgp_callback_push()
3381*ebfedea0SLionel Sambuc */
3382*ebfedea0SLionel Sambuc
3383*ebfedea0SLionel Sambuc void
pgp_set_callback(pgp_stream_t * stream,pgp_cbfunc_t * cb,void * arg)3384*ebfedea0SLionel Sambuc pgp_set_callback(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg)
3385*ebfedea0SLionel Sambuc {
3386*ebfedea0SLionel Sambuc stream->cbinfo.cbfunc = cb;
3387*ebfedea0SLionel Sambuc stream->cbinfo.arg = arg;
3388*ebfedea0SLionel Sambuc stream->cbinfo.errors = &stream->errors;
3389*ebfedea0SLionel Sambuc }
3390*ebfedea0SLionel Sambuc
3391*ebfedea0SLionel Sambuc /**
3392*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3393*ebfedea0SLionel Sambuc \brief Adds a further callback to a stack of callbacks
3394*ebfedea0SLionel Sambuc \sa pgp_set_callback()
3395*ebfedea0SLionel Sambuc */
3396*ebfedea0SLionel Sambuc void
pgp_callback_push(pgp_stream_t * stream,pgp_cbfunc_t * cb,void * arg)3397*ebfedea0SLionel Sambuc pgp_callback_push(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg)
3398*ebfedea0SLionel Sambuc {
3399*ebfedea0SLionel Sambuc pgp_cbdata_t *cbinfo;
3400*ebfedea0SLionel Sambuc
3401*ebfedea0SLionel Sambuc if ((cbinfo = calloc(1, sizeof(*cbinfo))) == NULL) {
3402*ebfedea0SLionel Sambuc (void) fprintf(stderr, "pgp_callback_push: bad alloc\n");
3403*ebfedea0SLionel Sambuc return;
3404*ebfedea0SLionel Sambuc }
3405*ebfedea0SLionel Sambuc (void) memcpy(cbinfo, &stream->cbinfo, sizeof(*cbinfo));
3406*ebfedea0SLionel Sambuc cbinfo->io = stream->io;
3407*ebfedea0SLionel Sambuc stream->cbinfo.next = cbinfo;
3408*ebfedea0SLionel Sambuc pgp_set_callback(stream, cb, arg);
3409*ebfedea0SLionel Sambuc }
3410*ebfedea0SLionel Sambuc
3411*ebfedea0SLionel Sambuc /**
3412*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3413*ebfedea0SLionel Sambuc \brief Returns callback's arg
3414*ebfedea0SLionel Sambuc */
3415*ebfedea0SLionel Sambuc void *
pgp_callback_arg(pgp_cbdata_t * cbinfo)3416*ebfedea0SLionel Sambuc pgp_callback_arg(pgp_cbdata_t *cbinfo)
3417*ebfedea0SLionel Sambuc {
3418*ebfedea0SLionel Sambuc return cbinfo->arg;
3419*ebfedea0SLionel Sambuc }
3420*ebfedea0SLionel Sambuc
3421*ebfedea0SLionel Sambuc /**
3422*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3423*ebfedea0SLionel Sambuc \brief Returns callback's errors
3424*ebfedea0SLionel Sambuc */
3425*ebfedea0SLionel Sambuc void *
pgp_callback_errors(pgp_cbdata_t * cbinfo)3426*ebfedea0SLionel Sambuc pgp_callback_errors(pgp_cbdata_t *cbinfo)
3427*ebfedea0SLionel Sambuc {
3428*ebfedea0SLionel Sambuc return cbinfo->errors;
3429*ebfedea0SLionel Sambuc }
3430*ebfedea0SLionel Sambuc
3431*ebfedea0SLionel Sambuc /**
3432*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3433*ebfedea0SLionel Sambuc \brief Calls the parse_cb_info's callback if present
3434*ebfedea0SLionel Sambuc \return Return value from callback, if present; else PGP_FINISHED
3435*ebfedea0SLionel Sambuc */
3436*ebfedea0SLionel Sambuc pgp_cb_ret_t
pgp_callback(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)3437*ebfedea0SLionel Sambuc pgp_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
3438*ebfedea0SLionel Sambuc {
3439*ebfedea0SLionel Sambuc return (cbinfo->cbfunc) ? cbinfo->cbfunc(pkt, cbinfo) : PGP_FINISHED;
3440*ebfedea0SLionel Sambuc }
3441*ebfedea0SLionel Sambuc
3442*ebfedea0SLionel Sambuc /**
3443*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3444*ebfedea0SLionel Sambuc \brief Calls the next callback in the stack
3445*ebfedea0SLionel Sambuc \return Return value from callback
3446*ebfedea0SLionel Sambuc */
3447*ebfedea0SLionel Sambuc pgp_cb_ret_t
pgp_stacked_callback(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)3448*ebfedea0SLionel Sambuc pgp_stacked_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
3449*ebfedea0SLionel Sambuc {
3450*ebfedea0SLionel Sambuc return pgp_callback(pkt, cbinfo->next);
3451*ebfedea0SLionel Sambuc }
3452*ebfedea0SLionel Sambuc
3453*ebfedea0SLionel Sambuc /**
3454*ebfedea0SLionel Sambuc \ingroup Core_ReadPackets
3455*ebfedea0SLionel Sambuc \brief Returns the parse_info's errors
3456*ebfedea0SLionel Sambuc \return parse_info's errors
3457*ebfedea0SLionel Sambuc */
3458*ebfedea0SLionel Sambuc pgp_error_t *
pgp_stream_get_errors(pgp_stream_t * stream)3459*ebfedea0SLionel Sambuc pgp_stream_get_errors(pgp_stream_t *stream)
3460*ebfedea0SLionel Sambuc {
3461*ebfedea0SLionel Sambuc return stream->errors;
3462*ebfedea0SLionel Sambuc }
3463*ebfedea0SLionel Sambuc
3464*ebfedea0SLionel Sambuc pgp_crypt_t *
pgp_get_decrypt(pgp_stream_t * stream)3465*ebfedea0SLionel Sambuc pgp_get_decrypt(pgp_stream_t *stream)
3466*ebfedea0SLionel Sambuc {
3467*ebfedea0SLionel Sambuc return (stream->decrypt.alg) ? &stream->decrypt : NULL;
3468*ebfedea0SLionel Sambuc }
3469