~ubuntu-branches/ubuntu/jaunty/gnupg2/jaunty

« back to all changes in this revision

Viewing changes to g10/build-packet.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* build-packet.c - assemble packets and write them
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
 
3
 *               2003 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 2 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, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <assert.h>
 
27
 
 
28
#include "gpg.h"
 
29
#include "packet.h"
 
30
#include "errors.h"
 
31
#include "iobuf.h"
 
32
#include "mpi.h"
 
33
#include "util.h"
 
34
#include "cipher.h"
 
35
#include "memory.h"
 
36
#include "options.h"
 
37
 
 
38
 
 
39
static int do_comment( iobuf_t out, int ctb, PKT_comment *rem );
 
40
static int do_user_id( iobuf_t out, int ctb, PKT_user_id *uid );
 
41
static int do_public_key( iobuf_t out, int ctb, PKT_public_key *pk );
 
42
static int do_secret_key( iobuf_t out, int ctb, PKT_secret_key *pk );
 
43
static int do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc );
 
44
static int do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc );
 
45
static u32 calc_plaintext( PKT_plaintext *pt );
 
46
static int do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt );
 
47
static int do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed );
 
48
static int do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed );
 
49
static int do_compressed( iobuf_t out, int ctb, PKT_compressed *cd );
 
50
static int do_signature( iobuf_t out, int ctb, PKT_signature *sig );
 
51
static int do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops );
 
52
 
 
53
static int calc_header_length( u32 len, int new_ctb );
 
54
static int write_16(iobuf_t inp, u16 a);
 
55
static int write_32(iobuf_t inp, u32 a);
 
56
static int write_header( iobuf_t out, int ctb, u32 len );
 
57
static int write_sign_packet_header( iobuf_t out, int ctb, u32 len );
 
58
static int write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode );
 
59
static int write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen );
 
60
static int write_version( iobuf_t out, int ctb );
 
61
 
 
62
/****************
 
63
 * Build a packet and write it to INP
 
64
 * Returns: 0 := okay
 
65
 *         >0 := error
 
66
 * Note: Caller must free the packet
 
67
 */
 
68
int
 
69
build_packet( iobuf_t out, PACKET *pkt )
 
70
{
 
71
    int new_ctb=0, rc=0, ctb;
 
72
    int pkttype;
 
73
 
 
74
    if( DBG_PACKET )
 
75
        log_debug("build_packet() type=%d\n", pkt->pkttype );
 
76
    assert( pkt->pkt.generic );
 
77
 
 
78
    switch( (pkttype = pkt->pkttype) ) {
 
79
      case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
 
80
      case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
 
81
      case PKT_ENCRYPTED:
 
82
      case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
 
83
      case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
 
84
      case PKT_USER_ID:
 
85
            if( pkt->pkt.user_id->attrib_data )
 
86
                pkttype = PKT_ATTRIBUTE;
 
87
            break;
 
88
      default: break;
 
89
    }
 
90
 
 
91
    if( new_ctb || pkttype > 15 ) /* new format */
 
92
        ctb = 0xc0 | (pkttype & 0x3f);
 
93
    else
 
94
        ctb = 0x80 | ((pkttype & 15)<<2);
 
95
    switch( pkttype ) {
 
96
      case PKT_ATTRIBUTE:
 
97
      case PKT_USER_ID:
 
98
        rc = do_user_id( out, ctb, pkt->pkt.user_id );
 
99
        break;
 
100
      case PKT_COMMENT:
 
101
        rc = do_comment( out, ctb, pkt->pkt.comment );
 
102
        break;
 
103
      case PKT_PUBLIC_SUBKEY:
 
104
      case PKT_PUBLIC_KEY:
 
105
        rc = do_public_key( out, ctb, pkt->pkt.public_key );
 
106
        break;
 
107
      case PKT_SECRET_SUBKEY:
 
108
      case PKT_SECRET_KEY:
 
109
        rc = do_secret_key( out, ctb, pkt->pkt.secret_key );
 
110
        break;
 
111
      case PKT_SYMKEY_ENC:
 
112
        rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
 
113
        break;
 
114
      case PKT_PUBKEY_ENC:
 
115
        rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
 
116
        break;
 
117
      case PKT_PLAINTEXT:
 
118
        rc = do_plaintext( out, ctb, pkt->pkt.plaintext );
 
119
        break;
 
120
      case PKT_ENCRYPTED:
 
121
        rc = do_encrypted( out, ctb, pkt->pkt.encrypted );
 
122
        break;
 
123
      case PKT_ENCRYPTED_MDC:
 
124
        rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
 
125
        break;
 
126
      case PKT_COMPRESSED:
 
127
        rc = do_compressed( out, ctb, pkt->pkt.compressed );
 
128
        break;
 
129
      case PKT_SIGNATURE:
 
130
        rc = do_signature( out, ctb, pkt->pkt.signature );
 
131
        break;
 
132
      case PKT_ONEPASS_SIG:
 
133
        rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig );
 
134
        break;
 
135
      case PKT_RING_TRUST:
 
136
        break; /* ignore it (keyring.c does write it directly)*/
 
137
      case PKT_MDC: /* we write it directly, so we should never see it here. */
 
138
      default:
 
139
        log_bug("invalid packet type in build_packet()\n");
 
140
        break;
 
141
    }
 
142
 
 
143
    return rc;
 
144
}
 
145
 
 
146
/****************
 
147
 * calculate the length of a packet described by PKT
 
148
 */
 
149
u32
 
150
calc_packet_length( PACKET *pkt )
 
151
{
 
152
    u32 n=0;
 
153
    int new_ctb = 0;
 
154
 
 
155
    assert( pkt->pkt.generic );
 
156
    switch( pkt->pkttype ) {
 
157
      case PKT_PLAINTEXT:
 
158
        n = calc_plaintext( pkt->pkt.plaintext );
 
159
        new_ctb = pkt->pkt.plaintext->new_ctb;
 
160
        break;
 
161
      case PKT_ATTRIBUTE:
 
162
      case PKT_USER_ID:
 
163
      case PKT_COMMENT:
 
164
      case PKT_PUBLIC_KEY:
 
165
      case PKT_SECRET_KEY:
 
166
      case PKT_SYMKEY_ENC:
 
167
      case PKT_PUBKEY_ENC:
 
168
      case PKT_ENCRYPTED:
 
169
      case PKT_SIGNATURE:
 
170
      case PKT_ONEPASS_SIG:
 
171
      case PKT_RING_TRUST:
 
172
      case PKT_COMPRESSED:
 
173
      default:
 
174
        log_bug("invalid packet type in calc_packet_length()");
 
175
        break;
 
176
    }
 
177
 
 
178
    n += calc_header_length(n, new_ctb);
 
179
    return n;
 
180
}
 
181
 
 
182
static void
 
183
write_fake_data( iobuf_t out, gcry_mpi_t a )
 
184
{
 
185
    if( a ) {
 
186
        unsigned int n;
 
187
        void *p;
 
188
 
 
189
        assert( gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE));
 
190
        p = gcry_mpi_get_opaque (a, &n);
 
191
        iobuf_write (out, p, (n+7)/8);
 
192
    }
 
193
}
 
194
 
 
195
 
 
196
static int
 
197
do_comment (iobuf_t out, int ctb, PKT_comment *rem)
 
198
{
 
199
  int rc = 0;
 
200
 
 
201
  if (opt.sk_comments)
 
202
    {
 
203
      write_header(out, ctb, rem->len);
 
204
      rc = iobuf_write( out, rem->data, rem->len );
 
205
    }
 
206
  return rc;
 
207
}
 
208
 
 
209
static int
 
210
do_user_id( iobuf_t out, int ctb, PKT_user_id *uid )
 
211
{
 
212
  int rc;
 
213
 
 
214
  if (uid->attrib_data)
 
215
    {
 
216
      write_header (out, ctb, uid->attrib_len);
 
217
      rc = iobuf_write (out, uid->attrib_data, uid->attrib_len );
 
218
    }
 
219
  else
 
220
    {
 
221
      write_header (out, ctb, uid->len);
 
222
      rc = iobuf_write (out, uid->name, uid->len );
 
223
    }
 
224
  return rc;
 
225
}
 
226
 
 
227
static int
 
228
do_public_key( iobuf_t out, int ctb, PKT_public_key *pk )
 
229
{
 
230
    int rc = 0;
 
231
    int n, i;
 
232
    iobuf_t a = iobuf_temp();
 
233
 
 
234
    if( !pk->version )
 
235
        iobuf_put( a, 3 );
 
236
    else
 
237
        iobuf_put( a, pk->version );
 
238
    write_32(a, pk->timestamp );
 
239
    if( pk->version < 4 ) {
 
240
        u16 ndays;
 
241
        if( pk->expiredate )
 
242
            ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
 
243
        else
 
244
            ndays = 0;
 
245
        write_16(a, ndays );
 
246
    }
 
247
    iobuf_put(a, pk->pubkey_algo );
 
248
    n = pubkey_get_npkey( pk->pubkey_algo );
 
249
    if( !n )
 
250
        write_fake_data( a, pk->pkey[0] );
 
251
    for(i=0; i < n; i++ )
 
252
        mpi_write(a, pk->pkey[i] );
 
253
 
 
254
    write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes, 1 );
 
255
    rc = iobuf_write_temp (out, a);
 
256
 
 
257
    iobuf_close(a);
 
258
    return rc;
 
259
}
 
260
 
 
261
 
 
262
/****************
 
263
 * Make a hash value from the public key certificate
 
264
 */
 
265
void
 
266
hash_public_key( MD_HANDLE md, PKT_public_key *pk )
 
267
{
 
268
    PACKET pkt;
 
269
    int rc = 0;
 
270
    int ctb;
 
271
    ulong pktlen;
 
272
    int c;
 
273
    iobuf_t a = iobuf_temp();
 
274
#if 0
 
275
    FILE *fp = fopen("dump.pk", "a");
 
276
    int i=0;
 
277
 
 
278
    fprintf(fp, "\nHashing PK (v%d):\n", pk->version);
 
279
#endif
 
280
 
 
281
    /* build the packet */
 
282
    init_packet(&pkt);
 
283
    pkt.pkttype = PKT_PUBLIC_KEY;
 
284
    pkt.pkt.public_key = pk;
 
285
    if( (rc = build_packet( a, &pkt )) )
 
286
        log_fatal("build public_key for hashing failed: %s\n", gpg_strerror (rc));
 
287
 
 
288
    if( !(pk->version == 3 && pk->pubkey_algo == 16) ) {
 
289
        /* skip the constructed header but don't do this for our very old
 
290
         * v3 ElG keys */
 
291
        ctb = iobuf_get_noeof(a);
 
292
        pktlen = 0;
 
293
        if( (ctb & 0x40) ) {
 
294
            c = iobuf_get_noeof(a);
 
295
            if( c < 192 )
 
296
                pktlen = c;
 
297
            else if( c < 224 ) {
 
298
                pktlen = (c - 192) * 256;
 
299
                c = iobuf_get_noeof(a);
 
300
                pktlen += c + 192;
 
301
            }
 
302
            else if( c == 255 ) {
 
303
                pktlen  = iobuf_get_noeof(a) << 24;
 
304
                pktlen |= iobuf_get_noeof(a) << 16;
 
305
                pktlen |= iobuf_get_noeof(a) << 8;
 
306
                pktlen |= iobuf_get_noeof(a);
 
307
            }
 
308
        }
 
309
        else {
 
310
            int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
 
311
            for( ; lenbytes; lenbytes-- ) {
 
312
                pktlen <<= 8;
 
313
                pktlen |= iobuf_get_noeof(a);
 
314
            }
 
315
        }
 
316
        /* hash a header */
 
317
        gcry_md_putc ( md, 0x99 );
 
318
        pktlen &= 0xffff; /* can't handle longer packets */
 
319
        gcry_md_putc ( md, pktlen >> 8 );
 
320
        gcry_md_putc ( md, pktlen & 0xff );
 
321
    }
 
322
    /* hash the packet body */
 
323
    while( (c=iobuf_get(a)) != -1 ) {
 
324
#if 0
 
325
        fprintf( fp," %02x", c );
 
326
        if( (++i == 24) ) {
 
327
            putc('\n', fp);
 
328
            i=0;
 
329
        }
 
330
#endif
 
331
        gcry_md_putc ( md, c );
 
332
    }
 
333
#if 0
 
334
    putc('\n', fp);
 
335
    fclose(fp);
 
336
#endif
 
337
    iobuf_cancel(a);
 
338
}
 
339
 
 
340
 
 
341
static int
 
342
do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
 
343
{
 
344
    int rc = 0;
 
345
    int i, nskey, npkey;
 
346
    iobuf_t a = iobuf_temp(); /* build in a self-enlarging buffer */
 
347
 
 
348
    /* Write the version number - if none is specified, use 3 */
 
349
    if( !sk->version )
 
350
        iobuf_put( a, 3 );
 
351
    else
 
352
        iobuf_put( a, sk->version );
 
353
    write_32(a, sk->timestamp );
 
354
 
 
355
    /* v3  needs the expiration time */
 
356
    if( sk->version < 4 ) {
 
357
        u16 ndays;
 
358
        if( sk->expiredate )
 
359
            ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
 
360
        else
 
361
            ndays = 0;
 
362
        write_16(a, ndays);
 
363
    }
 
364
 
 
365
    iobuf_put(a, sk->pubkey_algo );
 
366
 
 
367
    /* get number of secret and public parameters.  They are held in
 
368
       one array first the public ones, then the secret ones */
 
369
    nskey = pubkey_get_nskey( sk->pubkey_algo );
 
370
    npkey = pubkey_get_npkey( sk->pubkey_algo );
 
371
 
 
372
    /* If we don't have any public parameters - which is the case if
 
373
       we don't know the algorithm used - the parameters are stored as
 
374
       one blob in a faked (opaque) gcry_mpi_t */
 
375
    if( !npkey ) {
 
376
        write_fake_data( a, sk->skey[0] );
 
377
        goto leave;
 
378
    }
 
379
    assert( npkey < nskey );
 
380
 
 
381
    /* Writing the public parameters is easy */
 
382
    for(i=0; i < npkey; i++ )
 
383
        mpi_write(a, sk->skey[i] );
 
384
 
 
385
    /* build the header for protected (encrypted) secret parameters */
 
386
    if( sk->is_protected ) {
 
387
        if( is_RSA(sk->pubkey_algo) && sk->version < 4
 
388
                                    && !sk->protect.s2k.mode ) {
 
389
            /* the simple rfc1991 (v3) way */
 
390
            iobuf_put(a, sk->protect.algo );
 
391
            iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
 
392
        }
 
393
        else {
 
394
          /* OpenPGP protection according to rfc2440 */
 
395
            iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
 
396
            iobuf_put(a, sk->protect.algo );
 
397
            if( sk->protect.s2k.mode >= 1000 ) {
 
398
                /* These modes are not possible in OpenPGP, we use them
 
399
                   to implement our extensions, 101 can be seen as a
 
400
                   private/experimental extension (this is not
 
401
                   specified in rfc2440 but the same scheme is used
 
402
                   for all other algorithm identifiers) */
 
403
                iobuf_put(a, 101 ); 
 
404
                iobuf_put(a, sk->protect.s2k.hash_algo );
 
405
                iobuf_write(a, "GNU", 3 );
 
406
                iobuf_put(a, sk->protect.s2k.mode - 1000 );
 
407
            }
 
408
            else {
 
409
                iobuf_put(a, sk->protect.s2k.mode );
 
410
                iobuf_put(a, sk->protect.s2k.hash_algo );
 
411
            }
 
412
            if( sk->protect.s2k.mode == 1
 
413
                || sk->protect.s2k.mode == 3 )
 
414
                iobuf_write(a, sk->protect.s2k.salt, 8 );
 
415
            if( sk->protect.s2k.mode == 3 )
 
416
                iobuf_put(a, sk->protect.s2k.count ); 
 
417
 
 
418
            /* For our special modes 1001 and 1002 we do not need an IV */
 
419
            if( sk->protect.s2k.mode != 1001
 
420
                && sk->protect.s2k.mode != 1002 )
 
421
                iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
 
422
        }
 
423
    }
 
424
    else
 
425
        iobuf_put(a, 0 );
 
426
 
 
427
    if( sk->protect.s2k.mode == 1001 )
 
428
        ; /* GnuPG extension - don't write a secret key at all */ 
 
429
    else if( sk->protect.s2k.mode == 1002 )
 
430
      {  /* GnuPG extension - divert to OpenPGP smartcard. */ 
 
431
        iobuf_put(a, sk->protect.ivlen ); /* length of the serial
 
432
                                             number or 0 for no serial
 
433
                                             number. */
 
434
        /* The serial number gets stored in the IV field. */
 
435
        iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
 
436
      }
 
437
    else if( sk->is_protected && sk->version >= 4 ) {
 
438
        /* The secret key is protected - write it out as it is */
 
439
        byte *p;
 
440
        assert( gcry_mpi_get_flag( sk->skey[npkey], GCRYMPI_FLAG_OPAQUE ) );
 
441
        p = gcry_mpi_get_opaque( sk->skey[npkey], &i );
 
442
        iobuf_write(a, p, (i+7)/8 );
 
443
    }
 
444
    else if( sk->is_protected ) {
 
445
        /* The secret key is protected the old v4 way. */
 
446
        for(   ; i < nskey; i++ ) {
 
447
            byte *p;
 
448
            size_t n;
 
449
 
 
450
            assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
 
451
            p = gcry_mpi_get_opaque( sk->skey[i], &n );
 
452
            iobuf_write (a, p, (n+7)/8);
 
453
        }
 
454
        write_16(a, sk->csum );
 
455
    }
 
456
    else {
 
457
        /* non-protected key */
 
458
        for(   ; i < nskey; i++ )
 
459
            mpi_write(a, sk->skey[i] );
 
460
        write_16(a, sk->csum );
 
461
    }
 
462
 
 
463
  leave:
 
464
    /* Build the header of the packet - which we must do after writing all
 
465
       the other stuff, so that we know the length of the packet */
 
466
    write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 );
 
467
    /* And finally write it out the real stream */
 
468
    rc = iobuf_write_temp (out, a );
 
469
 
 
470
    iobuf_close(a); /* close the remporary buffer */
 
471
    return rc;
 
472
}
 
473
 
 
474
static int
 
475
do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc )
 
476
{
 
477
    int rc = 0;
 
478
    iobuf_t a = iobuf_temp();
 
479
 
 
480
    assert( enc->version == 4 );
 
481
    switch( enc->s2k.mode ) {
 
482
      case 0: case 1: case 3: break;
 
483
      default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
 
484
    }
 
485
    iobuf_put( a, enc->version );
 
486
    iobuf_put( a, enc->cipher_algo );
 
487
    iobuf_put( a, enc->s2k.mode );
 
488
    iobuf_put( a, enc->s2k.hash_algo );
 
489
    if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
 
490
        iobuf_write(a, enc->s2k.salt, 8 );
 
491
        if( enc->s2k.mode == 3 )
 
492
            iobuf_put(a, enc->s2k.count);
 
493
    }
 
494
    if( enc->seskeylen )
 
495
        iobuf_write(a, enc->seskey, enc->seskeylen );
 
496
 
 
497
    write_header(out, ctb, iobuf_get_temp_length(a) );
 
498
    rc = iobuf_write_temp (out, a);
 
499
 
 
500
    iobuf_close(a);
 
501
    return rc;
 
502
}
 
503
 
 
504
 
 
505
 
 
506
 
 
507
static int
 
508
do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc )
 
509
{
 
510
    int rc = 0;
 
511
    int n, i;
 
512
    iobuf_t a = iobuf_temp();
 
513
 
 
514
    write_version( a, ctb );
 
515
    if( enc->throw_keyid ) {
 
516
        write_32(a, 0 );  /* don't tell Eve who can decrypt the message */
 
517
        write_32(a, 0 );
 
518
    }
 
519
    else {
 
520
        write_32(a, enc->keyid[0] );
 
521
        write_32(a, enc->keyid[1] );
 
522
    }
 
523
    iobuf_put(a,enc->pubkey_algo );
 
524
    n = pubkey_get_nenc( enc->pubkey_algo );
 
525
    if( !n )
 
526
        write_fake_data( a, enc->data[0] );
 
527
    for(i=0; i < n; i++ )
 
528
        mpi_write(a, enc->data[i] );
 
529
 
 
530
    write_header(out, ctb, iobuf_get_temp_length(a) );
 
531
    rc = iobuf_write_temp (out, a);
 
532
 
 
533
    iobuf_close(a);
 
534
    return rc;
 
535
}
 
536
 
 
537
 
 
538
 
 
539
 
 
540
static u32
 
541
calc_plaintext( PKT_plaintext *pt )
 
542
{
 
543
    return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
 
544
}
 
545
 
 
546
static int
 
547
do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt )
 
548
{
 
549
    int i, rc = 0;
 
550
    u32 n;
 
551
    byte buf[1000]; /* this buffer has the plaintext! */
 
552
    int nbytes;
 
553
 
 
554
    /* Truncate namelen to the maximum 255 characters.  This does mean
 
555
       that a function that calls build_packet with an illegal literal
 
556
       packet will get it back legalized. */
 
557
    if(pt->namelen>255)
 
558
      pt->namelen=255;
 
559
 
 
560
    write_header(out, ctb, calc_plaintext( pt ) );
 
561
    iobuf_put(out, pt->mode );
 
562
    iobuf_put(out, pt->namelen );
 
563
    for(i=0; i < pt->namelen; i++ )
 
564
        iobuf_put(out, pt->name[i] );
 
565
    rc = write_32 (out, pt->timestamp);
 
566
 
 
567
    n = 0;
 
568
    while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
 
569
        rc = iobuf_write(out, buf, nbytes);
 
570
        if (rc)
 
571
          break;
 
572
        n += nbytes;
 
573
    }
 
574
    wipememory(buf,1000); /* burn the buffer */
 
575
    if( !pt->len )
 
576
        iobuf_set_block_mode(out, 0 ); /* write end marker */
 
577
    else if( n != pt->len )
 
578
        log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
 
579
                        (ulong)n, (ulong)pt->len );
 
580
 
 
581
    return rc;
 
582
}
 
583
 
 
584
 
 
585
 
 
586
static int
 
587
do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed )
 
588
{
 
589
    int rc = 0;
 
590
    u32 n;
 
591
 
 
592
    n = ed->len ? (ed->len + ed->extralen) : 0;
 
593
    write_header(out, ctb, n );
 
594
 
 
595
    /* This is all. The caller has to write the real data */
 
596
 
 
597
    return rc;
 
598
}
 
599
 
 
600
static int
 
601
do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed )
 
602
{
 
603
    int rc = 0;
 
604
    u32 n;
 
605
 
 
606
    assert( ed->mdc_method );
 
607
 
 
608
    /* Take version number and the following MDC packet in account. */
 
609
    n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0;
 
610
    write_header(out, ctb, n );
 
611
    iobuf_put(out, 1 );  /* version */
 
612
 
 
613
    /* This is all. The caller has to write the real data */
 
614
 
 
615
    return rc;
 
616
}
 
617
 
 
618
 
 
619
static int
 
620
do_compressed( iobuf_t out, int ctb, PKT_compressed *cd )
 
621
{
 
622
    int rc = 0;
 
623
 
 
624
    /* We must use the old convention and don't use blockmode for tyhe
 
625
       sake of PGP 2 compatibility.  However if the new_ctb flag was
 
626
       set, CTB is already formatted as new style and write_header2
 
627
       does create a partial length encoding using new the new
 
628
       style. */
 
629
    write_header2(out, ctb, 0, 0, 0 );
 
630
    iobuf_put(out, cd->algorithm );
 
631
 
 
632
    /* This is all. The caller has to write the real data */
 
633
 
 
634
    return rc;
 
635
}
 
636
 
 
637
 
 
638
/****************
 
639
 * Delete all subpackets of type REQTYPE and return a bool whether a packet
 
640
 * was deleted.
 
641
 */
 
642
int
 
643
delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
 
644
{
 
645
    int buflen;
 
646
    sigsubpkttype_t type;
 
647
    byte *buffer, *bufstart;
 
648
    size_t n;
 
649
    size_t unused = 0;
 
650
    int okay = 0;
 
651
 
 
652
    if( !area )
 
653
        return 0;
 
654
    buflen = area->len;
 
655
    buffer = area->data;
 
656
    for(;;) {
 
657
        if( !buflen ) {
 
658
            okay = 1;
 
659
            break;
 
660
        }
 
661
        bufstart = buffer;
 
662
        n = *buffer++; buflen--;
 
663
        if( n == 255 ) {
 
664
            if( buflen < 4 )
 
665
                break;
 
666
            n = (buffer[0] << 24) | (buffer[1] << 16)
 
667
                | (buffer[2] << 8) | buffer[3];
 
668
            buffer += 4;
 
669
            buflen -= 4;
 
670
        }
 
671
        else if( n >= 192 ) {
 
672
            if( buflen < 2 )
 
673
                break;
 
674
            n = (( n - 192 ) << 8) + *buffer + 192;
 
675
            buffer++;
 
676
            buflen--;
 
677
        }
 
678
        if( buflen < n )
 
679
            break;
 
680
        
 
681
        type = *buffer & 0x7f;
 
682
        if( type == reqtype ) {
 
683
            buffer++;
 
684
            buflen--;
 
685
            n--;
 
686
            if( n > buflen )
 
687
                break;
 
688
            buffer += n; /* point to next subpkt */
 
689
            buflen -= n;
 
690
            memmove (bufstart, buffer, buflen); /* shift */
 
691
            unused +=  buffer - bufstart;
 
692
            buffer = bufstart;
 
693
        }
 
694
        else {
 
695
            buffer += n; buflen -=n;
 
696
        }
 
697
    }
 
698
 
 
699
    if (!okay)
 
700
        log_error ("delete_subpkt: buffer shorter than subpacket\n");
 
701
    assert (unused <= area->len);
 
702
    area->len -= unused;
 
703
    return !!unused;
 
704
}
 
705
 
 
706
 
 
707
/****************
 
708
 * Create or update a signature subpacket for SIG of TYPE.  This
 
709
 * functions knows where to put the data (hashed or unhashed).  The
 
710
 * function may move data from the unhashed part to the hashed one.
 
711
 * Note: All pointers into sig->[un]hashed (e.g. returned by
 
712
 * parse_sig_subpkt) are not valid after a call to this function.  The
 
713
 * data to put into the subpaket should be in a buffer with a length
 
714
 * of buflen. 
 
715
 */
 
716
void
 
717
build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
 
718
                  const byte *buffer, size_t buflen )
 
719
{
 
720
    byte *p;
 
721
    int critical, hashed;
 
722
    subpktarea_t *oldarea, *newarea;
 
723
    size_t nlen, n, n0;
 
724
 
 
725
    critical = (type & SIGSUBPKT_FLAG_CRITICAL);
 
726
    type &= ~SIGSUBPKT_FLAG_CRITICAL;
 
727
 
 
728
    /* Sanity check buffer sizes */
 
729
    if(parse_one_sig_subpkt(buffer,buflen,type)<0)
 
730
      BUG();
 
731
 
 
732
    switch(type)
 
733
      {
 
734
      case SIGSUBPKT_NOTATION:
 
735
      case SIGSUBPKT_POLICY:
 
736
      case SIGSUBPKT_REV_KEY:
 
737
        /* we do allow multiple subpackets */
 
738
        break;
 
739
 
 
740
      default:
 
741
        /* we don't allow multiple subpackets */
 
742
        delete_sig_subpkt(sig->hashed,type);
 
743
        delete_sig_subpkt(sig->unhashed,type);
 
744
        break;
 
745
      }
 
746
 
 
747
    /* Any special magic that needs to be done for this type so the
 
748
       packet doesn't need to be reparsed? */
 
749
    switch(type)
 
750
      {
 
751
      case SIGSUBPKT_NOTATION:
 
752
        sig->flags.notation=1;
 
753
        break;
 
754
 
 
755
      case SIGSUBPKT_POLICY:
 
756
        sig->flags.policy_url=1;
 
757
        break;
 
758
 
 
759
      case SIGSUBPKT_PREF_KS:
 
760
        sig->flags.pref_ks=1;
 
761
        break;
 
762
 
 
763
      case SIGSUBPKT_EXPORTABLE:
 
764
        if(buffer[0])
 
765
          sig->flags.exportable=1;
 
766
        else
 
767
          sig->flags.exportable=0;
 
768
        break;
 
769
 
 
770
      case SIGSUBPKT_REVOCABLE:
 
771
        if(buffer[0])
 
772
          sig->flags.revocable=1;
 
773
        else
 
774
          sig->flags.revocable=0;
 
775
        break;
 
776
 
 
777
      case SIGSUBPKT_TRUST:
 
778
        sig->trust_depth=buffer[0];
 
779
        sig->trust_value=buffer[1];
 
780
        break;
 
781
 
 
782
      case SIGSUBPKT_REGEXP:
 
783
        sig->trust_regexp=buffer;
 
784
        break;
 
785
 
 
786
        /* This should never happen since we don't currently allow
 
787
           creating such a subpacket, but just in case... */
 
788
      case SIGSUBPKT_SIG_EXPIRE:
 
789
        if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp())
 
790
          sig->flags.expired=1;
 
791
        else
 
792
          sig->flags.expired=0;
 
793
        break;
 
794
 
 
795
      default:
 
796
        break;
 
797
      }
 
798
 
 
799
    if( (buflen+1) >= 8384 )
 
800
        nlen = 5; /* write 5 byte length header */
 
801
    else if( (buflen+1) >= 192 )
 
802
        nlen = 2; /* write 2 byte length header */
 
803
    else
 
804
        nlen = 1; /* just a 1 byte length header */
 
805
 
 
806
    switch( type ) {
 
807
        /* The issuer being unhashed is a historical oddity.  It
 
808
           should work equally as well hashed.  Of course, if even an
 
809
           unhashed issuer is tampered with, it makes it awfully hard
 
810
           to verify the sig... */
 
811
      case SIGSUBPKT_ISSUER:
 
812
        hashed = 0;
 
813
        break;
 
814
      default: 
 
815
        hashed = 1;
 
816
        break;
 
817
    }
 
818
 
 
819
    if( critical )
 
820
        type |= SIGSUBPKT_FLAG_CRITICAL;
 
821
 
 
822
    oldarea = hashed? sig->hashed : sig->unhashed;
 
823
 
 
824
    /* Calculate new size of the area and allocate */
 
825
    n0 = oldarea? oldarea->len : 0;
 
826
    n = n0 + nlen + 1 + buflen; /* length, type, buffer */
 
827
    if (oldarea && n <= oldarea->size) { /* fits into the unused space */
 
828
        newarea = oldarea;
 
829
        /*log_debug ("updating area for type %d\n", type );*/
 
830
    }
 
831
    else if (oldarea) {
 
832
        newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1);
 
833
        newarea->size = n;
 
834
        /*log_debug ("reallocating area for type %d\n", type );*/
 
835
    }
 
836
    else {
 
837
        newarea = xmalloc (sizeof (*newarea) + n - 1);
 
838
        newarea->size = n;
 
839
        /*log_debug ("allocating area for type %d\n", type );*/
 
840
    }
 
841
    newarea->len = n;
 
842
 
 
843
    p = newarea->data + n0;
 
844
    if (nlen == 5) {
 
845
        *p++ = 255;
 
846
        *p++ = (buflen+1) >> 24;
 
847
        *p++ = (buflen+1) >> 16;
 
848
        *p++ = (buflen+1) >>  8;
 
849
        *p++ = (buflen+1);
 
850
        *p++ = type;
 
851
        memcpy (p, buffer, buflen);
 
852
    }
 
853
    else if (nlen == 2) {
 
854
        *p++ = (buflen+1-192) / 256 + 192;
 
855
        *p++ = (buflen+1-192) % 256;
 
856
        *p++ = type;
 
857
        memcpy (p, buffer, buflen);
 
858
    }
 
859
    else {
 
860
        *p++ = buflen+1;
 
861
        *p++ = type;
 
862
        memcpy (p, buffer, buflen);
 
863
    }
 
864
 
 
865
    if (hashed) 
 
866
        sig->hashed = newarea;
 
867
    else
 
868
        sig->unhashed = newarea;
 
869
}
 
870
 
 
871
/****************
 
872
 * Put all the required stuff from SIG into subpackets of sig.
 
873
 * Hmmm, should we delete those subpackets which are in a wrong area?
 
874
 */
 
875
void
 
876
build_sig_subpkt_from_sig( PKT_signature *sig )
 
877
{
 
878
    u32  u;
 
879
    byte buf[8];
 
880
 
 
881
    u = sig->keyid[0];
 
882
    buf[0] = (u >> 24) & 0xff;
 
883
    buf[1] = (u >> 16) & 0xff;
 
884
    buf[2] = (u >>  8) & 0xff;
 
885
    buf[3] = u & 0xff;
 
886
    u = sig->keyid[1];
 
887
    buf[4] = (u >> 24) & 0xff;
 
888
    buf[5] = (u >> 16) & 0xff;
 
889
    buf[6] = (u >>  8) & 0xff;
 
890
    buf[7] = u & 0xff;
 
891
    build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 );
 
892
 
 
893
    u = sig->timestamp;
 
894
    buf[0] = (u >> 24) & 0xff;
 
895
    buf[1] = (u >> 16) & 0xff;
 
896
    buf[2] = (u >>  8) & 0xff;
 
897
    buf[3] = u & 0xff;
 
898
    build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 );
 
899
 
 
900
    if(sig->expiredate)
 
901
      {
 
902
        if(sig->expiredate>sig->timestamp)
 
903
          u=sig->expiredate-sig->timestamp;
 
904
        else
 
905
          u=0;
 
906
 
 
907
        buf[0] = (u >> 24) & 0xff;
 
908
        buf[1] = (u >> 16) & 0xff;
 
909
        buf[2] = (u >>  8) & 0xff;
 
910
        buf[3] = u & 0xff;
 
911
 
 
912
        /* Mark this CRITICAL, so if any implementation doesn't
 
913
           understand sigs that can expire, it'll just disregard this
 
914
           sig altogether. */
 
915
 
 
916
        build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
 
917
                          buf, 4 );
 
918
      }
 
919
}
 
920
 
 
921
void
 
922
build_attribute_subpkt(PKT_user_id *uid,byte type,
 
923
                       const void *buf,u32 buflen,
 
924
                       const void *header,u32 headerlen)
 
925
{
 
926
  byte *attrib;
 
927
  int idx;
 
928
 
 
929
  if(1+headerlen+buflen>8383)
 
930
    idx=5;
 
931
  else if(1+headerlen+buflen>191)
 
932
    idx=2;
 
933
  else
 
934
    idx=1;
 
935
 
 
936
  /* realloc uid->attrib_data to the right size */
 
937
 
 
938
  uid->attrib_data=xrealloc(uid->attrib_data,
 
939
                             uid->attrib_len+idx+1+headerlen+buflen);
 
940
 
 
941
  attrib=&uid->attrib_data[uid->attrib_len];
 
942
 
 
943
  if(idx==5)
 
944
    {
 
945
      attrib[0]=255;
 
946
      attrib[1]=(1+headerlen+buflen) >> 24;
 
947
      attrib[2]=(1+headerlen+buflen) >> 16;
 
948
      attrib[3]=(1+headerlen+buflen) >> 8;
 
949
      attrib[4]=1+headerlen+buflen;
 
950
    }
 
951
  else if(idx==2)
 
952
    {
 
953
      attrib[0]=(1+headerlen+buflen-192) / 256 + 192;
 
954
      attrib[1]=(1+headerlen+buflen-192) % 256;
 
955
    }
 
956
  else
 
957
    attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */
 
958
 
 
959
  attrib[idx++]=type;
 
960
 
 
961
  /* Tack on our data at the end */
 
962
 
 
963
  if(headerlen>0)
 
964
    memcpy(&attrib[idx],header,headerlen);
 
965
  memcpy(&attrib[idx+headerlen],buf,buflen);
 
966
  uid->attrib_len+=idx+headerlen+buflen;
 
967
}
 
968
 
 
969
static int
 
970
do_signature( iobuf_t out, int ctb, PKT_signature *sig )
 
971
{
 
972
    int rc = 0;
 
973
    int n, i;
 
974
    iobuf_t a = iobuf_temp();
 
975
 
 
976
    if( !sig->version )
 
977
        iobuf_put( a, 3 );
 
978
    else
 
979
        iobuf_put( a, sig->version );
 
980
    if( sig->version < 4 )
 
981
        iobuf_put(a, 5 ); /* constant */
 
982
    iobuf_put(a, sig->sig_class );
 
983
    if( sig->version < 4 ) {
 
984
        write_32(a, sig->timestamp );
 
985
        write_32(a, sig->keyid[0] );
 
986
        write_32(a, sig->keyid[1] );
 
987
    }
 
988
    iobuf_put(a, sig->pubkey_algo );
 
989
    iobuf_put(a, sig->digest_algo );
 
990
    if( sig->version >= 4 ) {
 
991
        size_t nn;
 
992
        /* timestamp and keyid must have been packed into the
 
993
         * subpackets prior to the call of this function, because
 
994
         * these subpackets are hashed */
 
995
        nn = sig->hashed? sig->hashed->len : 0;
 
996
        write_16(a, nn);
 
997
        if( nn )
 
998
            iobuf_write( a, sig->hashed->data, nn );
 
999
        nn = sig->unhashed? sig->unhashed->len : 0;
 
1000
        write_16(a, nn);
 
1001
        if( nn )
 
1002
            iobuf_write( a, sig->unhashed->data, nn );
 
1003
    }
 
1004
    iobuf_put(a, sig->digest_start[0] );
 
1005
    iobuf_put(a, sig->digest_start[1] );
 
1006
    n = pubkey_get_nsig( sig->pubkey_algo );
 
1007
    if( !n )
 
1008
        write_fake_data( a, sig->data[0] );
 
1009
    for(i=0; i < n; i++ )
 
1010
        mpi_write(a, sig->data[i] );
 
1011
 
 
1012
    if( is_RSA(sig->pubkey_algo) && sig->version < 4 )
 
1013
        write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
 
1014
    else
 
1015
        write_header(out, ctb, iobuf_get_temp_length(a) );
 
1016
    rc = iobuf_write_temp (out, a);
 
1017
 
 
1018
    iobuf_close(a);
 
1019
    return rc;
 
1020
}
 
1021
 
 
1022
 
 
1023
static int
 
1024
do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops )
 
1025
{
 
1026
    int rc = 0;
 
1027
    iobuf_t a = iobuf_temp();
 
1028
 
 
1029
    write_version( a, ctb );
 
1030
    iobuf_put(a, ops->sig_class );
 
1031
    iobuf_put(a, ops->digest_algo );
 
1032
    iobuf_put(a, ops->pubkey_algo );
 
1033
    write_32(a, ops->keyid[0] );
 
1034
    write_32(a, ops->keyid[1] );
 
1035
    iobuf_put(a, ops->last );
 
1036
 
 
1037
    write_header(out, ctb, iobuf_get_temp_length(a) );
 
1038
    rc = iobuf_write_temp (out, a);
 
1039
 
 
1040
    iobuf_close(a);
 
1041
    return rc;
 
1042
}
 
1043
 
 
1044
 
 
1045
static int
 
1046
write_16(iobuf_t out, u16 a)
 
1047
{
 
1048
    iobuf_put(out, a>>8);
 
1049
    return iobuf_put(out,a);
 
1050
}
 
1051
 
 
1052
static int
 
1053
write_32(iobuf_t out, u32 a)
 
1054
{
 
1055
    iobuf_put(out, a>> 24);
 
1056
    iobuf_put(out, a>> 16);
 
1057
    iobuf_put(out, a>> 8);
 
1058
    return iobuf_put (out, a);
 
1059
}
 
1060
 
 
1061
 
 
1062
/****************
 
1063
 * calculate the length of a header
 
1064
 */
 
1065
static int
 
1066
calc_header_length( u32 len, int new_ctb )
 
1067
{
 
1068
    if( !len )
 
1069
        return 1; /* only the ctb */
 
1070
 
 
1071
    if( new_ctb ) {
 
1072
        if( len < 192 )
 
1073
            return 2;
 
1074
        if( len < 8384 )
 
1075
            return 3;
 
1076
        else
 
1077
            return 6;
 
1078
    }
 
1079
    if( len < 256 )
 
1080
        return 2;
 
1081
    if( len < 65536 )
 
1082
        return 3;
 
1083
 
 
1084
    return 5;
 
1085
}
 
1086
 
 
1087
/****************
 
1088
 * Write the CTB and the packet length
 
1089
 */
 
1090
static int
 
1091
write_header( iobuf_t out, int ctb, u32 len )
 
1092
{
 
1093
    return write_header2( out, ctb, len, 0, 1 );
 
1094
}
 
1095
 
 
1096
 
 
1097
static int
 
1098
write_sign_packet_header( iobuf_t out, int ctb, u32 len )
 
1099
{
 
1100
    /* work around a bug in the pgp read function for signature packets,
 
1101
     * which are not correctly coded and silently assume at some
 
1102
     * point 2 byte length headers.*/
 
1103
    iobuf_put(out, 0x89 );
 
1104
    iobuf_put(out, len >> 8 );
 
1105
    return iobuf_put(out, len ) == -1 ? -1:0;
 
1106
}
 
1107
 
 
1108
/****************
 
1109
 * if HDRLEN is > 0, try to build a header of this length.
 
1110
 * we need this, so that we can hash packets without reading them again.
 
1111
 */
 
1112
static int
 
1113
write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode )
 
1114
{
 
1115
    if( ctb & 0x40 )
 
1116
        return write_new_header( out, ctb, len, hdrlen );
 
1117
 
 
1118
    if( hdrlen ) {
 
1119
        if( !len )
 
1120
            ctb |= 3;
 
1121
        else if( hdrlen == 2 && len < 256 )
 
1122
            ;
 
1123
        else if( hdrlen == 3 && len < 65536 )
 
1124
            ctb |= 1;
 
1125
        else
 
1126
            ctb |= 2;
 
1127
    }
 
1128
    else {
 
1129
        if( !len )
 
1130
            ctb |= 3;
 
1131
        else if( len < 256 )
 
1132
            ;
 
1133
        else if( len < 65536 )
 
1134
            ctb |= 1;
 
1135
        else
 
1136
            ctb |= 2;
 
1137
    }
 
1138
    if( iobuf_put(out, ctb ) )
 
1139
        return -1;
 
1140
    if( !len ) {
 
1141
        if( blkmode )
 
1142
            iobuf_set_block_mode(out, 8196 );
 
1143
    }
 
1144
    else {
 
1145
        if( ctb & 2 ) {
 
1146
            iobuf_put(out, len >> 24 );
 
1147
            iobuf_put(out, len >> 16 );
 
1148
        }
 
1149
        if( ctb & 3 )
 
1150
            iobuf_put(out, len >> 8 );
 
1151
        if( iobuf_put(out, len ) )
 
1152
            return -1;
 
1153
    }
 
1154
    return 0;
 
1155
}
 
1156
 
 
1157
 
 
1158
static int
 
1159
write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen )
 
1160
{
 
1161
    if( hdrlen )
 
1162
        log_bug("can't cope with hdrlen yet\n");
 
1163
 
 
1164
    if( iobuf_put(out, ctb ) )
 
1165
        return -1;
 
1166
    if( !len ) {
 
1167
        iobuf_set_partial_block_mode(out, 512 );
 
1168
    }
 
1169
    else {
 
1170
        if( len < 192 ) {
 
1171
            if( iobuf_put(out, len ) )
 
1172
                return -1;
 
1173
        }
 
1174
        else if( len < 8384 ) {
 
1175
            len -= 192;
 
1176
            if( iobuf_put( out, (len / 256) + 192) )
 
1177
                return -1;
 
1178
            if( iobuf_put( out, (len % 256) )  )
 
1179
                return -1;
 
1180
        }
 
1181
        else {
 
1182
            if( iobuf_put( out, 0xff ) )
 
1183
                return -1;
 
1184
            if( iobuf_put( out, (len >> 24)&0xff ) )
 
1185
                return -1;
 
1186
            if( iobuf_put( out, (len >> 16)&0xff ) )
 
1187
                return -1;
 
1188
            if( iobuf_put( out, (len >> 8)&0xff )  )
 
1189
                return -1;
 
1190
            if( iobuf_put( out, len & 0xff ) )
 
1191
                return -1;
 
1192
        }
 
1193
    }
 
1194
    return 0;
 
1195
}
 
1196
 
 
1197
static int
 
1198
write_version( iobuf_t out, int ctb )
 
1199
{
 
1200
    if( iobuf_put( out, 3 ) )
 
1201
        return -1;
 
1202
    return 0;
 
1203
}