Line data Source code
1 : /* build-packet.c - assemble packets and write them
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 : * 2006, 2010, 2011 Free Software Foundation, Inc.
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <assert.h>
26 : #include <ctype.h>
27 :
28 : #include "gpg.h"
29 : #include "util.h"
30 : #include "packet.h"
31 : #include "status.h"
32 : #include "iobuf.h"
33 : #include "i18n.h"
34 : #include "options.h"
35 : #include "host2net.h"
36 :
37 : static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
38 : static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
39 : static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
40 : static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
41 : static u32 calc_plaintext( PKT_plaintext *pt );
42 : static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
43 : static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
44 : static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
45 : static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
46 : static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
47 : static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
48 :
49 : static int calc_header_length( u32 len, int new_ctb );
50 : static int write_16(IOBUF inp, u16 a);
51 : static int write_32(IOBUF inp, u32 a);
52 : static int write_header( IOBUF out, int ctb, u32 len );
53 : static int write_sign_packet_header( IOBUF out, int ctb, u32 len );
54 : static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen );
55 : static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen );
56 :
57 : /****************
58 : * Build a packet and write it to INP
59 : * Returns: 0 := okay
60 : * >0 := error
61 : * Note: Caller must free the packet
62 : */
63 : int
64 2583 : build_packet( IOBUF out, PACKET *pkt )
65 : {
66 2583 : int new_ctb=0, rc=0, ctb;
67 : int pkttype;
68 :
69 2583 : if( DBG_PACKET )
70 0 : log_debug("build_packet() type=%d\n", pkt->pkttype );
71 2583 : assert( pkt->pkt.generic );
72 :
73 2583 : switch ((pkttype = pkt->pkttype))
74 : {
75 : case PKT_PUBLIC_KEY:
76 61 : if (pkt->pkt.public_key->seckey_info)
77 0 : pkttype = PKT_SECRET_KEY;
78 61 : break;
79 : case PKT_PUBLIC_SUBKEY:
80 47 : if (pkt->pkt.public_key->seckey_info)
81 0 : pkttype = PKT_SECRET_SUBKEY;
82 47 : break;
83 510 : case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
84 : case PKT_ENCRYPTED:
85 454 : case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
86 510 : case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
87 : case PKT_USER_ID:
88 75 : if( pkt->pkt.user_id->attrib_data )
89 0 : pkttype = PKT_ATTRIBUTE;
90 75 : break;
91 926 : default: break;
92 : }
93 :
94 2583 : if( new_ctb || pkttype > 15 ) /* new format */
95 482 : ctb = 0xc0 | (pkttype & 0x3f);
96 : else
97 2101 : ctb = 0x80 | ((pkttype & 15)<<2);
98 2583 : switch( pkttype )
99 : {
100 : case PKT_ATTRIBUTE:
101 : case PKT_USER_ID:
102 75 : rc = do_user_id( out, ctb, pkt->pkt.user_id );
103 75 : break;
104 : case PKT_OLD_COMMENT:
105 : case PKT_COMMENT:
106 : /*
107 : Ignore these. Theoretically, this will never be called as
108 : we have no way to output comment packets any longer, but
109 : just in case there is some code path that would end up
110 : outputting a comment that was written before comments were
111 : dropped (in the public key?) this is a no-op.
112 : */
113 0 : break;
114 : case PKT_PUBLIC_SUBKEY:
115 : case PKT_PUBLIC_KEY:
116 : case PKT_SECRET_SUBKEY:
117 : case PKT_SECRET_KEY:
118 108 : rc = do_key (out, ctb, pkt->pkt.public_key);
119 108 : break;
120 : case PKT_SYMKEY_ENC:
121 218 : rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
122 218 : break;
123 : case PKT_PUBKEY_ENC:
124 236 : rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
125 236 : break;
126 : case PKT_PLAINTEXT:
127 510 : rc = do_plaintext( out, ctb, pkt->pkt.plaintext );
128 510 : break;
129 : case PKT_ENCRYPTED:
130 52 : rc = do_encrypted( out, ctb, pkt->pkt.encrypted );
131 52 : break;
132 : case PKT_ENCRYPTED_MDC:
133 402 : rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
134 402 : break;
135 : case PKT_COMPRESSED:
136 510 : rc = do_compressed( out, ctb, pkt->pkt.compressed );
137 510 : break;
138 : case PKT_SIGNATURE:
139 383 : rc = do_signature( out, ctb, pkt->pkt.signature );
140 383 : break;
141 : case PKT_ONEPASS_SIG:
142 89 : rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig );
143 89 : break;
144 : case PKT_RING_TRUST:
145 0 : break; /* ignore it (keyring.c does write it directly)*/
146 : case PKT_MDC: /* we write it directly, so we should never see it here. */
147 : default:
148 0 : log_bug("invalid packet type in build_packet()\n");
149 : break;
150 : }
151 :
152 2583 : return rc;
153 : }
154 :
155 :
156 : /*
157 : * Write the mpi A to OUT.
158 : */
159 : gpg_error_t
160 1463 : gpg_mpi_write (iobuf_t out, gcry_mpi_t a)
161 : {
162 : int rc;
163 :
164 1463 : if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
165 : {
166 : unsigned int nbits;
167 : const unsigned char *p;
168 : unsigned char lenhdr[2];
169 :
170 : /* gcry_log_debugmpi ("a", a); */
171 0 : p = gcry_mpi_get_opaque (a, &nbits);
172 0 : if (p)
173 : {
174 : /* Strip leading zero bits. */
175 0 : for (; nbits >= 8 && !*p; p++, nbits -= 8)
176 : ;
177 0 : if (nbits >= 8 && !(*p & 0x80))
178 0 : if (--nbits >= 7 && !(*p & 0x40))
179 0 : if (--nbits >= 6 && !(*p & 0x20))
180 0 : if (--nbits >= 5 && !(*p & 0x10))
181 0 : if (--nbits >= 4 && !(*p & 0x08))
182 0 : if (--nbits >= 3 && !(*p & 0x04))
183 0 : if (--nbits >= 2 && !(*p & 0x02))
184 0 : if (--nbits >= 1 && !(*p & 0x01))
185 0 : --nbits;
186 : }
187 : /* gcry_log_debug (" [%u bit]\n", nbits); */
188 : /* gcry_log_debughex (" ", p, (nbits+7)/8); */
189 0 : lenhdr[0] = nbits >> 8;
190 0 : lenhdr[1] = nbits;
191 0 : rc = iobuf_write (out, lenhdr, 2);
192 0 : if (!rc && p)
193 0 : rc = iobuf_write (out, p, (nbits+7)/8);
194 : }
195 : else
196 : {
197 : char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
198 : size_t nbytes;
199 :
200 1463 : nbytes = DIM(buffer);
201 1463 : rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
202 1463 : if( !rc )
203 1463 : rc = iobuf_write( out, buffer, nbytes );
204 0 : else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
205 : {
206 0 : log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
207 : /* The buffer was too small. We better tell the user about the MPI. */
208 0 : rc = gpg_error (GPG_ERR_TOO_LARGE);
209 : }
210 : }
211 :
212 1463 : return rc;
213 : }
214 :
215 :
216 : /*
217 : * Write an opaque MPI to the output stream without length info.
218 : */
219 : gpg_error_t
220 125 : gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
221 : {
222 : int rc;
223 :
224 125 : if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
225 : {
226 : unsigned int nbits;
227 : const void *p;
228 :
229 125 : p = gcry_mpi_get_opaque (a, &nbits);
230 125 : rc = p ? iobuf_write (out, p, (nbits+7)/8) : 0;
231 : }
232 : else
233 0 : rc = gpg_error (GPG_ERR_BAD_MPI);
234 :
235 125 : return rc;
236 : }
237 :
238 :
239 : /* Calculate the length of a packet described by PKT. */
240 : u32
241 0 : calc_packet_length( PACKET *pkt )
242 : {
243 0 : u32 n=0;
244 0 : int new_ctb = 0;
245 :
246 0 : assert( pkt->pkt.generic );
247 0 : switch( pkt->pkttype ) {
248 : case PKT_PLAINTEXT:
249 0 : n = calc_plaintext( pkt->pkt.plaintext );
250 0 : new_ctb = pkt->pkt.plaintext->new_ctb;
251 0 : break;
252 : case PKT_ATTRIBUTE:
253 : case PKT_USER_ID:
254 : case PKT_COMMENT:
255 : case PKT_PUBLIC_KEY:
256 : case PKT_SECRET_KEY:
257 : case PKT_SYMKEY_ENC:
258 : case PKT_PUBKEY_ENC:
259 : case PKT_ENCRYPTED:
260 : case PKT_SIGNATURE:
261 : case PKT_ONEPASS_SIG:
262 : case PKT_RING_TRUST:
263 : case PKT_COMPRESSED:
264 : default:
265 0 : log_bug("invalid packet type in calc_packet_length()");
266 : break;
267 : }
268 :
269 0 : n += calc_header_length(n, new_ctb);
270 0 : return n;
271 : }
272 :
273 :
274 : static gpg_error_t
275 0 : write_fake_data (IOBUF out, gcry_mpi_t a)
276 : {
277 : unsigned int n;
278 : void *p;
279 :
280 0 : if (!a)
281 0 : return 0;
282 0 : p = gcry_mpi_get_opaque ( a, &n);
283 0 : if (!p)
284 0 : return 0; /* For example due to a read error in
285 : parse-packet.c:read_rest. */
286 0 : return iobuf_write (out, p, (n+7)/8 );
287 : }
288 :
289 :
290 : static int
291 75 : do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
292 : {
293 : int rc;
294 :
295 75 : if (uid->attrib_data)
296 : {
297 0 : write_header(out, ctb, uid->attrib_len);
298 0 : rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
299 : }
300 : else
301 : {
302 75 : write_header2( out, ctb, uid->len, 2 );
303 75 : rc = iobuf_write( out, uid->name, uid->len );
304 : }
305 75 : return rc;
306 : }
307 :
308 :
309 : static int
310 108 : do_key (iobuf_t out, int ctb, PKT_public_key *pk)
311 : {
312 108 : gpg_error_t err = 0;
313 : int i, nskey, npkey;
314 108 : iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer. */
315 :
316 : /* Write the version number - if none is specified, use 4 */
317 108 : if ( !pk->version )
318 0 : iobuf_put ( a, 4 );
319 : else
320 108 : iobuf_put ( a, pk->version );
321 108 : write_32 (a, pk->timestamp );
322 :
323 108 : iobuf_put (a, pk->pubkey_algo );
324 :
325 : /* Get number of secret and public parameters. They are held in one
326 : array first the public ones, then the secret ones. */
327 108 : nskey = pubkey_get_nskey (pk->pubkey_algo);
328 108 : npkey = pubkey_get_npkey (pk->pubkey_algo);
329 :
330 : /* If we don't have any public parameters - which is for example the
331 : case if we don't know the algorithm used - the parameters are
332 : stored as one blob in a faked (opaque) MPI. */
333 108 : if (!npkey)
334 : {
335 0 : write_fake_data (a, pk->pkey[0]);
336 0 : goto leave;
337 : }
338 108 : assert (npkey < nskey);
339 :
340 448 : for (i=0; i < npkey; i++ )
341 : {
342 340 : if ( (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0))
343 334 : || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
344 334 : || (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
345 14 : err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
346 : else
347 326 : err = gpg_mpi_write (a, pk->pkey[i]);
348 340 : if (err)
349 0 : goto leave;
350 : }
351 :
352 :
353 108 : if (pk->seckey_info)
354 : {
355 : /* This is a secret key packet. */
356 0 : struct seckey_info *ski = pk->seckey_info;
357 :
358 : /* Build the header for protected (encrypted) secret parameters. */
359 0 : if (ski->is_protected)
360 : {
361 : /* OpenPGP protection according to rfc2440. */
362 0 : iobuf_put (a, ski->sha1chk? 0xfe : 0xff);
363 0 : iobuf_put (a, ski->algo);
364 0 : if (ski->s2k.mode >= 1000)
365 : {
366 : /* These modes are not possible in OpenPGP, we use them
367 : to implement our extensions, 101 can be viewed as a
368 : private/experimental extension (this is not specified
369 : in rfc2440 but the same scheme is used for all other
370 : algorithm identifiers). */
371 0 : iobuf_put (a, 101);
372 0 : iobuf_put (a, ski->s2k.hash_algo);
373 0 : iobuf_write (a, "GNU", 3 );
374 0 : iobuf_put (a, ski->s2k.mode - 1000);
375 : }
376 : else
377 : {
378 0 : iobuf_put (a, ski->s2k.mode);
379 0 : iobuf_put (a, ski->s2k.hash_algo);
380 : }
381 :
382 0 : if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
383 0 : iobuf_write (a, ski->s2k.salt, 8);
384 :
385 0 : if (ski->s2k.mode == 3)
386 0 : iobuf_put (a, ski->s2k.count);
387 :
388 : /* For our special modes 1001, 1002 we do not need an IV. */
389 0 : if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
390 0 : iobuf_write (a, ski->iv, ski->ivlen);
391 :
392 : }
393 : else /* Not protected. */
394 0 : iobuf_put (a, 0 );
395 :
396 0 : if (ski->s2k.mode == 1001)
397 : ; /* GnuPG extension - don't write a secret key at all. */
398 0 : else if (ski->s2k.mode == 1002)
399 : {
400 : /* GnuPG extension - divert to OpenPGP smartcard. */
401 : /* Length of the serial number or 0 for no serial number. */
402 0 : iobuf_put (a, ski->ivlen );
403 : /* The serial number gets stored in the IV field. */
404 0 : iobuf_write (a, ski->iv, ski->ivlen);
405 : }
406 0 : else if (ski->is_protected)
407 : {
408 : /* The secret key is protected - write it out as it is. */
409 : byte *p;
410 : unsigned int ndatabits;
411 :
412 0 : assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
413 0 : p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
414 0 : if (p)
415 0 : iobuf_write (a, p, (ndatabits+7)/8 );
416 : }
417 : else
418 : {
419 : /* Non-protected key. */
420 0 : for ( ; i < nskey; i++ )
421 0 : if ( (err = gpg_mpi_write (a, pk->pkey[i])))
422 0 : goto leave;
423 0 : write_16 (a, ski->csum );
424 : }
425 : }
426 :
427 : leave:
428 108 : if (!err)
429 : {
430 : /* Build the header of the packet - which we must do after
431 : writing all the other stuff, so that we know the length of
432 : the packet */
433 108 : write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
434 : /* And finally write it out to the real stream. */
435 108 : err = iobuf_write_temp (out, a);
436 : }
437 :
438 108 : iobuf_close (a); /* Close the temporary buffer */
439 108 : return err;
440 : }
441 :
442 : static int
443 218 : do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
444 : {
445 218 : int rc = 0;
446 218 : IOBUF a = iobuf_temp();
447 :
448 218 : assert( enc->version == 4 );
449 218 : switch( enc->s2k.mode ) {
450 218 : case 0: case 1: case 3: break;
451 0 : default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
452 : }
453 218 : iobuf_put( a, enc->version );
454 218 : iobuf_put( a, enc->cipher_algo );
455 218 : iobuf_put( a, enc->s2k.mode );
456 218 : iobuf_put( a, enc->s2k.hash_algo );
457 218 : if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
458 218 : iobuf_write(a, enc->s2k.salt, 8 );
459 218 : if( enc->s2k.mode == 3 )
460 218 : iobuf_put(a, enc->s2k.count);
461 : }
462 218 : if( enc->seskeylen )
463 0 : iobuf_write(a, enc->seskey, enc->seskeylen );
464 :
465 218 : write_header(out, ctb, iobuf_get_temp_length(a) );
466 218 : rc = iobuf_write_temp( out, a );
467 :
468 218 : iobuf_close(a);
469 218 : return rc;
470 : }
471 :
472 :
473 : static int
474 236 : do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
475 : {
476 236 : int rc = 0;
477 : int n, i;
478 236 : IOBUF a = iobuf_temp();
479 :
480 236 : iobuf_put (a, 3); /* Version. */
481 :
482 236 : if ( enc->throw_keyid )
483 : {
484 0 : write_32(a, 0 ); /* Don't tell Eve who can decrypt the message. */
485 0 : write_32(a, 0 );
486 : }
487 : else
488 : {
489 236 : write_32(a, enc->keyid[0] );
490 236 : write_32(a, enc->keyid[1] );
491 : }
492 236 : iobuf_put(a,enc->pubkey_algo );
493 236 : n = pubkey_get_nenc( enc->pubkey_algo );
494 236 : if ( !n )
495 0 : write_fake_data( a, enc->data[0] );
496 :
497 708 : for (i=0; i < n && !rc ; i++ )
498 : {
499 472 : if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
500 21 : rc = gpg_mpi_write_nohdr (a, enc->data[i]);
501 : else
502 451 : rc = gpg_mpi_write (a, enc->data[i]);
503 : }
504 :
505 236 : if (!rc)
506 : {
507 236 : write_header (out, ctb, iobuf_get_temp_length(a) );
508 236 : rc = iobuf_write_temp (out, a);
509 : }
510 236 : iobuf_close(a);
511 236 : return rc;
512 : }
513 :
514 :
515 : static u32
516 510 : calc_plaintext( PKT_plaintext *pt )
517 : {
518 : /* Truncate namelen to the maximum 255 characters. Note this means
519 : that a function that calls build_packet with an illegal literal
520 : packet will get it back legalized. */
521 :
522 510 : if(pt->namelen>255)
523 0 : pt->namelen=255;
524 :
525 510 : return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
526 : }
527 :
528 : static int
529 510 : do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
530 : {
531 510 : int i, rc = 0;
532 : u32 n;
533 : byte buf[1000]; /* this buffer has the plaintext! */
534 : int nbytes;
535 :
536 510 : write_header(out, ctb, calc_plaintext( pt ) );
537 510 : iobuf_put(out, pt->mode );
538 510 : iobuf_put(out, pt->namelen );
539 3238 : for(i=0; i < pt->namelen; i++ )
540 2728 : iobuf_put(out, pt->name[i] );
541 510 : rc = write_32(out, pt->timestamp );
542 510 : if (rc)
543 0 : return rc;
544 :
545 510 : n = 0;
546 7678 : while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
547 6658 : rc = iobuf_write (out, buf, nbytes);
548 6658 : if (rc)
549 0 : break;
550 6658 : n += nbytes;
551 : }
552 510 : wipememory(buf,1000); /* burn the buffer */
553 510 : if( (ctb&0x40) && !pt->len )
554 28 : iobuf_set_partial_block_mode(out, 0 ); /* turn off partial */
555 510 : if( pt->len && n != pt->len )
556 0 : log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
557 0 : (ulong)n, (ulong)pt->len );
558 :
559 510 : return rc;
560 : }
561 :
562 :
563 :
564 : static int
565 52 : do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
566 : {
567 52 : int rc = 0;
568 : u32 n;
569 :
570 52 : n = ed->len ? (ed->len + ed->extralen) : 0;
571 52 : write_header(out, ctb, n );
572 :
573 : /* This is all. The caller has to write the real data */
574 :
575 52 : return rc;
576 : }
577 :
578 : static int
579 402 : do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
580 : {
581 402 : int rc = 0;
582 : u32 n;
583 :
584 402 : assert( ed->mdc_method );
585 :
586 : /* Take version number and the following MDC packet in account. */
587 402 : n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0;
588 402 : write_header(out, ctb, n );
589 402 : iobuf_put(out, 1 ); /* version */
590 :
591 : /* This is all. The caller has to write the real data */
592 :
593 402 : return rc;
594 : }
595 :
596 :
597 : static int
598 510 : do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
599 : {
600 510 : int rc = 0;
601 :
602 : /* We must use the old convention and don't use blockmode for the
603 : sake of PGP 2 compatibility. However if the new_ctb flag was
604 : set, CTB is already formatted as new style and write_header2
605 : does create a partial length encoding using new the new
606 : style. */
607 510 : write_header2(out, ctb, 0, 0);
608 510 : iobuf_put(out, cd->algorithm );
609 :
610 : /* This is all. The caller has to write the real data */
611 :
612 510 : return rc;
613 : }
614 :
615 :
616 : /****************
617 : * Delete all subpackets of type REQTYPE and return a bool whether a packet
618 : * was deleted.
619 : */
620 : int
621 520 : delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
622 : {
623 : int buflen;
624 : sigsubpkttype_t type;
625 : byte *buffer, *bufstart;
626 : size_t n;
627 520 : size_t unused = 0;
628 520 : int okay = 0;
629 :
630 520 : if( !area )
631 360 : return 0;
632 160 : buflen = area->len;
633 160 : buffer = area->data;
634 : for(;;) {
635 391 : if( !buflen ) {
636 160 : okay = 1;
637 160 : break;
638 : }
639 231 : bufstart = buffer;
640 231 : n = *buffer++; buflen--;
641 231 : if( n == 255 ) {
642 0 : if( buflen < 4 )
643 0 : break;
644 0 : n = buf32_to_size_t (buffer);
645 0 : buffer += 4;
646 0 : buflen -= 4;
647 : }
648 231 : else if( n >= 192 ) {
649 0 : if( buflen < 2 )
650 0 : break;
651 0 : n = (( n - 192 ) << 8) + *buffer + 192;
652 0 : buffer++;
653 0 : buflen--;
654 : }
655 231 : if( buflen < n )
656 0 : break;
657 :
658 231 : type = *buffer & 0x7f;
659 231 : if( type == reqtype ) {
660 0 : buffer++;
661 0 : buflen--;
662 0 : n--;
663 0 : if( n > buflen )
664 0 : break;
665 0 : buffer += n; /* point to next subpkt */
666 0 : buflen -= n;
667 0 : memmove (bufstart, buffer, buflen); /* shift */
668 0 : unused += buffer - bufstart;
669 0 : buffer = bufstart;
670 : }
671 : else {
672 231 : buffer += n; buflen -=n;
673 : }
674 231 : }
675 :
676 160 : if (!okay)
677 0 : log_error ("delete_subpkt: buffer shorter than subpacket\n");
678 160 : assert (unused <= area->len);
679 160 : area->len -= unused;
680 160 : return !!unused;
681 : }
682 :
683 :
684 : /****************
685 : * Create or update a signature subpacket for SIG of TYPE. This
686 : * functions knows where to put the data (hashed or unhashed). The
687 : * function may move data from the unhashed part to the hashed one.
688 : * Note: All pointers into sig->[un]hashed (e.g. returned by
689 : * parse_sig_subpkt) are not valid after a call to this function. The
690 : * data to put into the subpaket should be in a buffer with a length
691 : * of buflen.
692 : */
693 : void
694 258 : build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
695 : const byte *buffer, size_t buflen )
696 : {
697 : byte *p;
698 : int critical, hashed;
699 : subpktarea_t *oldarea, *newarea;
700 : size_t nlen, n, n0;
701 :
702 258 : critical = (type & SIGSUBPKT_FLAG_CRITICAL);
703 258 : type &= ~SIGSUBPKT_FLAG_CRITICAL;
704 :
705 : /* Sanity check buffer sizes */
706 258 : if(parse_one_sig_subpkt(buffer,buflen,type)<0)
707 0 : BUG();
708 :
709 258 : switch(type)
710 : {
711 : case SIGSUBPKT_NOTATION:
712 : case SIGSUBPKT_POLICY:
713 : case SIGSUBPKT_REV_KEY:
714 : case SIGSUBPKT_SIGNATURE:
715 : /* we do allow multiple subpackets */
716 0 : break;
717 :
718 : default:
719 : /* we don't allow multiple subpackets */
720 258 : delete_sig_subpkt(sig->hashed,type);
721 258 : delete_sig_subpkt(sig->unhashed,type);
722 258 : break;
723 : }
724 :
725 : /* Any special magic that needs to be done for this type so the
726 : packet doesn't need to be reparsed? */
727 258 : switch(type)
728 : {
729 : case SIGSUBPKT_NOTATION:
730 0 : sig->flags.notation=1;
731 0 : break;
732 :
733 : case SIGSUBPKT_POLICY:
734 0 : sig->flags.policy_url=1;
735 0 : break;
736 :
737 : case SIGSUBPKT_PREF_KS:
738 0 : sig->flags.pref_ks=1;
739 0 : break;
740 :
741 : case SIGSUBPKT_EXPORTABLE:
742 0 : if(buffer[0])
743 0 : sig->flags.exportable=1;
744 : else
745 0 : sig->flags.exportable=0;
746 0 : break;
747 :
748 : case SIGSUBPKT_REVOCABLE:
749 0 : if(buffer[0])
750 0 : sig->flags.revocable=1;
751 : else
752 0 : sig->flags.revocable=0;
753 0 : break;
754 :
755 : case SIGSUBPKT_TRUST:
756 0 : sig->trust_depth=buffer[0];
757 0 : sig->trust_value=buffer[1];
758 0 : break;
759 :
760 : case SIGSUBPKT_REGEXP:
761 0 : sig->trust_regexp=buffer;
762 0 : break;
763 :
764 : /* This should never happen since we don't currently allow
765 : creating such a subpacket, but just in case... */
766 : case SIGSUBPKT_SIG_EXPIRE:
767 0 : if(buf32_to_u32(buffer)+sig->timestamp<=make_timestamp())
768 0 : sig->flags.expired=1;
769 : else
770 0 : sig->flags.expired=0;
771 0 : break;
772 :
773 : default:
774 258 : break;
775 : }
776 :
777 258 : if( (buflen+1) >= 8384 )
778 0 : nlen = 5; /* write 5 byte length header */
779 258 : else if( (buflen+1) >= 192 )
780 0 : nlen = 2; /* write 2 byte length header */
781 : else
782 258 : nlen = 1; /* just a 1 byte length header */
783 :
784 258 : switch( type )
785 : {
786 : /* The issuer being unhashed is a historical oddity. It
787 : should work equally as well hashed. Of course, if even an
788 : unhashed issuer is tampered with, it makes it awfully hard
789 : to verify the sig... */
790 : case SIGSUBPKT_ISSUER:
791 : case SIGSUBPKT_SIGNATURE:
792 120 : hashed = 0;
793 120 : break;
794 : default:
795 138 : hashed = 1;
796 138 : break;
797 : }
798 :
799 258 : if( critical )
800 0 : type |= SIGSUBPKT_FLAG_CRITICAL;
801 :
802 258 : oldarea = hashed? sig->hashed : sig->unhashed;
803 :
804 : /* Calculate new size of the area and allocate */
805 258 : n0 = oldarea? oldarea->len : 0;
806 258 : n = n0 + nlen + 1 + buflen; /* length, type, buffer */
807 258 : if (oldarea && n <= oldarea->size) { /* fits into the unused space */
808 0 : newarea = oldarea;
809 : /*log_debug ("updating area for type %d\n", type );*/
810 : }
811 258 : else if (oldarea) {
812 18 : newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1);
813 18 : newarea->size = n;
814 : /*log_debug ("reallocating area for type %d\n", type );*/
815 : }
816 : else {
817 240 : newarea = xmalloc (sizeof (*newarea) + n - 1);
818 240 : newarea->size = n;
819 : /*log_debug ("allocating area for type %d\n", type );*/
820 : }
821 258 : newarea->len = n;
822 :
823 258 : p = newarea->data + n0;
824 258 : if (nlen == 5) {
825 0 : *p++ = 255;
826 0 : *p++ = (buflen+1) >> 24;
827 0 : *p++ = (buflen+1) >> 16;
828 0 : *p++ = (buflen+1) >> 8;
829 0 : *p++ = (buflen+1);
830 0 : *p++ = type;
831 0 : memcpy (p, buffer, buflen);
832 : }
833 258 : else if (nlen == 2) {
834 0 : *p++ = (buflen+1-192) / 256 + 192;
835 0 : *p++ = (buflen+1-192) % 256;
836 0 : *p++ = type;
837 0 : memcpy (p, buffer, buflen);
838 : }
839 : else {
840 258 : *p++ = buflen+1;
841 258 : *p++ = type;
842 258 : memcpy (p, buffer, buflen);
843 : }
844 :
845 258 : if (hashed)
846 138 : sig->hashed = newarea;
847 : else
848 120 : sig->unhashed = newarea;
849 258 : }
850 :
851 : /****************
852 : * Put all the required stuff from SIG into subpackets of sig.
853 : * Hmmm, should we delete those subpackets which are in a wrong area?
854 : */
855 : void
856 120 : build_sig_subpkt_from_sig( PKT_signature *sig )
857 : {
858 : u32 u;
859 : byte buf[8];
860 :
861 120 : u = sig->keyid[0];
862 120 : buf[0] = (u >> 24) & 0xff;
863 120 : buf[1] = (u >> 16) & 0xff;
864 120 : buf[2] = (u >> 8) & 0xff;
865 120 : buf[3] = u & 0xff;
866 120 : u = sig->keyid[1];
867 120 : buf[4] = (u >> 24) & 0xff;
868 120 : buf[5] = (u >> 16) & 0xff;
869 120 : buf[6] = (u >> 8) & 0xff;
870 120 : buf[7] = u & 0xff;
871 120 : build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 );
872 :
873 120 : u = sig->timestamp;
874 120 : buf[0] = (u >> 24) & 0xff;
875 120 : buf[1] = (u >> 16) & 0xff;
876 120 : buf[2] = (u >> 8) & 0xff;
877 120 : buf[3] = u & 0xff;
878 120 : build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 );
879 :
880 120 : if(sig->expiredate)
881 : {
882 0 : if(sig->expiredate>sig->timestamp)
883 0 : u=sig->expiredate-sig->timestamp;
884 : else
885 0 : u=1; /* A 1-second expiration time is the shortest one
886 : OpenPGP has */
887 :
888 0 : buf[0] = (u >> 24) & 0xff;
889 0 : buf[1] = (u >> 16) & 0xff;
890 0 : buf[2] = (u >> 8) & 0xff;
891 0 : buf[3] = u & 0xff;
892 :
893 : /* Mark this CRITICAL, so if any implementation doesn't
894 : understand sigs that can expire, it'll just disregard this
895 : sig altogether. */
896 :
897 0 : build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
898 : buf, 4 );
899 : }
900 120 : }
901 :
902 : void
903 0 : build_attribute_subpkt(PKT_user_id *uid,byte type,
904 : const void *buf,u32 buflen,
905 : const void *header,u32 headerlen)
906 : {
907 : byte *attrib;
908 : int idx;
909 :
910 0 : if(1+headerlen+buflen>8383)
911 0 : idx=5;
912 0 : else if(1+headerlen+buflen>191)
913 0 : idx=2;
914 : else
915 0 : idx=1;
916 :
917 : /* realloc uid->attrib_data to the right size */
918 :
919 0 : uid->attrib_data=xrealloc(uid->attrib_data,
920 : uid->attrib_len+idx+1+headerlen+buflen);
921 :
922 0 : attrib=&uid->attrib_data[uid->attrib_len];
923 :
924 0 : if(idx==5)
925 : {
926 0 : attrib[0]=255;
927 0 : attrib[1]=(1+headerlen+buflen) >> 24;
928 0 : attrib[2]=(1+headerlen+buflen) >> 16;
929 0 : attrib[3]=(1+headerlen+buflen) >> 8;
930 0 : attrib[4]=1+headerlen+buflen;
931 : }
932 0 : else if(idx==2)
933 : {
934 0 : attrib[0]=(1+headerlen+buflen-192) / 256 + 192;
935 0 : attrib[1]=(1+headerlen+buflen-192) % 256;
936 : }
937 : else
938 0 : attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */
939 :
940 0 : attrib[idx++]=type;
941 :
942 : /* Tack on our data at the end */
943 :
944 0 : if(headerlen>0)
945 0 : memcpy(&attrib[idx],header,headerlen);
946 0 : memcpy(&attrib[idx+headerlen],buf,buflen);
947 0 : uid->attrib_len+=idx+headerlen+buflen;
948 0 : }
949 :
950 : struct notation *
951 0 : string_to_notation(const char *string,int is_utf8)
952 : {
953 : const char *s;
954 0 : int saw_at=0;
955 : struct notation *notation;
956 :
957 0 : notation=xmalloc_clear(sizeof(*notation));
958 :
959 0 : if(*string=='-')
960 : {
961 0 : notation->flags.ignore=1;
962 0 : string++;
963 : }
964 :
965 0 : if(*string=='!')
966 : {
967 0 : notation->flags.critical=1;
968 0 : string++;
969 : }
970 :
971 : /* If and when the IETF assigns some official name tags, we'll have
972 : to add them here. */
973 :
974 0 : for( s=string ; *s != '='; s++ )
975 : {
976 0 : if( *s=='@')
977 0 : saw_at++;
978 :
979 : /* -notationname is legal without an = sign */
980 0 : if(!*s && notation->flags.ignore)
981 0 : break;
982 :
983 0 : if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
984 : {
985 0 : log_error(_("a notation name must have only printable characters"
986 : " or spaces, and end with an '='\n") );
987 0 : goto fail;
988 : }
989 : }
990 :
991 0 : notation->name=xmalloc((s-string)+1);
992 0 : strncpy(notation->name,string,s-string);
993 0 : notation->name[s-string]='\0';
994 :
995 0 : if(!saw_at && !opt.expert)
996 : {
997 0 : log_error(_("a user notation name must contain the '@' character\n"));
998 0 : goto fail;
999 : }
1000 :
1001 0 : if (saw_at > 1)
1002 : {
1003 0 : log_error(_("a notation name must not contain more than"
1004 : " one '@' character\n"));
1005 0 : goto fail;
1006 : }
1007 :
1008 0 : if(*s)
1009 : {
1010 0 : const char *i=s+1;
1011 0 : int highbit=0;
1012 :
1013 : /* we only support printable text - therefore we enforce the use
1014 : of only printable characters (an empty value is valid) */
1015 0 : for(s++; *s ; s++ )
1016 : {
1017 0 : if ( !isascii (*s) )
1018 0 : highbit=1;
1019 0 : else if (iscntrl(*s))
1020 : {
1021 0 : log_error(_("a notation value must not use any"
1022 : " control characters\n"));
1023 0 : goto fail;
1024 : }
1025 : }
1026 :
1027 0 : if(!highbit || is_utf8)
1028 0 : notation->value=xstrdup(i);
1029 : else
1030 0 : notation->value=native_to_utf8(i);
1031 : }
1032 :
1033 0 : return notation;
1034 :
1035 : fail:
1036 0 : free_notation(notation);
1037 0 : return NULL;
1038 : }
1039 :
1040 : struct notation *
1041 143 : sig_to_notation(PKT_signature *sig)
1042 : {
1043 : const byte *p;
1044 : size_t len;
1045 143 : int seq=0,crit;
1046 143 : struct notation *list=NULL;
1047 :
1048 286 : while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
1049 : {
1050 : int n1,n2;
1051 0 : struct notation *n=NULL;
1052 :
1053 0 : if(len<8)
1054 : {
1055 0 : log_info(_("WARNING: invalid notation data found\n"));
1056 0 : continue;
1057 : }
1058 :
1059 0 : n1=(p[4]<<8)|p[5];
1060 0 : n2=(p[6]<<8)|p[7];
1061 :
1062 0 : if(8+n1+n2!=len)
1063 : {
1064 0 : log_info(_("WARNING: invalid notation data found\n"));
1065 0 : continue;
1066 : }
1067 :
1068 0 : n=xmalloc_clear(sizeof(*n));
1069 0 : n->name=xmalloc(n1+1);
1070 :
1071 0 : memcpy(n->name,&p[8],n1);
1072 0 : n->name[n1]='\0';
1073 :
1074 0 : if(p[0]&0x80)
1075 : {
1076 0 : n->value=xmalloc(n2+1);
1077 0 : memcpy(n->value,&p[8+n1],n2);
1078 0 : n->value[n2]='\0';
1079 : }
1080 : else
1081 : {
1082 0 : n->bdat=xmalloc(n2);
1083 0 : n->blen=n2;
1084 0 : memcpy(n->bdat,&p[8+n1],n2);
1085 :
1086 0 : n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
1087 0 : strcpy(n->value,"[ ");
1088 0 : strcat(n->value,_("not human readable"));
1089 0 : strcat(n->value," ]");
1090 : }
1091 :
1092 0 : n->flags.critical=crit;
1093 :
1094 0 : n->next=list;
1095 0 : list=n;
1096 : }
1097 :
1098 143 : return list;
1099 : }
1100 :
1101 : void
1102 143 : free_notation(struct notation *notation)
1103 : {
1104 286 : while(notation)
1105 : {
1106 0 : struct notation *n=notation;
1107 :
1108 0 : xfree(n->name);
1109 0 : xfree(n->value);
1110 0 : xfree(n->altvalue);
1111 0 : xfree(n->bdat);
1112 0 : notation=n->next;
1113 0 : xfree(n);
1114 : }
1115 143 : }
1116 :
1117 : static int
1118 383 : do_signature( IOBUF out, int ctb, PKT_signature *sig )
1119 : {
1120 383 : int rc = 0;
1121 : int n, i;
1122 383 : IOBUF a = iobuf_temp();
1123 :
1124 383 : if ( !sig->version )
1125 0 : iobuf_put( a, 3 );
1126 : else
1127 383 : iobuf_put( a, sig->version );
1128 383 : if ( sig->version < 4 )
1129 2 : iobuf_put (a, 5 ); /* Constant */
1130 383 : iobuf_put (a, sig->sig_class );
1131 383 : if ( sig->version < 4 )
1132 : {
1133 2 : write_32(a, sig->timestamp );
1134 2 : write_32(a, sig->keyid[0] );
1135 2 : write_32(a, sig->keyid[1] );
1136 : }
1137 383 : iobuf_put(a, sig->pubkey_algo );
1138 383 : iobuf_put(a, sig->digest_algo );
1139 383 : if ( sig->version >= 4 )
1140 : {
1141 : size_t nn;
1142 : /* Timestamp and keyid must have been packed into the subpackets
1143 : prior to the call of this function, because these subpackets
1144 : are hashed. */
1145 381 : nn = sig->hashed? sig->hashed->len : 0;
1146 381 : write_16(a, nn);
1147 381 : if (nn)
1148 381 : iobuf_write( a, sig->hashed->data, nn );
1149 381 : nn = sig->unhashed? sig->unhashed->len : 0;
1150 381 : write_16(a, nn);
1151 381 : if (nn)
1152 381 : iobuf_write( a, sig->unhashed->data, nn );
1153 : }
1154 383 : iobuf_put(a, sig->digest_start[0] );
1155 383 : iobuf_put(a, sig->digest_start[1] );
1156 383 : n = pubkey_get_nsig( sig->pubkey_algo );
1157 383 : if ( !n )
1158 0 : write_fake_data( a, sig->data[0] );
1159 1069 : for (i=0; i < n && !rc ; i++ )
1160 686 : rc = gpg_mpi_write (a, sig->data[i] );
1161 :
1162 383 : if (!rc)
1163 : {
1164 383 : if ( is_RSA(sig->pubkey_algo) && sig->version < 4 )
1165 1 : write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
1166 : else
1167 382 : write_header(out, ctb, iobuf_get_temp_length(a) );
1168 383 : rc = iobuf_write_temp( out, a );
1169 : }
1170 :
1171 383 : iobuf_close(a);
1172 383 : return rc;
1173 : }
1174 :
1175 :
1176 : static int
1177 89 : do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
1178 : {
1179 89 : int rc = 0;
1180 89 : IOBUF a = iobuf_temp();
1181 :
1182 89 : iobuf_put (a, 3); /* Version. */
1183 89 : iobuf_put(a, ops->sig_class );
1184 89 : iobuf_put(a, ops->digest_algo );
1185 89 : iobuf_put(a, ops->pubkey_algo );
1186 89 : write_32(a, ops->keyid[0] );
1187 89 : write_32(a, ops->keyid[1] );
1188 89 : iobuf_put(a, ops->last );
1189 :
1190 89 : write_header(out, ctb, iobuf_get_temp_length(a) );
1191 89 : rc = iobuf_write_temp( out, a );
1192 :
1193 89 : iobuf_close(a);
1194 89 : return rc;
1195 : }
1196 :
1197 :
1198 : static int
1199 762 : write_16(IOBUF out, u16 a)
1200 : {
1201 762 : iobuf_put(out, a>>8);
1202 762 : if( iobuf_put(out,a) )
1203 0 : return -1;
1204 762 : return 0;
1205 : }
1206 :
1207 : static int
1208 1274 : write_32(IOBUF out, u32 a)
1209 : {
1210 1274 : iobuf_put(out, a>> 24);
1211 1274 : iobuf_put(out, a>> 16);
1212 1274 : iobuf_put(out, a>> 8);
1213 1274 : return iobuf_put(out, a);
1214 : }
1215 :
1216 :
1217 : /****************
1218 : * calculate the length of a header
1219 : */
1220 : static int
1221 0 : calc_header_length( u32 len, int new_ctb )
1222 : {
1223 0 : if( !len )
1224 0 : return 1; /* only the ctb */
1225 :
1226 0 : if( new_ctb ) {
1227 0 : if( len < 192 )
1228 0 : return 2;
1229 0 : if( len < 8384 )
1230 0 : return 3;
1231 : else
1232 0 : return 6;
1233 : }
1234 0 : if( len < 256 )
1235 0 : return 2;
1236 0 : if( len < 65536 )
1237 0 : return 3;
1238 :
1239 0 : return 5;
1240 : }
1241 :
1242 : /****************
1243 : * Write the CTB and the packet length
1244 : */
1245 : static int
1246 1889 : write_header( IOBUF out, int ctb, u32 len )
1247 : {
1248 1889 : return write_header2( out, ctb, len, 0 );
1249 : }
1250 :
1251 :
1252 : static int
1253 1 : write_sign_packet_header (IOBUF out, int ctb, u32 len)
1254 : {
1255 : (void)ctb;
1256 :
1257 : /* Work around a bug in the pgp read function for signature packets,
1258 : which are not correctly coded and silently assume at some point 2
1259 : byte length headers.*/
1260 1 : iobuf_put (out, 0x89 );
1261 1 : iobuf_put (out, len >> 8 );
1262 1 : return iobuf_put (out, len) == -1 ? -1:0;
1263 : }
1264 :
1265 : /****************
1266 : * If HDRLEN is > 0, try to build a header of this length. We need
1267 : * this so that we can hash packets without reading them again. If
1268 : * len is 0, write a partial or indeterminate length header, unless
1269 : * hdrlen is specified in which case write an actual zero length
1270 : * (using the specified hdrlen).
1271 : */
1272 : static int
1273 2582 : write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
1274 : {
1275 2582 : if( ctb & 0x40 )
1276 482 : return write_new_header( out, ctb, len, hdrlen );
1277 :
1278 2100 : if( hdrlen )
1279 : {
1280 180 : if( hdrlen == 2 && len < 256 )
1281 : ;
1282 86 : else if( hdrlen == 3 && len < 65536 )
1283 86 : ctb |= 1;
1284 : else
1285 0 : ctb |= 2;
1286 : }
1287 : else
1288 : {
1289 1920 : if( !len )
1290 510 : ctb |= 3;
1291 1410 : else if( len < 256 )
1292 : ;
1293 469 : else if( len < 65536 )
1294 420 : ctb |= 1;
1295 : else
1296 49 : ctb |= 2;
1297 : }
1298 :
1299 2100 : if( iobuf_put(out, ctb ) )
1300 0 : return -1;
1301 :
1302 2100 : if( len || hdrlen )
1303 : {
1304 1590 : if( ctb & 2 )
1305 : {
1306 49 : if(iobuf_put(out, len >> 24 ))
1307 0 : return -1;
1308 49 : if(iobuf_put(out, len >> 16 ))
1309 0 : return -1;
1310 : }
1311 :
1312 1590 : if( ctb & 3 )
1313 555 : if(iobuf_put(out, len >> 8 ))
1314 0 : return -1;
1315 :
1316 1590 : if( iobuf_put(out, len ) )
1317 0 : return -1;
1318 : }
1319 :
1320 2100 : return 0;
1321 : }
1322 :
1323 :
1324 : static int
1325 482 : write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
1326 : {
1327 482 : if( hdrlen )
1328 0 : log_bug("can't cope with hdrlen yet\n");
1329 :
1330 482 : if( iobuf_put(out, ctb ) )
1331 0 : return -1;
1332 482 : if( !len ) {
1333 482 : iobuf_set_partial_block_mode(out, 512 );
1334 : }
1335 : else {
1336 0 : if( len < 192 ) {
1337 0 : if( iobuf_put(out, len ) )
1338 0 : return -1;
1339 : }
1340 0 : else if( len < 8384 ) {
1341 0 : len -= 192;
1342 0 : if( iobuf_put( out, (len / 256) + 192) )
1343 0 : return -1;
1344 0 : if( iobuf_put( out, (len % 256) ) )
1345 0 : return -1;
1346 : }
1347 : else {
1348 0 : if( iobuf_put( out, 0xff ) )
1349 0 : return -1;
1350 0 : if( iobuf_put( out, (len >> 24)&0xff ) )
1351 0 : return -1;
1352 0 : if( iobuf_put( out, (len >> 16)&0xff ) )
1353 0 : return -1;
1354 0 : if( iobuf_put( out, (len >> 8)&0xff ) )
1355 0 : return -1;
1356 0 : if( iobuf_put( out, len & 0xff ) )
1357 0 : return -1;
1358 : }
1359 : }
1360 482 : return 0;
1361 : }
|