Bug Summary

File:lib/opencdk/write-packet.c
Location:line 151, column 3
Description:Value stored to 'rc' is never read

Annotated Source Code

1/* write-packet.c - Write OpenPGP packets
2 * Copyright (C) 2001-2003, 2007-2010, 2012 Free Software Foundation,
3 * Inc.
4 *
5 * Author: Timo Schulz
6 *
7 * This file is part of OpenCDK.
8 *
9 * The OpenCDK library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23#ifdef HAVE_CONFIG_H1
24#include <config.h>
25#endif
26#include <string.h>
27#include <stdio.h>
28#include <assert.h>
29
30#include "opencdk.h"
31#include "main.h"
32
33
34static int
35stream_write (cdk_stream_t s, const void *buf, size_t buflen)
36{
37 int nwritten;
38
39 nwritten = cdk_stream_write (s, buf, buflen);
40 if (nwritten == EOF(-1))
41 return _cdk_stream_get_errno (s);
42 return 0;
43}
44
45
46static int
47stream_read (cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread)
48{
49 int nread;
50
51 assert (r_nread)((r_nread) ? (void) (0) : __assert_fail ("r_nread", "write-packet.c"
, 51, __PRETTY_FUNCTION__))
;
52
53 nread = cdk_stream_read (s, buf, buflen);
54 if (nread == EOF(-1))
55 return _cdk_stream_get_errno (s);
56 *r_nread = nread;
57 return 0;
58}
59
60
61static int
62stream_putc (cdk_stream_t s, int c)
63{
64 int nwritten = cdk_stream_putc (s, c);
65 if (nwritten == EOF(-1))
66 return _cdk_stream_get_errno (s);
67 return 0;
68}
69
70
71static int
72write_32 (cdk_stream_t out, u32 u)
73{
74 byte buf[4];
75
76 buf[0] = u >> 24;
77 buf[1] = u >> 16;
78 buf[2] = u >> 8;
79 buf[3] = u;
80 return stream_write (out, buf, 4);
81}
82
83
84static int
85write_16 (cdk_stream_t out, u16 u)
86{
87 byte buf[2];
88
89 buf[0] = u >> 8;
90 buf[1] = u;
91 return stream_write (out, buf, 2);
92}
93
94
95static size_t
96calc_mpisize (bigint_t mpi[MAX_CDK_PK_PARTS4], size_t ncount)
97{
98 size_t size, i;
99
100 size = 0;
101 for (i = 0; i < ncount; i++)
102 size += (_gnutls_mpi_get_nbits (mpi[i])_gnutls_mpi_ops.bigint_get_nbits(mpi[i]) + 7) / 8 + 2;
103 return size;
104}
105
106
107static int
108write_mpi (cdk_stream_t out, bigint_t m)
109{
110 byte buf[MAX_MPI_BYTES(16384/8) + 2];
111 size_t nbits, nread;
112 int err;
113
114 if (!out || !m)
115 return CDK_Inv_Value;
116 nbits = _gnutls_mpi_get_nbits (m)_gnutls_mpi_ops.bigint_get_nbits(m);
117 if (nbits > MAX_MPI_BITS16384 || nbits < 1)
118 return CDK_MPI_Error;
119
120 nread = MAX_MPI_BYTES(16384/8) + 2;
121 err = _gnutls_mpi_print_pgp (m, buf, &nread)_gnutls_mpi_ops.bigint_print(m,buf,&nread,GNUTLS_MPI_FORMAT_PGP
)
;
122 if (err < 0)
123 return map_gnutls_error_cdk_map_gnutls_error (err);
124 return stream_write (out, buf, nread);
125}
126
127
128static cdk_error_t
129write_mpibuf (cdk_stream_t out, bigint_t mpi[MAX_CDK_PK_PARTS4], size_t count)
130{
131 size_t i;
132 cdk_error_t rc;
133
134 for (i = 0; i < count; i++)
135 {
136 rc = write_mpi (out, mpi[i]);
137 if (rc)
138 return rc;
139 }
140 return 0;
141}
142
143
144static cdk_error_t
145pkt_encode_len (cdk_stream_t out, size_t pktlen)
146{
147 cdk_error_t rc;
148
149 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
149, __PRETTY_FUNCTION__))
;
150
151 rc = 0;
Value stored to 'rc' is never read
152 if (!pktlen)
153 {
154 /* Block mode, partial bodies, with 'DEF_BLOCKSIZE' from main.h */
155 rc = stream_putc (out, (0xE0 | DEF_BLOCKBITS13));
156 }
157 else if (pktlen < 192)
158 rc = stream_putc (out, pktlen);
159 else if (pktlen < 8384)
160 {
161 pktlen -= 192;
162 rc = stream_putc (out, (pktlen / 256) + 192);
163 if (!rc)
164 rc = stream_putc (out, (pktlen % 256));
165 }
166 else
167 {
168 rc = stream_putc (out, 255);
169 if (!rc)
170 rc = write_32 (out, pktlen);
171 }
172
173 return rc;
174}
175
176
177static cdk_error_t
178write_head_new (cdk_stream_t out, size_t size, int type)
179{
180 cdk_error_t rc;
181
182 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
182, __PRETTY_FUNCTION__))
;
183
184 if (type < 0 || type > 63)
185 return CDK_Inv_Packet;
186 rc = stream_putc (out, (0xC0 | type));
187 if (!rc)
188 rc = pkt_encode_len (out, size);
189 return rc;
190}
191
192
193static cdk_error_t
194write_head_old (cdk_stream_t out, size_t size, int type)
195{
196 cdk_error_t rc;
197 int ctb;
198
199 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
199, __PRETTY_FUNCTION__))
;
200
201 if (type < 0 || type > 16)
202 return CDK_Inv_Packet;
203 ctb = 0x80 | (type << 2);
204 if (!size)
205 ctb |= 3;
206 else if (size < 256)
207 ;
208 else if (size < 65536)
209 ctb |= 1;
210 else
211 ctb |= 2;
212 rc = stream_putc (out, ctb);
213 if (!size)
214 return rc;
215 if (!rc)
216 {
217 if (size < 256)
218 rc = stream_putc (out, size);
219 else if (size < 65536)
220 rc = write_16 (out, size);
221 else
222 rc = write_32 (out, size);
223 }
224
225 return rc;
226}
227
228
229/* Write special PGP2 packet header. PGP2 (wrongly) uses two byte header
230 length for signatures and keys even if the size is < 256. */
231static cdk_error_t
232pkt_write_head2 (cdk_stream_t out, size_t size, int type)
233{
234 cdk_error_t rc;
235
236 rc = cdk_stream_putc (out, 0x80 | (type << 2) | 1);
237 if (!rc)
238 rc = cdk_stream_putc (out, size >> 8);
239 if (!rc)
240 rc = cdk_stream_putc (out, size & 0xff);
241 return rc;
242}
243
244
245static int
246pkt_write_head (cdk_stream_t out, int old_ctb, size_t size, int type)
247{
248 if (old_ctb)
249 return write_head_old (out, size, type);
250 return write_head_new (out, size, type);
251}
252
253
254static int
255write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb)
256{
257 size_t size;
258 int rc, nenc;
259
260 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
260, __PRETTY_FUNCTION__))
;
261 assert (pke)((pke) ? (void) (0) : __assert_fail ("pke", "write-packet.c",
261, __PRETTY_FUNCTION__))
;
262
263 if (pke->version < 2 || pke->version > 3)
264 return CDK_Inv_Packet;
265 if (!KEY_CAN_ENCRYPT (pke->pubkey_algo)((_cdk_pk_algo_usage ((pke->pubkey_algo))) & (CDK_KEY_USG_COMM_ENCR
| CDK_KEY_USG_STORAGE_ENCR))
)
266 return CDK_Inv_Algo;
267
268 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
269 _gnutls_write_log ("write_pubkey_enc:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_pubkey_enc:\n"); } while
(0)
;
270
271 nenc = cdk_pk_get_nenc (pke->pubkey_algo);
272 size = 10 + calc_mpisize (pke->mpi, nenc);
273 rc = pkt_write_head (out, old_ctb, size, CDK_PKT_PUBKEY_ENC);
274 if (rc)
275 return rc;
276
277 rc = stream_putc (out, pke->version);
278 if (!rc)
279 rc = write_32 (out, pke->keyid[0]);
280 if (!rc)
281 rc = write_32 (out, pke->keyid[1]);
282 if (!rc)
283 rc = stream_putc (out, _cdk_pub_algo_to_pgp (pke->pubkey_algo)(pke->pubkey_algo));
284 if (!rc)
285 rc = write_mpibuf (out, pke->mpi, nenc);
286 return rc;
287}
288
289
290static cdk_error_t
291write_mdc (cdk_stream_t out, cdk_pkt_mdc_t mdc)
292{
293 cdk_error_t rc;
294
295 assert (mdc)((mdc) ? (void) (0) : __assert_fail ("mdc", "write-packet.c",
295, __PRETTY_FUNCTION__))
;
296 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
296, __PRETTY_FUNCTION__))
;
297
298 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
299 _gnutls_write_log ("write_mdc:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_mdc:\n"); } while(0)
;
300
301 /* This packet requires a fixed header encoding */
302 rc = stream_putc (out, 0xD3); /* packet ID and 1 byte length */
303 if (!rc)
304 rc = stream_putc (out, 0x14);
305 if (!rc)
306 rc = stream_write (out, mdc->hash, DIM (mdc->hash)(sizeof (mdc->hash)/sizeof ((mdc->hash)[0])));
307 return rc;
308}
309
310
311static size_t
312calc_subpktsize (cdk_subpkt_t s)
313{
314 size_t nbytes;
315
316 /* In the count mode, no buffer is returned. */
317 _cdk_subpkt_get_array (s, 1, &nbytes);
318 return nbytes;
319}
320
321
322static cdk_error_t
323write_v3_sig (cdk_stream_t out, cdk_pkt_signature_t sig, int nsig)
324{
325 size_t size;
326 cdk_error_t rc;
327
328 size = 19 + calc_mpisize (sig->mpi, nsig);
329 if (is_RSA (sig->pubkey_algo)((sig->pubkey_algo) == CDK_PK_RSA || (sig->pubkey_algo)
== CDK_PK_RSA_E || (sig->pubkey_algo) == CDK_PK_RSA_S)
)
330 rc = pkt_write_head2 (out, size, CDK_PKT_SIGNATURE);
331 else
332 rc = pkt_write_head (out, 1, size, CDK_PKT_SIGNATURE);
333 if (!rc)
334 rc = stream_putc (out, sig->version);
335 if (!rc)
336 rc = stream_putc (out, 5);
337 if (!rc)
338 rc = stream_putc (out, sig->sig_class);
339 if (!rc)
340 rc = write_32 (out, sig->timestamp);
341 if (!rc)
342 rc = write_32 (out, sig->keyid[0]);
343 if (!rc)
344 rc = write_32 (out, sig->keyid[1]);
345 if (!rc)
346 rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo)(sig->pubkey_algo));
347 if (!rc)
348 rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
349 if (!rc)
350 rc = stream_putc (out, sig->digest_start[0]);
351 if (!rc)
352 rc = stream_putc (out, sig->digest_start[1]);
353 if (!rc)
354 rc = write_mpibuf (out, sig->mpi, nsig);
355 return rc;
356}
357
358
359static cdk_error_t
360write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb)
361{
362 byte *buf;
363 size_t nbytes, size, nsig;
364 cdk_error_t rc;
365
366 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
366, __PRETTY_FUNCTION__))
;
367 assert (sig)((sig) ? (void) (0) : __assert_fail ("sig", "write-packet.c",
367, __PRETTY_FUNCTION__))
;
368
369 if (!KEY_CAN_SIGN (sig->pubkey_algo)((_cdk_pk_algo_usage ((sig->pubkey_algo))) & (CDK_KEY_USG_DATA_SIGN
| CDK_KEY_USG_CERT_SIGN))
)
370 return CDK_Inv_Algo;
371 if (sig->version < 2 || sig->version > 4)
372 return CDK_Inv_Packet;
373
374 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
375 _gnutls_write_log ("write_signature:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_signature:\n"); } while(
0)
;
376
377 nsig = cdk_pk_get_nsig (sig->pubkey_algo);
378 if (!nsig)
379 return CDK_Inv_Algo;
380 if (sig->version < 4)
381 return write_v3_sig (out, sig, nsig);
382
383 size = 10 + calc_subpktsize (sig->hashed)
384 + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig);
385 rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE);
386 if (!rc)
387 rc = stream_putc (out, 4);
388 if (!rc)
389 rc = stream_putc (out, sig->sig_class);
390 if (!rc)
391 rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo)(sig->pubkey_algo));
392 if (!rc)
393 rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
394 if (!rc)
395 rc = write_16 (out, sig->hashed_size);
396 if (!rc)
397 {
398 buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes);
399 if (!buf)
400 return CDK_Out_Of_Core;
401 rc = stream_write (out, buf, nbytes);
402 cdk_freegnutls_free (buf);
403 }
404 if (!rc)
405 rc = write_16 (out, sig->unhashed_size);
406 if (!rc)
407 {
408 buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes);
409 if (!buf)
410 return CDK_Out_Of_Core;
411 rc = stream_write (out, buf, nbytes);
412 cdk_freegnutls_free (buf);
413 }
414 if (!rc)
415 rc = stream_putc (out, sig->digest_start[0]);
416 if (!rc)
417 rc = stream_putc (out, sig->digest_start[1]);
418 if (!rc)
419 rc = write_mpibuf (out, sig->mpi, nsig);
420 return rc;
421}
422
423
424static cdk_error_t
425write_public_key (cdk_stream_t out, cdk_pkt_pubkey_t pk,
426 int is_subkey, int old_ctb)
427{
428 int pkttype, ndays = 0;
429 size_t npkey = 0, size = 6;
430 cdk_error_t rc;
431
432 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
432, __PRETTY_FUNCTION__))
;
433 assert (pk)((pk) ? (void) (0) : __assert_fail ("pk", "write-packet.c", 433
, __PRETTY_FUNCTION__))
;
434
435 if (pk->version < 2 || pk->version > 4)
436 return CDK_Inv_Packet;
437
438 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
439 _gnutls_write_log ("write_public_key: subkey=%d\n", is_subkey)do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_public_key: subkey=%d\n"
, is_subkey); } while(0)
;
440
441 pkttype = is_subkey ? CDK_PKT_PUBLIC_SUBKEY : CDK_PKT_PUBLIC_KEY;
442 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
443 if (!npkey)
444 return CDK_Inv_Algo;
445 if (pk->version < 4)
446 size += 2; /* expire date */
447 if (is_subkey)
448 old_ctb = 0;
449 size += calc_mpisize (pk->mpi, npkey);
450 if (old_ctb)
451 rc = pkt_write_head2 (out, size, pkttype);
452 else
453 rc = pkt_write_head (out, old_ctb, size, pkttype);
454 if (!rc)
455 rc = stream_putc (out, pk->version);
456 if (!rc)
457 rc = write_32 (out, pk->timestamp);
458 if (!rc && pk->version < 4)
459 {
460 if (pk->expiredate)
461 ndays = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
462 rc = write_16 (out, ndays);
463 }
464 if (!rc)
465 rc = stream_putc (out, _cdk_pub_algo_to_pgp (pk->pubkey_algo)(pk->pubkey_algo));
466 if (!rc)
467 rc = write_mpibuf (out, pk->mpi, npkey);
468 return rc;
469}
470
471
472static int
473calc_s2ksize (cdk_pkt_seckey_t sk)
474{
475 size_t nbytes = 0;
476
477 if (!sk->is_protected)
478 return 0;
479 switch (sk->protect.s2k->mode)
480 {
481 case CDK_S2K_SIMPLE:
482 nbytes = 2;
483 break;
484 case CDK_S2K_SALTED:
485 nbytes = 10;
486 break;
487 case CDK_S2K_ITERSALTED:
488 nbytes = 11;
489 break;
490 }
491 nbytes += sk->protect.ivlen;
492 nbytes++; /* single cipher byte */
493 return nbytes;
494}
495
496
497static cdk_error_t
498write_secret_key (cdk_stream_t out, cdk_pkt_seckey_t sk,
499 int is_subkey, int old_ctb)
500{
501 cdk_pkt_pubkey_t pk = NULL((void*)0);
502 size_t size = 6, npkey, nskey;
503 int pkttype, s2k_mode;
504 cdk_error_t rc;
505
506 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
506, __PRETTY_FUNCTION__))
;
507 assert (sk)((sk) ? (void) (0) : __assert_fail ("sk", "write-packet.c", 507
, __PRETTY_FUNCTION__))
;
508
509 if (!sk->pk)
510 return CDK_Inv_Value;
511 pk = sk->pk;
512 if (pk->version < 2 || pk->version > 4)
513 return CDK_Inv_Packet;
514
515 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
516 _gnutls_write_log ("write_secret_key:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_secret_key:\n"); } while
(0)
;
517
518 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
519 nskey = cdk_pk_get_nskey (pk->pubkey_algo);
520 if (!npkey || !nskey)
521 {
522 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "write-packet.c",522); } while(0);
;
523 return CDK_Inv_Algo;
524 }
525 if (pk->version < 4)
526 size += 2;
527 /* If the key is unprotected, the 1 extra byte:
528 1 octet - cipher algorithm byte (0x00)
529 the other bytes depend on the mode:
530 a) simple checksum - 2 octets
531 b) sha-1 checksum - 20 octets */
532 size = !sk->is_protected ? size + 1 : size + 1 + calc_s2ksize (sk);
533 size += calc_mpisize (pk->mpi, npkey);
534 if (sk->version == 3 || !sk->is_protected)
535 {
536 if (sk->version == 3)
537 {
538 size += 2; /* force simple checksum */
539 sk->protect.sha1chk = 0;
540 }
541 else
542 size += sk->protect.sha1chk ? 20 : 2;
543 size += calc_mpisize (sk->mpi, nskey);
544 }
545 else /* We do not know anything about the encrypted mpi's so we
546 treat the data as opaque. */
547 size += sk->enclen;
548
549 pkttype = is_subkey ? CDK_PKT_SECRET_SUBKEY : CDK_PKT_SECRET_KEY;
550 rc = pkt_write_head (out, old_ctb, size, pkttype);
551 if (!rc)
552 rc = stream_putc (out, pk->version);
553 if (!rc)
554 rc = write_32 (out, pk->timestamp);
555 if (!rc && pk->version < 4)
556 {
557 u16 ndays = 0;
558 if (pk->expiredate)
559 ndays = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
560 rc = write_16 (out, ndays);
561 }
562 if (!rc)
563 rc = stream_putc (out, _cdk_pub_algo_to_pgp (pk->pubkey_algo)(pk->pubkey_algo));
564
565 if (!rc)
566 rc = write_mpibuf (out, pk->mpi, npkey);
567
568 if (!rc)
569 {
570 if (sk->is_protected == 0)
571 rc = stream_putc (out, 0x00);
572 else
573 {
574 if (is_RSA (pk->pubkey_algo)((pk->pubkey_algo) == CDK_PK_RSA || (pk->pubkey_algo) ==
CDK_PK_RSA_E || (pk->pubkey_algo) == CDK_PK_RSA_S)
&& pk->version < 4)
575 rc = stream_putc (out, _gnutls_cipher_to_pgp (sk->protect.algo));
576 else if (sk->protect.s2k)
577 {
578 s2k_mode = sk->protect.s2k->mode;
579 rc = stream_putc (out, sk->protect.sha1chk ? 0xFE : 0xFF);
580 if (!rc)
581 rc =
582 stream_putc (out, _gnutls_cipher_to_pgp (sk->protect.algo));
583 if (!rc)
584 rc = stream_putc (out, sk->protect.s2k->mode);
585 if (!rc)
586 rc = stream_putc (out, sk->protect.s2k->hash_algo);
587 if (!rc && (s2k_mode == 1 || s2k_mode == 3))
588 {
589 rc = stream_write (out, sk->protect.s2k->salt, 8);
590 if (!rc && s2k_mode == 3)
591 rc = stream_putc (out, sk->protect.s2k->count);
592 }
593 }
594 else
595 return CDK_Inv_Value;
596 if (!rc)
597 rc = stream_write (out, sk->protect.iv, sk->protect.ivlen);
598 }
599 }
600 if (!rc && sk->is_protected && pk->version == 4)
601 {
602 if (sk->encdata && sk->enclen)
603 rc = stream_write (out, sk->encdata, sk->enclen);
604 }
605 else
606 {
607 if (!rc)
608 rc = write_mpibuf (out, sk->mpi, nskey);
609 if (!rc)
610 {
611 if (!sk->csum)
612 sk->csum = _cdk_sk_get_csum (sk);
613 rc = write_16 (out, sk->csum);
614 }
615 }
616
617 return rc;
618}
619
620
621static cdk_error_t
622write_compressed (cdk_stream_t out, cdk_pkt_compressed_t cd)
623{
624 cdk_error_t rc;
625
626 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
626, __PRETTY_FUNCTION__))
;
627 assert (cd)((cd) ? (void) (0) : __assert_fail ("cd", "write-packet.c", 627
, __PRETTY_FUNCTION__))
;
628
629 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
630 _gnutls_write_log ("packet: write_compressed\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "packet: write_compressed\n"); }
while(0)
;
631
632 /* Use an old (RFC1991) header for this packet. */
633 rc = pkt_write_head (out, 1, 0, CDK_PKT_COMPRESSED);
634 if (!rc)
635 rc = stream_putc (out, cd->algorithm);
636 return rc;
637}
638
639
640static cdk_error_t
641write_literal (cdk_stream_t out, cdk_pkt_literal_t pt, int old_ctb)
642{
643 byte buf[BUFSIZE8192];
644 size_t size;
645 cdk_error_t rc;
646
647 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
647, __PRETTY_FUNCTION__))
;
648 assert (pt)((pt) ? (void) (0) : __assert_fail ("pt", "write-packet.c", 648
, __PRETTY_FUNCTION__))
;
649
650 /* We consider a packet without a body as an invalid packet.
651 At least one octet must be present. */
652 if (!pt->len)
653 return CDK_Inv_Packet;
654
655 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
656 _gnutls_write_log ("write_literal:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_literal:\n"); } while(0)
;
657
658 size = 6 + pt->namelen + pt->len;
659 rc = pkt_write_head (out, old_ctb, size, CDK_PKT_LITERAL);
660 if (rc)
661 return rc;
662
663 rc = stream_putc (out, pt->mode);
664 if (rc)
665 return rc;
666 rc = stream_putc (out, pt->namelen);
667 if (rc)
668 return rc;
669
670 if (pt->namelen > 0)
671 rc = stream_write (out, pt->name, pt->namelen);
672 if (!rc)
673 rc = write_32 (out, pt->timestamp);
674 if (rc)
675 return rc;
676
677 while (!cdk_stream_eof (pt->buf) && !rc)
678 {
679 rc = stream_read (pt->buf, buf, DIM (buf)(sizeof (buf)/sizeof ((buf)[0])), &size);
680 if (!rc)
681 rc = stream_write (out, buf, size);
682 }
683
684 memset (buf, 0, sizeof (buf));
685 return rc;
686}
687
688
689static cdk_error_t
690write_onepass_sig (cdk_stream_t out, cdk_pkt_onepass_sig_t sig)
691{
692 cdk_error_t rc;
693
694 assert (out)((out) ? (void) (0) : __assert_fail ("out", "write-packet.c",
694, __PRETTY_FUNCTION__))
;
695 assert (sig)((sig) ? (void) (0) : __assert_fail ("sig", "write-packet.c",
695, __PRETTY_FUNCTION__))
;
696
697 if (sig->version != 3)
698 return CDK_Inv_Packet;
699
700 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
701 _gnutls_write_log ("write_onepass_sig:\n")do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_onepass_sig:\n"); } while
(0)
;
702
703 rc = pkt_write_head (out, 0, 13, CDK_PKT_ONEPASS_SIG);
704 if (!rc)
705 rc = stream_putc (out, sig->version);
706 if (!rc)
707 rc = stream_putc (out, sig->sig_class);
708 if (!rc)
709 rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
710 if (!rc)
711 rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo)(sig->pubkey_algo));
712 if (!rc)
713 rc = write_32 (out, sig->keyid[0]);
714 if (!rc)
715 rc = write_32 (out, sig->keyid[1]);
716 if (!rc)
717 rc = stream_putc (out, sig->last);
718 return rc;
719}
720
721
722static cdk_error_t
723write_user_id (cdk_stream_t out, cdk_pkt_userid_t id, int old_ctb,
724 int pkttype)
725{
726 cdk_error_t rc;
727
728 if (!out || !id)
729 return CDK_Inv_Value;
730
731 if (pkttype == CDK_PKT_ATTRIBUTE)
732 {
733 if (!id->attrib_img)
734 return CDK_Inv_Value;
735 rc =
736 pkt_write_head (out, old_ctb, id->attrib_len + 6, CDK_PKT_ATTRIBUTE);
737 if (rc)
738 return rc;
739 /* Write subpacket part. */
740 stream_putc (out, 255);
741 write_32 (out, id->attrib_len + 1);
742 stream_putc (out, 1);
743 rc = stream_write (out, id->attrib_img, id->attrib_len);
744 }
745 else
746 {
747 if (!id->name)
748 return CDK_Inv_Value;
749 rc = pkt_write_head (out, old_ctb, id->len, CDK_PKT_USER_ID);
750 if (!rc)
751 rc = stream_write (out, id->name, id->len);
752 }
753
754 return rc;
755}
756
757
758/**
759 * cdk_pkt_write:
760 * @out: the output stream handle
761 * @pkt: the packet itself
762 *
763 * Write the contents of @pkt into the @out stream.
764 * Return 0 on success.
765 **/
766cdk_error_t
767cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt)
768{
769 cdk_error_t rc;
770
771 if (!out || !pkt)
772 return CDK_Inv_Value;
773
774 _gnutls_write_log ("write packet pkttype=%d\n", pkt->pkttype)do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write packet pkttype=%d\n", pkt
->pkttype); } while(0)
;
775 switch (pkt->pkttype)
776 {
777 case CDK_PKT_LITERAL:
778 rc = write_literal (out, pkt->pkt.literal, pkt->old_ctb);
779 break;
780 case CDK_PKT_ONEPASS_SIG:
781 rc = write_onepass_sig (out, pkt->pkt.onepass_sig);
782 break;
783 case CDK_PKT_MDC:
784 rc = write_mdc (out, pkt->pkt.mdc);
785 break;
786 case CDK_PKT_PUBKEY_ENC:
787 rc = write_pubkey_enc (out, pkt->pkt.pubkey_enc, pkt->old_ctb);
788 break;
789 case CDK_PKT_SIGNATURE:
790 rc = write_signature (out, pkt->pkt.signature, pkt->old_ctb);
791 break;
792 case CDK_PKT_PUBLIC_KEY:
793 rc = write_public_key (out, pkt->pkt.public_key, 0, pkt->old_ctb);
794 break;
795 case CDK_PKT_PUBLIC_SUBKEY:
796 rc = write_public_key (out, pkt->pkt.public_key, 1, pkt->old_ctb);
797 break;
798 case CDK_PKT_COMPRESSED:
799 rc = write_compressed (out, pkt->pkt.compressed);
800 break;
801 case CDK_PKT_SECRET_KEY:
802 rc = write_secret_key (out, pkt->pkt.secret_key, 0, pkt->old_ctb);
803 break;
804 case CDK_PKT_SECRET_SUBKEY:
805 rc = write_secret_key (out, pkt->pkt.secret_key, 1, pkt->old_ctb);
806 break;
807 case CDK_PKT_USER_ID:
808 case CDK_PKT_ATTRIBUTE:
809 rc = write_user_id (out, pkt->pkt.user_id, pkt->old_ctb, pkt->pkttype);
810 break;
811 default:
812 rc = CDK_Inv_Packet;
813 break;
814 }
815
816 if (DEBUG_PKT(_gnutls_log_level == (CDK_LOG_DEBUG+1)))
817 _gnutls_write_log ("write_packet rc=%d pkttype=%d\n", rc, pkt->pkttype)do { if (__builtin_expect((_gnutls_log_level == 7 || _gnutls_log_level
> 9), 0)) _gnutls_log( 7, "write_packet rc=%d pkttype=%d\n"
, rc, pkt->pkttype); } while(0)
;
818 return rc;
819}
820
821
822cdk_error_t
823_cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx)
824{
825 cdk_packet_t pkt;
826 cdk_error_t rc;
827
828 rc = cdk_pkt_new (&pkt);
829 if (rc)
830 return rc;
831
832 switch (pkttype)
833 {
834 case CDK_PKT_PUBLIC_KEY:
835 case CDK_PKT_PUBLIC_SUBKEY:
836 pkt->pkt.public_key = pktctx;
837 break;
838 case CDK_PKT_SIGNATURE:
839 pkt->pkt.signature = pktctx;
840 break;
841 case CDK_PKT_SECRET_KEY:
842 case CDK_PKT_SECRET_SUBKEY:
843 pkt->pkt.secret_key = pktctx;
844 break;
845
846 case CDK_PKT_USER_ID:
847 pkt->pkt.user_id = pktctx;
848 break;
849 }
850 pkt->pkttype = pkttype;
851 rc = cdk_pkt_write (out, pkt);
852 cdk_freegnutls_free (pkt);
853 return rc;
854}
855
856
857cdk_error_t
858_cdk_pkt_write_fp (FILE * out, cdk_packet_t pkt)
859{
860 cdk_stream_t so;
861 cdk_error_t rc;
862
863 rc = _cdk_stream_fpopen (out, 1, &so);
864 if (rc)
865 return rc;
866 rc = cdk_pkt_write (so, pkt);
867 cdk_stream_close (so);
868 return rc;
869}