1 /* read-packet.c - Read OpenPGP packets
2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
6 * This file is part of OpenCDK.
8 * The OpenCDK library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
35 #include <algorithms.h>
36 #include <gnutls_str.h>
39 /* The version of the MDC packet considering the lastest OpenPGP draft. */
43 stream_read (cdk_stream_t s
, void *buf
, size_t buflen
, size_t * r_nread
)
45 *r_nread
= cdk_stream_read (s
, buf
, buflen
);
46 return *r_nread
> 0 ? 0 : _cdk_stream_get_errno (s
);
50 /* Try to read 4 octets from the stream. */
52 read_32 (cdk_stream_t s
)
59 stream_read (s
, buf
, 4, &nread
);
62 return buf
[0] << 24 | buf
[1] << 16 | buf
[2] << 8 | buf
[3];
66 /* Try to read 2 octets from a stream. */
68 read_16 (cdk_stream_t s
)
75 stream_read (s
, buf
, 2, &nread
);
78 return buf
[0] << 8 | buf
[1];
82 /* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */
84 read_s2k (cdk_stream_t inp
, cdk_s2k_t s2k
)
88 s2k
->mode
= cdk_stream_getc (inp
);
89 s2k
->hash_algo
= cdk_stream_getc (inp
);
90 if (s2k
->mode
== CDK_S2K_SIMPLE
)
92 else if (s2k
->mode
== CDK_S2K_SALTED
|| s2k
->mode
== CDK_S2K_ITERSALTED
)
94 if (stream_read (inp
, s2k
->salt
, DIM (s2k
->salt
), &nread
))
95 return CDK_Inv_Packet
;
96 if (nread
!= DIM (s2k
->salt
))
97 return CDK_Inv_Packet
;
99 if (s2k
->mode
== CDK_S2K_ITERSALTED
)
100 s2k
->count
= cdk_stream_getc (inp
);
102 else if (s2k
->mode
== CDK_S2K_GNU_EXT
)
104 /* GNU extensions to the S2K : read DETAILS from gnupg */
108 return CDK_Not_Implemented
;
115 read_mpi (cdk_stream_t inp
, bigint_t
* ret_m
, int secure
)
119 byte buf
[MAX_MPI_BYTES
+ 2];
124 return CDK_Inv_Value
;
127 nbits
= read_16 (inp
);
128 nread
= (nbits
+ 7) / 8;
130 if (nbits
> MAX_MPI_BITS
|| nbits
== 0)
132 _gnutls_write_log ("read_mpi: too large %d bits\n", (int) nbits
);
133 return gnutls_assert_val(CDK_MPI_Error
); /* Sanity check */
136 rc
= stream_read (inp
, buf
+ 2, nread
, &nread
);
137 if (!rc
&& nread
!= ((nbits
+ 7) / 8))
139 _gnutls_write_log ("read_mpi: too short %d < %d\n", (int) nread
,
140 (int) ((nbits
+ 7) / 8));
141 return gnutls_assert_val(CDK_MPI_Error
);
147 err
= _gnutls_mpi_scan_pgp (&m
, buf
, nread
);
149 return gnutls_assert_val(map_gnutls_error (err
));
156 /* Read the encoded packet length directly from the file
157 object INP and return it. Reset RET_PARTIAL if this is
158 the last packet in block mode. */
160 _cdk_pkt_read_len (FILE * inp
, size_t * ret_partial
)
168 if (c1
< 224 || c1
== 255)
169 *ret_partial
= 0; /* End of partial data */
172 else if (c1
>= 192 && c1
<= 223)
177 pktlen
= ((c1
- 192) << 8) + c2
+ 192;
181 pktlen
= fgetc (inp
) << 24;
182 pktlen
|= fgetc (inp
) << 16;
183 pktlen
|= fgetc (inp
) << 8;
184 pktlen
|= fgetc (inp
) << 0;
187 pktlen
= 1 << (c1
& 0x1f);
193 read_pubkey_enc (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_pubkey_enc_t pke
)
198 return CDK_Inv_Value
;
201 _gnutls_write_log ("read_pubkey_enc: %d octets\n", (int) pktlen
);
204 return CDK_Inv_Packet
;
205 pke
->version
= cdk_stream_getc (inp
);
206 if (pke
->version
< 2 || pke
->version
> 3)
207 return CDK_Inv_Packet
;
208 pke
->keyid
[0] = read_32 (inp
);
209 pke
->keyid
[1] = read_32 (inp
);
210 if (!pke
->keyid
[0] && !pke
->keyid
[1])
211 pke
->throw_keyid
= 1; /* RFC2440 "speculative" keyID */
212 pke
->pubkey_algo
= _pgp_pub_algo_to_cdk (cdk_stream_getc (inp
));
213 nenc
= cdk_pk_get_nenc (pke
->pubkey_algo
);
216 for (i
= 0; i
< nenc
; i
++)
218 cdk_error_t rc
= read_mpi (inp
, &pke
->mpi
[i
], 0);
220 return gnutls_assert_val(rc
);
229 read_mdc (cdk_stream_t inp
, cdk_pkt_mdc_t mdc
)
235 return CDK_Inv_Value
;
238 _gnutls_write_log ("read_mdc:\n");
240 rc
= stream_read (inp
, mdc
->hash
, DIM (mdc
->hash
), &n
);
244 return n
!= DIM (mdc
->hash
) ? CDK_Inv_Packet
: 0;
249 read_compressed (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_compressed_t c
)
252 return CDK_Inv_Value
;
255 _gnutls_write_log ("read_compressed: %d octets\n", (int) pktlen
);
257 c
->algorithm
= cdk_stream_getc (inp
);
258 if (c
->algorithm
> 3)
259 return CDK_Inv_Packet
;
261 /* don't know the size, so we read until EOF */
268 /* FIXME: Support partial bodies. */
274 read_public_key (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_pubkey_t pk
)
276 size_t i
, ndays
, npkey
;
279 return CDK_Inv_Value
;
282 _gnutls_write_log ("read_public_key: %d octets\n", (int) pktlen
);
284 pk
->is_invalid
= 1; /* default to detect missing self signatures */
288 pk
->version
= cdk_stream_getc (inp
);
289 if (pk
->version
< 2 || pk
->version
> 4)
290 return CDK_Inv_Packet_Ver
;
291 pk
->timestamp
= read_32 (inp
);
294 ndays
= read_16 (inp
);
296 pk
->expiredate
= pk
->timestamp
+ ndays
* 86400L;
299 pk
->pubkey_algo
= _pgp_pub_algo_to_cdk (cdk_stream_getc (inp
));
300 npkey
= cdk_pk_get_npkey (pk
->pubkey_algo
);
304 _gnutls_write_log ("invalid public key algorithm %d\n",
308 for (i
= 0; i
< npkey
; i
++)
310 cdk_error_t rc
= read_mpi (inp
, &pk
->mpi
[i
], 0);
312 return gnutls_assert_val(rc
);
315 /* This value is just for the first run and will be
316 replaced with the actual key flags from the self signature. */
317 pk
->pubkey_usage
= 0;
323 read_public_subkey (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_pubkey_t pk
)
326 return CDK_Inv_Value
;
327 return read_public_key (inp
, pktlen
, pk
);
331 read_secret_key (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_seckey_t sk
)
333 size_t p1
, p2
, nread
;
337 if (!inp
|| !sk
|| !sk
->pk
)
338 return CDK_Inv_Value
;
341 _gnutls_write_log ("read_secret_key: %d octets\n", (int) pktlen
);
343 p1
= cdk_stream_tell (inp
);
344 rc
= read_public_key (inp
, pktlen
, sk
->pk
);
348 sk
->s2k_usage
= cdk_stream_getc (inp
);
349 sk
->protect
.sha1chk
= 0;
350 if (sk
->s2k_usage
== 254 || sk
->s2k_usage
== 255)
352 sk
->protect
.sha1chk
= (sk
->s2k_usage
== 254);
353 sk
->protect
.algo
= _pgp_cipher_to_gnutls (cdk_stream_getc (inp
));
354 if (sk
->protect
.algo
== GNUTLS_CIPHER_UNKNOWN
)
355 return gnutls_assert_val(CDK_Inv_Algo
);
357 sk
->protect
.s2k
= cdk_calloc (1, sizeof *sk
->protect
.s2k
);
358 if (!sk
->protect
.s2k
)
359 return CDK_Out_Of_Core
;
360 rc
= read_s2k (inp
, sk
->protect
.s2k
);
363 /* refer to --export-secret-subkeys in gpg(1) */
364 if (sk
->protect
.s2k
->mode
== CDK_S2K_GNU_EXT
)
365 sk
->protect
.ivlen
= 0;
368 sk
->protect
.ivlen
= gnutls_cipher_get_block_size (sk
->protect
.algo
);
369 if (!sk
->protect
.ivlen
)
370 return CDK_Inv_Packet
;
371 rc
= stream_read (inp
, sk
->protect
.iv
, sk
->protect
.ivlen
, &nread
);
374 if (nread
!= sk
->protect
.ivlen
)
375 return CDK_Inv_Packet
;
379 sk
->protect
.algo
= _pgp_cipher_to_gnutls (sk
->s2k_usage
);
380 if (sk
->protect
.algo
== GNUTLS_CIPHER_UNKNOWN
)
381 return gnutls_assert_val(CDK_Inv_Algo
);
382 else if (sk
->protect
.algo
== GNUTLS_CIPHER_NULL
)
385 nskey
= cdk_pk_get_nskey (sk
->pk
->pubkey_algo
);
391 for (i
= 0; i
< nskey
; i
++)
393 rc
= read_mpi (inp
, &sk
->mpi
[i
], 1);
395 return gnutls_assert_val(rc
);
397 sk
->csum
= read_16 (inp
);
398 sk
->is_protected
= 0;
400 else if (sk
->pk
->version
< 4)
402 /* The length of each multiprecision integer is stored in plaintext. */
403 nskey
= cdk_pk_get_nskey (sk
->pk
->pubkey_algo
);
409 for (i
= 0; i
< nskey
; i
++)
411 rc
= read_mpi (inp
, &sk
->mpi
[i
], 1);
413 return gnutls_assert_val(rc
);
415 sk
->csum
= read_16 (inp
);
416 sk
->is_protected
= 1;
420 /* We need to read the rest of the packet because we do not
421 have any information how long the encrypted mpi's are */
422 p2
= cdk_stream_tell (inp
);
424 sk
->enclen
= pktlen
- p2
;
426 return CDK_Inv_Packet
; /* at least 16 bits for the checksum! */
427 sk
->encdata
= cdk_calloc (1, sk
->enclen
+ 1);
429 return CDK_Out_Of_Core
;
430 if (stream_read (inp
, sk
->encdata
, sk
->enclen
, &nread
))
431 return CDK_Inv_Packet
;
432 /* Handle the GNU S2K extensions we know (just gnu-dummy right now): */
433 if (sk
->protect
.s2k
->mode
== CDK_S2K_GNU_EXT
)
435 unsigned char gnumode
;
436 if ((sk
->enclen
< strlen ("GNU") + 1) ||
437 (0 != memcmp ("GNU", sk
->encdata
, strlen ("GNU"))))
438 return CDK_Inv_Packet
;
439 gnumode
= sk
->encdata
[strlen ("GNU")];
440 /* we only handle gnu-dummy (mode 1).
441 mode 2 should refer to external smart cards.
444 return CDK_Inv_Packet
;
445 /* gnu-dummy should have no more data */
446 if (sk
->enclen
!= strlen ("GNU") + 1)
447 return CDK_Inv_Packet
;
449 nskey
= cdk_pk_get_nskey (sk
->pk
->pubkey_algo
);
455 /* We mark each MPI entry with NULL to indicate a protected key. */
456 for (i
= 0; i
< nskey
; i
++)
458 sk
->is_protected
= 1;
462 _cdk_copy_pk_to_sk (sk
->pk
, sk
);
468 read_secret_subkey (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_seckey_t sk
)
472 if (!inp
|| !sk
|| !sk
->pk
)
473 return CDK_Inv_Value
;
475 rc
= read_secret_key (inp
, pktlen
, sk
);
480 #define ATTRIBUTE "[attribute]"
483 read_attribute (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_userid_t attr
, int name_size
)
490 if (!inp
|| !attr
|| !pktlen
)
491 return CDK_Inv_Value
;
494 _gnutls_write_log ("read_attribute: %d octets\n", (int) pktlen
);
496 _gnutls_str_cpy (attr
->name
, name_size
, ATTRIBUTE
);
497 attr
->len
= MIN(name_size
, sizeof(ATTRIBUTE
)-1);
499 buf
= cdk_calloc (1, pktlen
);
501 return CDK_Out_Of_Core
;
502 rc
= stream_read (inp
, buf
, pktlen
, &nread
);
506 return CDK_Inv_Packet
;
513 len
= _cdk_buftou32 (p
);
522 return CDK_Inv_Packet
;
524 len
= ((len
- 192) << 8) + *p
+ 192;
529 if (*p
!= 1) /* Currently only 1, meaning an image, is defined. */
532 return CDK_Inv_Packet
;
538 return CDK_Inv_Packet
;
539 attr
->attrib_img
= cdk_calloc (1, len
);
540 if (!attr
->attrib_img
)
543 return CDK_Out_Of_Core
;
545 attr
->attrib_len
= len
;
546 memcpy (attr
->attrib_img
, p
, len
);
553 read_user_id (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_userid_t user_id
)
558 if (!inp
|| !user_id
)
559 return CDK_Inv_Value
;
561 return CDK_Inv_Packet
;
564 _gnutls_write_log ("read_user_id: %lu octets\n", (unsigned long)pktlen
);
566 user_id
->len
= pktlen
;
567 rc
= stream_read (inp
, user_id
->name
, pktlen
, &nread
);
571 return CDK_Inv_Packet
;
572 user_id
->name
[nread
] = '\0';
578 read_subpkt (cdk_stream_t inp
, cdk_subpkt_t
* r_ctx
, size_t * r_nbytes
)
581 size_t size
, nread
, n
;
585 if (!inp
|| !r_nbytes
)
586 return CDK_Inv_Value
;
589 _gnutls_write_log ("read_subpkt:\n");
593 c
= cdk_stream_getc (inp
);
597 size
= read_32 (inp
);
600 else if (c
>= 192 && c
< 255)
602 c1
= cdk_stream_getc (inp
);
606 size
= ((c
- 192) << 8) + c1
+ 192;
611 return CDK_Inv_Packet
;
613 node
= cdk_subpkt_new (size
);
615 return CDK_Out_Of_Core
;
617 node
->type
= cdk_stream_getc (inp
);
619 _gnutls_write_log (" %d octets %d type\n", node
->size
, node
->type
);
622 rc
= stream_read (inp
, node
->d
, node
->size
, &nread
);
630 cdk_subpkt_add (*r_ctx
, node
);
636 read_onepass_sig (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_onepass_sig_t sig
)
639 return CDK_Inv_Value
;
642 _gnutls_write_log ("read_onepass_sig: %d octets\n", (int) pktlen
);
645 return CDK_Inv_Packet
;
646 sig
->version
= cdk_stream_getc (inp
);
647 if (sig
->version
!= 3)
648 return CDK_Inv_Packet_Ver
;
649 sig
->sig_class
= cdk_stream_getc (inp
);
650 sig
->digest_algo
= _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp
));
651 sig
->pubkey_algo
= _pgp_pub_algo_to_cdk (cdk_stream_getc (inp
));
652 sig
->keyid
[0] = read_32 (inp
);
653 sig
->keyid
[1] = read_32 (inp
);
654 sig
->last
= cdk_stream_getc (inp
);
660 parse_sig_subpackets (cdk_pkt_signature_t sig
)
664 /* Setup the standard packet entries, so we can use V4
665 signatures similar to V3. */
666 for (node
= sig
->unhashed
; node
; node
= node
->next
)
668 if (node
->type
== CDK_SIGSUBPKT_ISSUER
&& node
->size
>= 8)
670 sig
->keyid
[0] = _cdk_buftou32 (node
->d
);
671 sig
->keyid
[1] = _cdk_buftou32 (node
->d
+ 4);
673 else if (node
->type
== CDK_SIGSUBPKT_EXPORTABLE
&& node
->d
[0] == 0)
675 /* Sometimes this packet might be placed in the unhashed area */
676 sig
->flags
.exportable
= 0;
679 for (node
= sig
->hashed
; node
; node
= node
->next
)
681 if (node
->type
== CDK_SIGSUBPKT_SIG_CREATED
&& node
->size
>= 4)
682 sig
->timestamp
= _cdk_buftou32 (node
->d
);
683 else if (node
->type
== CDK_SIGSUBPKT_SIG_EXPIRE
&& node
->size
>= 4)
685 sig
->expiredate
= _cdk_buftou32 (node
->d
);
686 if (sig
->expiredate
> 0 && sig
->expiredate
< (u32
) gnutls_time (NULL
))
687 sig
->flags
.expired
= 1;
689 else if (node
->type
== CDK_SIGSUBPKT_POLICY
)
690 sig
->flags
.policy_url
= 1;
691 else if (node
->type
== CDK_SIGSUBPKT_NOTATION
)
692 sig
->flags
.notation
= 1;
693 else if (node
->type
== CDK_SIGSUBPKT_REVOCABLE
&& node
->d
[0] == 0)
694 sig
->flags
.revocable
= 0;
695 else if (node
->type
== CDK_SIGSUBPKT_EXPORTABLE
&& node
->d
[0] == 0)
696 sig
->flags
.exportable
= 0;
698 if (sig
->sig_class
== 0x1F)
700 cdk_desig_revoker_t r
, rnode
;
702 for (node
= sig
->hashed
; node
; node
= node
->next
)
704 if (node
->type
== CDK_SIGSUBPKT_REV_KEY
)
708 rnode
= cdk_calloc (1, sizeof *rnode
);
710 return CDK_Out_Of_Core
;
711 rnode
->r_class
= node
->d
[0];
712 rnode
->algid
= node
->d
[1];
713 memcpy (rnode
->fpr
, node
->d
+ 2, KEY_FPR_LEN
);
715 sig
->revkeys
= rnode
;
718 for (r
= sig
->revkeys
; r
->next
; r
= r
->next
)
731 read_signature (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_signature_t sig
)
739 return gnutls_assert_val(CDK_Inv_Value
);
742 _gnutls_write_log ("read_signature: %d octets\n", (int) pktlen
);
745 return gnutls_assert_val(CDK_Inv_Packet
);
746 sig
->version
= cdk_stream_getc (inp
);
747 if (sig
->version
< 2 || sig
->version
> 4)
748 return gnutls_assert_val(CDK_Inv_Packet_Ver
);
750 sig
->flags
.exportable
= 1;
751 sig
->flags
.revocable
= 1;
753 if (sig
->version
< 4)
755 if (cdk_stream_getc (inp
) != 5)
756 return gnutls_assert_val(CDK_Inv_Packet
);
757 sig
->sig_class
= cdk_stream_getc (inp
);
758 sig
->timestamp
= read_32 (inp
);
759 sig
->keyid
[0] = read_32 (inp
);
760 sig
->keyid
[1] = read_32 (inp
);
761 sig
->pubkey_algo
= _pgp_pub_algo_to_cdk (cdk_stream_getc (inp
));
762 sig
->digest_algo
= _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp
));
763 sig
->digest_start
[0] = cdk_stream_getc (inp
);
764 sig
->digest_start
[1] = cdk_stream_getc (inp
);
765 nsig
= cdk_pk_get_nsig (sig
->pubkey_algo
);
767 return gnutls_assert_val(CDK_Inv_Algo
);
768 for (i
= 0; i
< nsig
; i
++)
770 rc
= read_mpi (inp
, &sig
->mpi
[i
], 0);
772 return gnutls_assert_val(rc
);
777 sig
->sig_class
= cdk_stream_getc (inp
);
778 sig
->pubkey_algo
= _pgp_pub_algo_to_cdk (cdk_stream_getc (inp
));
779 sig
->digest_algo
= _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp
));
780 sig
->hashed_size
= read_16 (inp
);
781 size
= sig
->hashed_size
;
785 rc
= read_subpkt (inp
, &sig
->hashed
, &nbytes
);
787 return gnutls_assert_val(rc
);
790 sig
->unhashed_size
= read_16 (inp
);
791 size
= sig
->unhashed_size
;
792 sig
->unhashed
= NULL
;
795 rc
= read_subpkt (inp
, &sig
->unhashed
, &nbytes
);
797 return gnutls_assert_val(rc
);
801 rc
= parse_sig_subpackets (sig
);
803 return gnutls_assert_val(rc
);
805 sig
->digest_start
[0] = cdk_stream_getc (inp
);
806 sig
->digest_start
[1] = cdk_stream_getc (inp
);
807 nsig
= cdk_pk_get_nsig (sig
->pubkey_algo
);
809 return gnutls_assert_val(CDK_Inv_Algo
);
810 for (i
= 0; i
< nsig
; i
++)
812 rc
= read_mpi (inp
, &sig
->mpi
[i
], 0);
814 return gnutls_assert_val(rc
);
823 read_literal (cdk_stream_t inp
, size_t pktlen
,
824 cdk_pkt_literal_t
* ret_pt
, int is_partial
)
826 cdk_pkt_literal_t pt
= *ret_pt
;
831 return CDK_Inv_Value
;
834 _gnutls_write_log ("read_literal: %d octets\n", (int) pktlen
);
836 pt
->mode
= cdk_stream_getc (inp
);
837 if (pt
->mode
!= 0x62 && pt
->mode
!= 0x74 && pt
->mode
!= 0x75)
838 return CDK_Inv_Packet
;
839 if (cdk_stream_eof (inp
))
840 return CDK_Inv_Packet
;
842 pt
->namelen
= cdk_stream_getc (inp
);
845 *ret_pt
= pt
= cdk_realloc (pt
, sizeof *pt
+ pt
->namelen
+ 2);
847 return CDK_Out_Of_Core
;
848 pt
->name
= (char *) pt
+ sizeof (*pt
);
849 rc
= stream_read (inp
, pt
->name
, pt
->namelen
, &nread
);
852 if ((int) nread
!= pt
->namelen
)
853 return CDK_Inv_Packet
;
854 pt
->name
[pt
->namelen
] = '\0';
856 pt
->timestamp
= read_32 (inp
);
857 pktlen
= pktlen
- 6 - pt
->namelen
;
859 _cdk_stream_set_blockmode (inp
, pktlen
);
866 /* Read an old packet CTB and return the length of the body. */
868 read_old_length (cdk_stream_t inp
, int ctb
, size_t * r_len
, size_t * r_size
)
870 int llen
= ctb
& 0x03;
874 *r_len
= cdk_stream_getc (inp
);
879 *r_len
= read_16 (inp
);
884 *r_len
= read_32 (inp
);
895 /* Read a new CTB and decode the body length. */
897 read_new_length (cdk_stream_t inp
,
898 size_t * r_len
, size_t * r_size
, size_t * r_partial
)
902 c
= cdk_stream_getc (inp
);
906 else if (c
>= 192 && c
<= 223)
908 c1
= cdk_stream_getc (inp
);
910 *r_len
= ((c
- 192) << 8) + c1
+ 192;
914 *r_len
= read_32 (inp
);
919 *r_len
= 1 << (c
& 0x1f);
925 /* Skip the current packet body. */
927 skip_packet (cdk_stream_t inp
, size_t pktlen
)
930 size_t nread
, buflen
= DIM (buf
);
934 stream_read (inp
, buf
, pktlen
> buflen
? buflen
: pktlen
, &nread
);
938 assert (pktlen
== 0);
944 * @inp: the input stream
945 * @pkt: allocated packet handle to store the packet
947 * Parse the next packet on the @inp stream and return its contents in @pkt.
950 cdk_pkt_read (cdk_stream_t inp
, cdk_packet_t pkt
)
954 size_t pktlen
= 0, pktsize
= 0, is_partial
= 0;
958 return CDK_Inv_Value
;
960 ctb
= cdk_stream_getc (inp
);
961 if (cdk_stream_eof (inp
) || ctb
== EOF
)
964 return gnutls_assert_val(CDK_Inv_Packet
);
969 _cdk_log_info ("cdk_pkt_read: no openpgp data found. "
970 "(ctb=%02X; fpos=%02X)\n", (int) ctb
,
971 (int) cdk_stream_tell (inp
));
972 return gnutls_assert_val(CDK_Inv_Packet
);
975 if (ctb
& 0x40) /* RFC2440 packet format. */
977 pkttype
= ctb
& 0x3f;
980 else /* the old RFC1991 packet format. */
982 pkttype
= ctb
& 0x3f;
989 _cdk_log_info ("cdk_pkt_read: unknown type %d\n", pkttype
);
990 return gnutls_assert_val(CDK_Inv_Packet
);
994 read_new_length (inp
, &pktlen
, &pktsize
, &is_partial
);
996 read_old_length (inp
, ctb
, &pktlen
, &pktsize
);
998 pkt
->pkttype
= pkttype
;
999 pkt
->pktlen
= pktlen
;
1000 pkt
->pktsize
= pktsize
+ pktlen
;
1001 pkt
->old_ctb
= is_newctb
? 0 : 1;
1004 switch (pkt
->pkttype
)
1006 case CDK_PKT_ATTRIBUTE
:
1007 #define NAME_SIZE (pkt->pktlen + 16 + 1)
1008 pkt
->pkt
.user_id
= cdk_calloc (1, sizeof *pkt
->pkt
.user_id
1010 if (!pkt
->pkt
.user_id
)
1011 return gnutls_assert_val(CDK_Out_Of_Core
);
1012 pkt
->pkt
.user_id
->name
=
1013 (char *) pkt
->pkt
.user_id
+ sizeof (*pkt
->pkt
.user_id
);
1015 rc
= read_attribute (inp
, pktlen
, pkt
->pkt
.user_id
, NAME_SIZE
);
1016 pkt
->pkttype
= CDK_PKT_ATTRIBUTE
;
1018 return gnutls_assert_val(rc
);
1021 case CDK_PKT_USER_ID
:
1022 pkt
->pkt
.user_id
= cdk_calloc (1, sizeof *pkt
->pkt
.user_id
1024 if (!pkt
->pkt
.user_id
)
1025 return gnutls_assert_val(CDK_Out_Of_Core
);
1026 pkt
->pkt
.user_id
->name
=
1027 (char *) pkt
->pkt
.user_id
+ sizeof (*pkt
->pkt
.user_id
);
1028 rc
= read_user_id (inp
, pktlen
, pkt
->pkt
.user_id
);
1030 return gnutls_assert_val(rc
);
1033 case CDK_PKT_PUBLIC_KEY
:
1034 pkt
->pkt
.public_key
= cdk_calloc (1, sizeof *pkt
->pkt
.public_key
);
1035 if (!pkt
->pkt
.public_key
)
1036 return gnutls_assert_val(CDK_Out_Of_Core
);
1037 rc
= read_public_key (inp
, pktlen
, pkt
->pkt
.public_key
);
1039 return gnutls_assert_val(rc
);
1042 case CDK_PKT_PUBLIC_SUBKEY
:
1043 pkt
->pkt
.public_key
= cdk_calloc (1, sizeof *pkt
->pkt
.public_key
);
1044 if (!pkt
->pkt
.public_key
)
1045 return gnutls_assert_val(CDK_Out_Of_Core
);
1046 rc
= read_public_subkey (inp
, pktlen
, pkt
->pkt
.public_key
);
1048 return gnutls_assert_val(rc
);
1051 case CDK_PKT_SECRET_KEY
:
1052 pkt
->pkt
.secret_key
= cdk_calloc (1, sizeof *pkt
->pkt
.secret_key
);
1053 if (!pkt
->pkt
.secret_key
)
1054 return gnutls_assert_val(CDK_Out_Of_Core
);
1055 pkt
->pkt
.secret_key
->pk
= cdk_calloc (1,
1056 sizeof *pkt
->pkt
.secret_key
->pk
);
1057 if (!pkt
->pkt
.secret_key
->pk
)
1058 return gnutls_assert_val(CDK_Out_Of_Core
);
1059 rc
= read_secret_key (inp
, pktlen
, pkt
->pkt
.secret_key
);
1061 return gnutls_assert_val(rc
);
1064 case CDK_PKT_SECRET_SUBKEY
:
1065 pkt
->pkt
.secret_key
= cdk_calloc (1, sizeof *pkt
->pkt
.secret_key
);
1066 if (!pkt
->pkt
.secret_key
)
1067 return gnutls_assert_val(CDK_Out_Of_Core
);
1068 pkt
->pkt
.secret_key
->pk
= cdk_calloc (1,
1069 sizeof *pkt
->pkt
.secret_key
->pk
);
1070 if (!pkt
->pkt
.secret_key
->pk
)
1071 return gnutls_assert_val(CDK_Out_Of_Core
);
1072 rc
= read_secret_subkey (inp
, pktlen
, pkt
->pkt
.secret_key
);
1074 return gnutls_assert_val(rc
);
1077 case CDK_PKT_LITERAL
:
1078 pkt
->pkt
.literal
= cdk_calloc (1, sizeof *pkt
->pkt
.literal
);
1079 if (!pkt
->pkt
.literal
)
1080 return gnutls_assert_val(CDK_Out_Of_Core
);
1081 rc
= read_literal (inp
, pktlen
, &pkt
->pkt
.literal
, is_partial
);
1083 return gnutls_assert_val(rc
);
1086 case CDK_PKT_ONEPASS_SIG
:
1087 pkt
->pkt
.onepass_sig
= cdk_calloc (1, sizeof *pkt
->pkt
.onepass_sig
);
1088 if (!pkt
->pkt
.onepass_sig
)
1089 return gnutls_assert_val(CDK_Out_Of_Core
);
1090 rc
= read_onepass_sig (inp
, pktlen
, pkt
->pkt
.onepass_sig
);
1092 return gnutls_assert_val(rc
);
1095 case CDK_PKT_SIGNATURE
:
1096 pkt
->pkt
.signature
= cdk_calloc (1, sizeof *pkt
->pkt
.signature
);
1097 if (!pkt
->pkt
.signature
)
1098 return gnutls_assert_val(CDK_Out_Of_Core
);
1099 rc
= read_signature (inp
, pktlen
, pkt
->pkt
.signature
);
1101 return gnutls_assert_val(rc
);
1104 case CDK_PKT_PUBKEY_ENC
:
1105 pkt
->pkt
.pubkey_enc
= cdk_calloc (1, sizeof *pkt
->pkt
.pubkey_enc
);
1106 if (!pkt
->pkt
.pubkey_enc
)
1107 return gnutls_assert_val(CDK_Out_Of_Core
);
1108 rc
= read_pubkey_enc (inp
, pktlen
, pkt
->pkt
.pubkey_enc
);
1110 return gnutls_assert_val(rc
);
1113 case CDK_PKT_COMPRESSED
:
1114 pkt
->pkt
.compressed
= cdk_calloc (1, sizeof *pkt
->pkt
.compressed
);
1115 if (!pkt
->pkt
.compressed
)
1116 return gnutls_assert_val(CDK_Out_Of_Core
);
1117 rc
= read_compressed (inp
, pktlen
, pkt
->pkt
.compressed
);
1119 return gnutls_assert_val(rc
);
1123 pkt
->pkt
.mdc
= cdk_calloc (1, sizeof *pkt
->pkt
.mdc
);
1125 return gnutls_assert_val(CDK_Out_Of_Core
);
1126 rc
= read_mdc (inp
, pkt
->pkt
.mdc
);
1128 return gnutls_assert_val(rc
);
1132 /* Skip all packets we don't understand */
1133 skip_packet (inp
, pktlen
);