Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / crypto / external / bsd / netpgp / dist / src / lib / packet-parse.c
blobab11cfd6bbc29059fbda4ace66b101fceeb7079f
1 /*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31 * All rights reserved.
32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33 * their moral rights under the UK Copyright Design and Patents Act 1988 to
34 * be recorded as the authors of this copyright work.
36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37 * use this file except in compliance with the License.
39 * You may obtain a copy of the License at
40 * http://www.apache.org/licenses/LICENSE-2.0
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
50 /** \file
51 * \brief Parser for OpenPGP packets
53 #include "config.h"
55 #ifdef HAVE_SYS_CDEFS_H
56 #include <sys/cdefs.h>
57 #endif
59 #if defined(__NetBSD__)
60 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61 __RCSID("$NetBSD: packet-parse.c,v 1.26 2009/10/09 06:02:55 agc Exp $");
62 #endif
64 #ifdef HAVE_OPENSSL_CAST_H
65 #include <openssl/cast.h>
66 #endif
68 #include <stdarg.h>
69 #include <stdlib.h>
70 #include <string.h>
72 #ifdef HAVE_UNISTD_H
73 #include <unistd.h>
74 #endif
76 #ifdef HAVE_LIMITS_H
77 #include <limits.h>
78 #endif
80 #include "packet.h"
81 #include "packet-parse.h"
82 #include "keyring.h"
83 #include "errors.h"
84 #include "packet-show.h"
85 #include "create.h"
86 #include "readerwriter.h"
87 #include "netpgpdefs.h"
88 #include "crypto.h"
89 #include "netpgpdigest.h"
91 #define ERRP(cbinfo, cont, err) do { \
92 cont.u.error.error = err; \
93 CALLBACK(OPS_PARSER_ERROR, cbinfo, &cont); \
94 return 0; \
95 /*NOTREACHED*/ \
96 } while(/*CONSTCOND*/0)
98 /**
99 * limread_data reads the specified amount of the subregion's data
100 * into a data_t structure
102 * \param data Empty structure which will be filled with data
103 * \param len Number of octets to read
104 * \param subregion
105 * \param stream How to parse
107 * \return 1 on success, 0 on failure
109 static int
110 limread_data(__ops_data_t *data, unsigned int len,
111 __ops_region_t *subregion, __ops_stream_t *stream)
113 data->len = len;
115 if (subregion->length - subregion->readc < len) {
116 (void) fprintf(stderr, "limread_data: bad length\n");
117 return 0;
120 data->contents = calloc(1, data->len);
121 if (!data->contents) {
122 return 0;
125 return __ops_limited_read(data->contents, data->len, subregion,
126 &stream->errors, &stream->readinfo, &stream->cbinfo);
130 * read_data reads the remainder of the subregion's data
131 * into a data_t structure
133 * \param data
134 * \param subregion
135 * \param stream
137 * \return 1 on success, 0 on failure
139 static int
140 read_data(__ops_data_t *data, __ops_region_t *region, __ops_stream_t *stream)
142 int cc;
144 cc = region->length - region->readc;
145 return (cc >= 0) ? limread_data(data, (unsigned)cc, region, stream) : 0;
149 * Reads the remainder of the subregion as a string.
150 * It is the user's responsibility to free the memory allocated here.
153 static int
154 read_unsig_str(unsigned char **str, __ops_region_t *subregion,
155 __ops_stream_t *stream)
157 size_t len;
159 len = subregion->length - subregion->readc;
160 if ((*str = calloc(1, len + 1)) == NULL) {
161 return 0;
163 if (len &&
164 !__ops_limited_read(*str, len, subregion, &stream->errors,
165 &stream->readinfo, &stream->cbinfo)) {
166 return 0;
168 (*str)[len] = '\0';
169 return 1;
172 static int
173 read_string(char **str, __ops_region_t *subregion, __ops_stream_t *stream)
175 return read_unsig_str((unsigned char **) str, subregion, stream);
178 void
179 __ops_init_subregion(__ops_region_t *subregion, __ops_region_t *region)
181 (void) memset(subregion, 0x0, sizeof(*subregion));
182 subregion->parent = region;
186 * XXX: replace __ops_ptag_t with something more appropriate for limiting reads
190 * low-level function to read data from reader function
192 * Use this function, rather than calling the reader directly.
194 * If the accumulate flag is set in *stream, the function
195 * adds the read data to the accumulated data, and updates
196 * the accumulated length. This is useful if, for example,
197 * the application wants access to the raw data as well as the
198 * parsed data.
200 * This function will also try to read the entire amount asked for, but not
201 * if it is over INT_MAX. Obviously many callers will know that they
202 * never ask for that much and so can avoid the extra complexity of
203 * dealing with return codes and filled-in lengths.
205 * \param *dest
206 * \param *plength
207 * \param flags
208 * \param *stream
210 * \return OPS_R_OK
211 * \return OPS_R_PARTIAL_READ
212 * \return OPS_R_EOF
213 * \return OPS_R_EARLY_EOF
215 * \sa #__ops_reader_ret_t for details of return codes
218 static int
219 sub_base_read(void *dest, size_t length, __ops_error_t **errors,
220 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo)
222 size_t n;
224 /* reading more than this would look like an error */
225 if (length > INT_MAX)
226 length = INT_MAX;
228 for (n = 0; n < length;) {
229 int r;
231 r = readinfo->reader((char *) dest + n, length - n, errors,
232 readinfo, cbinfo);
233 if (r > (int)(length - n)) {
234 (void) fprintf(stderr, "sub_base_read: bad read\n");
235 return 0;
237 if (r < 0) {
238 return r;
240 if (r == 0) {
241 break;
243 n += (unsigned)r;
246 if (n == 0) {
247 return 0;
249 if (readinfo->accumulate) {
250 if (readinfo->asize < readinfo->alength) {
251 (void) fprintf(stderr, "sub_base_read: bad size\n");
252 return 0;
254 if (readinfo->alength + n > readinfo->asize) {
255 unsigned char *temp;
257 readinfo->asize = (readinfo->asize * 2) + n;
258 temp = realloc(readinfo->accumulated, readinfo->asize);
259 if (temp == NULL) {
260 (void) fprintf(stderr,
261 "sub_base_read: bad alloc\n");
262 return 0;
264 readinfo->accumulated = temp;
266 if (readinfo->asize < readinfo->alength + n) {
267 (void) fprintf(stderr, "sub_base_read: bad realloc\n");
268 return 0;
270 (void) memcpy(readinfo->accumulated + readinfo->alength, dest,
273 /* we track length anyway, because it is used for packet offsets */
274 readinfo->alength += n;
275 /* and also the position */
276 readinfo->position += n;
278 return n;
281 int
282 __ops_stacked_read(void *dest, size_t length, __ops_error_t **errors,
283 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo)
285 return sub_base_read(dest, length, errors, readinfo->next, cbinfo);
288 /* This will do a full read so long as length < MAX_INT */
289 static int
290 base_read(unsigned char *dest, size_t length,
291 __ops_stream_t *stream)
293 return sub_base_read(dest, length, &stream->errors, &stream->readinfo,
294 &stream->cbinfo);
298 * Read a full size_t's worth. If the return is < than length, then
299 * *last_read tells you why - < 0 for an error, == 0 for EOF
302 static size_t
303 full_read(unsigned char *dest,
304 size_t length,
305 int *last_read,
306 __ops_error_t **errors,
307 __ops_reader_t *readinfo,
308 __ops_cbdata_t *cbinfo)
310 size_t t;
311 int r = 0; /* preset in case some loon calls with length
312 * == 0 */
314 for (t = 0; t < length;) {
315 r = sub_base_read(dest + t, length - t, errors, readinfo,
316 cbinfo);
317 if (r <= 0) {
318 *last_read = r;
319 return t;
321 t += (size_t)r;
324 *last_read = r;
326 return t;
331 /** Read a scalar value of selected length from reader.
333 * Read an unsigned scalar value from reader in Big Endian representation.
335 * This function does not know or care about packet boundaries. It
336 * also assumes that an EOF is an error.
338 * \param *result The scalar value is stored here
339 * \param *reader Our reader
340 * \param length How many bytes to read
341 * \return 1 on success, 0 on failure
343 static unsigned
344 _read_scalar(unsigned *result, unsigned length,
345 __ops_stream_t *stream)
347 unsigned t = 0;
349 if (length > sizeof(*result)) {
350 (void) fprintf(stderr, "_read_scalar: bad length\n");
351 return 0;
354 while (length--) {
355 unsigned char c;
356 int r;
358 r = base_read(&c, 1, stream);
359 if (r != 1)
360 return 0;
361 t = (t << 8) + c;
364 *result = t;
365 return 1;
369 * \ingroup Core_ReadPackets
370 * \brief Read bytes from a region within the packet.
372 * Read length bytes into the buffer pointed to by *dest.
373 * Make sure we do not read over the packet boundary.
374 * Updates the Packet Tag's __ops_ptag_t::readc.
376 * If length would make us read over the packet boundary, or if
377 * reading fails, we call the callback with an error.
379 * Note that if the region is indeterminate, this can return a short
380 * read - check region->last_read for the length. EOF is indicated by
381 * a success return and region->last_read == 0 in this case (for a
382 * region of known length, EOF is an error).
384 * This function makes sure to respect packet boundaries.
386 * \param dest The destination buffer
387 * \param length How many bytes to read
388 * \param region Pointer to packet region
389 * \param errors Error stack
390 * \param readinfo Reader info
391 * \param cbinfo Callback info
392 * \return 1 on success, 0 on error
394 unsigned
395 __ops_limited_read(unsigned char *dest,
396 size_t length,
397 __ops_region_t *region,
398 __ops_error_t **errors,
399 __ops_reader_t *readinfo,
400 __ops_cbdata_t *cbinfo)
402 size_t r;
403 int lr;
405 if (!region->indeterminate &&
406 region->readc + length > region->length) {
407 OPS_ERROR(errors, OPS_E_P_NOT_ENOUGH_DATA, "Not enough data");
408 return 0;
410 r = full_read(dest, length, &lr, errors, readinfo, cbinfo);
411 if (lr < 0) {
412 OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
413 return 0;
415 if (!region->indeterminate && r != length) {
416 OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
417 return 0;
419 region->last_read = r;
420 do {
421 region->readc += r;
422 if (region->parent && region->length > region->parent->length) {
423 (void) fprintf(stderr,
424 "ops_limited_read: bad length\n");
425 return 0;
427 } while ((region = region->parent) != NULL);
428 return 1;
432 \ingroup Core_ReadPackets
433 \brief Call __ops_limited_read on next in stack
435 unsigned
436 __ops_stacked_limited_read(unsigned char *dest, unsigned length,
437 __ops_region_t *region,
438 __ops_error_t **errors,
439 __ops_reader_t *readinfo,
440 __ops_cbdata_t *cbinfo)
442 return __ops_limited_read(dest, length, region, errors,
443 readinfo->next, cbinfo);
446 static unsigned
447 limread(unsigned char *dest, unsigned length,
448 __ops_region_t *region, __ops_stream_t *info)
450 return __ops_limited_read(dest, length, region, &info->errors,
451 &info->readinfo, &info->cbinfo);
454 static unsigned
455 exact_limread(unsigned char *dest, unsigned len,
456 __ops_region_t *region,
457 __ops_stream_t *stream)
459 unsigned ret;
461 stream->exact_read = 1;
462 ret = limread(dest, len, region, stream);
463 stream->exact_read = 0;
464 return ret;
467 /** Skip over length bytes of this packet.
469 * Calls limread() to skip over some data.
471 * This function makes sure to respect packet boundaries.
473 * \param length How many bytes to skip
474 * \param *region Pointer to packet region
475 * \param *stream How to parse
476 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
478 static int
479 limskip(unsigned length, __ops_region_t *region, __ops_stream_t *stream)
481 unsigned char buf[NETPGP_BUFSIZ];
483 while (length > 0) {
484 unsigned n = length % NETPGP_BUFSIZ;
486 if (!limread(buf, n, region, stream)) {
487 return 0;
489 length -= n;
491 return 1;
494 /** Read a scalar.
496 * Read a big-endian scalar of length bytes, respecting packet
497 * boundaries (by calling limread() to read the raw data).
499 * This function makes sure to respect packet boundaries.
501 * \param *dest The scalar value is stored here
502 * \param length How many bytes make up this scalar (at most 4)
503 * \param *region Pointer to current packet region
504 * \param *stream How to parse
505 * \param *cb The callback
506 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
508 * \see RFC4880 3.1
510 static int
511 limread_scalar(unsigned *dest,
512 unsigned len,
513 __ops_region_t *region,
514 __ops_stream_t *stream)
516 unsigned char c[4] = "";
517 unsigned t;
518 unsigned n;
520 if (len > 4) {
521 (void) fprintf(stderr, "limread_scalar: bad length\n");
522 return 0;
524 /*LINTED*/
525 if (/*CONSTCOND*/sizeof(*dest) < 4) {
526 (void) fprintf(stderr, "limread_scalar: bad dest\n");
527 return 0;
529 if (!limread(c, len, region, stream)) {
530 return 0;
532 for (t = 0, n = 0; n < len; ++n) {
533 t = (t << 8) + c[n];
535 *dest = t;
536 return 1;
539 /** Read a scalar.
541 * Read a big-endian scalar of length bytes, respecting packet
542 * boundaries (by calling limread() to read the raw data).
544 * The value read is stored in a size_t, which is a different size
545 * from an unsigned on some platforms.
547 * This function makes sure to respect packet boundaries.
549 * \param *dest The scalar value is stored here
550 * \param length How many bytes make up this scalar (at most 4)
551 * \param *region Pointer to current packet region
552 * \param *stream How to parse
553 * \param *cb The callback
554 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
556 * \see RFC4880 3.1
558 static int
559 limread_size_t(size_t *dest,
560 unsigned length,
561 __ops_region_t *region,
562 __ops_stream_t *stream)
564 unsigned tmp;
567 * Note that because the scalar is at most 4 bytes, we don't care if
568 * size_t is bigger than usigned
570 if (!limread_scalar(&tmp, length, region, stream))
571 return 0;
573 *dest = tmp;
574 return 1;
577 /** Read a timestamp.
579 * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970). They are stored in an unsigned scalar
580 * of 4 bytes.
582 * This function reads the timestamp using limread_scalar().
584 * This function makes sure to respect packet boundaries.
586 * \param *dest The timestamp is stored here
587 * \param *ptag Pointer to current packet's Packet Tag.
588 * \param *reader Our reader
589 * \param *cb The callback
590 * \return see limread_scalar()
592 * \see RFC4880 3.5
594 static int
595 limited_read_time(time_t *dest, __ops_region_t *region,
596 __ops_stream_t *stream)
598 unsigned char c;
599 time_t mytime = 0;
600 int i;
603 * Cannot assume that time_t is 4 octets long -
604 * SunOS 5.10 and NetBSD both have 64-bit time_ts.
606 if (/* CONSTCOND */sizeof(time_t) == 4) {
607 return limread_scalar((unsigned *)(void *)dest, 4, region, stream);
609 for (i = 0; i < 4; i++) {
610 if (!limread(&c, 1, region, stream)) {
611 return 0;
613 mytime = (mytime << 8) + c;
615 *dest = mytime;
616 return 1;
620 * \ingroup Core_MPI
621 * Read a multiprecision integer.
623 * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts. First there is a 2 byte scalar
624 * indicating the length of the following MPI in Bits. Then follow the bits that make up the actual number, most
625 * significant bits first (Big Endian). The most significant bit in the MPI is supposed to be 1 (unless the MPI is
626 * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted).
628 * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are
629 * supposed to be cleared - I guess. XXX - does anything actually say so?
631 * This function makes sure to respect packet boundaries.
633 * \param **pgn return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed
634 * by the caller XXX right ben?
635 * \param *ptag Pointer to current packet's Packet Tag.
636 * \param *reader Our reader
637 * \param *cb The callback
638 * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
639 * see comment below - the callback is called with a OPS_PARSER_ERROR in case of an error)
641 * \see RFC4880 3.2
643 static int
644 limread_mpi(BIGNUM **pbn, __ops_region_t *region, __ops_stream_t *stream)
646 unsigned char buf[NETPGP_BUFSIZ] = "";
647 /* an MPI has a 2 byte length part.
648 * Length is given in bits, so the
649 * largest we should ever need for
650 * the buffer is NETPGP_BUFSIZ bytes. */
651 unsigned length;
652 unsigned nonzero;
653 unsigned ret;
655 stream->reading_mpi_len = 1;
656 ret = (unsigned)limread_scalar(&length, 2, region, stream);
658 stream->reading_mpi_len = 0;
659 if (!ret)
660 return 0;
662 nonzero = length & 7; /* there should be this many zero bits in the
663 * MS byte */
664 if (!nonzero)
665 nonzero = 8;
666 length = (length + 7) / 8;
668 if (length == 0) {
669 /* if we try to read a length of 0, then fail */
670 if (__ops_get_debug_level(__FILE__)) {
671 (void) fprintf(stderr, "limread_mpi: 0 length\n");
673 return 0;
675 if (length > NETPGP_BUFSIZ) {
676 (void) fprintf(stderr, "limread_mpi: bad length\n");
677 return 0;
679 if (!limread(buf, length, region, stream)) {
680 return 0;
682 if (((unsigned)buf[0] >> nonzero) != 0 ||
683 !((unsigned)buf[0] & (1U << (nonzero - 1U)))) {
684 OPS_ERROR(&stream->errors, OPS_E_P_MPI_FORMAT_ERROR, "MPI Format error");
685 /* XXX: Ben, one part of
686 * this constraint does
687 * not apply to
688 * encrypted MPIs the
689 * draft says. -- peter */
690 return 0;
692 *pbn = BN_bin2bn(buf, (int)length, NULL);
693 return 1;
696 /** Read some data with a New-Format length from reader.
698 * \sa Internet-Draft RFC4880.txt Section 4.2.2
700 * \param *length Where the decoded length will be put
701 * \param *stream How to parse
702 * \return 1 if OK, else 0
706 static unsigned
707 read_new_length(unsigned *length, __ops_stream_t *stream)
709 unsigned char c;
711 if (base_read(&c, 1, stream) != 1)
712 return 0;
713 if (c < 192) {
714 /* 1. One-octet packet */
715 *length = c;
716 return 1;
717 } else if (c >= 192 && c <= 223) {
718 /* 2. Two-octet packet */
719 unsigned t = (c - 192) << 8;
721 if (base_read(&c, 1, stream) != 1)
722 return 0;
723 *length = t + c + 192;
724 return 1;
725 } else if (c == 255) {
726 /* 3. Five-Octet packet */
727 return _read_scalar(length, 4, stream);
728 } else if (c >= 224 && c < 255) {
729 /* 4. Partial Body Length */
730 /* XXX - agc - gpg multi-recipient encryption uses this */
731 OPS_ERROR(&stream->errors, OPS_E_UNIMPLEMENTED,
732 "New format Partial Body Length fields not yet implemented");
733 return 0;
735 return 0;
738 /** Read the length information for a new format Packet Tag.
740 * New style Packet Tags encode the length in one to five octets. This function reads the right amount of bytes and
741 * decodes it to the proper length information.
743 * This function makes sure to respect packet boundaries.
745 * \param *length return the length here
746 * \param *ptag Pointer to current packet's Packet Tag.
747 * \param *reader Our reader
748 * \param *cb The callback
749 * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
750 * see comment below)
752 * \see RFC4880 4.2.2
753 * \see __ops_ptag_t
755 static int
756 limited_read_new_length(unsigned *length, __ops_region_t *region,
757 __ops_stream_t *stream)
759 unsigned char c = 0x0;
761 if (!limread(&c, 1, region, stream)) {
762 return 0;
764 if (c < 192) {
765 *length = c;
766 return 1;
768 if (c < 255) {
769 unsigned t = (c - 192) << 8;
771 if (!limread(&c, 1, region, stream)) {
772 return 0;
774 *length = t + c + 192;
775 return 1;
777 return limread_scalar(length, 4, region, stream);
781 \ingroup Core_Create
782 \brief Free allocated memory
784 static void
785 data_free(__ops_data_t *data)
787 free(data->contents);
788 data->contents = NULL;
789 data->len = 0;
793 \ingroup Core_Create
794 \brief Free allocated memory
796 static void
797 string_free(char **str)
799 free(*str);
800 *str = NULL;
804 \ingroup Core_Create
805 \brief Free allocated memory
807 /* ! Free packet memory, set pointer to NULL */
808 void
809 __ops_subpacket_free(__ops_subpacket_t *packet)
811 free(packet->raw);
812 packet->raw = NULL;
816 \ingroup Core_Create
817 \brief Free allocated memory
819 static void
820 __ops_headers_free(__ops_headers_t *headers)
822 unsigned n;
824 for (n = 0; n < headers->headerc; ++n) {
825 free(headers->headers[n].key);
826 free(headers->headers[n].value);
828 free(headers->headers);
829 headers->headers = NULL;
833 \ingroup Core_Create
834 \brief Free allocated memory
836 static void
837 cleartext_trailer_free(__ops_cleartext_trailer_t *trailer)
839 free(trailer->hash);
840 trailer->hash = NULL;
844 \ingroup Core_Create
845 \brief Free allocated memory
847 static void
848 __ops_cmd_get_passphrase_free(__ops_seckey_passphrase_t *skp)
850 if (skp->passphrase && *skp->passphrase) {
851 free(*skp->passphrase);
852 *skp->passphrase = NULL;
857 \ingroup Core_Create
858 \brief Free the memory used when parsing this signature sub-packet type
860 static void
861 ss_userdef_free(__ops_ss_userdef_t *ss_userdef)
863 data_free(&ss_userdef->data);
867 \ingroup Core_Create
868 \brief Free the memory used when parsing this signature sub-packet type
870 static void
871 ss_reserved_free(__ops_ss_unknown_t *ss_unknown)
873 data_free(&ss_unknown->data);
877 \ingroup Core_Create
878 \brief Free the memory used when parsing this packet type
880 static void
881 trust_free(__ops_trust_t *trust)
883 data_free(&trust->data);
887 * \ingroup Core_Create
888 * \brief Free the memory used when parsing a private/experimental PKA signature
889 * \param unknown_sig
891 static void
892 free_unknown_sig_pka(__ops_unknown_sig_t *unknown_sig)
894 data_free(&unknown_sig->data);
898 \ingroup Core_Create
899 \brief Free allocated memory
901 static void
902 free_BN(BIGNUM **pp)
904 BN_free(*pp);
905 *pp = NULL;
909 * \ingroup Core_Create
910 * \brief Free the memory used when parsing a signature
911 * \param sig
913 static void
914 sig_free(__ops_sig_t *sig)
916 switch (sig->info.key_alg) {
917 case OPS_PKA_RSA:
918 case OPS_PKA_RSA_SIGN_ONLY:
919 free_BN(&sig->info.sig.rsa.sig);
920 break;
922 case OPS_PKA_DSA:
923 free_BN(&sig->info.sig.dsa.r);
924 free_BN(&sig->info.sig.dsa.s);
925 break;
927 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
928 free_BN(&sig->info.sig.elgamal.r);
929 free_BN(&sig->info.sig.elgamal.s);
930 break;
932 case OPS_PKA_PRIVATE00:
933 case OPS_PKA_PRIVATE01:
934 case OPS_PKA_PRIVATE02:
935 case OPS_PKA_PRIVATE03:
936 case OPS_PKA_PRIVATE04:
937 case OPS_PKA_PRIVATE05:
938 case OPS_PKA_PRIVATE06:
939 case OPS_PKA_PRIVATE07:
940 case OPS_PKA_PRIVATE08:
941 case OPS_PKA_PRIVATE09:
942 case OPS_PKA_PRIVATE10:
943 free_unknown_sig_pka(&sig->info.sig.unknown);
944 break;
946 default:
947 (void) fprintf(stderr, "sig_free: bad sig type\n");
952 \ingroup Core_Create
953 \brief Free the memory used when parsing this signature sub-packet type
954 \param ss_skapref
956 static void
957 ss_skapref_free(__ops_ss_skapref_t *ss_skapref)
959 data_free(&ss_skapref->data);
963 \ingroup Core_Create
964 \brief Free the memory used when parsing this signature sub-packet type
965 \param ss_hashpref
967 static void
968 ss_hashpref_free(__ops_ss_hashpref_t *ss_hashpref)
970 data_free(&ss_hashpref->data);
974 \ingroup Core_Create
975 \brief Free the memory used when parsing this signature sub-packet type
977 static void
978 ss_zpref_free(__ops_ss_zpref_t *ss_zpref)
980 data_free(&ss_zpref->data);
984 \ingroup Core_Create
985 \brief Free the memory used when parsing this signature sub-packet type
987 static void
988 ss_key_flags_free(__ops_ss_key_flags_t *ss_key_flags)
990 data_free(&ss_key_flags->data);
994 \ingroup Core_Create
995 \brief Free the memory used when parsing this signature sub-packet type
997 static void
998 ss_key_server_prefs_free(__ops_ss_key_server_prefs_t *ss_key_server_prefs)
1000 data_free(&ss_key_server_prefs->data);
1004 \ingroup Core_Create
1005 \brief Free the memory used when parsing this signature sub-packet type
1007 static void
1008 ss_features_free(__ops_ss_features_t *ss_features)
1010 data_free(&ss_features->data);
1014 \ingroup Core_Create
1015 \brief Free the memory used when parsing this signature sub-packet type
1017 static void
1018 ss_notation_free(__ops_ss_notation_t *ss_notation)
1020 data_free(&ss_notation->name);
1021 data_free(&ss_notation->value);
1025 \ingroup Core_Create
1026 \brief Free allocated memory
1028 /* ! Free the memory used when parsing this signature sub-packet type */
1029 static void
1030 ss_regexp_free(__ops_ss_regexp_t *regexp)
1032 string_free(&regexp->regexp);
1036 \ingroup Core_Create
1037 \brief Free allocated memory
1039 /* ! Free the memory used when parsing this signature sub-packet type */
1040 static void
1041 ss_policy_free(__ops_ss_policy_t *policy)
1043 string_free(&policy->url);
1047 \ingroup Core_Create
1048 \brief Free allocated memory
1050 /* ! Free the memory used when parsing this signature sub-packet type */
1051 static void
1052 ss_keyserv_free(__ops_ss_keyserv_t *preferred_key_server)
1054 string_free(&preferred_key_server->name);
1058 \ingroup Core_Create
1059 \brief Free the memory used when parsing this signature sub-packet type
1061 static void
1062 ss_revocation_free(__ops_ss_revocation_t *ss_revocation)
1064 string_free(&ss_revocation->reason);
1067 static void
1068 ss_embedded_sig_free(__ops_ss_embedded_sig_t *ss_embedded_sig)
1070 data_free(&ss_embedded_sig->sig);
1074 \ingroup Core_Create
1075 \brief Free allocated memory
1077 /* ! Free any memory allocated when parsing the packet content */
1078 void
1079 __ops_parser_content_free(__ops_packet_t *c)
1081 switch (c->tag) {
1082 case OPS_PARSER_PTAG:
1083 case OPS_PTAG_CT_COMPRESSED:
1084 case OPS_PTAG_SS_CREATION_TIME:
1085 case OPS_PTAG_SS_EXPIRATION_TIME:
1086 case OPS_PTAG_SS_KEY_EXPIRY:
1087 case OPS_PTAG_SS_TRUST:
1088 case OPS_PTAG_SS_ISSUER_KEY_ID:
1089 case OPS_PTAG_CT_1_PASS_SIG:
1090 case OPS_PTAG_SS_PRIMARY_USER_ID:
1091 case OPS_PTAG_SS_REVOCABLE:
1092 case OPS_PTAG_SS_REVOCATION_KEY:
1093 case OPS_PTAG_CT_LITDATA_HEADER:
1094 case OPS_PTAG_CT_LITDATA_BODY:
1095 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
1096 case OPS_PTAG_CT_UNARMOURED_TEXT:
1097 case OPS_PTAG_CT_ARMOUR_TRAILER:
1098 case OPS_PTAG_CT_SIGNATURE_HEADER:
1099 case OPS_PTAG_CT_SE_DATA_HEADER:
1100 case OPS_PTAG_CT_SE_IP_DATA_HEADER:
1101 case OPS_PTAG_CT_SE_IP_DATA_BODY:
1102 case OPS_PTAG_CT_MDC:
1103 case OPS_GET_SECKEY:
1104 break;
1106 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1107 __ops_headers_free(&c->u.cleartext_head.headers);
1108 break;
1110 case OPS_PTAG_CT_ARMOUR_HEADER:
1111 __ops_headers_free(&c->u.armour_header.headers);
1112 break;
1114 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1115 cleartext_trailer_free(&c->u.cleartext_trailer);
1116 break;
1118 case OPS_PTAG_CT_TRUST:
1119 trust_free(&c->u.trust);
1120 break;
1122 case OPS_PTAG_CT_SIGNATURE:
1123 case OPS_PTAG_CT_SIGNATURE_FOOTER:
1124 sig_free(&c->u.sig);
1125 break;
1127 case OPS_PTAG_CT_PUBLIC_KEY:
1128 case OPS_PTAG_CT_PUBLIC_SUBKEY:
1129 __ops_pubkey_free(&c->u.pubkey);
1130 break;
1132 case OPS_PTAG_CT_USER_ID:
1133 __ops_userid_free(&c->u.userid);
1134 break;
1136 case OPS_PTAG_SS_SIGNERS_USER_ID:
1137 __ops_userid_free(&c->u.ss_signer);
1138 break;
1140 case OPS_PTAG_CT_USER_ATTR:
1141 __ops_userattr_free(&c->u.userattr);
1142 break;
1144 case OPS_PTAG_SS_PREFERRED_SKA:
1145 ss_skapref_free(&c->u.ss_skapref);
1146 break;
1148 case OPS_PTAG_SS_PREFERRED_HASH:
1149 ss_hashpref_free(&c->u.ss_hashpref);
1150 break;
1152 case OPS_PTAG_SS_PREF_COMPRESS:
1153 ss_zpref_free(&c->u.ss_zpref);
1154 break;
1156 case OPS_PTAG_SS_KEY_FLAGS:
1157 ss_key_flags_free(&c->u.ss_key_flags);
1158 break;
1160 case OPS_PTAG_SS_KEYSERV_PREFS:
1161 ss_key_server_prefs_free(&c->u.ss_key_server_prefs);
1162 break;
1164 case OPS_PTAG_SS_FEATURES:
1165 ss_features_free(&c->u.ss_features);
1166 break;
1168 case OPS_PTAG_SS_NOTATION_DATA:
1169 ss_notation_free(&c->u.ss_notation);
1170 break;
1172 case OPS_PTAG_SS_REGEXP:
1173 ss_regexp_free(&c->u.ss_regexp);
1174 break;
1176 case OPS_PTAG_SS_POLICY_URI:
1177 ss_policy_free(&c->u.ss_policy);
1178 break;
1180 case OPS_PTAG_SS_PREF_KEYSERV:
1181 ss_keyserv_free(&c->u.ss_keyserv);
1182 break;
1184 case OPS_PTAG_SS_USERDEFINED00:
1185 case OPS_PTAG_SS_USERDEFINED01:
1186 case OPS_PTAG_SS_USERDEFINED02:
1187 case OPS_PTAG_SS_USERDEFINED03:
1188 case OPS_PTAG_SS_USERDEFINED04:
1189 case OPS_PTAG_SS_USERDEFINED05:
1190 case OPS_PTAG_SS_USERDEFINED06:
1191 case OPS_PTAG_SS_USERDEFINED07:
1192 case OPS_PTAG_SS_USERDEFINED08:
1193 case OPS_PTAG_SS_USERDEFINED09:
1194 case OPS_PTAG_SS_USERDEFINED10:
1195 ss_userdef_free(&c->u.ss_userdef);
1196 break;
1198 case OPS_PTAG_SS_RESERVED:
1199 ss_reserved_free(&c->u.ss_unknown);
1200 break;
1202 case OPS_PTAG_SS_REVOCATION_REASON:
1203 ss_revocation_free(&c->u.ss_revocation);
1204 break;
1206 case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
1207 ss_embedded_sig_free(&c->u.ss_embedded_sig);
1208 break;
1210 case OPS_PARSER_PACKET_END:
1211 __ops_subpacket_free(&c->u.packet);
1212 break;
1214 case OPS_PARSER_ERROR:
1215 case OPS_PARSER_ERRCODE:
1216 break;
1218 case OPS_PTAG_CT_SECRET_KEY:
1219 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
1220 __ops_seckey_free(&c->u.seckey);
1221 break;
1223 case OPS_PTAG_CT_PK_SESSION_KEY:
1224 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1225 __ops_pk_sesskey_free(&c->u.pk_sesskey);
1226 break;
1228 case OPS_GET_PASSPHRASE:
1229 __ops_cmd_get_passphrase_free(&c->u.skey_passphrase);
1230 break;
1232 default:
1233 fprintf(stderr, "Can't free %d (0x%x)\n", c->tag, c->tag);
1238 \ingroup Core_Create
1239 \brief Free allocated memory
1241 void
1242 __ops_pk_sesskey_free(__ops_pk_sesskey_t *sk)
1244 switch (sk->alg) {
1245 case OPS_PKA_RSA:
1246 free_BN(&sk->params.rsa.encrypted_m);
1247 break;
1249 case OPS_PKA_ELGAMAL:
1250 free_BN(&sk->params.elgamal.g_to_k);
1251 free_BN(&sk->params.elgamal.encrypted_m);
1252 break;
1254 default:
1255 (void) fprintf(stderr, "__ops_pk_sesskey_free: bad alg\n");
1256 break;
1261 \ingroup Core_Create
1262 \brief Free allocated memory
1264 /* ! Free the memory used when parsing a public key */
1265 void
1266 __ops_pubkey_free(__ops_pubkey_t *p)
1268 switch (p->alg) {
1269 case OPS_PKA_RSA:
1270 case OPS_PKA_RSA_ENCRYPT_ONLY:
1271 case OPS_PKA_RSA_SIGN_ONLY:
1272 free_BN(&p->key.rsa.n);
1273 free_BN(&p->key.rsa.e);
1274 break;
1276 case OPS_PKA_DSA:
1277 free_BN(&p->key.dsa.p);
1278 free_BN(&p->key.dsa.q);
1279 free_BN(&p->key.dsa.g);
1280 free_BN(&p->key.dsa.y);
1281 break;
1283 case OPS_PKA_ELGAMAL:
1284 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1285 free_BN(&p->key.elgamal.p);
1286 free_BN(&p->key.elgamal.g);
1287 free_BN(&p->key.elgamal.y);
1288 break;
1290 case OPS_PKA_NOTHING:
1291 /* nothing to free */
1292 break;
1294 default:
1295 (void) fprintf(stderr, "__ops_pubkey_free: bad alg\n");
1300 \ingroup Core_ReadPackets
1302 static int
1303 parse_pubkey_data(__ops_pubkey_t *key, __ops_region_t *region,
1304 __ops_stream_t *stream)
1306 unsigned char c = 0x0;
1308 if (region->readc != 0) {
1309 /* We should not have read anything so far */
1310 (void) fprintf(stderr, "parse_pubkey_data: bad length\n");
1311 return 0;
1313 if (!limread(&c, 1, region, stream)) {
1314 return 0;
1316 key->version = (__ops_version_t)c;
1317 switch (key->version) {
1318 case OPS_V2:
1319 case OPS_V3:
1320 case OPS_V4:
1321 break;
1322 default:
1323 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN,
1324 "Bad public key version (0x%02x)", key->version);
1325 return 0;
1327 if (!limited_read_time(&key->birthtime, region, stream)) {
1328 return 0;
1331 key->days_valid = 0;
1332 if ((key->version == 2 || key->version == 3) &&
1333 !limread_scalar(&key->days_valid, 2, region, stream)) {
1334 return 0;
1337 if (!limread(&c, 1, region, stream)) {
1338 return 0;
1340 key->alg = c;
1342 switch (key->alg) {
1343 case OPS_PKA_DSA:
1344 if (!limread_mpi(&key->key.dsa.p, region, stream) ||
1345 !limread_mpi(&key->key.dsa.q, region, stream) ||
1346 !limread_mpi(&key->key.dsa.g, region, stream) ||
1347 !limread_mpi(&key->key.dsa.y, region, stream)) {
1348 return 0;
1350 break;
1352 case OPS_PKA_RSA:
1353 case OPS_PKA_RSA_ENCRYPT_ONLY:
1354 case OPS_PKA_RSA_SIGN_ONLY:
1355 if (!limread_mpi(&key->key.rsa.n, region, stream) ||
1356 !limread_mpi(&key->key.rsa.e, region, stream)) {
1357 return 0;
1359 break;
1361 case OPS_PKA_ELGAMAL:
1362 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1363 if (!limread_mpi(&key->key.elgamal.p, region, stream) ||
1364 !limread_mpi(&key->key.elgamal.g, region, stream) ||
1365 !limread_mpi(&key->key.elgamal.y, region, stream)) {
1366 return 0;
1368 break;
1370 default:
1371 OPS_ERROR_1(&stream->errors,
1372 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
1373 "Unsupported Public Key algorithm (%s)",
1374 __ops_show_pka(key->alg));
1375 return 0;
1378 return 1;
1383 * \ingroup Core_ReadPackets
1384 * \brief Parse a public key packet.
1386 * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys.
1388 * Once the key has been parsed successfully, it is passed to the callback.
1390 * \param *ptag Pointer to the current Packet Tag. This function should consume the entire packet.
1391 * \param *reader Our reader
1392 * \param *cb The callback
1393 * \return 1 on success, 0 on error
1395 * \see RFC4880 5.5.2
1397 static int
1398 parse_pubkey(__ops_content_tag_t tag, __ops_region_t *region,
1399 __ops_stream_t *stream)
1401 __ops_packet_t pkt;
1403 if (!parse_pubkey_data(&pkt.u.pubkey, region, stream))
1404 return 0;
1406 /* XXX: this test should be done for all packets, surely? */
1407 if (region->readc != region->length) {
1408 OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1409 "Unconsumed data (%d)", region->length - region->readc);
1410 return 0;
1412 CALLBACK(tag, &stream->cbinfo, &pkt);
1414 return 1;
1419 \ingroup Core_Create
1420 \brief Free allocated memory
1422 /* ! Free the memory used when parsing this packet type */
1423 void
1424 __ops_userattr_free(__ops_userattr_t *user_att)
1426 data_free(&user_att->data);
1430 * \ingroup Core_ReadPackets
1431 * \brief Parse one user attribute packet.
1433 * User attribute packets contain one or more attribute subpackets.
1434 * For now, handle the whole packet as raw data.
1437 static int
1438 parse_userattr(__ops_region_t *region, __ops_stream_t *stream)
1441 __ops_packet_t pkt;
1444 * xxx- treat as raw data for now. Could break down further into
1445 * attribute sub-packets later - rachel
1448 if (region->readc != 0) {
1449 /* We should not have read anything so far */
1450 (void) fprintf(stderr, "parse_userattr: bad length\n");
1451 return 0;
1454 if (!read_data(&pkt.u.userattr.data, region, stream))
1455 return 0;
1457 CALLBACK(OPS_PTAG_CT_USER_ATTR, &stream->cbinfo, &pkt);
1459 return 1;
1463 \ingroup Core_Create
1464 \brief Free allocated memory
1466 /* ! Free the memory used when parsing this packet type */
1467 void
1468 __ops_userid_free(__ops_userid_t *id)
1470 free(id->userid);
1471 id->userid = NULL;
1475 * \ingroup Core_ReadPackets
1476 * \brief Parse a user id.
1478 * This function parses an user id packet, which is basically just a char array the size of the packet.
1480 * The char array is to be treated as an UTF-8 string.
1482 * The userid gets null terminated by this function. Freeing it is the responsibility of the caller.
1484 * Once the userid has been parsed successfully, it is passed to the callback.
1486 * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
1487 * \param *reader Our reader
1488 * \param *cb The callback
1489 * \return 1 on success, 0 on error
1491 * \see RFC4880 5.11
1493 static int
1494 parse_userid(__ops_region_t *region, __ops_stream_t *stream)
1496 __ops_packet_t pkt;
1498 if (region->readc != 0) {
1499 /* We should not have read anything so far */
1500 (void) fprintf(stderr, "parse_userid: bad length\n");
1501 return 0;
1504 if ((pkt.u.userid.userid = calloc(1, region->length + 1)) == NULL) {
1505 (void) fprintf(stderr, "parse_userid: bad alloc\n");
1506 return 0;
1509 if (region->length &&
1510 !limread(pkt.u.userid.userid, region->length, region,
1511 stream)) {
1512 return 0;
1514 pkt.u.userid.userid[region->length] = '\0';
1515 CALLBACK(OPS_PTAG_CT_USER_ID, &stream->cbinfo, &pkt);
1516 return 1;
1519 static __ops_hash_t *
1520 parse_hash_find(__ops_stream_t *stream, const unsigned char *keyid)
1522 __ops_hashtype_t *hp;
1523 size_t n;
1525 for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) {
1526 if (memcmp(hp->keyid, keyid, OPS_KEY_ID_SIZE) == 0) {
1527 return &hp->hash;
1530 return NULL;
1534 * \ingroup Core_Parse
1535 * \brief Parse a version 3 signature.
1537 * This function parses an version 3 signature packet, handling RSA and DSA signatures.
1539 * Once the signature has been parsed successfully, it is passed to the callback.
1541 * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
1542 * \param *reader Our reader
1543 * \param *cb The callback
1544 * \return 1 on success, 0 on error
1546 * \see RFC4880 5.2.2
1548 static int
1549 parse_v3_sig(__ops_region_t *region,
1550 __ops_stream_t *stream)
1552 __ops_packet_t pkt;
1553 unsigned char c = 0x0;
1555 /* clear signature */
1556 (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
1558 pkt.u.sig.info.version = OPS_V3;
1560 /* hash info length */
1561 if (!limread(&c, 1, region, stream)) {
1562 return 0;
1564 if (c != 5) {
1565 ERRP(&stream->cbinfo, pkt, "bad hash info length");
1568 if (!limread(&c, 1, region, stream)) {
1569 return 0;
1571 pkt.u.sig.info.type = (__ops_sig_type_t)c;
1572 /* XXX: check signature type */
1574 if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) {
1575 return 0;
1577 pkt.u.sig.info.birthtime_set = 1;
1579 if (!limread(pkt.u.sig.info.signer_id, OPS_KEY_ID_SIZE, region,
1580 stream)) {
1581 return 0;
1583 pkt.u.sig.info.signer_id_set = 1;
1585 if (!limread(&c, 1, region, stream)) {
1586 return 0;
1588 pkt.u.sig.info.key_alg = (__ops_pubkey_alg_t)c;
1589 /* XXX: check algorithm */
1591 if (!limread(&c, 1, region, stream)) {
1592 return 0;
1594 pkt.u.sig.info.hash_alg = (__ops_hash_alg_t)c;
1595 /* XXX: check algorithm */
1597 if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
1598 return 0;
1601 switch (pkt.u.sig.info.key_alg) {
1602 case OPS_PKA_RSA:
1603 case OPS_PKA_RSA_SIGN_ONLY:
1604 if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
1605 return 0;
1607 break;
1609 case OPS_PKA_DSA:
1610 if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream) ||
1611 !limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
1612 return 0;
1614 break;
1616 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1617 if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
1618 stream) ||
1619 !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
1620 stream)) {
1621 return 0;
1623 break;
1625 default:
1626 OPS_ERROR_1(&stream->errors,
1627 OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
1628 "Unsupported signature key algorithm (%s)",
1629 __ops_show_pka(pkt.u.sig.info.key_alg));
1630 return 0;
1633 if (region->readc != region->length) {
1634 OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1635 "Unconsumed data (%d)",
1636 region->length - region->readc);
1637 return 0;
1639 if (pkt.u.sig.info.signer_id_set) {
1640 pkt.u.sig.hash = parse_hash_find(stream,
1641 pkt.u.sig.info.signer_id);
1643 CALLBACK(OPS_PTAG_CT_SIGNATURE, &stream->cbinfo, &pkt);
1644 return 1;
1648 * \ingroup Core_ReadPackets
1649 * \brief Parse one signature sub-packet.
1651 * Version 4 signatures can have an arbitrary amount of (hashed and unhashed) subpackets. Subpackets are used to hold
1652 * optional attributes of subpackets.
1654 * This function parses one such signature subpacket.
1656 * Once the subpacket has been parsed successfully, it is passed to the callback.
1658 * \param *ptag Pointer to the Packet Tag. This function should consume the entire subpacket.
1659 * \param *reader Our reader
1660 * \param *cb The callback
1661 * \return 1 on success, 0 on error
1663 * \see RFC4880 5.2.3
1665 static int
1666 parse_one_sig_subpacket(__ops_sig_t *sig,
1667 __ops_region_t *region,
1668 __ops_stream_t *stream)
1670 __ops_region_t subregion;
1671 __ops_packet_t pkt;
1672 unsigned char bools = 0x0;
1673 unsigned char c = 0x0;
1674 unsigned doread = 1;
1675 unsigned t8;
1676 unsigned t7;
1678 __ops_init_subregion(&subregion, region);
1679 if (!limited_read_new_length(&subregion.length, region, stream)) {
1680 return 0;
1683 if (subregion.length > region->length) {
1684 ERRP(&stream->cbinfo, pkt, "Subpacket too long");
1687 if (!limread(&c, 1, &subregion, stream)) {
1688 return 0;
1691 t8 = (c & 0x7f) / 8;
1692 t7 = 1 << (c & 7);
1694 pkt.critical = (unsigned)c >> 7;
1695 pkt.tag = (__ops_content_tag_t)(OPS_PTAG_SIG_SUBPKT_BASE + (c & 0x7f));
1697 /* Application wants it delivered raw */
1698 if (stream->ss_raw[t8] & t7) {
1699 pkt.u.ss_raw.tag = pkt.tag;
1700 pkt.u.ss_raw.length = subregion.length - 1;
1701 pkt.u.ss_raw.raw = calloc(1, pkt.u.ss_raw.length);
1702 if (pkt.u.ss_raw.raw == NULL) {
1703 (void) fprintf(stderr, "parse_one_sig_subpacket: bad alloc\n");
1704 return 0;
1706 if (!limread(pkt.u.ss_raw.raw, pkt.u.ss_raw.length,
1707 &subregion, stream)) {
1708 return 0;
1710 CALLBACK(OPS_PTAG_RAW_SS, &stream->cbinfo, &pkt);
1711 return 1;
1713 switch (pkt.tag) {
1714 case OPS_PTAG_SS_CREATION_TIME:
1715 case OPS_PTAG_SS_EXPIRATION_TIME:
1716 case OPS_PTAG_SS_KEY_EXPIRY:
1717 if (!limited_read_time(&pkt.u.ss_time.time, &subregion, stream))
1718 return 0;
1719 if (pkt.tag == OPS_PTAG_SS_CREATION_TIME) {
1720 sig->info.birthtime = pkt.u.ss_time.time;
1721 sig->info.birthtime_set = 1;
1723 break;
1725 case OPS_PTAG_SS_TRUST:
1726 if (!limread(&pkt.u.ss_trust.level, 1, &subregion, stream) ||
1727 !limread(&pkt.u.ss_trust.amount, 1, &subregion, stream)) {
1728 return 0;
1730 break;
1732 case OPS_PTAG_SS_REVOCABLE:
1733 if (!limread(&bools, 1, &subregion, stream)) {
1734 return 0;
1736 pkt.u.ss_revocable.revocable = !!bools;
1737 break;
1739 case OPS_PTAG_SS_ISSUER_KEY_ID:
1740 if (!limread(pkt.u.ss_issuer.key_id, OPS_KEY_ID_SIZE,
1741 &subregion, stream)) {
1742 return 0;
1744 (void) memcpy(sig->info.signer_id,
1745 pkt.u.ss_issuer.key_id, OPS_KEY_ID_SIZE);
1746 sig->info.signer_id_set = 1;
1747 break;
1749 case OPS_PTAG_SS_PREFERRED_SKA:
1750 if (!read_data(&pkt.u.ss_skapref.data, &subregion, stream)) {
1751 return 0;
1753 break;
1755 case OPS_PTAG_SS_PREFERRED_HASH:
1756 if (!read_data(&pkt.u.ss_hashpref.data, &subregion, stream)) {
1757 return 0;
1759 break;
1761 case OPS_PTAG_SS_PREF_COMPRESS:
1762 if (!read_data(&pkt.u.ss_zpref.data,
1763 &subregion, stream)) {
1764 return 0;
1766 break;
1768 case OPS_PTAG_SS_PRIMARY_USER_ID:
1769 if (!limread(&bools, 1, &subregion, stream)) {
1770 return 0;
1772 pkt.u.ss_primary_userid.primary_userid = !!bools;
1773 break;
1775 case OPS_PTAG_SS_KEY_FLAGS:
1776 if (!read_data(&pkt.u.ss_key_flags.data, &subregion, stream)) {
1777 return 0;
1779 break;
1781 case OPS_PTAG_SS_KEYSERV_PREFS:
1782 if (!read_data(&pkt.u.ss_key_server_prefs.data, &subregion,
1783 stream)) {
1784 return 0;
1786 break;
1788 case OPS_PTAG_SS_FEATURES:
1789 if (!read_data(&pkt.u.ss_features.data, &subregion, stream)) {
1790 return 0;
1792 break;
1794 case OPS_PTAG_SS_SIGNERS_USER_ID:
1795 if (!read_unsig_str(&pkt.u.ss_signer.userid, &subregion,
1796 stream)) {
1797 return 0;
1799 break;
1801 case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
1802 /* \todo should do something with this sig? */
1803 if (!read_data(&pkt.u.ss_embedded_sig.sig, &subregion, stream)) {
1804 return 0;
1806 break;
1808 case OPS_PTAG_SS_NOTATION_DATA:
1809 if (!limread_data(&pkt.u.ss_notation.flags, 4,
1810 &subregion, stream)) {
1811 return 0;
1813 if (!limread_size_t(&pkt.u.ss_notation.name.len, 2,
1814 &subregion, stream)) {
1815 return 0;
1817 if (!limread_size_t(&pkt.u.ss_notation.value.len, 2,
1818 &subregion, stream)) {
1819 return 0;
1821 if (!limread_data(&pkt.u.ss_notation.name,
1822 pkt.u.ss_notation.name.len,
1823 &subregion, stream)) {
1824 return 0;
1826 if (!limread_data(&pkt.u.ss_notation.value,
1827 pkt.u.ss_notation.value.len,
1828 &subregion, stream)) {
1829 return 0;
1831 break;
1833 case OPS_PTAG_SS_POLICY_URI:
1834 if (!read_string(&pkt.u.ss_policy.url, &subregion, stream)) {
1835 return 0;
1837 break;
1839 case OPS_PTAG_SS_REGEXP:
1840 if (!read_string(&pkt.u.ss_regexp.regexp, &subregion, stream)) {
1841 return 0;
1843 break;
1845 case OPS_PTAG_SS_PREF_KEYSERV:
1846 if (!read_string(&pkt.u.ss_keyserv.name, &subregion, stream)) {
1847 return 0;
1849 break;
1851 case OPS_PTAG_SS_USERDEFINED00:
1852 case OPS_PTAG_SS_USERDEFINED01:
1853 case OPS_PTAG_SS_USERDEFINED02:
1854 case OPS_PTAG_SS_USERDEFINED03:
1855 case OPS_PTAG_SS_USERDEFINED04:
1856 case OPS_PTAG_SS_USERDEFINED05:
1857 case OPS_PTAG_SS_USERDEFINED06:
1858 case OPS_PTAG_SS_USERDEFINED07:
1859 case OPS_PTAG_SS_USERDEFINED08:
1860 case OPS_PTAG_SS_USERDEFINED09:
1861 case OPS_PTAG_SS_USERDEFINED10:
1862 if (!read_data(&pkt.u.ss_userdef.data, &subregion, stream)) {
1863 return 0;
1865 break;
1867 case OPS_PTAG_SS_RESERVED:
1868 if (!read_data(&pkt.u.ss_unknown.data, &subregion, stream)) {
1869 return 0;
1871 break;
1873 case OPS_PTAG_SS_REVOCATION_REASON:
1874 /* first byte is the machine-readable code */
1875 if (!limread(&pkt.u.ss_revocation.code, 1, &subregion, stream)) {
1876 return 0;
1878 /* the rest is a human-readable UTF-8 string */
1879 if (!read_string(&pkt.u.ss_revocation.reason, &subregion,
1880 stream)) {
1881 return 0;
1883 break;
1885 case OPS_PTAG_SS_REVOCATION_KEY:
1886 /* octet 0 = class. Bit 0x80 must be set */
1887 if (!limread(&pkt.u.ss_revocation_key.class, 1,
1888 &subregion, stream)) {
1889 return 0;
1891 if (!(pkt.u.ss_revocation_key.class & 0x80)) {
1892 printf("Warning: OPS_PTAG_SS_REVOCATION_KEY class: "
1893 "Bit 0x80 should be set\n");
1894 return 0;
1896 /* octet 1 = algid */
1897 if (!limread(&pkt.u.ss_revocation_key.algid, 1,
1898 &subregion, stream)) {
1899 return 0;
1901 /* octets 2-21 = fingerprint */
1902 if (!limread(&pkt.u.ss_revocation_key.fingerprint[0],
1903 OPS_FINGERPRINT_SIZE, &subregion, stream)) {
1904 return 0;
1906 break;
1908 default:
1909 if (stream->ss_parsed[t8] & t7) {
1910 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_UNKNOWN_SS,
1911 "Unknown signature subpacket type (%d)",
1912 c & 0x7f);
1914 doread = 0;
1915 break;
1918 /* Application doesn't want it delivered parsed */
1919 if (!(stream->ss_parsed[t8] & t7)) {
1920 if (pkt.critical) {
1921 OPS_ERROR_1(&stream->errors,
1922 OPS_E_PROTO_CRITICAL_SS_IGNORED,
1923 "Critical signature subpacket ignored (%d)",
1924 c & 0x7f);
1926 if (!doread &&
1927 !limskip(subregion.length - 1, &subregion, stream)) {
1928 return 0;
1930 if (doread) {
1931 __ops_parser_content_free(&pkt);
1933 return 1;
1935 if (doread && subregion.readc != subregion.length) {
1936 OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1937 "Unconsumed data (%d)",
1938 subregion.length - subregion.readc);
1939 return 0;
1941 CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
1942 return 1;
1946 * \ingroup Core_ReadPackets
1947 * \brief Parse several signature subpackets.
1949 * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set.
1950 * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the
1951 * entire set is consumed.
1953 * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket.
1955 * \param *ptag Pointer to the Packet Tag.
1956 * \param *reader Our reader
1957 * \param *cb The callback
1958 * \return 1 on success, 0 on error
1960 * \see RFC4880 5.2.3
1962 static int
1963 parse_sig_subpkts(__ops_sig_t *sig,
1964 __ops_region_t *region,
1965 __ops_stream_t *stream)
1967 __ops_region_t subregion;
1968 __ops_packet_t pkt;
1970 __ops_init_subregion(&subregion, region);
1971 if (!limread_scalar(&subregion.length, 2, region, stream)) {
1972 return 0;
1975 if (subregion.length > region->length) {
1976 ERRP(&stream->cbinfo, pkt, "Subpacket set too long");
1979 while (subregion.readc < subregion.length) {
1980 if (!parse_one_sig_subpacket(sig, &subregion, stream)) {
1981 return 0;
1985 if (subregion.readc != subregion.length) {
1986 if (!limskip(subregion.length - subregion.readc,
1987 &subregion, stream)) {
1988 ERRP(&stream->cbinfo, pkt,
1989 "parse_sig_subpkts: subpacket length read mismatch");
1991 ERRP(&stream->cbinfo, pkt, "Subpacket length mismatch");
1993 return 1;
1997 * \ingroup Core_ReadPackets
1998 * \brief Parse a version 4 signature.
2000 * This function parses a version 4 signature including all its hashed and unhashed subpackets.
2002 * Once the signature packet has been parsed successfully, it is passed to the callback.
2004 * \param *ptag Pointer to the Packet Tag.
2005 * \param *reader Our reader
2006 * \param *cb The callback
2007 * \return 1 on success, 0 on error
2009 * \see RFC4880 5.2.3
2011 static int
2012 parse_v4_sig(__ops_region_t *region, __ops_stream_t *stream)
2014 unsigned char c = 0x0;
2015 __ops_packet_t pkt;
2017 /* debug=1; */
2018 if (__ops_get_debug_level(__FILE__)) {
2019 fprintf(stderr, "\nparse_v4_sig\n");
2021 /* clear signature */
2022 (void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
2025 * We need to hash the packet data from version through the hashed
2026 * subpacket data
2029 pkt.u.sig.v4_hashstart = stream->readinfo.alength - 1;
2031 /* Set version,type,algorithms */
2033 pkt.u.sig.info.version = OPS_V4;
2035 if (!limread(&c, 1, region, stream)) {
2036 return 0;
2038 pkt.u.sig.info.type = (__ops_sig_type_t)c;
2039 if (__ops_get_debug_level(__FILE__)) {
2040 fprintf(stderr, "signature type=%d (%s)\n",
2041 pkt.u.sig.info.type,
2042 __ops_show_sig_type(pkt.u.sig.info.type));
2044 /* XXX: check signature type */
2046 if (!limread(&c, 1, region, stream)) {
2047 return 0;
2049 pkt.u.sig.info.key_alg = (__ops_pubkey_alg_t)c;
2050 /* XXX: check algorithm */
2051 if (__ops_get_debug_level(__FILE__)) {
2052 (void) fprintf(stderr, "key_alg=%d (%s)\n",
2053 pkt.u.sig.info.key_alg,
2054 __ops_show_pka(pkt.u.sig.info.key_alg));
2056 if (!limread(&c, 1, region, stream)) {
2057 return 0;
2059 pkt.u.sig.info.hash_alg = (__ops_hash_alg_t)c;
2060 /* XXX: check algorithm */
2061 if (__ops_get_debug_level(__FILE__)) {
2062 fprintf(stderr, "hash_alg=%d %s\n",
2063 pkt.u.sig.info.hash_alg,
2064 __ops_show_hash_alg(pkt.u.sig.info.hash_alg));
2066 CALLBACK(OPS_PTAG_CT_SIGNATURE_HEADER, &stream->cbinfo, &pkt);
2068 if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
2069 return 0;
2072 pkt.u.sig.info.v4_hashlen = stream->readinfo.alength
2073 - pkt.u.sig.v4_hashstart;
2075 /* copy hashed subpackets */
2076 if (pkt.u.sig.info.v4_hashed) {
2077 free(pkt.u.sig.info.v4_hashed);
2079 pkt.u.sig.info.v4_hashed = calloc(1, pkt.u.sig.info.v4_hashlen);
2080 if (pkt.u.sig.info.v4_hashed == NULL) {
2081 (void) fprintf(stderr, "parse_v4_sig: bad alloc\n");
2082 return 0;
2085 if (!stream->readinfo.accumulate) {
2086 /* We must accumulate, else we can't check the signature */
2087 fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
2088 return 0;
2090 (void) memcpy(pkt.u.sig.info.v4_hashed,
2091 stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
2092 pkt.u.sig.info.v4_hashlen);
2094 if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
2095 return 0;
2098 if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
2099 return 0;
2102 switch (pkt.u.sig.info.key_alg) {
2103 case OPS_PKA_RSA:
2104 if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
2105 return 0;
2107 break;
2109 case OPS_PKA_DSA:
2110 if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream)) {
2112 * usually if this fails, it just means we've reached
2113 * the end of the keyring
2115 if (__ops_get_debug_level(__FILE__)) {
2116 (void) fprintf(stderr,
2117 "Error reading DSA r field in signature");
2119 return 0;
2121 if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
2122 ERRP(&stream->cbinfo, pkt,
2123 "Error reading DSA s field in signature");
2125 break;
2127 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
2128 if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
2129 stream) ||
2130 !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
2131 stream)) {
2132 return 0;
2134 break;
2136 case OPS_PKA_PRIVATE00:
2137 case OPS_PKA_PRIVATE01:
2138 case OPS_PKA_PRIVATE02:
2139 case OPS_PKA_PRIVATE03:
2140 case OPS_PKA_PRIVATE04:
2141 case OPS_PKA_PRIVATE05:
2142 case OPS_PKA_PRIVATE06:
2143 case OPS_PKA_PRIVATE07:
2144 case OPS_PKA_PRIVATE08:
2145 case OPS_PKA_PRIVATE09:
2146 case OPS_PKA_PRIVATE10:
2147 if (!read_data(&pkt.u.sig.info.sig.unknown.data, region,
2148 stream)) {
2149 return 0;
2151 break;
2153 default:
2154 OPS_ERROR_1(&stream->errors, OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
2155 "Bad v4 signature key algorithm (%s)",
2156 __ops_show_pka(pkt.u.sig.info.key_alg));
2157 return 0;
2159 if (region->readc != region->length) {
2160 OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
2161 "Unconsumed data (%d)",
2162 region->length - region->readc);
2163 return 0;
2165 CALLBACK(OPS_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
2166 return 1;
2170 * \ingroup Core_ReadPackets
2171 * \brief Parse a signature subpacket.
2173 * This function calls the appropriate function to handle v3 or v4 signatures.
2175 * Once the signature packet has been parsed successfully, it is passed to the callback.
2177 * \param *ptag Pointer to the Packet Tag.
2178 * \param *reader Our reader
2179 * \param *cb The callback
2180 * \return 1 on success, 0 on error
2182 static int
2183 parse_sig(__ops_region_t *region, __ops_stream_t *stream)
2185 unsigned char c = 0x0;
2186 __ops_packet_t pkt;
2188 if (region->readc != 0) {
2189 /* We should not have read anything so far */
2190 (void) fprintf(stderr, "parse_sig: bad length\n");
2191 return 0;
2194 (void) memset(&pkt, 0x0, sizeof(pkt));
2195 if (!limread(&c, 1, region, stream)) {
2196 return 0;
2198 if (c == 2 || c == 3) {
2199 return parse_v3_sig(region, stream);
2201 if (c == 4) {
2202 return parse_v4_sig(region, stream);
2204 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_SIGNATURE_VRSN,
2205 "Bad signature version (%d)", c);
2206 return 0;
2210 \ingroup Core_ReadPackets
2211 \brief Parse Compressed packet
2213 static int
2214 parse_compressed(__ops_region_t *region, __ops_stream_t *stream)
2216 __ops_packet_t pkt;
2217 unsigned char c = 0x0;
2219 if (!limread(&c, 1, region, stream)) {
2220 return 0;
2223 pkt.u.compressed.type = (__ops_compression_type_t)c;
2225 CALLBACK(OPS_PTAG_CT_COMPRESSED, &stream->cbinfo, &pkt);
2228 * The content of a compressed data packet is more OpenPGP packets
2229 * once decompressed, so recursively handle them
2232 return __ops_decompress(region, stream, pkt.u.compressed.type);
2235 /* XXX: this could be improved by sharing all hashes that are the */
2236 /* same, then duping them just before checking the signature. */
2237 static void
2238 parse_hash_init(__ops_stream_t *stream, __ops_hash_alg_t type,
2239 const unsigned char *keyid)
2241 __ops_hashtype_t *hash;
2243 hash = realloc(stream->hashes,
2244 (stream->hashc + 1) * sizeof(*stream->hashes));
2245 if (hash == NULL) {
2246 (void) fprintf(stderr, "parse_hash_init: bad alloc 0\n");
2247 /* just continue and die here */
2248 /* XXX - agc - no way to return failure */
2249 } else {
2250 stream->hashes = hash;
2252 hash = &stream->hashes[stream->hashc++];
2254 __ops_hash_any(&hash->hash, type);
2255 if (!hash->hash.init(&hash->hash)) {
2256 (void) fprintf(stderr, "parse_hash_init: bad alloc\n");
2257 /* just continue and die here */
2258 /* XXX - agc - no way to return failure */
2260 (void) memcpy(hash->keyid, keyid, sizeof(hash->keyid));
2264 \ingroup Core_ReadPackets
2265 \brief Parse a One Pass Signature packet
2267 static int
2268 parse_one_pass(__ops_region_t * region, __ops_stream_t * stream)
2270 unsigned char c = 0x0;
2271 __ops_packet_t pkt;
2273 if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) {
2274 return 0;
2276 if (pkt.u.one_pass_sig.version != 3) {
2277 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN,
2278 "Bad one-pass signature version (%d)",
2279 pkt.u.one_pass_sig.version);
2280 return 0;
2282 if (!limread(&c, 1, region, stream)) {
2283 return 0;
2285 pkt.u.one_pass_sig.sig_type = (__ops_sig_type_t)c;
2287 if (!limread(&c, 1, region, stream)) {
2288 return 0;
2290 pkt.u.one_pass_sig.hash_alg = (__ops_hash_alg_t)c;
2292 if (!limread(&c, 1, region, stream)) {
2293 return 0;
2295 pkt.u.one_pass_sig.key_alg = (__ops_pubkey_alg_t)c;
2297 if (!limread(pkt.u.one_pass_sig.keyid,
2298 sizeof(pkt.u.one_pass_sig.keyid), region, stream)) {
2299 return 0;
2302 if (!limread(&c, 1, region, stream)) {
2303 return 0;
2305 pkt.u.one_pass_sig.nested = !!c;
2306 CALLBACK(OPS_PTAG_CT_1_PASS_SIG, &stream->cbinfo, &pkt);
2307 /* XXX: we should, perhaps, let the app choose whether to hash or not */
2308 parse_hash_init(stream, pkt.u.one_pass_sig.hash_alg,
2309 pkt.u.one_pass_sig.keyid);
2310 return 1;
2314 \ingroup Core_ReadPackets
2315 \brief Parse a Trust packet
2317 static int
2318 parse_trust(__ops_region_t *region, __ops_stream_t *stream)
2320 __ops_packet_t pkt;
2322 if (!read_data(&pkt.u.trust.data, region, stream)) {
2323 return 0;
2325 CALLBACK(OPS_PTAG_CT_TRUST, &stream->cbinfo, &pkt);
2326 return 1;
2329 static void
2330 parse_hash_data(__ops_stream_t *stream, const void *data,
2331 size_t length)
2333 size_t n;
2335 for (n = 0; n < stream->hashc; ++n) {
2336 stream->hashes[n].hash.add(&stream->hashes[n].hash, data, length);
2341 \ingroup Core_ReadPackets
2342 \brief Parse a Literal Data packet
2344 static int
2345 parse_litdata(__ops_region_t *region, __ops_stream_t *stream)
2347 __ops_memory_t *mem;
2348 __ops_packet_t pkt;
2349 unsigned char c = 0x0;
2351 if (!limread(&c, 1, region, stream)) {
2352 return 0;
2354 pkt.u.litdata_header.format = (__ops_litdata_type_t)c;
2355 if (!limread(&c, 1, region, stream)) {
2356 return 0;
2358 if (!limread((unsigned char *)pkt.u.litdata_header.filename,
2359 (unsigned)c, region, stream)) {
2360 return 0;
2362 pkt.u.litdata_header.filename[c] = '\0';
2363 if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) {
2364 return 0;
2366 CALLBACK(OPS_PTAG_CT_LITDATA_HEADER, &stream->cbinfo, &pkt);
2367 mem = pkt.u.litdata_body.mem = __ops_memory_new();
2368 __ops_memory_init(pkt.u.litdata_body.mem,
2369 (unsigned)((region->length * 101) / 100) + 12);
2370 pkt.u.litdata_body.data = mem->buf;
2372 while (region->readc < region->length) {
2373 unsigned readc = region->length - region->readc;
2375 if (!limread(mem->buf, readc, region, stream)) {
2376 return 0;
2378 pkt.u.litdata_body.length = readc;
2379 parse_hash_data(stream, pkt.u.litdata_body.data, region->length);
2380 CALLBACK(OPS_PTAG_CT_LITDATA_BODY, &stream->cbinfo, &pkt);
2383 /* XXX - get rid of mem here? */
2385 return 1;
2389 * \ingroup Core_Create
2391 * __ops_seckey_free() frees the memory associated with "key". Note that
2392 * the key itself is not freed.
2394 * \param key
2397 void
2398 __ops_seckey_free(__ops_seckey_t *key)
2400 switch (key->pubkey.alg) {
2401 case OPS_PKA_RSA:
2402 case OPS_PKA_RSA_ENCRYPT_ONLY:
2403 case OPS_PKA_RSA_SIGN_ONLY:
2404 free_BN(&key->key.rsa.d);
2405 free_BN(&key->key.rsa.p);
2406 free_BN(&key->key.rsa.q);
2407 free_BN(&key->key.rsa.u);
2408 break;
2410 case OPS_PKA_DSA:
2411 free_BN(&key->key.dsa.x);
2412 break;
2414 default:
2415 (void) fprintf(stderr,
2416 "__ops_seckey_free: Unknown algorithm: %d (%s)\n",
2417 key->pubkey.alg,
2418 __ops_show_pka(key->pubkey.alg));
2420 free(key->checkhash);
2421 __ops_pubkey_free(&key->pubkey);
2424 static int
2425 consume_packet(__ops_region_t *region, __ops_stream_t *stream, unsigned warn)
2427 __ops_packet_t pkt;
2428 __ops_data_t remainder;
2430 if (region->indeterminate) {
2431 ERRP(&stream->cbinfo, pkt,
2432 "Can't consume indeterminate packets");
2435 if (read_data(&remainder, region, stream)) {
2436 /* now throw it away */
2437 data_free(&remainder);
2438 if (warn) {
2439 OPS_ERROR(&stream->errors, OPS_E_P_PACKET_CONSUMED,
2440 "Warning: packet consumer");
2442 return 1;
2444 OPS_ERROR(&stream->errors, OPS_E_P_PACKET_NOT_CONSUMED,
2445 (warn) ? "Warning: Packet was not consumed" :
2446 "Packet was not consumed");
2447 return warn;
2451 * \ingroup Core_ReadPackets
2452 * \brief Parse a secret key
2454 static int
2455 parse_seckey(__ops_region_t *region, __ops_stream_t *stream)
2457 __ops_packet_t pkt;
2458 __ops_region_t encregion;
2459 __ops_region_t *saved_region = NULL;
2460 unsigned char c = 0x0;
2461 __ops_crypt_t decrypt;
2462 __ops_hash_t checkhash;
2463 unsigned blocksize;
2464 unsigned crypted;
2465 int ret = 1;
2467 if (__ops_get_debug_level(__FILE__)) {
2468 fprintf(stderr, "\n---------\nparse_seckey:\n");
2469 fprintf(stderr,
2470 "region length=%u, readc=%u, remainder=%u\n",
2471 region->length, region->readc,
2472 region->length - region->readc);
2474 (void) memset(&pkt, 0x0, sizeof(pkt));
2475 if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) {
2476 return 0;
2478 if (__ops_get_debug_level(__FILE__)) {
2479 fprintf(stderr, "parse_seckey: public key parsed\n");
2480 __ops_print_pubkey(&pkt.u.seckey.pubkey);
2482 stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != OPS_V4);
2484 if (!limread(&c, 1, region, stream)) {
2485 return 0;
2487 pkt.u.seckey.s2k_usage = (__ops_s2k_usage_t)c;
2489 if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED ||
2490 pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2491 if (!limread(&c, 1, region, stream)) {
2492 return 0;
2494 pkt.u.seckey.alg = (__ops_symm_alg_t)c;
2495 if (!limread(&c, 1, region, stream)) {
2496 return 0;
2498 pkt.u.seckey.s2k_specifier = (__ops_s2k_specifier_t)c;
2499 switch (pkt.u.seckey.s2k_specifier) {
2500 case OPS_S2KS_SIMPLE:
2501 case OPS_S2KS_SALTED:
2502 case OPS_S2KS_ITERATED_AND_SALTED:
2503 break;
2504 default:
2505 (void) fprintf(stderr,
2506 "parse_seckey: bad seckey\n");
2507 return 0;
2509 if (!limread(&c, 1, region, stream)) {
2510 return 0;
2512 pkt.u.seckey.hash_alg = (__ops_hash_alg_t)c;
2513 if (pkt.u.seckey.s2k_specifier != OPS_S2KS_SIMPLE &&
2514 !limread(pkt.u.seckey.salt, 8, region, stream)) {
2515 return 0;
2517 if (pkt.u.seckey.s2k_specifier ==
2518 OPS_S2KS_ITERATED_AND_SALTED) {
2519 if (!limread(&c, 1, region, stream)) {
2520 return 0;
2522 pkt.u.seckey.octetc =
2523 (16 + ((unsigned)c & 15)) <<
2524 (((unsigned)c >> 4) + 6);
2526 } else if (pkt.u.seckey.s2k_usage != OPS_S2KU_NONE) {
2527 /* this is V3 style, looks just like a V4 simple hash */
2528 pkt.u.seckey.alg = (__ops_symm_alg_t)c;
2529 pkt.u.seckey.s2k_usage = OPS_S2KU_ENCRYPTED;
2530 pkt.u.seckey.s2k_specifier = OPS_S2KS_SIMPLE;
2531 pkt.u.seckey.hash_alg = OPS_HASH_MD5;
2533 crypted = pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED ||
2534 pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED;
2536 if (crypted) {
2537 __ops_packet_t seckey;
2538 unsigned char key[OPS_MAX_KEY_SIZE + OPS_MAX_HASH_SIZE];
2539 __ops_hash_t hashes[(OPS_MAX_KEY_SIZE + OPS_MIN_HASH_SIZE - 1) / OPS_MIN_HASH_SIZE];
2540 size_t passlen;
2541 char *passphrase;
2542 int hashsize;
2543 int keysize;
2544 int n;
2546 blocksize = __ops_block_size(pkt.u.seckey.alg);
2547 if (blocksize == 0 || blocksize > OPS_MAX_BLOCK_SIZE) {
2548 (void) fprintf(stderr,
2549 "parse_seckey: bad blocksize\n");
2550 return 0;
2553 if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) {
2554 return 0;
2556 (void) memset(&seckey, 0x0, sizeof(seckey));
2557 passphrase = NULL;
2558 seckey.u.skey_passphrase.passphrase = &passphrase;
2559 seckey.u.skey_passphrase.seckey = &pkt.u.seckey;
2560 CALLBACK(OPS_GET_PASSPHRASE, &stream->cbinfo, &seckey);
2561 if (!passphrase) {
2562 if (__ops_get_debug_level(__FILE__)) {
2563 /* \todo make into proper error */
2564 (void) fprintf(stderr,
2565 "parse_seckey: can't get passphrase\n");
2567 if (!consume_packet(region, stream, 0)) {
2568 return 0;
2571 CALLBACK(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY,
2572 &stream->cbinfo, &pkt);
2574 return 1;
2576 keysize = __ops_key_size(pkt.u.seckey.alg);
2577 if (keysize == 0 || keysize > OPS_MAX_KEY_SIZE) {
2578 (void) fprintf(stderr,
2579 "parse_seckey: bad keysize\n");
2580 return 0;
2583 hashsize = __ops_hash_size(pkt.u.seckey.hash_alg);
2584 if (hashsize == 0 || hashsize > OPS_MAX_HASH_SIZE) {
2585 (void) fprintf(stderr,
2586 "parse_seckey: bad hashsize\n");
2587 return 0;
2590 for (n = 0; n * hashsize < keysize; ++n) {
2591 int i;
2593 __ops_hash_any(&hashes[n],
2594 pkt.u.seckey.hash_alg);
2595 if (!hashes[n].init(&hashes[n])) {
2596 (void) fprintf(stderr,
2597 "parse_seckey: bad alloc\n");
2598 return 0;
2600 /* preload hashes with zeroes... */
2601 for (i = 0; i < n; ++i) {
2602 hashes[n].add(&hashes[n],
2603 (const unsigned char *) "", 1);
2606 passlen = strlen(passphrase);
2607 for (n = 0; n * hashsize < keysize; ++n) {
2608 unsigned i;
2610 switch (pkt.u.seckey.s2k_specifier) {
2611 case OPS_S2KS_SALTED:
2612 hashes[n].add(&hashes[n],
2613 pkt.u.seckey.salt,
2614 OPS_SALT_SIZE);
2615 /* FALLTHROUGH */
2616 case OPS_S2KS_SIMPLE:
2617 hashes[n].add(&hashes[n],
2618 (unsigned char *) passphrase, passlen);
2619 break;
2621 case OPS_S2KS_ITERATED_AND_SALTED:
2622 for (i = 0; i < pkt.u.seckey.octetc;
2623 i += passlen + OPS_SALT_SIZE) {
2624 unsigned j;
2626 j = passlen + OPS_SALT_SIZE;
2627 if (i + j > pkt.u.seckey.octetc && i != 0) {
2628 j = pkt.u.seckey.octetc - i;
2630 hashes[n].add(&hashes[n],
2631 pkt.u.seckey.salt,
2632 (unsigned)(j > OPS_SALT_SIZE) ?
2633 OPS_SALT_SIZE : j);
2634 if (j > OPS_SALT_SIZE) {
2635 hashes[n].add(&hashes[n],
2636 (unsigned char *) passphrase,
2637 j - OPS_SALT_SIZE);
2640 break;
2641 default:
2642 break;
2646 for (n = 0; n * hashsize < keysize; ++n) {
2647 int r;
2649 r = hashes[n].finish(&hashes[n], key + n * hashsize);
2650 if (r != hashsize) {
2651 (void) fprintf(stderr,
2652 "parse_seckey: bad r\n");
2653 return 0;
2657 __ops_forget(passphrase, passlen);
2659 __ops_crypt_any(&decrypt, pkt.u.seckey.alg);
2660 if (__ops_get_debug_level(__FILE__)) {
2661 unsigned i;
2663 fprintf(stderr, "\nREADING:\niv=");
2664 for (i = 0;
2665 i < __ops_block_size(pkt.u.seckey.alg);
2666 i++) {
2667 fprintf(stderr, "%02x ", pkt.u.seckey.iv[i]);
2669 fprintf(stderr, "\nkey=");
2670 for (i = 0; i < CAST_KEY_LENGTH; i++) {
2671 fprintf(stderr, "%02x ", key[i]);
2673 fprintf(stderr, "\n");
2675 decrypt.set_iv(&decrypt, pkt.u.seckey.iv);
2676 decrypt.set_crypt_key(&decrypt, key);
2678 /* now read encrypted data */
2680 __ops_reader_push_decrypt(stream, &decrypt, region);
2683 * Since all known encryption for PGP doesn't compress, we
2684 * can limit to the same length as the current region (for
2685 * now).
2687 __ops_init_subregion(&encregion, NULL);
2688 encregion.length = region->length - region->readc;
2689 if (pkt.u.seckey.pubkey.version != OPS_V4) {
2690 encregion.length -= 2;
2692 saved_region = region;
2693 region = &encregion;
2695 if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2696 pkt.u.seckey.checkhash = calloc(1, OPS_CHECKHASH_SIZE);
2697 if (pkt.u.seckey.checkhash == NULL) {
2698 (void) fprintf(stderr, "parse_seckey: bad alloc\n");
2699 return 0;
2701 __ops_hash_sha1(&checkhash);
2702 __ops_reader_push_hash(stream, &checkhash);
2703 } else {
2704 __ops_reader_push_sum16(stream);
2707 switch (pkt.u.seckey.pubkey.alg) {
2708 case OPS_PKA_RSA:
2709 case OPS_PKA_RSA_ENCRYPT_ONLY:
2710 case OPS_PKA_RSA_SIGN_ONLY:
2711 if (!limread_mpi(&pkt.u.seckey.key.rsa.d, region, stream) ||
2712 !limread_mpi(&pkt.u.seckey.key.rsa.p, region, stream) ||
2713 !limread_mpi(&pkt.u.seckey.key.rsa.q, region, stream) ||
2714 !limread_mpi(&pkt.u.seckey.key.rsa.u, region, stream)) {
2715 ret = 0;
2717 break;
2719 case OPS_PKA_DSA:
2720 if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) {
2721 ret = 0;
2723 break;
2725 default:
2726 OPS_ERROR_2(&stream->errors,
2727 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2728 "Unsupported Public Key algorithm %d (%s)",
2729 pkt.u.seckey.pubkey.alg,
2730 __ops_show_pka(pkt.u.seckey.pubkey.alg));
2731 ret = 0;
2734 if (__ops_get_debug_level(__FILE__)) {
2735 (void) fprintf(stderr, "4 MPIs read\n");
2737 stream->reading_v3_secret = 0;
2739 if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2740 unsigned char hash[OPS_CHECKHASH_SIZE];
2742 __ops_reader_pop_hash(stream);
2743 checkhash.finish(&checkhash, hash);
2745 if (crypted &&
2746 pkt.u.seckey.pubkey.version != OPS_V4) {
2747 __ops_reader_pop_decrypt(stream);
2748 region = saved_region;
2750 if (ret) {
2751 if (!limread(pkt.u.seckey.checkhash,
2752 OPS_CHECKHASH_SIZE, region, stream)) {
2753 return 0;
2756 if (memcmp(hash, pkt.u.seckey.checkhash,
2757 OPS_CHECKHASH_SIZE) != 0) {
2758 ERRP(&stream->cbinfo, pkt,
2759 "Hash mismatch in secret key");
2762 } else {
2763 unsigned short sum;
2765 sum = __ops_reader_pop_sum16(stream);
2766 if (crypted &&
2767 pkt.u.seckey.pubkey.version != OPS_V4) {
2768 __ops_reader_pop_decrypt(stream);
2769 region = saved_region;
2771 if (ret) {
2772 if (!limread_scalar(&pkt.u.seckey.checksum, 2,
2773 region, stream))
2774 return 0;
2776 if (sum != pkt.u.seckey.checksum) {
2777 ERRP(&stream->cbinfo, pkt,
2778 "Checksum mismatch in secret key");
2783 if (crypted && pkt.u.seckey.pubkey.version == OPS_V4) {
2784 __ops_reader_pop_decrypt(stream);
2786 if (region == NULL) {
2787 (void) fprintf(stderr, "parse_seckey: NULL region\n");
2788 return 0;
2790 if (ret && region->readc != region->length) {
2791 (void) fprintf(stderr, "parse_seckey: bad length\n");
2792 return 0;
2794 if (!ret) {
2795 return 0;
2797 CALLBACK(OPS_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
2798 if (__ops_get_debug_level(__FILE__)) {
2799 (void) fprintf(stderr, "--- end of parse_seckey\n\n");
2801 return 1;
2805 \ingroup Core_ReadPackets
2806 \brief Parse a Public Key Session Key packet
2808 static int
2809 parse_pk_sesskey(__ops_region_t *region,
2810 __ops_stream_t *stream)
2812 const __ops_seckey_t *secret;
2813 __ops_packet_t sesskey;
2814 __ops_packet_t pkt;
2815 unsigned char *iv;
2816 unsigned char c = 0x0;
2817 unsigned char cs[2];
2818 unsigned k;
2819 BIGNUM *enc_m;
2820 int n;
2822 /* Can't rely on it being CAST5 */
2823 /* \todo FIXME RW */
2824 /* const size_t sz_unencoded_m_buf=CAST_KEY_LENGTH+1+2; */
2825 unsigned char unencoded_m_buf[1024];
2827 if (!limread(&c, 1, region, stream)) {
2828 return 0;
2830 pkt.u.pk_sesskey.version = (__ops_pk_sesskey_version_t)c;
2831 if (pkt.u.pk_sesskey.version != OPS_PKSK_V3) {
2832 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_PKSK_VRSN,
2833 "Bad public-key encrypted session key version (%d)",
2834 pkt.u.pk_sesskey.version);
2835 return 0;
2837 if (!limread(pkt.u.pk_sesskey.key_id,
2838 sizeof(pkt.u.pk_sesskey.key_id), region, stream)) {
2839 return 0;
2841 if (__ops_get_debug_level(__FILE__)) {
2842 int i;
2843 int x = sizeof(pkt.u.pk_sesskey.key_id);
2845 printf("session key: public key id: x=%d\n", x);
2846 for (i = 0; i < x; i++) {
2847 printf("%2x ", pkt.u.pk_sesskey.key_id[i]);
2849 printf("\n");
2851 if (!limread(&c, 1, region, stream)) {
2852 return 0;
2854 pkt.u.pk_sesskey.alg = (__ops_pubkey_alg_t)c;
2855 switch (pkt.u.pk_sesskey.alg) {
2856 case OPS_PKA_RSA:
2857 if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m,
2858 region, stream)) {
2859 return 0;
2861 enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m;
2862 break;
2864 case OPS_PKA_ELGAMAL:
2865 if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k,
2866 region, stream) ||
2867 !limread_mpi(
2868 &pkt.u.pk_sesskey.params.elgamal.encrypted_m,
2869 region, stream)) {
2870 return 0;
2872 enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m;
2873 break;
2875 default:
2876 OPS_ERROR_1(&stream->errors,
2877 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2878 "Unknown public key algorithm in session key (%s)",
2879 __ops_show_pka(pkt.u.pk_sesskey.alg));
2880 return 0;
2883 (void) memset(&sesskey, 0x0, sizeof(sesskey));
2884 secret = NULL;
2885 sesskey.u.get_seckey.seckey = &secret;
2886 sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey;
2888 CALLBACK(OPS_GET_SECKEY, &stream->cbinfo, &sesskey);
2890 if (!secret) {
2891 CALLBACK(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo,
2892 &pkt);
2893 return 1;
2895 n = __ops_decrypt_decode_mpi(unencoded_m_buf, sizeof(unencoded_m_buf),
2896 enc_m, secret);
2897 if (n < 1) {
2898 ERRP(&stream->cbinfo, pkt, "decrypted message too short");
2899 return 0;
2902 /* PKA */
2903 pkt.u.pk_sesskey.symm_alg = (__ops_symm_alg_t)unencoded_m_buf[0];
2905 if (!__ops_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
2906 /* ERR1P */
2907 OPS_ERROR_1(&stream->errors, OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG,
2908 "Symmetric algorithm %s not supported",
2909 __ops_show_symm_alg(
2910 pkt.u.pk_sesskey.symm_alg));
2911 return 0;
2913 k = __ops_key_size(pkt.u.pk_sesskey.symm_alg);
2915 if ((unsigned) n != k + 3) {
2916 OPS_ERROR_2(&stream->errors, OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN,
2917 "decrypted message wrong length (got %d expected %d)",
2918 n, k + 3);
2919 return 0;
2921 if (k > sizeof(pkt.u.pk_sesskey.key)) {
2922 (void) fprintf(stderr, "parse_pk_sesskey: bad keylength\n");
2923 return 0;
2926 (void) memcpy(pkt.u.pk_sesskey.key, unencoded_m_buf + 1, k);
2928 if (__ops_get_debug_level(__FILE__)) {
2929 unsigned int j;
2930 printf("session key recovered (len=%u):\n", k);
2931 for (j = 0; j < k; j++)
2932 printf("%2x ", pkt.u.pk_sesskey.key[j]);
2933 printf("\n");
2935 pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] +
2936 (unencoded_m_buf[k + 2] << 8);
2937 if (__ops_get_debug_level(__FILE__)) {
2938 printf("session key checksum: %2x %2x\n",
2939 unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]);
2942 /* Check checksum */
2943 __ops_calc_sesskey_checksum(&pkt.u.pk_sesskey, &cs[0]);
2944 if (unencoded_m_buf[k + 1] != cs[0] ||
2945 unencoded_m_buf[k + 2] != cs[1]) {
2946 OPS_ERROR_4(&stream->errors, OPS_E_PROTO_BAD_SK_CHECKSUM,
2947 "Session key checksum wrong: expected %2x %2x, got %2x %2x",
2948 cs[0], cs[1], unencoded_m_buf[k + 1],
2949 unencoded_m_buf[k + 2]);
2950 return 0;
2952 /* all is well */
2953 CALLBACK(OPS_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt);
2955 __ops_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg);
2956 iv = calloc(1, stream->decrypt.blocksize);
2957 if (iv == NULL) {
2958 (void) fprintf(stderr, "parse_pk_sesskey: bad alloc\n");
2959 return 0;
2961 stream->decrypt.set_iv(&stream->decrypt, iv);
2962 stream->decrypt.set_crypt_key(&stream->decrypt, pkt.u.pk_sesskey.key);
2963 __ops_encrypt_init(&stream->decrypt);
2964 free(iv);
2965 return 1;
2968 static int
2969 __ops_decrypt_se_data(__ops_content_tag_t tag, __ops_region_t *region,
2970 __ops_stream_t *stream)
2972 __ops_crypt_t *decrypt;
2973 const int printerrors = 1;
2974 int r = 1;
2976 decrypt = __ops_get_decrypt(stream);
2977 if (decrypt) {
2978 unsigned char buf[OPS_MAX_BLOCK_SIZE + 2] = "";
2979 size_t b = decrypt->blocksize;
2980 /* __ops_packet_t pkt; */
2981 __ops_region_t encregion;
2984 __ops_reader_push_decrypt(stream, decrypt, region);
2986 __ops_init_subregion(&encregion, NULL);
2987 encregion.length = b + 2;
2989 if (!exact_limread(buf, b + 2, &encregion, stream)) {
2990 return 0;
2992 if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
2993 __ops_reader_pop_decrypt(stream);
2994 OPS_ERROR_4(&stream->errors,
2995 OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT,
2996 "Bad symmetric decrypt (%02x%02x vs %02x%02x)",
2997 buf[b - 2], buf[b - 1], buf[b], buf[b + 1]);
2998 return 0;
3000 if (tag == OPS_PTAG_CT_SE_DATA_BODY) {
3001 decrypt->decrypt_resync(decrypt);
3002 decrypt->block_encrypt(decrypt, decrypt->civ,
3003 decrypt->civ);
3005 r = __ops_parse(stream, !printerrors);
3007 __ops_reader_pop_decrypt(stream);
3008 } else {
3009 __ops_packet_t pkt;
3011 while (region->readc < region->length) {
3012 unsigned len;
3014 len = region->length - region->readc;
3015 if (len > sizeof(pkt.u.se_data_body.data))
3016 len = sizeof(pkt.u.se_data_body.data);
3018 if (!limread(pkt.u.se_data_body.data, len,
3019 region, stream)) {
3020 return 0;
3022 pkt.u.se_data_body.length = len;
3023 CALLBACK(tag, &stream->cbinfo, &pkt);
3027 return r;
3030 static int
3031 __ops_decrypt_se_ip_data(__ops_content_tag_t tag, __ops_region_t *region,
3032 __ops_stream_t *stream)
3034 __ops_crypt_t *decrypt;
3035 const int printerrors = 1;
3036 int r = 1;
3038 decrypt = __ops_get_decrypt(stream);
3039 if (decrypt) {
3040 __ops_reader_push_decrypt(stream, decrypt, region);
3041 __ops_reader_push_se_ip_data(stream, decrypt, region);
3043 r = __ops_parse(stream, !printerrors);
3045 __ops_reader_pop_se_ip_data(stream);
3046 __ops_reader_pop_decrypt(stream);
3047 } else {
3048 __ops_packet_t pkt;
3050 while (region->readc < region->length) {
3051 unsigned len;
3053 len = region->length - region->readc;
3054 if (len > sizeof(pkt.u.se_data_body.data)) {
3055 len = sizeof(pkt.u.se_data_body.data);
3058 if (!limread(pkt.u.se_data_body.data,
3059 len, region, stream)) {
3060 return 0;
3063 pkt.u.se_data_body.length = len;
3065 CALLBACK(tag, &stream->cbinfo, &pkt);
3069 return r;
3073 \ingroup Core_ReadPackets
3074 \brief Read a Symmetrically Encrypted packet
3076 static int
3077 parse_se_data(__ops_region_t *region, __ops_stream_t *stream)
3079 __ops_packet_t pkt;
3081 /* there's no info to go with this, so just announce it */
3082 CALLBACK(OPS_PTAG_CT_SE_DATA_HEADER, &stream->cbinfo, &pkt);
3085 * The content of an encrypted data packet is more OpenPGP packets
3086 * once decrypted, so recursively handle them
3088 return __ops_decrypt_se_data(OPS_PTAG_CT_SE_DATA_BODY, region, stream);
3092 \ingroup Core_ReadPackets
3093 \brief Read a Symmetrically Encrypted Integrity Protected packet
3095 static int
3096 parse_se_ip_data(__ops_region_t *region, __ops_stream_t *stream)
3098 __ops_packet_t pkt;
3099 unsigned char c = 0x0;
3101 if (!limread(&c, 1, region, stream)) {
3102 return 0;
3104 pkt.u.se_ip_data_header.version = (__ops_se_ip_version_t)c;
3106 if (pkt.u.se_ip_data_header.version != OPS_SE_IP_V1) {
3107 (void) fprintf(stderr, "parse_se_ip_data: bad version\n");
3108 return 0;
3112 * The content of an encrypted data packet is more OpenPGP packets
3113 * once decrypted, so recursively handle them
3115 return __ops_decrypt_se_ip_data(OPS_PTAG_CT_SE_IP_DATA_BODY, region,
3116 stream);
3120 \ingroup Core_ReadPackets
3121 \brief Read a MDC packet
3123 static int
3124 parse_mdc(__ops_region_t *region, __ops_stream_t *stream)
3126 __ops_packet_t pkt;
3128 pkt.u.mdc.length = OPS_SHA1_HASH_SIZE;
3129 if ((pkt.u.mdc.data = calloc(1, OPS_SHA1_HASH_SIZE)) == NULL) {
3130 (void) fprintf(stderr, "parse_mdc: bad alloc\n");
3131 return 0;
3133 if (!limread(pkt.u.mdc.data, OPS_SHA1_HASH_SIZE, region, stream)) {
3134 return 0;
3136 CALLBACK(OPS_PTAG_CT_MDC, &stream->cbinfo, &pkt);
3137 free(pkt.u.mdc.data);
3138 return 1;
3142 * \ingroup Core_ReadPackets
3143 * \brief Parse one packet.
3145 * This function parses the packet tag. It computes the value of the
3146 * content tag and then calls the appropriate function to handle the
3147 * content.
3149 * \param *stream How to parse
3150 * \param *pktlen On return, will contain number of bytes in packet
3151 * \return 1 on success, 0 on error, -1 on EOF */
3152 static int
3153 __ops_parse_packet(__ops_stream_t *stream, unsigned long *pktlen)
3155 __ops_packet_t pkt;
3156 __ops_region_t region;
3157 unsigned char ptag;
3158 unsigned indeterminate = 0;
3159 int ret;
3161 pkt.u.ptag.position = stream->readinfo.position;
3163 ret = base_read(&ptag, 1, stream);
3165 if (__ops_get_debug_level(__FILE__)) {
3166 (void) fprintf(stderr,
3167 "__ops_parse_packet: base_read returned %d\n",
3168 ret);
3171 /* errors in the base read are effectively EOF. */
3172 if (ret <= 0) {
3173 return -1;
3176 *pktlen = 0;
3178 if (!(ptag & OPS_PTAG_ALWAYS_SET)) {
3179 pkt.u.error.error = "Format error (ptag bit not set)";
3180 CALLBACK(OPS_PARSER_ERROR, &stream->cbinfo, &pkt);
3181 return 0;
3183 pkt.u.ptag.new_format = !!(ptag & OPS_PTAG_NEW_FORMAT);
3184 if (pkt.u.ptag.new_format) {
3185 pkt.u.ptag.type = (ptag & OPS_PTAG_NF_CONTENT_TAG_MASK);
3186 pkt.u.ptag.length_type = 0;
3187 if (!read_new_length(&pkt.u.ptag.length, stream)) {
3188 return 0;
3190 } else {
3191 unsigned rb;
3193 rb = 0;
3194 pkt.u.ptag.type = ((unsigned)ptag &
3195 OPS_PTAG_OF_CONTENT_TAG_MASK)
3196 >> OPS_PTAG_OF_CONTENT_TAG_SHIFT;
3197 pkt.u.ptag.length_type = ptag & OPS_PTAG_OF_LENGTH_TYPE_MASK;
3198 switch (pkt.u.ptag.length_type) {
3199 case OPS_PTAG_OLD_LEN_1:
3200 rb = _read_scalar(&pkt.u.ptag.length, 1, stream);
3201 break;
3203 case OPS_PTAG_OLD_LEN_2:
3204 rb = _read_scalar(&pkt.u.ptag.length, 2, stream);
3205 break;
3207 case OPS_PTAG_OLD_LEN_4:
3208 rb = _read_scalar(&pkt.u.ptag.length, 4, stream);
3209 break;
3211 case OPS_PTAG_OLD_LEN_INDETERMINATE:
3212 pkt.u.ptag.length = 0;
3213 indeterminate = 1;
3214 rb = 1;
3215 break;
3217 if (!rb) {
3218 return 0;
3222 CALLBACK(OPS_PARSER_PTAG, &stream->cbinfo, &pkt);
3224 __ops_init_subregion(&region, NULL);
3225 region.length = pkt.u.ptag.length;
3226 region.indeterminate = indeterminate;
3227 if (__ops_get_debug_level(__FILE__)) {
3228 (void) fprintf(stderr, "__ops_parse_packet: type %u\n",
3229 pkt.u.ptag.type);
3231 switch (pkt.u.ptag.type) {
3232 case OPS_PTAG_CT_SIGNATURE:
3233 ret = parse_sig(&region, stream);
3234 break;
3236 case OPS_PTAG_CT_PUBLIC_KEY:
3237 case OPS_PTAG_CT_PUBLIC_SUBKEY:
3238 ret = parse_pubkey(pkt.u.ptag.type, &region, stream);
3239 break;
3241 case OPS_PTAG_CT_TRUST:
3242 ret = parse_trust(&region, stream);
3243 break;
3245 case OPS_PTAG_CT_USER_ID:
3246 ret = parse_userid(&region, stream);
3247 break;
3249 case OPS_PTAG_CT_COMPRESSED:
3250 ret = parse_compressed(&region, stream);
3251 break;
3253 case OPS_PTAG_CT_1_PASS_SIG:
3254 ret = parse_one_pass(&region, stream);
3255 break;
3257 case OPS_PTAG_CT_LITDATA:
3258 ret = parse_litdata(&region, stream);
3259 break;
3261 case OPS_PTAG_CT_USER_ATTR:
3262 ret = parse_userattr(&region, stream);
3263 break;
3265 case OPS_PTAG_CT_SECRET_KEY:
3266 ret = parse_seckey(&region, stream);
3267 break;
3269 case OPS_PTAG_CT_SECRET_SUBKEY:
3270 ret = parse_seckey(&region, stream);
3271 break;
3273 case OPS_PTAG_CT_PK_SESSION_KEY:
3274 ret = parse_pk_sesskey(&region, stream);
3275 break;
3277 case OPS_PTAG_CT_SE_DATA:
3278 ret = parse_se_data(&region, stream);
3279 break;
3281 case OPS_PTAG_CT_SE_IP_DATA:
3282 ret = parse_se_ip_data(&region, stream);
3283 break;
3285 case OPS_PTAG_CT_MDC:
3286 ret = parse_mdc(&region, stream);
3287 break;
3289 default:
3290 OPS_ERROR_1(&stream->errors, OPS_E_P_UNKNOWN_TAG,
3291 "Unknown content tag 0x%x",
3292 pkt.u.ptag.type);
3293 ret = 0;
3296 /* Ensure that the entire packet has been consumed */
3298 if (region.length != region.readc && !region.indeterminate) {
3299 if (!consume_packet(&region, stream, 0)) {
3300 ret = -1;
3304 /* also consume it if there's been an error? */
3305 /* \todo decide what to do about an error on an */
3306 /* indeterminate packet */
3307 if (ret == 0) {
3308 if (!consume_packet(&region, stream, 0)) {
3309 ret = -1;
3312 /* set pktlen */
3314 *pktlen = stream->readinfo.alength;
3316 /* do callback on entire packet, if desired and there was no error */
3318 if (ret > 0 && stream->readinfo.accumulate) {
3319 pkt.u.packet.length = stream->readinfo.alength;
3320 pkt.u.packet.raw = stream->readinfo.accumulated;
3321 stream->readinfo.accumulated = NULL;
3322 stream->readinfo.asize = 0;
3323 CALLBACK(OPS_PARSER_PACKET_END, &stream->cbinfo, &pkt);
3325 stream->readinfo.alength = 0;
3327 return (ret < 0) ? -1 : (ret) ? 1 : 0;
3331 * \ingroup Core_ReadPackets
3333 * \brief Parse packets from an input stream until EOF or error.
3335 * \details Setup the necessary parsing configuration in "stream"
3336 * before calling __ops_parse().
3338 * That information includes :
3340 * - a "reader" function to be used to get the data to be parsed
3342 * - a "callback" function to be called when this library has identified
3343 * a parseable object within the data
3345 * - whether the calling function wants the signature subpackets
3346 * returned raw, parsed or not at all.
3348 * After returning, stream->errors holds any errors encountered while parsing.
3350 * \param stream Parsing configuration
3351 * \return 1 on success in all packets, 0 on error in any packet
3353 * \sa CoreAPI Overview
3355 * \sa __ops_print_errors()
3359 int
3360 __ops_parse(__ops_stream_t *stream, const int perrors)
3362 unsigned long pktlen;
3363 int r;
3365 do {
3366 r = __ops_parse_packet(stream, &pktlen);
3367 } while (r != -1);
3368 if (perrors) {
3369 __ops_print_errors(stream->errors);
3371 return (stream->errors == NULL);
3375 * \ingroup Core_ReadPackets
3377 * \brief Specifies whether one or more signature
3378 * subpacket types should be returned parsed; or raw; or ignored.
3380 * \param stream Pointer to previously allocated structure
3381 * \param tag Packet tag. OPS_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag
3382 * \param type Parse type
3383 * \todo Make all packet types optional, not just subpackets */
3384 void
3385 __ops_parse_options(__ops_stream_t *stream,
3386 __ops_content_tag_t tag,
3387 __ops_parse_type_t type)
3389 unsigned t7;
3390 unsigned t8;
3392 if (tag == OPS_PTAG_SS_ALL) {
3393 int n;
3395 for (n = 0; n < 256; ++n) {
3396 __ops_parse_options(stream,
3397 OPS_PTAG_SIG_SUBPKT_BASE + n,
3398 type);
3400 return;
3402 if (tag < OPS_PTAG_SIG_SUBPKT_BASE ||
3403 tag > OPS_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) {
3404 (void) fprintf(stderr, "__ops_parse_options: bad tag\n");
3405 return;
3407 t8 = (tag - OPS_PTAG_SIG_SUBPKT_BASE) / 8;
3408 t7 = 1 << ((tag - OPS_PTAG_SIG_SUBPKT_BASE) & 7);
3409 switch (type) {
3410 case OPS_PARSE_RAW:
3411 stream->ss_raw[t8] |= t7;
3412 stream->ss_parsed[t8] &= ~t7;
3413 break;
3415 case OPS_PARSE_PARSED:
3416 stream->ss_raw[t8] &= ~t7;
3417 stream->ss_parsed[t8] |= t7;
3418 break;
3420 case OPS_PARSE_IGNORE:
3421 stream->ss_raw[t8] &= ~t7;
3422 stream->ss_parsed[t8] &= ~t7;
3423 break;
3428 \ingroup Core_ReadPackets
3429 \brief Free __ops_stream_t struct and its contents
3431 void
3432 __ops_stream_delete(__ops_stream_t *stream)
3434 __ops_cbdata_t *cbinfo;
3435 __ops_cbdata_t *next;
3437 for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
3438 next = cbinfo->next;
3439 free(cbinfo);
3441 if (stream->readinfo.destroyer) {
3442 stream->readinfo.destroyer(&stream->readinfo);
3444 __ops_free_errors(stream->errors);
3445 if (stream->readinfo.accumulated) {
3446 free(stream->readinfo.accumulated);
3448 free(stream);
3452 \ingroup Core_ReadPackets
3453 \brief Returns the parse_info's reader_info
3454 \return Pointer to the reader_info inside the parse_info
3456 __ops_reader_t *
3457 __ops_readinfo(__ops_stream_t *stream)
3459 return &stream->readinfo;
3463 \ingroup Core_ReadPackets
3464 \brief Sets the parse_info's callback
3465 This is used when adding the first callback in a stack of callbacks.
3466 \sa __ops_callback_push()
3469 void
3470 __ops_set_callback(__ops_stream_t *stream, __ops_cbfunc_t *cb, void *arg)
3472 stream->cbinfo.cbfunc = cb;
3473 stream->cbinfo.arg = arg;
3474 stream->cbinfo.errors = &stream->errors;
3478 \ingroup Core_ReadPackets
3479 \brief Adds a further callback to a stack of callbacks
3480 \sa __ops_set_callback()
3482 void
3483 __ops_callback_push(__ops_stream_t *stream, __ops_cbfunc_t *cb, void *arg)
3485 __ops_cbdata_t *cbinfo;
3487 if ((cbinfo = calloc(1, sizeof(*cbinfo))) == NULL) {
3488 (void) fprintf(stderr, "__ops_callback_push: bad alloc\n");
3489 return;
3491 (void) memcpy(cbinfo, &stream->cbinfo, sizeof(*cbinfo));
3492 cbinfo->io = stream->io;
3493 stream->cbinfo.next = cbinfo;
3494 __ops_set_callback(stream, cb, arg);
3498 \ingroup Core_ReadPackets
3499 \brief Returns callback's arg
3501 void *
3502 __ops_callback_arg(__ops_cbdata_t *cbinfo)
3504 return cbinfo->arg;
3508 \ingroup Core_ReadPackets
3509 \brief Returns callback's errors
3511 void *
3512 __ops_callback_errors(__ops_cbdata_t *cbinfo)
3514 return cbinfo->errors;
3518 \ingroup Core_ReadPackets
3519 \brief Calls the parse_cb_info's callback if present
3520 \return Return value from callback, if present; else OPS_FINISHED
3522 __ops_cb_ret_t
3523 __ops_callback(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo)
3525 return (cbinfo->cbfunc) ? cbinfo->cbfunc(pkt, cbinfo) : OPS_FINISHED;
3529 \ingroup Core_ReadPackets
3530 \brief Calls the next callback in the stack
3531 \return Return value from callback
3533 __ops_cb_ret_t
3534 __ops_stacked_callback(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo)
3536 return __ops_callback(pkt, cbinfo->next);
3540 \ingroup Core_ReadPackets
3541 \brief Returns the parse_info's errors
3542 \return parse_info's errors
3544 __ops_error_t *
3545 __ops_stream_get_errors(__ops_stream_t *stream)
3547 return stream->errors;
3550 __ops_crypt_t *
3551 __ops_get_decrypt(__ops_stream_t *stream)
3553 return (stream->decrypt.alg) ? &stream->decrypt : NULL;