~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to g10/build-packet.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* build-packet.c - assemble packets and write them
2
 
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
 
 *               2003 Free Software Foundation, Inc.
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
 
3
 *               2006 Free Software Foundation, Inc.
4
4
 *
5
5
 * This file is part of GnuPG.
6
6
 *
7
7
 * GnuPG is free software; you can redistribute it and/or modify
8
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
 
9
 * the Free Software Foundation; either version 3 of the License, or
10
10
 * (at your option) any later version.
11
11
 *
12
12
 * GnuPG is distributed in the hope that it will be useful,
15
15
 * GNU General Public License for more details.
16
16
 *
17
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
 
18
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20
19
 */
21
20
 
22
21
#include <config.h>
24
23
#include <stdlib.h>
25
24
#include <string.h>
26
25
#include <assert.h>
 
26
#include <ctype.h>
27
27
 
28
28
#include "gpg.h"
29
29
#include "packet.h"
30
 
#include "errors.h"
 
30
#include "status.h"
31
31
#include "iobuf.h"
32
 
#include "mpi.h"
33
32
#include "util.h"
34
33
#include "cipher.h"
35
 
#include "memory.h"
 
34
#include "i18n.h"
36
35
#include "options.h"
37
36
 
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 );
 
37
static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
 
38
static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk );
 
39
static int do_secret_key( IOBUF out, int ctb, PKT_secret_key *pk );
 
40
static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
 
41
static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
45
42
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 );
 
43
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
 
44
static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
 
45
static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
 
46
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
 
47
static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
 
48
static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
52
49
 
53
50
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 );
 
51
static int write_16(IOBUF inp, u16 a);
 
52
static int write_32(IOBUF inp, u32 a);
 
53
static int write_header( IOBUF out, int ctb, u32 len );
 
54
static int write_sign_packet_header( IOBUF out, int ctb, u32 len );
 
55
static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen );
 
56
static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen );
 
57
static int write_version( IOBUF out, int ctb );
61
58
 
62
59
/****************
63
60
 * Build a packet and write it to INP
66
63
 * Note: Caller must free the packet
67
64
 */
68
65
int
69
 
build_packet( iobuf_t out, PACKET *pkt )
 
66
build_packet( IOBUF out, PACKET *pkt )
70
67
{
71
68
    int new_ctb=0, rc=0, ctb;
72
69
    int pkttype;
75
72
        log_debug("build_packet() type=%d\n", pkt->pkttype );
76
73
    assert( pkt->pkt.generic );
77
74
 
78
 
    switch( (pkttype = pkt->pkttype) ) {
79
 
      case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
 
75
    switch( (pkttype = pkt->pkttype) )
 
76
      {
80
77
      case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
81
78
      case PKT_ENCRYPTED:
82
79
      case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
83
80
      case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
84
81
      case PKT_USER_ID:
85
 
            if( pkt->pkt.user_id->attrib_data )
86
 
                pkttype = PKT_ATTRIBUTE;
87
 
            break;
 
82
        if( pkt->pkt.user_id->attrib_data )
 
83
          pkttype = PKT_ATTRIBUTE;
 
84
        break;
88
85
      default: break;
89
 
    }
 
86
      }
90
87
 
91
88
    if( new_ctb || pkttype > 15 ) /* new format */
92
89
        ctb = 0xc0 | (pkttype & 0x3f);
93
90
    else
94
91
        ctb = 0x80 | ((pkttype & 15)<<2);
95
 
    switch( pkttype ) {
 
92
    switch( pkttype )
 
93
      {
96
94
      case PKT_ATTRIBUTE:
97
95
      case PKT_USER_ID:
98
96
        rc = do_user_id( out, ctb, pkt->pkt.user_id );
99
97
        break;
 
98
      case PKT_OLD_COMMENT:
100
99
      case PKT_COMMENT:
101
 
        rc = do_comment( out, ctb, pkt->pkt.comment );
 
100
        /*
 
101
          Ignore these.  Theoretically, this will never be called as
 
102
          we have no way to output comment packets any longer, but
 
103
          just in case there is some code path that would end up
 
104
          outputting a comment that was written before comments were
 
105
          dropped (in the public key?) this is a no-op.
 
106
        */
102
107
        break;
103
108
      case PKT_PUBLIC_SUBKEY:
104
109
      case PKT_PUBLIC_KEY:
138
143
      default:
139
144
        log_bug("invalid packet type in build_packet()\n");
140
145
        break;
 
146
      }
 
147
 
 
148
    return rc;
 
149
}
 
150
 
 
151
 
 
152
/*
 
153
 * Write the mpi A to OUT.
 
154
 */
 
155
static int
 
156
mpi_write (iobuf_t out, gcry_mpi_t a)
 
157
{
 
158
  char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
 
159
  size_t nbytes;
 
160
  int rc;
 
161
 
 
162
  nbytes = DIM(buffer);
 
163
  rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
 
164
  if( !rc )
 
165
    rc = iobuf_write( out, buffer, nbytes );
 
166
  else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
 
167
    {
 
168
      log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
 
169
      /* The buffer was too small. We better tell the user about the MPI. */
 
170
      rc = gpg_error (GPG_ERR_TOO_LARGE);
141
171
    }
142
172
 
143
 
    return rc;
 
173
  return rc;
144
174
}
145
175
 
 
176
 
 
177
 
146
178
/****************
147
179
 * calculate the length of a packet described by PKT
148
180
 */
180
212
}
181
213
 
182
214
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);
 
215
write_fake_data (IOBUF out, gcry_mpi_t a)
 
216
{
 
217
  if (a) 
 
218
    {
 
219
      unsigned int n;
 
220
      void *p;
 
221
      
 
222
      p = gcry_mpi_get_opaque ( a, &n );
 
223
      iobuf_write (out, p, (n+7)/8 );
 
224
    }
 
225
}
 
226
 
 
227
static int
 
228
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
 
229
{
 
230
    int rc;
 
231
 
 
232
    if( uid->attrib_data )
 
233
      {
 
234
        write_header(out, ctb, uid->attrib_len);
 
235
        rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
 
236
      }
 
237
    else
 
238
      {
 
239
        write_header2( out, ctb, uid->len, 2 );
 
240
        rc = iobuf_write( out, uid->name, uid->len );
 
241
      }
 
242
    return 0;
 
243
}
 
244
 
 
245
static int
 
246
do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
 
247
{
 
248
  int rc = 0;
 
249
  int n, i;
 
250
  IOBUF a = iobuf_temp();
 
251
  
 
252
  if ( !pk->version )
 
253
    iobuf_put( a, 3 );
 
254
  else
 
255
    iobuf_put( a, pk->version );
 
256
  write_32(a, pk->timestamp );
 
257
  if ( pk->version < 4 ) 
 
258
    {
 
259
      u16 ndays;
 
260
      if ( pk->expiredate )
 
261
        ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
 
262
      else
 
263
        ndays = 0;
 
264
      write_16(a, ndays );
 
265
    }
 
266
  iobuf_put (a, pk->pubkey_algo );
 
267
  n = pubkey_get_npkey ( pk->pubkey_algo );
 
268
  if ( !n )
 
269
    write_fake_data( a, pk->pkey[0] );
 
270
  for (i=0; i < n && !rc ; i++ )
 
271
    rc = mpi_write(a, pk->pkey[i] );
 
272
 
 
273
  if (!rc)
 
274
    {
 
275
      write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
 
276
      rc = iobuf_write_temp ( out, a );
 
277
    }
 
278
 
 
279
  iobuf_close(a);
 
280
  return rc;
 
281
}
 
282
 
 
283
 
 
284
static int
 
285
do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
 
286
{
 
287
  int rc = 0;
 
288
  int i, nskey, npkey;
 
289
  IOBUF a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
 
290
 
 
291
  /* Write the version number - if none is specified, use 3 */
 
292
  if ( !sk->version )
 
293
    iobuf_put ( a, 3 );
 
294
  else
 
295
    iobuf_put ( a, sk->version );
 
296
  write_32 (a, sk->timestamp );
 
297
 
 
298
  /* v3 needs the expiration time. */
 
299
  if ( sk->version < 4 )
 
300
    {
 
301
      u16 ndays;
 
302
      if ( sk->expiredate )
 
303
        ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
 
304
      else
 
305
        ndays = 0;
 
306
      write_16(a, ndays);
 
307
    }
 
308
  
 
309
  iobuf_put (a, sk->pubkey_algo );
 
310
  
 
311
  /* Get number of secret and public parameters.  They are held in one
 
312
     array first the public ones, then the secret ones.  */
 
313
  nskey = pubkey_get_nskey ( sk->pubkey_algo );
 
314
  npkey = pubkey_get_npkey ( sk->pubkey_algo );
 
315
  
 
316
  /* If we don't have any public parameters - which is the case if we
 
317
     don't know the algorithm used - the parameters are stored as one
 
318
     blob in a faked (opaque) MPI. */
 
319
  if ( !npkey ) 
 
320
    {
 
321
      write_fake_data( a, sk->skey[0] );
 
322
      goto leave;
 
323
    }
 
324
  assert ( npkey < nskey );
 
325
 
 
326
  /* Writing the public parameters is easy. */
 
327
  for (i=0; i < npkey; i++ )
 
328
    if ((rc = mpi_write (a, sk->skey[i])))
 
329
      goto leave;
 
330
  
 
331
  /* Build the header for protected (encrypted) secret parameters.  */
 
332
  if ( sk->is_protected ) 
 
333
    {
 
334
      if ( is_RSA(sk->pubkey_algo) 
 
335
           && sk->version < 4
 
336
           && !sk->protect.s2k.mode )
 
337
        {
 
338
          /* The simple rfc1991 (v3) way. */
 
339
          iobuf_put (a, sk->protect.algo );
 
340
          iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
 
341
        }
 
342
      else
 
343
        {
 
344
          /* OpenPGP protection according to rfc2440. */
 
345
          iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
 
346
          iobuf_put(a, sk->protect.algo );
 
347
          if ( sk->protect.s2k.mode >= 1000 )
 
348
            {
 
349
              /* These modes are not possible in OpenPGP, we use them
 
350
                 to implement our extensions, 101 can be seen as a
 
351
                 private/experimental extension (this is not specified
 
352
                 in rfc2440 but the same scheme is used for all other
 
353
                 algorithm identifiers) */
 
354
              iobuf_put(a, 101 ); 
 
355
              iobuf_put(a, sk->protect.s2k.hash_algo );
 
356
              iobuf_write(a, "GNU", 3 );
 
357
              iobuf_put(a, sk->protect.s2k.mode - 1000 );
 
358
            }
 
359
          else 
 
360
            {
 
361
              iobuf_put(a, sk->protect.s2k.mode );
 
362
              iobuf_put(a, sk->protect.s2k.hash_algo );
 
363
            }
 
364
          if ( sk->protect.s2k.mode == 1
 
365
               || sk->protect.s2k.mode == 3 )
 
366
            iobuf_write (a, sk->protect.s2k.salt, 8 );
 
367
 
 
368
          if ( sk->protect.s2k.mode == 3 )
 
369
            iobuf_put (a, sk->protect.s2k.count ); 
 
370
 
 
371
          /* For our special modes 1001, 1002 we do not need an IV. */
 
372
          if ( sk->protect.s2k.mode != 1001 
 
373
               && sk->protect.s2k.mode != 1002 )
 
374
            iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
 
375
        }
 
376
    }
 
377
  else
 
378
    iobuf_put (a, 0 );
 
379
 
 
380
  if ( sk->protect.s2k.mode == 1001 )
 
381
    ; /* GnuPG extension - don't write a secret key at all. */ 
 
382
  else if ( sk->protect.s2k.mode == 1002 )
 
383
    { 
 
384
      /* GnuPG extension - divert to OpenPGP smartcard. */ 
 
385
      iobuf_put(a, sk->protect.ivlen ); /* Length of the serial number
 
386
                                           or 0 for no serial
 
387
                                           number. */
 
388
      /* The serial number gets stored in the IV field. */
 
389
      iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
 
390
    }
 
391
  else if ( sk->is_protected && sk->version >= 4 )
 
392
    {
 
393
      /* The secret key is protected - write it out as it is.  */
 
394
      byte *p;
 
395
      unsigned int ndatabits;
 
396
      
 
397
      assert (gcry_mpi_get_flag (sk->skey[npkey], GCRYMPI_FLAG_OPAQUE));
 
398
      p = gcry_mpi_get_opaque (sk->skey[npkey], &ndatabits );
 
399
      iobuf_write (a, p, (ndatabits+7)/8 );
 
400
    }
 
401
  else if ( sk->is_protected ) 
 
402
    {
 
403
      /* The secret key is protected the old v4 way. */
 
404
      for ( ; i < nskey; i++ ) 
 
405
        {
 
406
          byte *p;
 
407
          unsigned int ndatabits;
 
408
          
 
409
          assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
 
410
          p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
 
411
          iobuf_write (a, p, (ndatabits+7)/8);
453
412
        }
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;
 
413
      write_16(a, sk->csum );
 
414
    }
 
415
  else
 
416
    {
 
417
      /* Non-protected key. */
 
418
      for ( ; i < nskey; i++ )
 
419
        if ( (rc = mpi_write (a, sk->skey[i])))
 
420
          goto leave;
 
421
      write_16 (a, sk->csum );
 
422
    }
 
423
 
 
424
 leave:
 
425
  if (!rc)
 
426
    {
 
427
      /* Build the header of the packet - which we must do after
 
428
         writing all the other stuff, so that we know the length of
 
429
         the packet */
 
430
      write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes);
 
431
      /* And finally write it out the real stream */
 
432
      rc = iobuf_write_temp( out, a );
 
433
    }
 
434
 
 
435
  iobuf_close(a); /* Close the remporary buffer */
 
436
  return rc;
472
437
}
473
438
 
474
439
static int
475
 
do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc )
 
440
do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
476
441
{
477
442
    int rc = 0;
478
 
    iobuf_t a = iobuf_temp();
 
443
    IOBUF a = iobuf_temp();
479
444
 
480
445
    assert( enc->version == 4 );
481
446
    switch( enc->s2k.mode ) {
495
460
        iobuf_write(a, enc->seskey, enc->seskeylen );
496
461
 
497
462
    write_header(out, ctb, iobuf_get_temp_length(a) );
498
 
    rc = iobuf_write_temp (out, a);
 
463
    rc = iobuf_write_temp( out, a );
499
464
 
500
465
    iobuf_close(a);
501
466
    return rc;
502
467
}
503
468
 
504
469
 
505
 
 
506
 
 
507
470
static int
508
 
do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc )
 
471
do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
509
472
{
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;
 
473
  int rc = 0;
 
474
  int n, i;
 
475
  IOBUF a = iobuf_temp();
 
476
  
 
477
  write_version( a, ctb );
 
478
  if ( enc->throw_keyid ) 
 
479
    {
 
480
      write_32(a, 0 );  /* Don't tell Eve who can decrypt the message.  */
 
481
      write_32(a, 0 );
 
482
    }
 
483
  else
 
484
    {
 
485
      write_32(a, enc->keyid[0] );
 
486
      write_32(a, enc->keyid[1] );
 
487
    }
 
488
  iobuf_put(a,enc->pubkey_algo );
 
489
  n = pubkey_get_nenc( enc->pubkey_algo );
 
490
  if ( !n )
 
491
    write_fake_data( a, enc->data[0] );
 
492
  for (i=0; i < n && !rc ; i++ )
 
493
    rc = mpi_write(a, enc->data[i] );
 
494
 
 
495
  if (!rc)
 
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;
535
502
}
536
503
 
537
504
 
538
 
 
539
 
 
540
505
static u32
541
506
calc_plaintext( PKT_plaintext *pt )
542
507
{
543
 
    return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
 
508
  /* Truncate namelen to the maximum 255 characters.  Note this means
 
509
     that a function that calls build_packet with an illegal literal
 
510
     packet will get it back legalized. */
 
511
 
 
512
  if(pt->namelen>255)
 
513
    pt->namelen=255;
 
514
 
 
515
  return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
544
516
}
545
517
 
546
518
static int
547
 
do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt )
 
519
do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
548
520
{
549
521
    int i, rc = 0;
550
522
    u32 n;
551
523
    byte buf[1000]; /* this buffer has the plaintext! */
552
524
    int nbytes;
553
525
 
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
526
    write_header(out, ctb, calc_plaintext( pt ) );
561
527
    iobuf_put(out, pt->mode );
562
528
    iobuf_put(out, pt->namelen );
563
529
    for(i=0; i < pt->namelen; i++ )
564
530
        iobuf_put(out, pt->name[i] );
565
 
    rc = write_32 (out, pt->timestamp);
 
531
    rc = write_32(out, pt->timestamp );
 
532
    if (rc) 
 
533
      return rc;
566
534
 
567
535
    n = 0;
568
536
    while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
569
 
        rc = iobuf_write(out, buf, nbytes);
570
 
        if (rc)
571
 
          break;
572
 
        n += nbytes;
 
537
      rc = iobuf_write (out, buf, nbytes);
 
538
      if (rc)
 
539
        break;
 
540
      n += nbytes;
573
541
    }
574
542
    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 );
 
543
    if( (ctb&0x40) && !pt->len )
 
544
      iobuf_set_partial_block_mode(out, 0 ); /* turn off partial */
 
545
    if( pt->len && n != pt->len )
 
546
      log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
 
547
                (ulong)n, (ulong)pt->len );
580
548
 
581
549
    return rc;
582
550
}
584
552
 
585
553
 
586
554
static int
587
 
do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed )
 
555
do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
588
556
{
589
557
    int rc = 0;
590
558
    u32 n;
598
566
}
599
567
 
600
568
static int
601
 
do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed )
 
569
do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
602
570
{
603
571
    int rc = 0;
604
572
    u32 n;
617
585
 
618
586
 
619
587
static int
620
 
do_compressed( iobuf_t out, int ctb, PKT_compressed *cd )
 
588
do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
621
589
{
622
590
    int rc = 0;
623
591
 
626
594
       set, CTB is already formatted as new style and write_header2
627
595
       does create a partial length encoding using new the new
628
596
       style. */
629
 
    write_header2(out, ctb, 0, 0, 0 );
 
597
    write_header2(out, ctb, 0, 0);
630
598
    iobuf_put(out, cd->algorithm );
631
599
 
632
600
    /* This is all. The caller has to write the real data */
734
702
      case SIGSUBPKT_NOTATION:
735
703
      case SIGSUBPKT_POLICY:
736
704
      case SIGSUBPKT_REV_KEY:
 
705
      case SIGSUBPKT_SIGNATURE:
737
706
        /* we do allow multiple subpackets */
738
707
        break;
739
708
 
803
772
    else
804
773
        nlen = 1; /* just a 1 byte length header */
805
774
 
806
 
    switch( type ) {
 
775
    switch( type )
 
776
      {
807
777
        /* The issuer being unhashed is a historical oddity.  It
808
778
           should work equally as well hashed.  Of course, if even an
809
779
           unhashed issuer is tampered with, it makes it awfully hard
810
780
           to verify the sig... */
811
781
      case SIGSUBPKT_ISSUER:
 
782
      case SIGSUBPKT_SIGNATURE:
812
783
        hashed = 0;
813
784
        break;
814
785
      default: 
815
786
        hashed = 1;
816
787
        break;
817
 
    }
 
788
      }
818
789
 
819
790
    if( critical )
820
791
        type |= SIGSUBPKT_FLAG_CRITICAL;
902
873
        if(sig->expiredate>sig->timestamp)
903
874
          u=sig->expiredate-sig->timestamp;
904
875
        else
905
 
          u=0;
 
876
          u=1; /* A 1-second expiration time is the shortest one
 
877
                  OpenPGP has */
906
878
 
907
879
        buf[0] = (u >> 24) & 0xff;
908
880
        buf[1] = (u >> 16) & 0xff;
966
938
  uid->attrib_len+=idx+headerlen+buflen;
967
939
}
968
940
 
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();
 
941
struct notation *
 
942
string_to_notation(const char *string,int is_utf8)
 
943
{
 
944
  const char *s;
 
945
  int saw_at=0;
 
946
  struct notation *notation;
 
947
 
 
948
  notation=xmalloc_clear(sizeof(*notation));
 
949
 
 
950
  if(*string=='-')
 
951
    {
 
952
      notation->flags.ignore=1;
 
953
      string++;
 
954
    }
 
955
 
 
956
  if(*string=='!')
 
957
    {
 
958
      notation->flags.critical=1;
 
959
      string++;
 
960
    }
 
961
 
 
962
  /* If and when the IETF assigns some official name tags, we'll have
 
963
     to add them here. */
 
964
 
 
965
  for( s=string ; *s != '='; s++ )
 
966
    {
 
967
      if( *s=='@')
 
968
        saw_at++;
 
969
 
 
970
      /* -notationname is legal without an = sign */
 
971
      if(!*s && notation->flags.ignore)
 
972
        break;
 
973
 
 
974
      if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
 
975
        {
 
976
          log_error(_("a notation name must have only printable characters"
 
977
                      " or spaces, and end with an '='\n") );
 
978
          goto fail;
 
979
        }
 
980
    }
 
981
 
 
982
  notation->name=xmalloc((s-string)+1);
 
983
  strncpy(notation->name,string,s-string);
 
984
  notation->name[s-string]='\0';
 
985
 
 
986
  if(!saw_at && !opt.expert)
 
987
    {
 
988
      log_error(_("a user notation name must contain the '@' character\n"));
 
989
      goto fail;
 
990
    }
 
991
 
 
992
  if (saw_at > 1)
 
993
    {
 
994
      log_error(_("a notation name must not contain more than"
 
995
                  " one '@' character\n"));
 
996
      goto fail;
 
997
    }
 
998
 
 
999
  if(*s)
 
1000
    {
 
1001
      const char *i=s+1;
 
1002
      int highbit=0;
 
1003
 
 
1004
      /* we only support printable text - therefore we enforce the use
 
1005
         of only printable characters (an empty value is valid) */
 
1006
      for(s++; *s ; s++ )
 
1007
        {
 
1008
          if ( !isascii (*s) )
 
1009
            highbit=1;
 
1010
          else if (iscntrl(*s))
 
1011
            {
 
1012
              log_error(_("a notation value must not use any"
 
1013
                          " control characters\n"));
 
1014
              goto fail;
 
1015
            }
 
1016
        }
 
1017
 
 
1018
      if(!highbit || is_utf8)
 
1019
        notation->value=xstrdup(i);
 
1020
      else
 
1021
        notation->value=native_to_utf8(i);
 
1022
    }
 
1023
 
 
1024
  return notation;
 
1025
 
 
1026
 fail:
 
1027
  free_notation(notation);
 
1028
  return NULL;
 
1029
}
 
1030
 
 
1031
struct notation *
 
1032
sig_to_notation(PKT_signature *sig)
 
1033
{
 
1034
  const byte *p;
 
1035
  size_t len;
 
1036
  int seq=0,crit;
 
1037
  struct notation *list=NULL;
 
1038
 
 
1039
  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
 
1040
    {
 
1041
      int n1,n2;
 
1042
      struct notation *n=NULL;
 
1043
 
 
1044
      if(len<8)
 
1045
        {
 
1046
          log_info(_("WARNING: invalid notation data found\n"));
 
1047
          continue;
 
1048
        }
 
1049
 
 
1050
      n1=(p[4]<<8)|p[5];
 
1051
      n2=(p[6]<<8)|p[7];
 
1052
 
 
1053
      if(8+n1+n2!=len)
 
1054
        {
 
1055
          log_info(_("WARNING: invalid notation data found\n"));
 
1056
          continue;
 
1057
        }
 
1058
 
 
1059
      n=xmalloc_clear(sizeof(*n));
 
1060
      n->name=xmalloc(n1+1);
 
1061
 
 
1062
      memcpy(n->name,&p[8],n1);
 
1063
      n->name[n1]='\0';
 
1064
 
 
1065
      if(p[0]&0x80)
 
1066
        {
 
1067
          n->value=xmalloc(n2+1);
 
1068
          memcpy(n->value,&p[8+n1],n2);
 
1069
          n->value[n2]='\0';
 
1070
        }
 
1071
      else
 
1072
        {
 
1073
          n->bdat=xmalloc(n2);
 
1074
          n->blen=n2;
 
1075
          memcpy(n->bdat,&p[8+n1],n2);
 
1076
 
 
1077
          n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
 
1078
          strcpy(n->value,"[ ");
 
1079
          strcat(n->value,_("not human readable"));
 
1080
          strcat(n->value," ]");
 
1081
        }
 
1082
 
 
1083
      n->flags.critical=crit;
 
1084
 
 
1085
      n->next=list;
 
1086
      list=n;
 
1087
    }
 
1088
 
 
1089
  return list;
 
1090
}
 
1091
 
 
1092
void
 
1093
free_notation(struct notation *notation)
 
1094
{
 
1095
  while(notation)
 
1096
    {
 
1097
      struct notation *n=notation;
 
1098
 
 
1099
      xfree(n->name);
 
1100
      xfree(n->value);
 
1101
      xfree(n->altvalue);
 
1102
      xfree(n->bdat);
 
1103
      notation=n->next;
 
1104
      xfree(n);
 
1105
    }
 
1106
}
 
1107
 
 
1108
static int
 
1109
do_signature( IOBUF out, int ctb, PKT_signature *sig )
 
1110
{
 
1111
  int rc = 0;
 
1112
  int n, i;
 
1113
  IOBUF a = iobuf_temp();
 
1114
 
 
1115
  if ( !sig->version )
 
1116
    iobuf_put( a, 3 );
 
1117
  else
 
1118
    iobuf_put( a, sig->version );
 
1119
  if ( sig->version < 4 )
 
1120
    iobuf_put (a, 5 ); /* Constant */
 
1121
  iobuf_put (a, sig->sig_class );
 
1122
  if ( sig->version < 4 ) 
 
1123
    {
 
1124
      write_32(a, sig->timestamp );
 
1125
      write_32(a, sig->keyid[0] );
 
1126
      write_32(a, sig->keyid[1] );
 
1127
    }
 
1128
  iobuf_put(a, sig->pubkey_algo );
 
1129
  iobuf_put(a, sig->digest_algo );
 
1130
  if ( sig->version >= 4 ) 
 
1131
    {
 
1132
      size_t nn;
 
1133
      /* Timestamp and keyid must have been packed into the subpackets
 
1134
         prior to the call of this function, because these subpackets
 
1135
         are hashed. */
 
1136
      nn = sig->hashed? sig->hashed->len : 0;
 
1137
      write_16(a, nn);
 
1138
      if (nn)
 
1139
        iobuf_write( a, sig->hashed->data, nn );
 
1140
      nn = sig->unhashed? sig->unhashed->len : 0;
 
1141
      write_16(a, nn);
 
1142
      if (nn)
 
1143
        iobuf_write( a, sig->unhashed->data, nn );
 
1144
    }
 
1145
  iobuf_put(a, sig->digest_start[0] );
 
1146
  iobuf_put(a, sig->digest_start[1] );
 
1147
  n = pubkey_get_nsig( sig->pubkey_algo );
 
1148
  if ( !n )
 
1149
    write_fake_data( a, sig->data[0] );
 
1150
  for (i=0; i < n && !rc ; i++ )
 
1151
    rc = mpi_write(a, sig->data[i] );
 
1152
 
 
1153
  if (!rc)
 
1154
    {
 
1155
      if ( is_RSA(sig->pubkey_algo) && sig->version < 4 )
 
1156
        write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
 
1157
      else
 
1158
        write_header(out, ctb, iobuf_get_temp_length(a) );
 
1159
      rc = iobuf_write_temp( out, a );
 
1160
    }
 
1161
 
 
1162
  iobuf_close(a);
 
1163
  return rc;
 
1164
}
 
1165
 
 
1166
 
 
1167
static int
 
1168
do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
 
1169
{
 
1170
    int rc = 0;
 
1171
    IOBUF a = iobuf_temp();
1028
1172
 
1029
1173
    write_version( a, ctb );
1030
1174
    iobuf_put(a, ops->sig_class );
1035
1179
    iobuf_put(a, ops->last );
1036
1180
 
1037
1181
    write_header(out, ctb, iobuf_get_temp_length(a) );
1038
 
    rc = iobuf_write_temp (out, a);
 
1182
    rc = iobuf_write_temp( out, a );
1039
1183
 
1040
1184
    iobuf_close(a);
1041
1185
    return rc;
1043
1187
 
1044
1188
 
1045
1189
static int
1046
 
write_16(iobuf_t out, u16 a)
 
1190
write_16(IOBUF out, u16 a)
1047
1191
{
1048
1192
    iobuf_put(out, a>>8);
1049
 
    return iobuf_put(out,a);
 
1193
    if( iobuf_put(out,a) )
 
1194
        return -1;
 
1195
    return 0;
1050
1196
}
1051
1197
 
1052
1198
static int
1053
 
write_32(iobuf_t out, u32 a)
 
1199
write_32(IOBUF out, u32 a)
1054
1200
{
1055
1201
    iobuf_put(out, a>> 24);
1056
1202
    iobuf_put(out, a>> 16);
1057
1203
    iobuf_put(out, a>> 8);
1058
 
    return iobuf_put (out, a);
 
1204
    return iobuf_put(out, a);
1059
1205
}
1060
1206
 
1061
1207
 
1088
1234
 * Write the CTB and the packet length
1089
1235
 */
1090
1236
static int
1091
 
write_header( iobuf_t out, int ctb, u32 len )
 
1237
write_header( IOBUF out, int ctb, u32 len )
1092
1238
{
1093
 
    return write_header2( out, ctb, len, 0, 1 );
 
1239
    return write_header2( out, ctb, len, 0 );
1094
1240
}
1095
1241
 
1096
1242
 
1097
1243
static int
1098
 
write_sign_packet_header( iobuf_t out, int ctb, u32 len )
 
1244
write_sign_packet_header( IOBUF out, int ctb, u32 len )
1099
1245
{
1100
1246
    /* work around a bug in the pgp read function for signature packets,
1101
1247
     * which are not correctly coded and silently assume at some
1106
1252
}
1107
1253
 
1108
1254
/****************
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.
 
1255
 * If HDRLEN is > 0, try to build a header of this length.  We need
 
1256
 * this so that we can hash packets without reading them again.  If
 
1257
 * len is 0, write a partial or indeterminate length header, unless
 
1258
 * hdrlen is specified in which case write an actual zero length
 
1259
 * (using the specified hdrlen).
1111
1260
 */
1112
1261
static int
1113
 
write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode )
 
1262
write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
1114
1263
{
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 ) )
 
1264
  if( ctb & 0x40 )
 
1265
    return write_new_header( out, ctb, len, hdrlen );
 
1266
 
 
1267
  if( hdrlen )
 
1268
    {
 
1269
      if( hdrlen == 2 && len < 256 )
 
1270
        ;
 
1271
      else if( hdrlen == 3 && len < 65536 )
 
1272
        ctb |= 1;
 
1273
      else
 
1274
        ctb |= 2;
 
1275
    }
 
1276
  else
 
1277
    {
 
1278
      if( !len )
 
1279
        ctb |= 3;
 
1280
      else if( len < 256 )
 
1281
        ;
 
1282
      else if( len < 65536 )
 
1283
        ctb |= 1;
 
1284
      else
 
1285
        ctb |= 2;
 
1286
    }
 
1287
 
 
1288
  if( iobuf_put(out, ctb ) )
 
1289
    return -1;
 
1290
 
 
1291
  if( len || hdrlen )
 
1292
    {
 
1293
      if( ctb & 2 )
 
1294
        {
 
1295
          if(iobuf_put(out, len >> 24 ))
 
1296
            return -1;
 
1297
          if(iobuf_put(out, len >> 16 ))
 
1298
            return -1;
 
1299
        }
 
1300
 
 
1301
      if( ctb & 3 )
 
1302
        if(iobuf_put(out, len >> 8 ))
 
1303
          return -1;
 
1304
 
 
1305
      if( iobuf_put(out, len ) )
1139
1306
        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;
 
1307
    }
 
1308
 
 
1309
  return 0;
1155
1310
}
1156
1311
 
1157
1312
 
1158
1313
static int
1159
 
write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen )
 
1314
write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
1160
1315
{
1161
1316
    if( hdrlen )
1162
1317
        log_bug("can't cope with hdrlen yet\n");
1195
1350
}
1196
1351
 
1197
1352
static int
1198
 
write_version( iobuf_t out, int ctb )
 
1353
write_version( IOBUF out, int ctb )
1199
1354
{
1200
1355
    if( iobuf_put( out, 3 ) )
1201
1356
        return -1;