1 /* read-packet.c - Read OpenPGP packets
2 * Copyright (C) 2001, 2002, 2003 Timo Schulz
4 * This file is part of OpenCDK.
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with OpenCDK; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
35 stream_getc( cdk_stream_t s
)
37 return cdk_stream_getc( s
);
43 stream_read (cdk_stream_t s
, void * buf
, size_t count
, size_t * r_nread
)
45 int nread
= cdk_stream_read (s
, buf
, count
);
47 return CDK_File_Error
;
55 read_32 (cdk_stream_t buf
)
63 if( (c
= stream_getc( buf
)) == EOF
)
66 if( (c
= stream_getc( buf
)) == EOF
)
69 if( (c
= stream_getc( buf
)) == EOF
)
72 if( (c
= stream_getc( buf
)) == EOF
)
80 read_16 (cdk_stream_t buf
)
88 if( (c
= stream_getc( buf
)) == EOF
)
91 if( (c
= stream_getc( buf
)) == EOF
)
98 #define check_s2k_mode( mode ) ( \
99 (mode) == CDK_S2K_SIMPLE \
100 || (mode) == CDK_S2K_SALTED \
101 || (mode) == CDK_S2K_ITERSALTED \
105 read_s2k( cdk_stream_t inp
, cdk_s2k_t s2k
)
111 return CDK_Inv_Value
;
114 _cdk_log_debug( "** read S2K part\n" );
116 s2k
->mode
= stream_getc( inp
);
117 if( s2k
->mode
== EOF
|| !check_s2k_mode( s2k
->mode
) )
118 return CDK_Inv_Packet
;
119 s2k
->hash_algo
= stream_getc( inp
);
120 if( s2k
->mode
== CDK_S2K_SIMPLE
) {
121 memset( s2k
->salt
, 0, sizeof s2k
->salt
);
122 /* nothing else to do */
124 else if( s2k
->mode
== CDK_S2K_SALTED
|| s2k
->mode
== CDK_S2K_ITERSALTED
) {
125 rc
= stream_read( inp
, s2k
->salt
, sizeof s2k
->salt
, &nread
);
126 if( !rc
&& nread
!= sizeof s2k
->salt
)
127 return CDK_Inv_Packet
;
128 if( !rc
&& s2k
->mode
== CDK_S2K_ITERSALTED
) {
129 s2k
->count
= stream_getc( inp
);
130 if( s2k
->count
== EOF
)
131 return CDK_Inv_Packet
;
141 read_mpi (cdk_stream_t inp
, cdk_mpi_t
* ret_m
, int secure
)
144 size_t nread
= 0, nbits
= 0, nbytes
= 0;
148 return CDK_Inv_Value
;
151 _cdk_log_debug ("** read MPI part\n");
153 nbits
= read_16 (inp
);
154 nbytes
= (nbits
+ 7) / 8;
155 if( nbits
> MAX_MPI_BITS
|| nbits
== 0 )
156 return CDK_MPI_Error
; /* sanity check */
157 m
= secure
? cdk_salloc( sizeof *m
+ nbytes
+ 2, 1 ) :
158 cdk_calloc( 1, sizeof *m
+ nbytes
+ 2 );
160 return CDK_Out_Of_Core
;
164 /* the prefix encodes the length of the MPI data */
165 m
->data
[0] = nbits
>> 8;
167 rc
= stream_read( inp
, m
->data
+ 2, nbytes
, &nread
);
168 if( !rc
&& nread
!= nbytes
)
176 _cdk_pkt_read_len( FILE * inp
, int * ret_partial
)
181 if( (c1
= fgetc (inp
)) == EOF
)
183 if( c1
< 224 || c1
== 255 )
184 *ret_partial
= 0; /* end of partial data */
187 else if( c1
>= 192 && c1
<= 223 ) {
188 if( (c2
= fgetc( inp
)) == EOF
)
190 pktlen
= ((c1
- 192) << 8) + c2
+ 192;
192 else if( c1
== 255 ) {
193 pktlen
= fgetc( inp
) << 24;
194 pktlen
|= fgetc( inp
) << 16;
195 pktlen
|= fgetc( inp
) << 8;
196 pktlen
|= fgetc( inp
);
201 pktlen
= 1 << (c1
& 0x1f);
207 read_encrypted( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_encrypted_t enc
,
208 int partial
, int mdc
)
213 return CDK_Inv_Value
;
216 _cdk_log_debug( "** read encrypted packet %d bytes\n", pktlen
);
219 version
= stream_getc( inp
);
221 return CDK_Inv_Packet
;
222 enc
->mdc_method
= CDK_MD_SHA1
;
226 return CDK_Inv_Packet
; /* we need at least blocksize + 2 bytes */
228 _cdk_stream_set_blockmode( inp
, pktlen
);
236 read_symkey_enc( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_symkey_enc_t ske
)
239 size_t nread
= 0, minlen
= 0;
243 return CDK_Inv_Value
;
246 _cdk_log_debug( "** read symmetric key encrypted packet\n" );
248 ske
->version
= stream_getc( inp
);
249 if( ske
->version
!= 4 )
250 return CDK_Inv_Packet
;
252 s2k
= ske
->s2k
= cdk_calloc( 1, sizeof *ske
->s2k
);
254 return CDK_Out_Of_Core
;
256 ske
->cipher_algo
= stream_getc( inp
);
257 s2k
->mode
= stream_getc( inp
);
258 switch( s2k
->mode
) {
259 case 0: minlen
= 0; break;
260 case 1: minlen
= 8; break;
261 case 3: minlen
= 9; break;
263 s2k
->hash_algo
= stream_getc( inp
);
265 ; /* nothing to do */
266 else if( s2k
->mode
== 1 || s2k
->mode
== 3 ) {
267 rc
= stream_read( inp
, s2k
->salt
, DIM (s2k
->salt
), &nread
);
268 if( !rc
&& nread
!= DIM( s2k
->salt
) )
269 return CDK_Inv_Packet
;
270 if( !rc
&& s2k
->mode
== 3 )
271 s2k
->count
= stream_getc( inp
);
274 return CDK_Inv_Packet
;
275 ske
->seskeylen
= pktlen
- 4 - minlen
;
276 if( ske
->seskeylen
> sizeof ske
->seskey
)
277 return CDK_Inv_Packet
;
278 for( nread
= 0; nread
< ske
->seskeylen
; nread
++ ) {
279 ske
->seskey
[nread
] = stream_getc( inp
);
280 if( cdk_stream_eof( inp
) )
288 read_pubkey_enc( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_pubkey_enc_t pke
)
294 return CDK_Inv_Value
;
297 _cdk_log_debug( "** read public key encrypted packet\n" );
300 return CDK_Inv_Packet
;
301 pke
->version
= stream_getc( inp
);
302 if( pke
->version
< 2 || pke
->version
> 3 )
303 return CDK_Inv_Packet
;
304 pke
->keyid
[0] = read_32( inp
);
305 pke
->keyid
[1] = read_32( inp
);
306 if( !pke
->keyid
[0] && !pke
->keyid
[1] )
307 pke
->throw_keyid
= 1; /* RFC2440 "speculative" keyID */
308 pke
->pubkey_algo
= stream_getc( inp
);
309 nenc
= cdk_pk_get_nenc( pke
->pubkey_algo
);
312 for( i
= 0; i
< nenc
; i
++ ) {
313 rc
= read_mpi( inp
, &pke
->mpi
[i
], 0 );
322 read_mdc( cdk_stream_t inp
, cdk_pkt_mdc_t mdc
)
328 return CDK_Inv_Value
;
331 _cdk_log_debug ("** read MDC packet\n");
333 rc
= stream_read( inp
, mdc
->hash
, 20, &n
);
341 read_compressed( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_compressed_t c
)
344 return CDK_Inv_Value
;
347 _cdk_log_debug ("** read compressed packet\n");
349 c
->algorithm
= stream_getc( inp
);
350 if( c
->algorithm
> 2 )
351 return CDK_Inv_Packet
;
353 /* don't know the size, so we read until EOF */
364 read_public_key( cdk_stream_t inp
, cdk_pkt_pubkey_t pk
)
366 int i
= 0, ndays
, npkey
;
370 return CDK_Inv_Value
;
373 _cdk_log_debug( "** read public key packet\n" );
375 pk
->is_invalid
= 1; /* default to detect missing self signatures */
379 pk
->version
= stream_getc( inp
);
380 if( pk
->version
< 2 || pk
->version
> 4 )
381 return CDK_Inv_Packet_Ver
;
382 pk
->timestamp
= read_32( inp
);
383 if( pk
->version
< 4 ) {
384 ndays
= read_16( inp
);
386 pk
->expiredate
= pk
->timestamp
+ ndays
* 86400L;
388 pk
->pubkey_algo
= stream_getc( inp
);
389 npkey
= cdk_pk_get_npkey( pk
->pubkey_algo
);
392 for( i
= 0; i
< npkey
; i
++ ) {
393 rc
= read_mpi( inp
, &pk
->mpi
[i
], 0 );
397 pk
->pubkey_usage
= _cdk_pk_algo_usage( pk
->pubkey_algo
);
403 read_public_subkey( cdk_stream_t inp
, cdk_pkt_pubkey_t pk
)
406 return CDK_Inv_Value
;
407 return read_public_key( inp
, pk
);
412 read_secret_key( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_seckey_t sk
)
414 size_t p1
= 0, p2
= 0, nread
= 0;
415 int i
= 0, blklen
= 0, nskey
= 0;
418 if( !inp
|| !sk
|| !sk
->pk
)
419 return CDK_Inv_Value
;
422 _cdk_log_debug ("** read secret key\n");
424 p1
= cdk_stream_tell( inp
);
425 rc
= read_public_key( inp
, sk
->pk
);
429 sk
->s2k_usage
= stream_getc( inp
);
430 sk
->protect
.sha1chk
= 0;
431 if( sk
->s2k_usage
== 254 || sk
->s2k_usage
== 255 ) {
432 sk
->protect
.sha1chk
= (sk
->s2k_usage
== 254);
433 sk
->protect
.algo
= stream_getc( inp
);
434 sk
->protect
.s2k
= cdk_calloc( 1, sizeof *sk
->protect
.s2k
);
435 if( !sk
->protect
.s2k
)
436 return CDK_Out_Of_Core
;
437 rc
= read_s2k( inp
, sk
->protect
.s2k
);
440 blklen
= cdk_cipher_get_algo_blklen( sk
->protect
.algo
);
442 return CDK_Inv_Packet
;
443 sk
->protect
.ivlen
= blklen
;
444 rc
= stream_read( inp
, sk
->protect
.iv
, sk
->protect
.ivlen
, &nread
);
445 if( !rc
&& nread
!= sk
->protect
.ivlen
)
446 return CDK_Inv_Packet
;
449 sk
->protect
.algo
= sk
->s2k_usage
;
450 if( sk
->protect
.algo
== CDK_CIPHER_NONE
) {
452 nskey
= cdk_pk_get_nskey( sk
->pk
->pubkey_algo
);
455 for( i
= 0; i
< nskey
; i
++ ) {
456 rc
= read_mpi( inp
, &sk
->mpi
[i
], 1 );
461 sk
->csum
= read_16( inp
);
462 sk
->is_protected
= 0;
465 else if( sk
->pk
->version
< 4 ) {
466 /* mpi size isn't encrypted! */
467 nskey
= cdk_pk_get_nskey( sk
->pk
->pubkey_algo
);
470 for( i
= 0; i
< nskey
; i
++ ) {
471 rc
= read_mpi( inp
, &sk
->mpi
[i
], 1 );
476 sk
->csum
= read_16( inp
);
477 sk
->is_protected
= 1;
481 /* we need to read the rest of the packet because we don't
482 have any information how long the encrypted mpi's are */
483 p2
= cdk_stream_tell( inp
);
485 sk
->enclen
= pktlen
- p2
;
487 return CDK_Inv_Packet
; /* at least 16 bits for the checksum! */
488 sk
->encdata
= cdk_calloc( 1, sk
->enclen
+ 1 );
490 return CDK_Out_Of_Core
;
491 rc
= stream_read( inp
, sk
->encdata
, sk
->enclen
, &nread
);
493 return CDK_Inv_Packet
;
494 nskey
= cdk_pk_get_nskey( sk
->pk
->pubkey_algo
);
497 for( i
= 0; i
< nskey
; i
++ )
499 sk
->is_protected
= 1;
502 _cdk_copy_pk_to_sk( sk
->pk
, sk
);
508 read_secret_subkey( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_seckey_t sk
)
512 if( !inp
|| !sk
|| !sk
->pk
)
513 return CDK_Inv_Value
;
515 rc
= read_secret_key( inp
, pktlen
, sk
);
522 read_attribute (cdk_stream_t inp
, size_t pktlen
, cdk_pkt_userid_t attr
)
530 if( !inp
|| !attr
|| !pktlen
)
531 return CDK_Inv_Value
;
533 strcpy( attr
->name
, "[attribute]" );
534 attr
->len
= strlen( attr
->name
);
535 buf
= cdk_calloc( 1, pktlen
);
537 return CDK_Out_Of_Core
;
538 rc
= stream_read( inp
, buf
, pktlen
, &nread
);
541 return CDK_Inv_Packet
;
546 len
= _cdk_buftou32( p
);
550 else if (len
>= 192) {
553 return CDK_Inv_Packet
;
555 len
= ((len
- 192) << 8) + *p
+ 192;
559 if( *p
!= 1 ) { /* ATTRIBUTE IMAGE */
561 return CDK_Inv_Packet
;
565 attr
->attrib_img
= cdk_calloc( 1, len
);
566 if( !attr
->attrib_img
)
567 return CDK_Out_Of_Core
;
568 attr
->attrib_len
= len
;
569 memcpy( attr
->attrib_img
, p
, len
);
576 read_user_id( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_userid_t user_id
)
581 if( !inp
|| !user_id
)
582 return CDK_Inv_Value
;
584 return CDK_Inv_Packet
;
587 _cdk_log_debug ("** read user ID packet: ");
589 user_id
->len
= pktlen
;
590 rc
= stream_read( inp
, user_id
->name
, pktlen
, &nread
);
591 if( !rc
&& nread
!= pktlen
)
592 return CDK_Inv_Packet
;
593 user_id
->name
[nread
] = '\0';
595 _cdk_log_debug ("%s\n", user_id
->name
);
601 read_subpkt( cdk_stream_t inp
, cdk_subpkt_t
* r_ctx
, size_t * r_nbytes
)
604 size_t size
= 0, nread
, n
= 0;
608 if( !inp
|| !r_nbytes
)
609 return CDK_Inv_Value
;
612 _cdk_log_debug ("** read sub packet");
615 c
= stream_getc( inp
);
618 size
= read_32( inp
);
620 node
= cdk_subpkt_new( size
);
622 else if( c
>= 192 && c
< 255 ) {
623 c1
= stream_getc( inp
);
627 size
= ((c
- 192) << 8) + c1
+ 192;
628 node
= cdk_subpkt_new( size
);
632 node
= cdk_subpkt_new( size
);
635 return CDK_Inv_Packet
;
638 _cdk_log_debug (" `%d' bytes\n", size
);
641 return CDK_Out_Of_Core
;
643 node
->type
= stream_getc( inp
);
646 rc
= stream_read( inp
, node
->d
, node
->size
, &nread
);
654 cdk_subpkt_add( *r_ctx
, node
);
660 read_onepass_sig( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_onepass_sig_t sig
)
663 return CDK_Inv_Value
;
666 _cdk_log_debug ("** read one pass signature packet\n");
669 return CDK_Inv_Packet
;
670 sig
->version
= stream_getc( inp
);
671 if( sig
->version
!= 3 )
672 return CDK_Inv_Packet_Ver
;
673 sig
->sig_class
= stream_getc( inp
);
674 sig
->digest_algo
= stream_getc( inp
);
675 sig
->pubkey_algo
= stream_getc( inp
);
676 sig
->keyid
[0] = read_32( inp
);
677 sig
->keyid
[1] = read_32( inp
);
678 sig
->last
= stream_getc( inp
);
684 read_signature( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_signature_t sig
)
686 cdk_subpkt_t node
= NULL
;
692 return CDK_Inv_Value
;
695 _cdk_log_debug( "** read signature packet\n" );
698 return CDK_Inv_Packet
;
699 sig
->version
= stream_getc( inp
);
700 if( sig
->version
< 2 || sig
->version
> 4 )
701 return CDK_Inv_Packet_Ver
;
703 sig
->flags
.exportable
= 1;
704 sig
->flags
.revocable
= 1;
706 if( sig
->version
< 4 ) {
707 if( stream_getc( inp
) != 5 )
708 return CDK_Inv_Packet
;
709 sig
->sig_class
= stream_getc( inp
);
710 sig
->timestamp
= read_32( inp
);
711 sig
->keyid
[0] = read_32( inp
);
712 sig
->keyid
[1] = read_32( inp
);
713 sig
->pubkey_algo
= stream_getc( inp
);
714 sig
->digest_algo
= stream_getc( inp
);
715 sig
->digest_start
[0] = stream_getc( inp
);
716 sig
->digest_start
[1] = stream_getc( inp
);
717 nsig
= cdk_pk_get_nsig( sig
->pubkey_algo
);
720 for( i
= 0; i
< nsig
; i
++ ) {
721 rc
= read_mpi( inp
, &sig
->mpi
[i
], 0 );
727 sig
->sig_class
= stream_getc( inp
);
728 sig
->pubkey_algo
= stream_getc( inp
);
729 sig
->digest_algo
= stream_getc( inp
);
730 sig
->hashed_size
= read_16( inp
);
731 size
= sig
->hashed_size
;
734 rc
= read_subpkt( inp
, &sig
->hashed
, &nbytes
);
739 sig
->unhashed_size
= read_16( inp
);
740 size
= sig
->unhashed_size
;
741 sig
->unhashed
= NULL
;
743 rc
= read_subpkt( inp
, &sig
->unhashed
, &nbytes
);
749 /* Setup the standard packet entries, so we can use V4
750 signatures similar to V3. */
751 for( node
= sig
->unhashed
; node
; node
= node
->next
) {
752 if( node
->type
== CDK_SIGSUBPKT_ISSUER
) {
753 sig
->keyid
[0] = _cdk_buftou32( node
->d
);
754 sig
->keyid
[1] = _cdk_buftou32( node
->d
+ 4 );
756 else if( node
->type
== CDK_SIGSUBPKT_EXPORTABLE
757 && node
->d
[0] == 0 ) {
758 /* this packet might be also placed in the unhashed area */
759 sig
->flags
.exportable
= 0;
762 for( node
= sig
->hashed
; node
; node
= node
->next
) {
763 if( node
->type
== CDK_SIGSUBPKT_SIG_CREATED
)
764 sig
->timestamp
= _cdk_buftou32( node
->d
);
765 else if( node
->type
== CDK_SIGSUBPKT_SIG_EXPIRE
) {
766 sig
->expiredate
= _cdk_buftou32( node
->d
);
767 if( sig
->expiredate
> 0
768 && sig
->expiredate
< _cdk_timestamp() )
769 sig
->flags
.expired
= 1;
771 else if( node
->type
== CDK_SIGSUBPKT_POLICY
)
772 sig
->flags
.policy_url
= 1;
773 else if( node
->type
== CDK_SIGSUBPKT_NOTATION
)
774 sig
->flags
.notation
= 1;
775 else if( node
->type
== CDK_SIGSUBPKT_REVOCABLE
&& node
->d
[0] == 0 )
776 sig
->flags
.revocable
= 0;
777 else if( node
->type
== CDK_SIGSUBPKT_EXPORTABLE
779 sig
->flags
.exportable
= 0;
781 if( sig
->sig_class
== 0x1F ) {
782 cdk_desig_revoker_t r
, rnode
;
783 for( node
= sig
->hashed
; node
; node
= node
->next
) {
784 if( node
->type
== CDK_SIGSUBPKT_REV_KEY
) {
785 rnode
= cdk_calloc( 1, sizeof * rnode
);
787 return CDK_Out_Of_Core
;
788 rnode
->class = node
->d
[0];
789 rnode
->algid
= node
->d
[1];
790 memcpy( rnode
->fpr
, node
->d
+2, 20 );
792 sig
->revkeys
= rnode
;
794 for( r
= sig
->revkeys
; r
->next
; r
= r
->next
)
801 sig
->digest_start
[0] = stream_getc( inp
);
802 sig
->digest_start
[1] = stream_getc( inp
);
803 nsig
= cdk_pk_get_nsig( sig
->pubkey_algo
);
806 for( i
= 0; i
< nsig
; i
++ ) {
807 rc
= read_mpi( inp
, &sig
->mpi
[i
], 0 );
817 read_literal( cdk_stream_t inp
, size_t pktlen
, cdk_pkt_literal_t
* ret_pt
,
820 cdk_pkt_literal_t pt
= *ret_pt
;
825 return CDK_Inv_Value
;
828 _cdk_log_debug( "** read literal packet\n" );
830 pt
->mode
= stream_getc( inp
);
831 if( pt
->mode
!= 0x62 && pt
->mode
!= 0x74 )
832 return CDK_Inv_Packet
;
833 pt
->namelen
= stream_getc( inp
);
835 *ret_pt
= pt
= cdk_realloc( pt
, sizeof * pt
+ pt
->namelen
+ 1 );
837 return CDK_Out_Of_Core
;
838 rc
= stream_read( inp
, pt
->name
, pt
->namelen
, &nread
);
839 if( !rc
&& nread
!= pt
->namelen
)
840 return CDK_Inv_Packet
;
841 pt
->name
[pt
->namelen
] = '\0';
843 pt
->timestamp
= read_32( inp
);
844 pktlen
= pktlen
- 6 - pt
->namelen
;
846 _cdk_stream_set_blockmode( inp
, pktlen
);
854 read_old_length( cdk_stream_t inp
, int ctb
, size_t *r_len
, size_t *r_size
)
856 int llen
= ctb
& 0x03;
859 *r_len
= stream_getc( inp
);
862 else if( llen
== 1 ) {
863 *r_len
= read_16( inp
);
866 else if( llen
== 2 ) {
867 *r_len
= read_32( inp
);
878 read_new_length( cdk_stream_t inp
,
879 size_t *r_len
, size_t *r_size
, size_t *r_partial
)
883 c
= stream_getc( inp
);
887 else if( c
>= 192 && c
<= 223 ) {
888 c1
= stream_getc( inp
);
890 *r_len
= ((c
- 192) << 8) + c1
+ 192;
892 else if( c
== 255 ) {
893 *r_len
= read_32( inp
);
897 *r_len
= 1 << (c
& 0x1f);
903 /* we use a buffer to make it faster to skip larger unknown packets. */
905 skip_packet( cdk_stream_t inp
, size_t pktlen
)
910 while( pktlen
> 4095 ) {
911 stream_read( inp
, buf
, sizeof buf
-1, &nread
);
914 stream_read( inp
, buf
, pktlen
, &nread
);
916 assert( pktlen
== 0 );
922 * @inp: the input stream
923 * @pkt: allocated packet handle to store the packet
925 * Parse the next packet on the @inp stream and return its contents in @pkt.
928 cdk_pkt_read( cdk_stream_t inp
, cdk_packet_t pkt
)
931 int ctb
= 0, is_newctb
= 0, is_partial
= 0;
932 int rc
= 0, pkttype
= 0;
933 size_t pktlen
= 0, pktsize
= 0;
936 return CDK_Inv_Value
;
938 ctb
= stream_getc( inp
);
939 if( cdk_stream_eof( inp
) || ctb
== EOF
)
942 return CDK_Inv_Packet
;
945 if( !(ctb
& 0x80) ) {
946 _cdk_log_info ("no valid openpgp data found. "
947 "(ctb=%02X; fpos=%02X)\n",ctb
, cdk_stream_tell( inp
) );
948 return CDK_Inv_Packet
;
950 if( ctb
& 0x40 ) { /* RFC2440 */
951 pkttype
= ctb
& 0x3f;
955 pkttype
= ctb
& 0x3f;
959 _cdk_log_info ("unknown packet type (%d)\n", pkttype
);
960 return CDK_Inv_Packet
;
963 read_new_length( inp
, &pktlen
, &pktsize
, &is_partial
);
965 read_old_length( inp
, ctb
, &pktlen
, &pktsize
);
967 pkt
->pkttype
= pkttype
;
968 pkt
->pktlen
= pktlen
;
969 pkt
->pktsize
= pktsize
+ pktlen
;
970 pkt
->old_ctb
= is_newctb
? 0 : 1;
972 switch( pkt
->pkttype
) {
973 case CDK_PKT_ATTRIBUTE
:
974 pkt
->pkt
.user_id
= cdk_calloc (1,
975 sizeof *pkt
->pkt
.user_id
+ pkt
->pktlen
);
976 if (!pkt
->pkt
.user_id
)
977 return CDK_Out_Of_Core
;
978 rc
= read_attribute (inp
, pktlen
, pkt
->pkt
.user_id
);
979 pkt
->pkttype
= CDK_PKT_USER_ID
; /* treated as an user id */
982 case CDK_PKT_USER_ID
:
983 pkt
->pkt
.user_id
= cdk_calloc (1,
984 sizeof *pkt
->pkt
.user_id
+ pkt
->pktlen
);
985 if (!pkt
->pkt
.user_id
)
986 return CDK_Out_Of_Core
;
987 rc
= read_user_id (inp
, pktlen
, pkt
->pkt
.user_id
);
990 case CDK_PKT_PUBLIC_KEY
:
991 pkt
->pkt
.public_key
= cdk_calloc (1, sizeof *pkt
->pkt
.public_key
);
992 if (!pkt
->pkt
.public_key
)
993 return CDK_Out_Of_Core
;
994 rc
= read_public_key (inp
, pkt
->pkt
.public_key
);
997 case CDK_PKT_PUBLIC_SUBKEY
:
998 pkt
->pkt
.public_key
= cdk_calloc (1, sizeof *pkt
->pkt
.public_key
);
999 if (!pkt
->pkt
.public_key
)
1000 return CDK_Out_Of_Core
;
1001 rc
= read_public_subkey (inp
, pkt
->pkt
.public_key
);
1004 case CDK_PKT_SECRET_KEY
:
1005 pkt
->pkt
.secret_key
= cdk_calloc (1, sizeof *pkt
->pkt
.secret_key
);
1006 if (!pkt
->pkt
.secret_key
)
1007 return CDK_Out_Of_Core
;
1008 pkt
->pkt
.secret_key
->pk
=cdk_calloc (1,
1009 sizeof *pkt
->pkt
.secret_key
->pk
);
1010 if (!pkt
->pkt
.secret_key
->pk
)
1011 return CDK_Out_Of_Core
;
1012 rc
= read_secret_key (inp
, pktlen
, pkt
->pkt
.secret_key
);
1015 case CDK_PKT_SECRET_SUBKEY
:
1016 pkt
->pkt
.secret_key
= cdk_calloc (1, sizeof *pkt
->pkt
.secret_key
);
1017 if (!pkt
->pkt
.secret_key
)
1018 return CDK_Out_Of_Core
;
1019 pkt
->pkt
.secret_key
->pk
=
1020 cdk_calloc (1, sizeof *pkt
->pkt
.secret_key
->pk
);
1021 if (!pkt
->pkt
.secret_key
->pk
)
1022 return CDK_Out_Of_Core
;
1023 rc
= read_secret_subkey (inp
, pktlen
, pkt
->pkt
.secret_key
);
1026 case CDK_PKT_LITERAL
:
1027 pkt
->pkt
.literal
= cdk_calloc( 1, sizeof *pkt
->pkt
.literal
);
1028 if (!pkt
->pkt
.literal
)
1029 return CDK_Out_Of_Core
;
1030 rc
= read_literal( inp
, pktlen
, &pkt
->pkt
.literal
, is_partial
);
1033 case CDK_PKT_ONEPASS_SIG
:
1034 pkt
->pkt
.onepass_sig
= cdk_calloc (1, sizeof *pkt
->pkt
.onepass_sig
);
1035 if (!pkt
->pkt
.onepass_sig
)
1036 return CDK_Out_Of_Core
;
1037 rc
= read_onepass_sig (inp
, pktlen
, pkt
->pkt
.onepass_sig
);
1040 case CDK_PKT_SIGNATURE
:
1041 pkt
->pkt
.signature
= cdk_calloc (1, sizeof *pkt
->pkt
.signature
);
1042 if (!pkt
->pkt
.signature
)
1043 return CDK_Out_Of_Core
;
1044 rc
= read_signature (inp
, pktlen
, pkt
->pkt
.signature
);
1047 case CDK_PKT_ENCRYPTED_MDC
:
1048 case CDK_PKT_ENCRYPTED
:
1049 pkt
->pkt
.encrypted
= cdk_calloc (1, sizeof *pkt
->pkt
.encrypted
);
1050 if (!pkt
->pkt
.encrypted
)
1051 return CDK_Out_Of_Core
;
1052 use_mdc
= (pkt
->pkttype
== CDK_PKT_ENCRYPTED_MDC
) ? 1 : 0;
1053 rc
= read_encrypted( inp
, pktlen
, pkt
->pkt
.encrypted
,
1054 is_partial
, use_mdc
);
1057 case CDK_PKT_SYMKEY_ENC
:
1058 pkt
->pkt
.symkey_enc
= cdk_calloc (1, sizeof *pkt
->pkt
.symkey_enc
);
1059 if (!pkt
->pkt
.symkey_enc
)
1060 return CDK_Out_Of_Core
;
1061 rc
= read_symkey_enc (inp
, pktlen
, pkt
->pkt
.symkey_enc
);
1064 case CDK_PKT_PUBKEY_ENC
:
1065 pkt
->pkt
.pubkey_enc
= cdk_calloc (1, sizeof *pkt
->pkt
.pubkey_enc
);
1066 if (!pkt
->pkt
.pubkey_enc
)
1067 return CDK_Out_Of_Core
;
1068 rc
= read_pubkey_enc (inp
, pktlen
, pkt
->pkt
.pubkey_enc
);
1071 case CDK_PKT_COMPRESSED
:
1072 pkt
->pkt
.compressed
= cdk_calloc (1, sizeof *pkt
->pkt
.compressed
);
1073 if (!pkt
->pkt
.compressed
)
1074 return CDK_Out_Of_Core
;
1075 rc
= read_compressed (inp
, pktlen
, pkt
->pkt
.compressed
);
1079 pkt
->pkt
.mdc
= cdk_calloc (1, sizeof *pkt
->pkt
.mdc
);
1081 return CDK_Out_Of_Core
;
1082 rc
= read_mdc (inp
, pkt
->pkt
.mdc
);
1086 /* skip all packets we don't understand */
1087 skip_packet( inp
, pktlen
);