1 /* write-packet.c - Write OpenPGP packets
2 * Copyright (C) 2001, 2002, 2003, 2007, 2008 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
36 stream_write (cdk_stream_t s
, const void *buf
, size_t buflen
)
40 nwritten
= cdk_stream_write (s
, buf
, buflen
);
42 return _cdk_stream_get_errno (s
);
48 stream_read (cdk_stream_t s
, void *buf
, size_t buflen
, size_t *r_nread
)
54 nread
= cdk_stream_read (s
, buf
, buflen
);
56 return _cdk_stream_get_errno (s
);
63 stream_putc (cdk_stream_t s
, int c
)
65 int nwritten
= cdk_stream_putc (s
, c
);
67 return _cdk_stream_get_errno (s
);
73 write_32 (cdk_stream_t out
, u32 u
)
81 return stream_write (out
, buf
, 4);
86 write_16 (cdk_stream_t out
, u16 u
)
92 return stream_write (out
, buf
, 2);
97 calc_mpisize (gcry_mpi_t mpi
[MAX_CDK_PK_PARTS
], size_t ncount
)
102 for (i
= 0; i
< ncount
; i
++)
103 size
+= (gcry_mpi_get_nbits (mpi
[i
]) + 7) / 8 + 2;
109 write_mpi (cdk_stream_t out
, gcry_mpi_t m
)
111 byte buf
[MAX_MPI_BYTES
+2];
116 return CDK_Inv_Value
;
117 nbits
= gcry_mpi_get_nbits (m
);
118 if (nbits
> MAX_MPI_BITS
|| nbits
< 1)
119 return CDK_MPI_Error
;
120 err
= gcry_mpi_print (GCRYMPI_FMT_PGP
, buf
, MAX_MPI_BYTES
+2, &nread
, m
);
122 return map_gcry_error (err
);
123 return stream_write (out
, buf
, nread
);
128 write_mpibuf (cdk_stream_t out
, gcry_mpi_t mpi
[MAX_CDK_PK_PARTS
], size_t count
)
133 for (i
= 0; i
< count
; i
++)
135 rc
= write_mpi (out
, mpi
[i
]);
144 pkt_encode_len (cdk_stream_t out
, size_t pktlen
)
153 /* Block mode, partial bodies, with 'DEF_BLOCKSIZE' from main.h */
154 rc
= stream_putc( out
, (0xE0|DEF_BLOCKBITS
) );
156 else if (pktlen
< 192)
157 rc
= stream_putc (out
, pktlen
);
158 else if (pktlen
< 8384)
161 rc
= stream_putc (out
, (pktlen
/ 256) + 192);
163 rc
= stream_putc (out
, (pktlen
% 256));
167 rc
= stream_putc (out
, 255);
169 rc
= write_32 (out
, pktlen
);
177 write_head_new (cdk_stream_t out
, size_t size
, int type
)
183 if (type
< 0 || type
> 63)
184 return CDK_Inv_Packet
;
185 rc
= stream_putc (out
, (0xC0 | type
));
187 rc
= pkt_encode_len (out
, size
);
193 write_head_old (cdk_stream_t out
, size_t size
, int type
)
200 if (type
< 0 || type
> 16)
201 return CDK_Inv_Packet
;
202 ctb
= 0x80 | (type
<< 2);
207 else if (size
< 65536)
211 rc
= stream_putc (out
, ctb
);
217 rc
= stream_putc (out
, size
);
218 else if (size
< 65536)
219 rc
= write_16 (out
, size
);
221 rc
= write_32 (out
, size
);
228 /* Write special PGP2 packet header. PGP2 (wrongly) uses two byte header
229 length for signatures and keys even if the size is < 256. */
231 pkt_write_head2 (cdk_stream_t out
, size_t size
, int type
)
235 rc
= cdk_stream_putc (out
, 0x80 | (type
<< 2) | 1);
237 rc
= cdk_stream_putc (out
, size
>> 8);
239 rc
= cdk_stream_putc (out
, size
& 0xff);
245 pkt_write_head (cdk_stream_t out
, int old_ctb
, size_t size
, int type
)
248 return write_head_old (out
, size
, type
);
249 return write_head_new (out
, size
, type
);
254 write_encrypted (cdk_stream_t out
, cdk_pkt_encrypted_t enc
, int old_ctb
)
263 _cdk_log_debug ("write_encrypted: %lu bytes\n", enc
->len
);
265 nbytes
= enc
->len
? (enc
->len
+ enc
->extralen
) : 0;
266 rc
= pkt_write_head (out
, old_ctb
, nbytes
, CDK_PKT_ENCRYPTED
);
267 /* The rest of the packet is ciphertext */
273 write_encrypted_mdc (cdk_stream_t out
, cdk_pkt_encrypted_t enc
)
281 if (!enc
->mdc_method
)
282 return CDK_Inv_Packet
;
285 _cdk_log_debug ("write_encrypted_mdc: %lu bytes\n", enc
->len
);
287 nbytes
= enc
->len
? (enc
->len
+ enc
->extralen
+ 1) : 0;
288 rc
= pkt_write_head (out
, 0, nbytes
, CDK_PKT_ENCRYPTED_MDC
);
290 rc
= stream_putc (out
, 1); /* version */
291 /* The rest of the packet is ciphertext */
297 write_symkey_enc (cdk_stream_t out
, cdk_pkt_symkey_enc_t ske
)
300 size_t size
= 0, s2k_size
= 0;
306 if (ske
->version
!= 4)
307 return CDK_Inv_Packet
;
310 _cdk_log_debug ("write_symkey_enc:\n");
313 if (s2k
->mode
== CDK_S2K_SALTED
|| s2k
->mode
== CDK_S2K_ITERSALTED
)
315 if (s2k
->mode
== CDK_S2K_ITERSALTED
)
317 size
= 4 + s2k_size
+ ske
->seskeylen
;
318 rc
= pkt_write_head (out
, 0, size
, CDK_PKT_SYMKEY_ENC
);
320 rc
= stream_putc (out
, ske
->version
);
322 rc
= stream_putc (out
, ske
->cipher_algo
);
324 rc
= stream_putc (out
, s2k
->mode
);
326 rc
= stream_putc (out
, s2k
->hash_algo
);
327 if (s2k
->mode
== CDK_S2K_SALTED
|| s2k
->mode
== CDK_S2K_ITERSALTED
)
329 rc
= stream_write (out
, s2k
->salt
, 8);
332 if (s2k
->mode
== CDK_S2K_ITERSALTED
)
333 rc
= stream_putc (out
, s2k
->count
);
341 write_pubkey_enc (cdk_stream_t out
, cdk_pkt_pubkey_enc_t pke
, int old_ctb
)
349 if (pke
->version
< 2 || pke
->version
> 3)
350 return CDK_Inv_Packet
;
351 if (!KEY_CAN_ENCRYPT (pke
->pubkey_algo
))
355 _cdk_log_debug ("write_pubkey_enc:\n");
357 nenc
= cdk_pk_get_nenc (pke
->pubkey_algo
);
358 size
= 10 + calc_mpisize (pke
->mpi
, nenc
);
359 rc
= pkt_write_head (out
, old_ctb
, size
, CDK_PKT_PUBKEY_ENC
);
363 rc
= stream_putc (out
, pke
->version
);
365 rc
= write_32 (out
, pke
->keyid
[0]);
367 rc
= write_32 (out
, pke
->keyid
[1]);
369 rc
= stream_putc (out
, pke
->pubkey_algo
);
371 rc
= write_mpibuf (out
, pke
->mpi
, nenc
);
377 write_mdc (cdk_stream_t out
, cdk_pkt_mdc_t mdc
)
385 _cdk_log_debug ("write_mdc:\n");
387 /* This packet requires a fixed header encoding */
388 rc
= stream_putc (out
, 0xD3); /* packet ID and 1 byte length */
390 rc
= stream_putc (out
, 0x14);
392 rc
= stream_write (out
, mdc
->hash
, DIM (mdc
->hash
));
398 calc_subpktsize (cdk_subpkt_t s
)
402 /* In the count mode, no buffer is returned. */
403 _cdk_subpkt_get_array (s
, 1, &nbytes
);
409 write_v3_sig (cdk_stream_t out
, cdk_pkt_signature_t sig
, int nsig
)
414 size
= 19 + calc_mpisize (sig
->mpi
, nsig
);
415 if (is_RSA (sig
->pubkey_algo
))
416 rc
= pkt_write_head2 (out
, size
, CDK_PKT_SIGNATURE
);
418 rc
= pkt_write_head (out
, 1, size
, CDK_PKT_SIGNATURE
);
420 rc
= stream_putc (out
, sig
->version
);
422 rc
= stream_putc (out
, 5);
424 rc
= stream_putc (out
, sig
->sig_class
);
426 rc
= write_32 (out
, sig
->timestamp
);
428 rc
= write_32 (out
, sig
->keyid
[0]);
430 rc
= write_32 (out
, sig
->keyid
[1]);
432 rc
= stream_putc (out
, sig
->pubkey_algo
);
434 rc
= stream_putc (out
, sig
->digest_algo
);
436 rc
= stream_putc (out
, sig
->digest_start
[0]);
438 rc
= stream_putc (out
, sig
->digest_start
[1]);
440 rc
= write_mpibuf (out
, sig
->mpi
, nsig
);
446 write_signature (cdk_stream_t out
, cdk_pkt_signature_t sig
, int old_ctb
)
449 size_t nbytes
, size
, nsig
;
455 if (!KEY_CAN_SIGN (sig
->pubkey_algo
))
457 if (sig
->version
< 2 || sig
->version
> 4)
458 return CDK_Inv_Packet
;
461 _cdk_log_debug ("write_signature:\n");
463 nsig
= cdk_pk_get_nsig (sig
->pubkey_algo
);
466 if (sig
->version
< 4)
467 return write_v3_sig (out
, sig
, nsig
);
469 size
= 10 + calc_subpktsize (sig
->hashed
)
470 + calc_subpktsize (sig
->unhashed
)
471 + calc_mpisize (sig
->mpi
, nsig
);
472 rc
= pkt_write_head (out
, 0, size
, CDK_PKT_SIGNATURE
);
474 rc
= stream_putc (out
, 4);
476 rc
= stream_putc (out
, sig
->sig_class
);
478 rc
= stream_putc (out
, sig
->pubkey_algo
);
480 rc
= stream_putc (out
, sig
->digest_algo
);
482 rc
= write_16 (out
, sig
->hashed_size
);
485 buf
= _cdk_subpkt_get_array (sig
->hashed
, 0, &nbytes
);
487 return CDK_Out_Of_Core
;
488 rc
= stream_write (out
, buf
, nbytes
);
492 rc
= write_16 (out
, sig
->unhashed_size
);
495 buf
= _cdk_subpkt_get_array (sig
->unhashed
, 0, &nbytes
);
497 return CDK_Out_Of_Core
;
498 rc
= stream_write (out
, buf
, nbytes
);
502 rc
= stream_putc (out
, sig
->digest_start
[0]);
504 rc
= stream_putc (out
, sig
->digest_start
[1]);
506 rc
= write_mpibuf (out
, sig
->mpi
, nsig
);
512 write_public_key (cdk_stream_t out
, cdk_pkt_pubkey_t pk
,
513 int is_subkey
, int old_ctb
)
515 int pkttype
, ndays
= 0;
516 size_t npkey
= 0, size
= 6;
522 if (pk
->version
< 2 || pk
->version
> 4)
523 return CDK_Inv_Packet
;
526 _cdk_log_debug ("write_public_key: subkey=%d\n", is_subkey
);
528 pkttype
= is_subkey
? CDK_PKT_PUBLIC_SUBKEY
: CDK_PKT_PUBLIC_KEY
;
529 npkey
= cdk_pk_get_npkey (pk
->pubkey_algo
);
533 size
+= 2; /* expire date */
536 size
+= calc_mpisize (pk
->mpi
, npkey
);
538 rc
= pkt_write_head2 (out
, size
, pkttype
);
540 rc
= pkt_write_head (out
, old_ctb
, size
, pkttype
);
542 rc
= stream_putc (out
, pk
->version
);
544 rc
= write_32 (out
, pk
->timestamp
);
545 if (!rc
&& pk
->version
< 4)
548 ndays
= (u16
) ((pk
->expiredate
- pk
->timestamp
) / 86400L);
549 rc
= write_16 (out
, ndays
);
552 rc
= stream_putc (out
, pk
->pubkey_algo
);
554 rc
= write_mpibuf (out
, pk
->mpi
, npkey
);
560 calc_s2ksize (cdk_pkt_seckey_t sk
)
564 if (!sk
->is_protected
)
566 switch (sk
->protect
.s2k
->mode
)
568 case CDK_S2K_SIMPLE
: nbytes
= 2; break;
569 case CDK_S2K_SALTED
: nbytes
= 10; break;
570 case CDK_S2K_ITERSALTED
: nbytes
= 11; break;
572 nbytes
+= sk
->protect
.ivlen
;
573 nbytes
++; /* single cipher byte */
579 write_secret_key( cdk_stream_t out
, cdk_pkt_seckey_t sk
,
580 int is_subkey
, int old_ctb
)
582 cdk_pkt_pubkey_t pk
= NULL
;
583 size_t size
= 6, npkey
, nskey
;
584 int pkttype
, s2k_mode
;
591 return CDK_Inv_Value
;
593 if (pk
->version
< 2 || pk
->version
> 4)
594 return CDK_Inv_Packet
;
597 _cdk_log_debug ("write_secret_key:\n");
599 npkey
= cdk_pk_get_npkey (pk
->pubkey_algo
);
600 nskey
= cdk_pk_get_nskey (pk
->pubkey_algo
);
601 if (!npkey
|| !nskey
)
605 /* If the key is unprotected, the 1 extra byte:
606 1 octet - cipher algorithm byte (0x00)
607 the other bytes depend on the mode:
608 a) simple checksum - 2 octets
609 b) sha-1 checksum - 20 octets */
610 size
= !sk
->is_protected
? size
+ 1 : size
+ 1 + calc_s2ksize (sk
);
611 size
+= calc_mpisize (pk
->mpi
, npkey
);
612 if (sk
->version
== 3 || !sk
->is_protected
)
614 if (sk
->version
== 3)
616 size
+= 2; /* force simple checksum */
617 sk
->protect
.sha1chk
= 0;
620 size
+= sk
->protect
.sha1chk
? 20 : 2;
621 size
+= calc_mpisize (sk
->mpi
, nskey
);
623 else /* We do not know anything about the encrypted mpi's so we
624 treat the data as opaque. */
627 pkttype
= is_subkey
? CDK_PKT_SECRET_SUBKEY
: CDK_PKT_SECRET_KEY
;
628 rc
= pkt_write_head (out
, old_ctb
, size
, pkttype
);
630 rc
= stream_putc (out
, pk
->version
);
632 rc
= write_32 (out
, pk
->timestamp
);
633 if (!rc
&& pk
->version
< 4)
637 ndays
= (u16
) ((pk
->expiredate
- pk
->timestamp
) / 86400L);
638 rc
= write_16 (out
, ndays
);
641 rc
= stream_putc (out
, pk
->pubkey_algo
);
643 rc
= write_mpibuf (out
, pk
->mpi
, npkey
);
644 if (sk
->is_protected
== 0)
645 rc
= stream_putc (out
, 0x00);
648 if (is_RSA (pk
->pubkey_algo
) && pk
->version
< 4)
649 stream_putc (out
, sk
->protect
.algo
);
650 else if (sk
->protect
.s2k
)
652 s2k_mode
= sk
->protect
.s2k
->mode
;
653 rc
= stream_putc (out
, sk
->protect
.sha1chk
? 0xFE : 0xFF);
655 rc
= stream_putc (out
, sk
->protect
.algo
);
657 rc
= stream_putc (out
, sk
->protect
.s2k
->mode
);
659 rc
= stream_putc( out
, sk
->protect
.s2k
->hash_algo
);
660 if (!rc
&& (s2k_mode
== 1 || s2k_mode
== 3))
662 rc
= stream_write (out
, sk
->protect
.s2k
->salt
, 8);
663 if (!rc
&& s2k_mode
== 3)
664 rc
= stream_putc (out
, sk
->protect
.s2k
->count
);
668 return CDK_Inv_Value
;
669 rc
= stream_write (out
, sk
->protect
.iv
, sk
->protect
.ivlen
);
671 if (!rc
&& sk
->is_protected
&& pk
->version
== 4)
673 if (sk
->encdata
&& sk
->enclen
)
674 rc
= stream_write (out
, sk
->encdata
, sk
->enclen
);
679 rc
= write_mpibuf (out
, sk
->mpi
, nskey
);
683 sk
->csum
= _cdk_sk_get_csum (sk
);
684 rc
= write_16 (out
, sk
->csum
);
693 write_compressed (cdk_stream_t out
, cdk_pkt_compressed_t cd
)
701 _cdk_log_debug ("packet: write_compressed\n");
703 /* Use an old (RFC1991) header for this packet. */
704 rc
= pkt_write_head (out
, 1, 0, CDK_PKT_COMPRESSED
);
706 rc
= stream_putc (out
, cd
->algorithm
);
712 write_literal (cdk_stream_t out
, cdk_pkt_literal_t pt
, int old_ctb
)
721 /* We consider a packet without a body as an invalid packet.
722 At least one octet must be present. */
724 return CDK_Inv_Packet
;
727 _cdk_log_debug ("write_literal:\n");
729 size
= 6 + pt
->namelen
+ pt
->len
;
730 rc
= pkt_write_head (out
, old_ctb
, size
, CDK_PKT_LITERAL
);
734 rc
= stream_putc (out
, pt
->mode
);
737 rc
= stream_putc (out
, pt
->namelen
);
742 rc
= stream_write (out
, pt
->name
, pt
->namelen
);
744 rc
= write_32 (out
, pt
->timestamp
);
748 while (!cdk_stream_eof (pt
->buf
) && !rc
)
750 rc
= stream_read (pt
->buf
, buf
, DIM (buf
), &size
);
752 rc
= stream_write (out
, buf
, size
);
755 wipemem (buf
, sizeof (buf
));
761 write_onepass_sig (cdk_stream_t out
, cdk_pkt_onepass_sig_t sig
)
768 if (sig
->version
!= 3)
769 return CDK_Inv_Packet
;
772 _cdk_log_debug ("write_onepass_sig:\n");
774 rc
= pkt_write_head (out
, 0, 13, CDK_PKT_ONEPASS_SIG
);
776 rc
= stream_putc (out
, sig
->version
);
778 rc
= stream_putc (out
, sig
->sig_class
);
780 rc
= stream_putc (out
, sig
->digest_algo
);
782 rc
= stream_putc (out
, sig
->pubkey_algo
);
784 rc
= write_32 (out
, sig
->keyid
[0]);
786 rc
= write_32 (out
, sig
->keyid
[1]);
788 rc
= stream_putc (out
, sig
->last
);
794 write_user_id (cdk_stream_t out
, cdk_pkt_userid_t id
, int old_ctb
, int pkttype
)
799 return CDK_Inv_Value
;
801 if (pkttype
== CDK_PKT_ATTRIBUTE
)
804 return CDK_Inv_Value
;
805 rc
= pkt_write_head (out
, old_ctb
, id
->attrib_len
+6, CDK_PKT_ATTRIBUTE
);
808 /* Write subpacket part. */
809 stream_putc (out
, 255);
810 write_32 (out
, id
->attrib_len
+1);
811 stream_putc (out
, 1);
812 rc
= stream_write (out
, id
->attrib_img
, id
->attrib_len
);
817 return CDK_Inv_Value
;
818 rc
= pkt_write_head (out
, old_ctb
, id
->len
, CDK_PKT_USER_ID
);
820 rc
= stream_write (out
, id
->name
, id
->len
);
829 * @out: the output stream handle
830 * @pkt: the packet itself
832 * Write the contents of @pkt into the @out stream.
833 * Return 0 on success.
836 cdk_pkt_write (cdk_stream_t out
, cdk_packet_t pkt
)
841 return CDK_Inv_Value
;
843 _cdk_log_debug ("write packet pkttype=%d\n", pkt
->pkttype
);
844 switch (pkt
->pkttype
)
846 case CDK_PKT_LITERAL
:
847 rc
= write_literal (out
, pkt
->pkt
.literal
, pkt
->old_ctb
);
849 case CDK_PKT_ONEPASS_SIG
:
850 rc
= write_onepass_sig (out
, pkt
->pkt
.onepass_sig
);
853 rc
= write_mdc (out
, pkt
->pkt
.mdc
);
855 case CDK_PKT_SYMKEY_ENC
:
856 rc
= write_symkey_enc (out
, pkt
->pkt
.symkey_enc
);
858 case CDK_PKT_ENCRYPTED
:
859 rc
= write_encrypted (out
, pkt
->pkt
.encrypted
, pkt
->old_ctb
);
861 case CDK_PKT_ENCRYPTED_MDC
:
862 rc
= write_encrypted_mdc (out
, pkt
->pkt
.encrypted
);
864 case CDK_PKT_PUBKEY_ENC
:
865 rc
= write_pubkey_enc (out
, pkt
->pkt
.pubkey_enc
, pkt
->old_ctb
);
867 case CDK_PKT_SIGNATURE
:
868 rc
= write_signature (out
, pkt
->pkt
.signature
, pkt
->old_ctb
);
870 case CDK_PKT_PUBLIC_KEY
:
871 rc
= write_public_key (out
, pkt
->pkt
.public_key
, 0, pkt
->old_ctb
);
873 case CDK_PKT_PUBLIC_SUBKEY
:
874 rc
= write_public_key (out
, pkt
->pkt
.public_key
, 1, pkt
->old_ctb
);
876 case CDK_PKT_COMPRESSED
:
877 rc
= write_compressed (out
, pkt
->pkt
.compressed
);
879 case CDK_PKT_SECRET_KEY
:
880 rc
= write_secret_key (out
, pkt
->pkt
.secret_key
, 0, pkt
->old_ctb
);
882 case CDK_PKT_SECRET_SUBKEY
:
883 rc
= write_secret_key (out
, pkt
->pkt
.secret_key
, 1, pkt
->old_ctb
);
885 case CDK_PKT_USER_ID
:
886 case CDK_PKT_ATTRIBUTE
:
887 rc
= write_user_id (out
, pkt
->pkt
.user_id
, pkt
->old_ctb
, pkt
->pkttype
);
895 _cdk_log_debug ("write_packet rc=%d pkttype=%d\n", rc
, pkt
->pkttype
);
901 _cdk_pkt_write2 (cdk_stream_t out
, int pkttype
, void *pktctx
)
906 rc
= cdk_pkt_new (&pkt
);
912 case CDK_PKT_PUBLIC_KEY
:
913 case CDK_PKT_PUBLIC_SUBKEY
:
914 pkt
->pkt
.public_key
= pktctx
;
916 case CDK_PKT_SIGNATURE
:
917 pkt
->pkt
.signature
= pktctx
;
919 case CDK_PKT_SECRET_KEY
:
920 case CDK_PKT_SECRET_SUBKEY
:
921 pkt
->pkt
.secret_key
= pktctx
;
924 case CDK_PKT_USER_ID
:
925 pkt
->pkt
.user_id
= pktctx
;
928 pkt
->pkttype
= pkttype
;
929 rc
= cdk_pkt_write (out
, pkt
);
936 _cdk_pkt_write_fp (FILE *out
, cdk_packet_t pkt
)
941 rc
= _cdk_stream_fpopen (out
, 1, &so
);
944 rc
= cdk_pkt_write (so
, pkt
);
945 cdk_stream_close (so
);