2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
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
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.
51 * \brief Parser for OpenPGP packets
55 #ifdef HAVE_SYS_CDEFS_H
56 #include <sys/cdefs.h>
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 $");
64 #ifdef HAVE_OPENSSL_CAST_H
65 #include <openssl/cast.h>
81 #include "packet-parse.h"
84 #include "packet-show.h"
86 #include "readerwriter.h"
87 #include "netpgpdefs.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); \
96 } while(/*CONSTCOND*/0)
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
105 * \param stream How to parse
107 * \return 1 on success, 0 on failure
110 limread_data(__ops_data_t
*data
, unsigned int len
,
111 __ops_region_t
*subregion
, __ops_stream_t
*stream
)
115 if (subregion
->length
- subregion
->readc
< len
) {
116 (void) fprintf(stderr
, "limread_data: bad length\n");
120 data
->contents
= calloc(1, data
->len
);
121 if (!data
->contents
) {
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
137 * \return 1 on success, 0 on failure
140 read_data(__ops_data_t
*data
, __ops_region_t
*region
, __ops_stream_t
*stream
)
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.
154 read_unsig_str(unsigned char **str
, __ops_region_t
*subregion
,
155 __ops_stream_t
*stream
)
159 len
= subregion
->length
- subregion
->readc
;
160 if ((*str
= calloc(1, len
+ 1)) == NULL
) {
164 !__ops_limited_read(*str
, len
, subregion
, &stream
->errors
,
165 &stream
->readinfo
, &stream
->cbinfo
)) {
173 read_string(char **str
, __ops_region_t
*subregion
, __ops_stream_t
*stream
)
175 return read_unsig_str((unsigned char **) str
, subregion
, stream
);
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
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.
211 * \return OPS_R_PARTIAL_READ
213 * \return OPS_R_EARLY_EOF
215 * \sa #__ops_reader_ret_t for details of return codes
219 sub_base_read(void *dest
, size_t length
, __ops_error_t
**errors
,
220 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbinfo
)
224 /* reading more than this would look like an error */
225 if (length
> INT_MAX
)
228 for (n
= 0; n
< length
;) {
231 r
= readinfo
->reader((char *) dest
+ n
, length
- n
, errors
,
233 if (r
> (int)(length
- n
)) {
234 (void) fprintf(stderr
, "sub_base_read: bad read\n");
249 if (readinfo
->accumulate
) {
250 if (readinfo
->asize
< readinfo
->alength
) {
251 (void) fprintf(stderr
, "sub_base_read: bad size\n");
254 if (readinfo
->alength
+ n
> readinfo
->asize
) {
257 readinfo
->asize
= (readinfo
->asize
* 2) + n
;
258 temp
= realloc(readinfo
->accumulated
, readinfo
->asize
);
260 (void) fprintf(stderr
,
261 "sub_base_read: bad alloc\n");
264 readinfo
->accumulated
= temp
;
266 if (readinfo
->asize
< readinfo
->alength
+ n
) {
267 (void) fprintf(stderr
, "sub_base_read: bad realloc\n");
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
;
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 */
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
,
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
303 full_read(unsigned char *dest
,
306 __ops_error_t
**errors
,
307 __ops_reader_t
*readinfo
,
308 __ops_cbdata_t
*cbinfo
)
311 int r
= 0; /* preset in case some loon calls with length
314 for (t
= 0; t
< length
;) {
315 r
= sub_base_read(dest
+ t
, length
- t
, errors
, readinfo
,
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
344 _read_scalar(unsigned *result
, unsigned length
,
345 __ops_stream_t
*stream
)
349 if (length
> sizeof(*result
)) {
350 (void) fprintf(stderr
, "_read_scalar: bad length\n");
358 r
= base_read(&c
, 1, stream
);
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
395 __ops_limited_read(unsigned char *dest
,
397 __ops_region_t
*region
,
398 __ops_error_t
**errors
,
399 __ops_reader_t
*readinfo
,
400 __ops_cbdata_t
*cbinfo
)
405 if (!region
->indeterminate
&&
406 region
->readc
+ length
> region
->length
) {
407 OPS_ERROR(errors
, OPS_E_P_NOT_ENOUGH_DATA
, "Not enough data");
410 r
= full_read(dest
, length
, &lr
, errors
, readinfo
, cbinfo
);
412 OPS_ERROR(errors
, OPS_E_R_READ_FAILED
, "Read failed");
415 if (!region
->indeterminate
&& r
!= length
) {
416 OPS_ERROR(errors
, OPS_E_R_READ_FAILED
, "Read failed");
419 region
->last_read
= r
;
422 if (region
->parent
&& region
->length
> region
->parent
->length
) {
423 (void) fprintf(stderr
,
424 "ops_limited_read: bad length\n");
427 } while ((region
= region
->parent
) != NULL
);
432 \ingroup Core_ReadPackets
433 \brief Call __ops_limited_read on next in stack
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
);
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
);
455 exact_limread(unsigned char *dest
, unsigned len
,
456 __ops_region_t
*region
,
457 __ops_stream_t
*stream
)
461 stream
->exact_read
= 1;
462 ret
= limread(dest
, len
, region
, stream
);
463 stream
->exact_read
= 0;
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()).
479 limskip(unsigned length
, __ops_region_t
*region
, __ops_stream_t
*stream
)
481 unsigned char buf
[NETPGP_BUFSIZ
];
484 unsigned n
= length
% NETPGP_BUFSIZ
;
486 if (!limread(buf
, n
, region
, stream
)) {
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()).
511 limread_scalar(unsigned *dest
,
513 __ops_region_t
*region
,
514 __ops_stream_t
*stream
)
516 unsigned char c
[4] = "";
521 (void) fprintf(stderr
, "limread_scalar: bad length\n");
525 if (/*CONSTCOND*/sizeof(*dest
) < 4) {
526 (void) fprintf(stderr
, "limread_scalar: bad dest\n");
529 if (!limread(c
, len
, region
, stream
)) {
532 for (t
= 0, n
= 0; n
< len
; ++n
) {
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()).
559 limread_size_t(size_t *dest
,
561 __ops_region_t
*region
,
562 __ops_stream_t
*stream
)
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
))
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
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()
595 limited_read_time(time_t *dest
, __ops_region_t
*region
,
596 __ops_stream_t
*stream
)
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
)) {
613 mytime
= (mytime
<< 8) + c
;
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)
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. */
655 stream
->reading_mpi_len
= 1;
656 ret
= (unsigned)limread_scalar(&length
, 2, region
, stream
);
658 stream
->reading_mpi_len
= 0;
662 nonzero
= length
& 7; /* there should be this many zero bits in the
666 length
= (length
+ 7) / 8;
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");
675 if (length
> NETPGP_BUFSIZ
) {
676 (void) fprintf(stderr
, "limread_mpi: bad length\n");
679 if (!limread(buf
, length
, region
, stream
)) {
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
689 * draft says. -- peter */
692 *pbn
= BN_bin2bn(buf
, (int)length
, NULL
);
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
707 read_new_length(unsigned *length
, __ops_stream_t
*stream
)
711 if (base_read(&c
, 1, stream
) != 1)
714 /* 1. One-octet packet */
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)
723 *length
= t
+ c
+ 192;
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");
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
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
)) {
769 unsigned t
= (c
- 192) << 8;
771 if (!limread(&c
, 1, region
, stream
)) {
774 *length
= t
+ c
+ 192;
777 return limread_scalar(length
, 4, region
, stream
);
782 \brief Free allocated memory
785 data_free(__ops_data_t
*data
)
787 free(data
->contents
);
788 data
->contents
= NULL
;
794 \brief Free allocated memory
797 string_free(char **str
)
805 \brief Free allocated memory
807 /* ! Free packet memory, set pointer to NULL */
809 __ops_subpacket_free(__ops_subpacket_t
*packet
)
817 \brief Free allocated memory
820 __ops_headers_free(__ops_headers_t
*headers
)
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
;
834 \brief Free allocated memory
837 cleartext_trailer_free(__ops_cleartext_trailer_t
*trailer
)
840 trailer
->hash
= NULL
;
845 \brief Free allocated memory
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
;
858 \brief Free the memory used when parsing this signature sub-packet type
861 ss_userdef_free(__ops_ss_userdef_t
*ss_userdef
)
863 data_free(&ss_userdef
->data
);
868 \brief Free the memory used when parsing this signature sub-packet type
871 ss_reserved_free(__ops_ss_unknown_t
*ss_unknown
)
873 data_free(&ss_unknown
->data
);
878 \brief Free the memory used when parsing this packet type
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
892 free_unknown_sig_pka(__ops_unknown_sig_t
*unknown_sig
)
894 data_free(&unknown_sig
->data
);
899 \brief Free allocated memory
909 * \ingroup Core_Create
910 * \brief Free the memory used when parsing a signature
914 sig_free(__ops_sig_t
*sig
)
916 switch (sig
->info
.key_alg
) {
918 case OPS_PKA_RSA_SIGN_ONLY
:
919 free_BN(&sig
->info
.sig
.rsa
.sig
);
923 free_BN(&sig
->info
.sig
.dsa
.r
);
924 free_BN(&sig
->info
.sig
.dsa
.s
);
927 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
928 free_BN(&sig
->info
.sig
.elgamal
.r
);
929 free_BN(&sig
->info
.sig
.elgamal
.s
);
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
);
947 (void) fprintf(stderr
, "sig_free: bad sig type\n");
953 \brief Free the memory used when parsing this signature sub-packet type
957 ss_skapref_free(__ops_ss_skapref_t
*ss_skapref
)
959 data_free(&ss_skapref
->data
);
964 \brief Free the memory used when parsing this signature sub-packet type
968 ss_hashpref_free(__ops_ss_hashpref_t
*ss_hashpref
)
970 data_free(&ss_hashpref
->data
);
975 \brief Free the memory used when parsing this signature sub-packet type
978 ss_zpref_free(__ops_ss_zpref_t
*ss_zpref
)
980 data_free(&ss_zpref
->data
);
985 \brief Free the memory used when parsing this signature sub-packet type
988 ss_key_flags_free(__ops_ss_key_flags_t
*ss_key_flags
)
990 data_free(&ss_key_flags
->data
);
995 \brief Free the memory used when parsing this signature sub-packet type
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
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
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 */
1030 ss_regexp_free(__ops_ss_regexp_t
*regexp
)
1032 string_free(®exp
->regexp
);
1036 \ingroup Core_Create
1037 \brief Free allocated memory
1039 /* ! Free the memory used when parsing this signature sub-packet type */
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 */
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
1062 ss_revocation_free(__ops_ss_revocation_t
*ss_revocation
)
1064 string_free(&ss_revocation
->reason
);
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 */
1079 __ops_parser_content_free(__ops_packet_t
*c
)
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
:
1106 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER
:
1107 __ops_headers_free(&c
->u
.cleartext_head
.headers
);
1110 case OPS_PTAG_CT_ARMOUR_HEADER
:
1111 __ops_headers_free(&c
->u
.armour_header
.headers
);
1114 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER
:
1115 cleartext_trailer_free(&c
->u
.cleartext_trailer
);
1118 case OPS_PTAG_CT_TRUST
:
1119 trust_free(&c
->u
.trust
);
1122 case OPS_PTAG_CT_SIGNATURE
:
1123 case OPS_PTAG_CT_SIGNATURE_FOOTER
:
1124 sig_free(&c
->u
.sig
);
1127 case OPS_PTAG_CT_PUBLIC_KEY
:
1128 case OPS_PTAG_CT_PUBLIC_SUBKEY
:
1129 __ops_pubkey_free(&c
->u
.pubkey
);
1132 case OPS_PTAG_CT_USER_ID
:
1133 __ops_userid_free(&c
->u
.userid
);
1136 case OPS_PTAG_SS_SIGNERS_USER_ID
:
1137 __ops_userid_free(&c
->u
.ss_signer
);
1140 case OPS_PTAG_CT_USER_ATTR
:
1141 __ops_userattr_free(&c
->u
.userattr
);
1144 case OPS_PTAG_SS_PREFERRED_SKA
:
1145 ss_skapref_free(&c
->u
.ss_skapref
);
1148 case OPS_PTAG_SS_PREFERRED_HASH
:
1149 ss_hashpref_free(&c
->u
.ss_hashpref
);
1152 case OPS_PTAG_SS_PREF_COMPRESS
:
1153 ss_zpref_free(&c
->u
.ss_zpref
);
1156 case OPS_PTAG_SS_KEY_FLAGS
:
1157 ss_key_flags_free(&c
->u
.ss_key_flags
);
1160 case OPS_PTAG_SS_KEYSERV_PREFS
:
1161 ss_key_server_prefs_free(&c
->u
.ss_key_server_prefs
);
1164 case OPS_PTAG_SS_FEATURES
:
1165 ss_features_free(&c
->u
.ss_features
);
1168 case OPS_PTAG_SS_NOTATION_DATA
:
1169 ss_notation_free(&c
->u
.ss_notation
);
1172 case OPS_PTAG_SS_REGEXP
:
1173 ss_regexp_free(&c
->u
.ss_regexp
);
1176 case OPS_PTAG_SS_POLICY_URI
:
1177 ss_policy_free(&c
->u
.ss_policy
);
1180 case OPS_PTAG_SS_PREF_KEYSERV
:
1181 ss_keyserv_free(&c
->u
.ss_keyserv
);
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
);
1198 case OPS_PTAG_SS_RESERVED
:
1199 ss_reserved_free(&c
->u
.ss_unknown
);
1202 case OPS_PTAG_SS_REVOCATION_REASON
:
1203 ss_revocation_free(&c
->u
.ss_revocation
);
1206 case OPS_PTAG_SS_EMBEDDED_SIGNATURE
:
1207 ss_embedded_sig_free(&c
->u
.ss_embedded_sig
);
1210 case OPS_PARSER_PACKET_END
:
1211 __ops_subpacket_free(&c
->u
.packet
);
1214 case OPS_PARSER_ERROR
:
1215 case OPS_PARSER_ERRCODE
:
1218 case OPS_PTAG_CT_SECRET_KEY
:
1219 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
:
1220 __ops_seckey_free(&c
->u
.seckey
);
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
);
1228 case OPS_GET_PASSPHRASE
:
1229 __ops_cmd_get_passphrase_free(&c
->u
.skey_passphrase
);
1233 fprintf(stderr
, "Can't free %d (0x%x)\n", c
->tag
, c
->tag
);
1238 \ingroup Core_Create
1239 \brief Free allocated memory
1242 __ops_pk_sesskey_free(__ops_pk_sesskey_t
*sk
)
1246 free_BN(&sk
->params
.rsa
.encrypted_m
);
1249 case OPS_PKA_ELGAMAL
:
1250 free_BN(&sk
->params
.elgamal
.g_to_k
);
1251 free_BN(&sk
->params
.elgamal
.encrypted_m
);
1255 (void) fprintf(stderr
, "__ops_pk_sesskey_free: bad alg\n");
1261 \ingroup Core_Create
1262 \brief Free allocated memory
1264 /* ! Free the memory used when parsing a public key */
1266 __ops_pubkey_free(__ops_pubkey_t
*p
)
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
);
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
);
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
);
1290 case OPS_PKA_NOTHING
:
1291 /* nothing to free */
1295 (void) fprintf(stderr
, "__ops_pubkey_free: bad alg\n");
1300 \ingroup Core_ReadPackets
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");
1313 if (!limread(&c
, 1, region
, stream
)) {
1316 key
->version
= (__ops_version_t
)c
;
1317 switch (key
->version
) {
1323 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN
,
1324 "Bad public key version (0x%02x)", key
->version
);
1327 if (!limited_read_time(&key
->birthtime
, region
, stream
)) {
1331 key
->days_valid
= 0;
1332 if ((key
->version
== 2 || key
->version
== 3) &&
1333 !limread_scalar(&key
->days_valid
, 2, region
, stream
)) {
1337 if (!limread(&c
, 1, region
, stream
)) {
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
)) {
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
)) {
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
)) {
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
));
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
1398 parse_pubkey(__ops_content_tag_t tag
, __ops_region_t
*region
,
1399 __ops_stream_t
*stream
)
1403 if (!parse_pubkey_data(&pkt
.u
.pubkey
, region
, stream
))
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
);
1412 CALLBACK(tag
, &stream
->cbinfo
, &pkt
);
1419 \ingroup Core_Create
1420 \brief Free allocated memory
1422 /* ! Free the memory used when parsing this packet type */
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.
1438 parse_userattr(__ops_region_t
*region
, __ops_stream_t
*stream
)
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");
1454 if (!read_data(&pkt
.u
.userattr
.data
, region
, stream
))
1457 CALLBACK(OPS_PTAG_CT_USER_ATTR
, &stream
->cbinfo
, &pkt
);
1463 \ingroup Core_Create
1464 \brief Free allocated memory
1466 /* ! Free the memory used when parsing this packet type */
1468 __ops_userid_free(__ops_userid_t
*id
)
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
1494 parse_userid(__ops_region_t
*region
, __ops_stream_t
*stream
)
1498 if (region
->readc
!= 0) {
1499 /* We should not have read anything so far */
1500 (void) fprintf(stderr
, "parse_userid: bad length\n");
1504 if ((pkt
.u
.userid
.userid
= calloc(1, region
->length
+ 1)) == NULL
) {
1505 (void) fprintf(stderr
, "parse_userid: bad alloc\n");
1509 if (region
->length
&&
1510 !limread(pkt
.u
.userid
.userid
, region
->length
, region
,
1514 pkt
.u
.userid
.userid
[region
->length
] = '\0';
1515 CALLBACK(OPS_PTAG_CT_USER_ID
, &stream
->cbinfo
, &pkt
);
1519 static __ops_hash_t
*
1520 parse_hash_find(__ops_stream_t
*stream
, const unsigned char *keyid
)
1522 __ops_hashtype_t
*hp
;
1525 for (n
= 0, hp
= stream
->hashes
; n
< stream
->hashc
; n
++, hp
++) {
1526 if (memcmp(hp
->keyid
, keyid
, OPS_KEY_ID_SIZE
) == 0) {
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
1549 parse_v3_sig(__ops_region_t
*region
,
1550 __ops_stream_t
*stream
)
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
)) {
1565 ERRP(&stream
->cbinfo
, pkt
, "bad hash info length");
1568 if (!limread(&c
, 1, region
, stream
)) {
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
)) {
1577 pkt
.u
.sig
.info
.birthtime_set
= 1;
1579 if (!limread(pkt
.u
.sig
.info
.signer_id
, OPS_KEY_ID_SIZE
, region
,
1583 pkt
.u
.sig
.info
.signer_id_set
= 1;
1585 if (!limread(&c
, 1, region
, stream
)) {
1588 pkt
.u
.sig
.info
.key_alg
= (__ops_pubkey_alg_t
)c
;
1589 /* XXX: check algorithm */
1591 if (!limread(&c
, 1, region
, stream
)) {
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
)) {
1601 switch (pkt
.u
.sig
.info
.key_alg
) {
1603 case OPS_PKA_RSA_SIGN_ONLY
:
1604 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.rsa
.sig
, region
, stream
)) {
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
)) {
1616 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
1617 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.r
, region
,
1619 !limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.s
, region
,
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
));
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
);
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
);
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
1666 parse_one_sig_subpacket(__ops_sig_t
*sig
,
1667 __ops_region_t
*region
,
1668 __ops_stream_t
*stream
)
1670 __ops_region_t subregion
;
1672 unsigned char bools
= 0x0;
1673 unsigned char c
= 0x0;
1674 unsigned doread
= 1;
1678 __ops_init_subregion(&subregion
, region
);
1679 if (!limited_read_new_length(&subregion
.length
, region
, stream
)) {
1683 if (subregion
.length
> region
->length
) {
1684 ERRP(&stream
->cbinfo
, pkt
, "Subpacket too long");
1687 if (!limread(&c
, 1, &subregion
, stream
)) {
1691 t8
= (c
& 0x7f) / 8;
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");
1706 if (!limread(pkt
.u
.ss_raw
.raw
, pkt
.u
.ss_raw
.length
,
1707 &subregion
, stream
)) {
1710 CALLBACK(OPS_PTAG_RAW_SS
, &stream
->cbinfo
, &pkt
);
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
))
1719 if (pkt
.tag
== OPS_PTAG_SS_CREATION_TIME
) {
1720 sig
->info
.birthtime
= pkt
.u
.ss_time
.time
;
1721 sig
->info
.birthtime_set
= 1;
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
)) {
1732 case OPS_PTAG_SS_REVOCABLE
:
1733 if (!limread(&bools
, 1, &subregion
, stream
)) {
1736 pkt
.u
.ss_revocable
.revocable
= !!bools
;
1739 case OPS_PTAG_SS_ISSUER_KEY_ID
:
1740 if (!limread(pkt
.u
.ss_issuer
.key_id
, OPS_KEY_ID_SIZE
,
1741 &subregion
, stream
)) {
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;
1749 case OPS_PTAG_SS_PREFERRED_SKA
:
1750 if (!read_data(&pkt
.u
.ss_skapref
.data
, &subregion
, stream
)) {
1755 case OPS_PTAG_SS_PREFERRED_HASH
:
1756 if (!read_data(&pkt
.u
.ss_hashpref
.data
, &subregion
, stream
)) {
1761 case OPS_PTAG_SS_PREF_COMPRESS
:
1762 if (!read_data(&pkt
.u
.ss_zpref
.data
,
1763 &subregion
, stream
)) {
1768 case OPS_PTAG_SS_PRIMARY_USER_ID
:
1769 if (!limread(&bools
, 1, &subregion
, stream
)) {
1772 pkt
.u
.ss_primary_userid
.primary_userid
= !!bools
;
1775 case OPS_PTAG_SS_KEY_FLAGS
:
1776 if (!read_data(&pkt
.u
.ss_key_flags
.data
, &subregion
, stream
)) {
1781 case OPS_PTAG_SS_KEYSERV_PREFS
:
1782 if (!read_data(&pkt
.u
.ss_key_server_prefs
.data
, &subregion
,
1788 case OPS_PTAG_SS_FEATURES
:
1789 if (!read_data(&pkt
.u
.ss_features
.data
, &subregion
, stream
)) {
1794 case OPS_PTAG_SS_SIGNERS_USER_ID
:
1795 if (!read_unsig_str(&pkt
.u
.ss_signer
.userid
, &subregion
,
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
)) {
1808 case OPS_PTAG_SS_NOTATION_DATA
:
1809 if (!limread_data(&pkt
.u
.ss_notation
.flags
, 4,
1810 &subregion
, stream
)) {
1813 if (!limread_size_t(&pkt
.u
.ss_notation
.name
.len
, 2,
1814 &subregion
, stream
)) {
1817 if (!limread_size_t(&pkt
.u
.ss_notation
.value
.len
, 2,
1818 &subregion
, stream
)) {
1821 if (!limread_data(&pkt
.u
.ss_notation
.name
,
1822 pkt
.u
.ss_notation
.name
.len
,
1823 &subregion
, stream
)) {
1826 if (!limread_data(&pkt
.u
.ss_notation
.value
,
1827 pkt
.u
.ss_notation
.value
.len
,
1828 &subregion
, stream
)) {
1833 case OPS_PTAG_SS_POLICY_URI
:
1834 if (!read_string(&pkt
.u
.ss_policy
.url
, &subregion
, stream
)) {
1839 case OPS_PTAG_SS_REGEXP
:
1840 if (!read_string(&pkt
.u
.ss_regexp
.regexp
, &subregion
, stream
)) {
1845 case OPS_PTAG_SS_PREF_KEYSERV
:
1846 if (!read_string(&pkt
.u
.ss_keyserv
.name
, &subregion
, stream
)) {
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
)) {
1867 case OPS_PTAG_SS_RESERVED
:
1868 if (!read_data(&pkt
.u
.ss_unknown
.data
, &subregion
, stream
)) {
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
)) {
1878 /* the rest is a human-readable UTF-8 string */
1879 if (!read_string(&pkt
.u
.ss_revocation
.reason
, &subregion
,
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
)) {
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");
1896 /* octet 1 = algid */
1897 if (!limread(&pkt
.u
.ss_revocation_key
.algid
, 1,
1898 &subregion
, stream
)) {
1901 /* octets 2-21 = fingerprint */
1902 if (!limread(&pkt
.u
.ss_revocation_key
.fingerprint
[0],
1903 OPS_FINGERPRINT_SIZE
, &subregion
, stream
)) {
1909 if (stream
->ss_parsed
[t8
] & t7
) {
1910 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_UNKNOWN_SS
,
1911 "Unknown signature subpacket type (%d)",
1918 /* Application doesn't want it delivered parsed */
1919 if (!(stream
->ss_parsed
[t8
] & t7
)) {
1921 OPS_ERROR_1(&stream
->errors
,
1922 OPS_E_PROTO_CRITICAL_SS_IGNORED
,
1923 "Critical signature subpacket ignored (%d)",
1927 !limskip(subregion
.length
- 1, &subregion
, stream
)) {
1931 __ops_parser_content_free(&pkt
);
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
);
1941 CALLBACK(pkt
.tag
, &stream
->cbinfo
, &pkt
);
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
1963 parse_sig_subpkts(__ops_sig_t
*sig
,
1964 __ops_region_t
*region
,
1965 __ops_stream_t
*stream
)
1967 __ops_region_t subregion
;
1970 __ops_init_subregion(&subregion
, region
);
1971 if (!limread_scalar(&subregion
.length
, 2, region
, stream
)) {
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
)) {
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");
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
2012 parse_v4_sig(__ops_region_t
*region
, __ops_stream_t
*stream
)
2014 unsigned char c
= 0x0;
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
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
)) {
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
)) {
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
)) {
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
)) {
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");
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");
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
)) {
2098 if (!limread(pkt
.u
.sig
.hash2
, 2, region
, stream
)) {
2102 switch (pkt
.u
.sig
.info
.key_alg
) {
2104 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.rsa
.sig
, region
, stream
)) {
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");
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");
2127 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
2128 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.r
, region
,
2130 !limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.s
, region
,
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
,
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
));
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
);
2165 CALLBACK(OPS_PTAG_CT_SIGNATURE_FOOTER
, &stream
->cbinfo
, &pkt
);
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
2183 parse_sig(__ops_region_t
*region
, __ops_stream_t
*stream
)
2185 unsigned char c
= 0x0;
2188 if (region
->readc
!= 0) {
2189 /* We should not have read anything so far */
2190 (void) fprintf(stderr
, "parse_sig: bad length\n");
2194 (void) memset(&pkt
, 0x0, sizeof(pkt
));
2195 if (!limread(&c
, 1, region
, stream
)) {
2198 if (c
== 2 || c
== 3) {
2199 return parse_v3_sig(region
, stream
);
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
);
2210 \ingroup Core_ReadPackets
2211 \brief Parse Compressed packet
2214 parse_compressed(__ops_region_t
*region
, __ops_stream_t
*stream
)
2217 unsigned char c
= 0x0;
2219 if (!limread(&c
, 1, region
, stream
)) {
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. */
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
));
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 */
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
2268 parse_one_pass(__ops_region_t
* region
, __ops_stream_t
* stream
)
2270 unsigned char c
= 0x0;
2273 if (!limread(&pkt
.u
.one_pass_sig
.version
, 1, region
, stream
)) {
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
);
2282 if (!limread(&c
, 1, region
, stream
)) {
2285 pkt
.u
.one_pass_sig
.sig_type
= (__ops_sig_type_t
)c
;
2287 if (!limread(&c
, 1, region
, stream
)) {
2290 pkt
.u
.one_pass_sig
.hash_alg
= (__ops_hash_alg_t
)c
;
2292 if (!limread(&c
, 1, region
, stream
)) {
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
)) {
2302 if (!limread(&c
, 1, region
, stream
)) {
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
);
2314 \ingroup Core_ReadPackets
2315 \brief Parse a Trust packet
2318 parse_trust(__ops_region_t
*region
, __ops_stream_t
*stream
)
2322 if (!read_data(&pkt
.u
.trust
.data
, region
, stream
)) {
2325 CALLBACK(OPS_PTAG_CT_TRUST
, &stream
->cbinfo
, &pkt
);
2330 parse_hash_data(__ops_stream_t
*stream
, const void *data
,
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
2345 parse_litdata(__ops_region_t
*region
, __ops_stream_t
*stream
)
2347 __ops_memory_t
*mem
;
2349 unsigned char c
= 0x0;
2351 if (!limread(&c
, 1, region
, stream
)) {
2354 pkt
.u
.litdata_header
.format
= (__ops_litdata_type_t
)c
;
2355 if (!limread(&c
, 1, region
, stream
)) {
2358 if (!limread((unsigned char *)pkt
.u
.litdata_header
.filename
,
2359 (unsigned)c
, region
, stream
)) {
2362 pkt
.u
.litdata_header
.filename
[c
] = '\0';
2363 if (!limited_read_time(&pkt
.u
.litdata_header
.mtime
, region
, stream
)) {
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
)) {
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? */
2389 * \ingroup Core_Create
2391 * __ops_seckey_free() frees the memory associated with "key". Note that
2392 * the key itself is not freed.
2398 __ops_seckey_free(__ops_seckey_t
*key
)
2400 switch (key
->pubkey
.alg
) {
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
);
2411 free_BN(&key
->key
.dsa
.x
);
2415 (void) fprintf(stderr
,
2416 "__ops_seckey_free: Unknown algorithm: %d (%s)\n",
2418 __ops_show_pka(key
->pubkey
.alg
));
2420 free(key
->checkhash
);
2421 __ops_pubkey_free(&key
->pubkey
);
2425 consume_packet(__ops_region_t
*region
, __ops_stream_t
*stream
, unsigned warn
)
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
);
2439 OPS_ERROR(&stream
->errors
, OPS_E_P_PACKET_CONSUMED
,
2440 "Warning: packet consumer");
2444 OPS_ERROR(&stream
->errors
, OPS_E_P_PACKET_NOT_CONSUMED
,
2445 (warn
) ? "Warning: Packet was not consumed" :
2446 "Packet was not consumed");
2451 * \ingroup Core_ReadPackets
2452 * \brief Parse a secret key
2455 parse_seckey(__ops_region_t
*region
, __ops_stream_t
*stream
)
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
;
2467 if (__ops_get_debug_level(__FILE__
)) {
2468 fprintf(stderr
, "\n---------\nparse_seckey:\n");
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
)) {
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
)) {
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
)) {
2494 pkt
.u
.seckey
.alg
= (__ops_symm_alg_t
)c
;
2495 if (!limread(&c
, 1, region
, stream
)) {
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
:
2505 (void) fprintf(stderr
,
2506 "parse_seckey: bad seckey\n");
2509 if (!limread(&c
, 1, region
, stream
)) {
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
)) {
2517 if (pkt
.u
.seckey
.s2k_specifier
==
2518 OPS_S2KS_ITERATED_AND_SALTED
) {
2519 if (!limread(&c
, 1, region
, stream
)) {
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
;
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
];
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");
2553 if (!limread(pkt
.u
.seckey
.iv
, blocksize
, region
, stream
)) {
2556 (void) memset(&seckey
, 0x0, sizeof(seckey
));
2558 seckey
.u
.skey_passphrase
.passphrase
= &passphrase
;
2559 seckey
.u
.skey_passphrase
.seckey
= &pkt
.u
.seckey
;
2560 CALLBACK(OPS_GET_PASSPHRASE
, &stream
->cbinfo
, &seckey
);
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)) {
2571 CALLBACK(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
,
2572 &stream
->cbinfo
, &pkt
);
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");
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");
2590 for (n
= 0; n
* hashsize
< keysize
; ++n
) {
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");
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
) {
2610 switch (pkt
.u
.seckey
.s2k_specifier
) {
2611 case OPS_S2KS_SALTED
:
2612 hashes
[n
].add(&hashes
[n
],
2616 case OPS_S2KS_SIMPLE
:
2617 hashes
[n
].add(&hashes
[n
],
2618 (unsigned char *) passphrase
, passlen
);
2621 case OPS_S2KS_ITERATED_AND_SALTED
:
2622 for (i
= 0; i
< pkt
.u
.seckey
.octetc
;
2623 i
+= passlen
+ OPS_SALT_SIZE
) {
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
],
2632 (unsigned)(j
> OPS_SALT_SIZE
) ?
2634 if (j
> OPS_SALT_SIZE
) {
2635 hashes
[n
].add(&hashes
[n
],
2636 (unsigned char *) passphrase
,
2646 for (n
= 0; n
* hashsize
< keysize
; ++n
) {
2649 r
= hashes
[n
].finish(&hashes
[n
], key
+ n
* hashsize
);
2650 if (r
!= hashsize
) {
2651 (void) fprintf(stderr
,
2652 "parse_seckey: bad r\n");
2657 __ops_forget(passphrase
, passlen
);
2659 __ops_crypt_any(&decrypt
, pkt
.u
.seckey
.alg
);
2660 if (__ops_get_debug_level(__FILE__
)) {
2663 fprintf(stderr
, "\nREADING:\niv=");
2665 i
< __ops_block_size(pkt
.u
.seckey
.alg
);
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
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");
2701 __ops_hash_sha1(&checkhash
);
2702 __ops_reader_push_hash(stream
, &checkhash
);
2704 __ops_reader_push_sum16(stream
);
2707 switch (pkt
.u
.seckey
.pubkey
.alg
) {
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
)) {
2720 if (!limread_mpi(&pkt
.u
.seckey
.key
.dsa
.x
, region
, stream
)) {
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
));
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
);
2746 pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
) {
2747 __ops_reader_pop_decrypt(stream
);
2748 region
= saved_region
;
2751 if (!limread(pkt
.u
.seckey
.checkhash
,
2752 OPS_CHECKHASH_SIZE
, region
, stream
)) {
2756 if (memcmp(hash
, pkt
.u
.seckey
.checkhash
,
2757 OPS_CHECKHASH_SIZE
) != 0) {
2758 ERRP(&stream
->cbinfo
, pkt
,
2759 "Hash mismatch in secret key");
2765 sum
= __ops_reader_pop_sum16(stream
);
2767 pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
) {
2768 __ops_reader_pop_decrypt(stream
);
2769 region
= saved_region
;
2772 if (!limread_scalar(&pkt
.u
.seckey
.checksum
, 2,
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");
2790 if (ret
&& region
->readc
!= region
->length
) {
2791 (void) fprintf(stderr
, "parse_seckey: bad length\n");
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");
2805 \ingroup Core_ReadPackets
2806 \brief Parse a Public Key Session Key packet
2809 parse_pk_sesskey(__ops_region_t
*region
,
2810 __ops_stream_t
*stream
)
2812 const __ops_seckey_t
*secret
;
2813 __ops_packet_t sesskey
;
2816 unsigned char c
= 0x0;
2817 unsigned char cs
[2];
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
)) {
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
);
2837 if (!limread(pkt
.u
.pk_sesskey
.key_id
,
2838 sizeof(pkt
.u
.pk_sesskey
.key_id
), region
, stream
)) {
2841 if (__ops_get_debug_level(__FILE__
)) {
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
]);
2851 if (!limread(&c
, 1, region
, stream
)) {
2854 pkt
.u
.pk_sesskey
.alg
= (__ops_pubkey_alg_t
)c
;
2855 switch (pkt
.u
.pk_sesskey
.alg
) {
2857 if (!limread_mpi(&pkt
.u
.pk_sesskey
.params
.rsa
.encrypted_m
,
2861 enc_m
= pkt
.u
.pk_sesskey
.params
.rsa
.encrypted_m
;
2864 case OPS_PKA_ELGAMAL
:
2865 if (!limread_mpi(&pkt
.u
.pk_sesskey
.params
.elgamal
.g_to_k
,
2868 &pkt
.u
.pk_sesskey
.params
.elgamal
.encrypted_m
,
2872 enc_m
= pkt
.u
.pk_sesskey
.params
.elgamal
.encrypted_m
;
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
));
2883 (void) memset(&sesskey
, 0x0, sizeof(sesskey
));
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
);
2891 CALLBACK(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY
, &stream
->cbinfo
,
2895 n
= __ops_decrypt_decode_mpi(unencoded_m_buf
, sizeof(unencoded_m_buf
),
2898 ERRP(&stream
->cbinfo
, pkt
, "decrypted message too short");
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
)) {
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
));
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)",
2921 if (k
> sizeof(pkt
.u
.pk_sesskey
.key
)) {
2922 (void) fprintf(stderr
, "parse_pk_sesskey: bad keylength\n");
2926 (void) memcpy(pkt
.u
.pk_sesskey
.key
, unencoded_m_buf
+ 1, k
);
2928 if (__ops_get_debug_level(__FILE__
)) {
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
]);
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]);
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
);
2958 (void) fprintf(stderr
, "parse_pk_sesskey: bad alloc\n");
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
);
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;
2976 decrypt
= __ops_get_decrypt(stream
);
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
)) {
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]);
3000 if (tag
== OPS_PTAG_CT_SE_DATA_BODY
) {
3001 decrypt
->decrypt_resync(decrypt
);
3002 decrypt
->block_encrypt(decrypt
, decrypt
->civ
,
3005 r
= __ops_parse(stream
, !printerrors
);
3007 __ops_reader_pop_decrypt(stream
);
3011 while (region
->readc
< region
->length
) {
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
,
3022 pkt
.u
.se_data_body
.length
= len
;
3023 CALLBACK(tag
, &stream
->cbinfo
, &pkt
);
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;
3038 decrypt
= __ops_get_decrypt(stream
);
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
);
3050 while (region
->readc
< region
->length
) {
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
)) {
3063 pkt
.u
.se_data_body
.length
= len
;
3065 CALLBACK(tag
, &stream
->cbinfo
, &pkt
);
3073 \ingroup Core_ReadPackets
3074 \brief Read a Symmetrically Encrypted packet
3077 parse_se_data(__ops_region_t
*region
, __ops_stream_t
*stream
)
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
3096 parse_se_ip_data(__ops_region_t
*region
, __ops_stream_t
*stream
)
3099 unsigned char c
= 0x0;
3101 if (!limread(&c
, 1, region
, stream
)) {
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");
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
,
3120 \ingroup Core_ReadPackets
3121 \brief Read a MDC packet
3124 parse_mdc(__ops_region_t
*region
, __ops_stream_t
*stream
)
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");
3133 if (!limread(pkt
.u
.mdc
.data
, OPS_SHA1_HASH_SIZE
, region
, stream
)) {
3136 CALLBACK(OPS_PTAG_CT_MDC
, &stream
->cbinfo
, &pkt
);
3137 free(pkt
.u
.mdc
.data
);
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
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 */
3153 __ops_parse_packet(__ops_stream_t
*stream
, unsigned long *pktlen
)
3156 __ops_region_t region
;
3158 unsigned indeterminate
= 0;
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",
3171 /* errors in the base read are effectively EOF. */
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
);
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
)) {
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
);
3203 case OPS_PTAG_OLD_LEN_2
:
3204 rb
= _read_scalar(&pkt
.u
.ptag
.length
, 2, stream
);
3207 case OPS_PTAG_OLD_LEN_4
:
3208 rb
= _read_scalar(&pkt
.u
.ptag
.length
, 4, stream
);
3211 case OPS_PTAG_OLD_LEN_INDETERMINATE
:
3212 pkt
.u
.ptag
.length
= 0;
3222 CALLBACK(OPS_PARSER_PTAG
, &stream
->cbinfo
, &pkt
);
3224 __ops_init_subregion(®ion
, 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",
3231 switch (pkt
.u
.ptag
.type
) {
3232 case OPS_PTAG_CT_SIGNATURE
:
3233 ret
= parse_sig(®ion
, stream
);
3236 case OPS_PTAG_CT_PUBLIC_KEY
:
3237 case OPS_PTAG_CT_PUBLIC_SUBKEY
:
3238 ret
= parse_pubkey(pkt
.u
.ptag
.type
, ®ion
, stream
);
3241 case OPS_PTAG_CT_TRUST
:
3242 ret
= parse_trust(®ion
, stream
);
3245 case OPS_PTAG_CT_USER_ID
:
3246 ret
= parse_userid(®ion
, stream
);
3249 case OPS_PTAG_CT_COMPRESSED
:
3250 ret
= parse_compressed(®ion
, stream
);
3253 case OPS_PTAG_CT_1_PASS_SIG
:
3254 ret
= parse_one_pass(®ion
, stream
);
3257 case OPS_PTAG_CT_LITDATA
:
3258 ret
= parse_litdata(®ion
, stream
);
3261 case OPS_PTAG_CT_USER_ATTR
:
3262 ret
= parse_userattr(®ion
, stream
);
3265 case OPS_PTAG_CT_SECRET_KEY
:
3266 ret
= parse_seckey(®ion
, stream
);
3269 case OPS_PTAG_CT_SECRET_SUBKEY
:
3270 ret
= parse_seckey(®ion
, stream
);
3273 case OPS_PTAG_CT_PK_SESSION_KEY
:
3274 ret
= parse_pk_sesskey(®ion
, stream
);
3277 case OPS_PTAG_CT_SE_DATA
:
3278 ret
= parse_se_data(®ion
, stream
);
3281 case OPS_PTAG_CT_SE_IP_DATA
:
3282 ret
= parse_se_ip_data(®ion
, stream
);
3285 case OPS_PTAG_CT_MDC
:
3286 ret
= parse_mdc(®ion
, stream
);
3290 OPS_ERROR_1(&stream
->errors
, OPS_E_P_UNKNOWN_TAG
,
3291 "Unknown content tag 0x%x",
3296 /* Ensure that the entire packet has been consumed */
3298 if (region
.length
!= region
.readc
&& !region
.indeterminate
) {
3299 if (!consume_packet(®ion
, stream
, 0)) {
3304 /* also consume it if there's been an error? */
3305 /* \todo decide what to do about an error on an */
3306 /* indeterminate packet */
3308 if (!consume_packet(®ion
, stream
, 0)) {
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()
3360 __ops_parse(__ops_stream_t
*stream
, const int perrors
)
3362 unsigned long pktlen
;
3366 r
= __ops_parse_packet(stream
, &pktlen
);
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 */
3385 __ops_parse_options(__ops_stream_t
*stream
,
3386 __ops_content_tag_t tag
,
3387 __ops_parse_type_t type
)
3392 if (tag
== OPS_PTAG_SS_ALL
) {
3395 for (n
= 0; n
< 256; ++n
) {
3396 __ops_parse_options(stream
,
3397 OPS_PTAG_SIG_SUBPKT_BASE
+ n
,
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");
3407 t8
= (tag
- OPS_PTAG_SIG_SUBPKT_BASE
) / 8;
3408 t7
= 1 << ((tag
- OPS_PTAG_SIG_SUBPKT_BASE
) & 7);
3411 stream
->ss_raw
[t8
] |= t7
;
3412 stream
->ss_parsed
[t8
] &= ~t7
;
3415 case OPS_PARSE_PARSED
:
3416 stream
->ss_raw
[t8
] &= ~t7
;
3417 stream
->ss_parsed
[t8
] |= t7
;
3420 case OPS_PARSE_IGNORE
:
3421 stream
->ss_raw
[t8
] &= ~t7
;
3422 stream
->ss_parsed
[t8
] &= ~t7
;
3428 \ingroup Core_ReadPackets
3429 \brief Free __ops_stream_t struct and its contents
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
;
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
);
3452 \ingroup Core_ReadPackets
3453 \brief Returns the parse_info's reader_info
3454 \return Pointer to the reader_info inside the parse_info
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()
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()
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");
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
3502 __ops_callback_arg(__ops_cbdata_t
*cbinfo
)
3508 \ingroup Core_ReadPackets
3509 \brief Returns callback's errors
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
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
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
3545 __ops_stream_get_errors(__ops_stream_t
*stream
)
3547 return stream
->errors
;
3551 __ops_get_decrypt(__ops_stream_t
*stream
)
3553 return (stream
->decrypt
.alg
) ? &stream
->decrypt
: NULL
;