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

« back to all changes in this revision

Viewing changes to g10/pubkey-enc.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
/* pubkey-enc.c -  public key encoded packet handling
2
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
 
 *               2003 Free Software Foundation, Inc.
 
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>
27
26
 
28
27
#include "gpg.h"
29
28
#include "util.h"
30
 
#include "memory.h"
31
29
#include "packet.h"
32
 
#include "mpi.h"
33
30
#include "keydb.h"
34
31
#include "trustdb.h"
35
32
#include "cipher.h"
40
37
#include "pkglue.h"
41
38
#include "call-agent.h"
42
39
 
 
40
 
43
41
static int get_it( PKT_pubkey_enc *k,
44
42
                   DEK *dek, PKT_secret_key *sk, u32 *keyid );
45
43
 
77
75
    PKT_secret_key *sk = NULL;
78
76
    int rc;
79
77
 
80
 
    rc = openpgp_pk_test_algo (k->pubkey_algo, PUBKEY_USAGE_ENC);
 
78
    rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
81
79
    if( rc )
82
80
        goto leave;
83
81
 
84
82
    if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
85
 
        sk = xcalloc (1, sizeof *sk );
 
83
        sk = xmalloc_clear( sizeof *sk );
86
84
        sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
87
85
        if( !(rc = get_seckey( sk, k->keyid )) )
88
86
            rc = get_it( k, dek, sk, k->keyid );
95
93
        for(;;) {
96
94
            if( sk )
97
95
                free_secret_key( sk );
98
 
            sk = xcalloc (1, sizeof *sk );
 
96
            sk = xmalloc_clear( sizeof *sk );
99
97
            rc=enum_secret_keys( &enum_context, sk, 1, 0);
100
98
            if( rc ) {
101
 
                rc = GPG_ERR_NO_SECKEY;
 
99
                rc = G10ERR_NO_SECKEY;
102
100
                break;
103
101
            }
104
102
            if( sk->pubkey_algo != k->pubkey_algo )
105
103
                continue;
106
104
            keyid_from_sk( sk, keyid );
107
 
            log_info(_("anonymous recipient; trying secret key %08lX ...\n"),
108
 
                     (ulong)keyid[1] );
 
105
            log_info(_("anonymous recipient; trying secret key %s ...\n"),
 
106
                     keystr(keyid));
109
107
 
110
108
            if(!opt.try_all_secrets && !is_status_enabled())
111
109
              {
112
110
                p=get_last_passphrase();
113
111
                set_next_passphrase(p);
114
 
                xfree (p);
 
112
                xfree(p);
115
113
              }
116
114
 
117
115
            rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
118
116
                                                                      only
119
117
                                                                      once */
120
118
            if( !rc )
 
119
              {
121
120
                rc = get_it( k, dek, sk, keyid );
122
 
            if( !rc ) {
 
121
                /* Successfully checked the secret key (either it was
 
122
                   a card, had no passphrase, or had the right
 
123
                   passphrase) but couldn't decrypt the session key,
 
124
                   so thus that key is not the anonymous recipient.
 
125
                   Move the next passphrase into last for the next
 
126
                   round.  We only do this if the secret key was
 
127
                   successfully checked as in the normal case,
 
128
                   check_secret_key handles this for us via
 
129
                   passphrase_to_dek */
 
130
                if(rc)
 
131
                  next_to_last_passphrase();
 
132
              }
 
133
 
 
134
            if( !rc )
 
135
              {
123
136
                log_info(_("okay, we are the anonymous recipient.\n") );
124
137
                break;
125
 
            }
 
138
              }
126
139
        }
127
140
        enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
128
141
    }
138
151
get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
139
152
{
140
153
  int rc;
141
 
  gcry_mpi_t plain_dek = NULL;
 
154
  gcry_mpi_t plain_dek  = NULL;
142
155
  byte *frame = NULL;
143
 
  unsigned n, nframe;
 
156
  unsigned int n;
 
157
  size_t nframe;
144
158
  u16 csum, csum2;
 
159
  
145
160
  int card = 0;
146
161
 
147
162
  if (sk->is_protected && sk->protect.s2k.mode == 1002)
148
 
    { /* FIXME: Note that we do only support RSA for now. */
149
 
      char *rbuf;
 
163
    { /* Note, that we only support RSA for now. */
 
164
#ifdef ENABLE_CARD_SUPPORT
 
165
      unsigned char *rbuf;
150
166
      size_t rbuflen;
151
167
      char *snbuf;
152
168
      unsigned char *indata = NULL;
153
 
      unsigned int indatalen;
 
169
      size_t indatalen;
154
170
 
155
171
      snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
156
172
 
157
 
      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen,
158
 
                           enc->data[0]))
159
 
        BUG();
 
173
      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
 
174
        BUG ();
160
175
 
161
176
      rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
162
177
      xfree (snbuf);
167
182
      frame = rbuf;
168
183
      nframe = rbuflen;
169
184
      card = 1;
 
185
#else
 
186
      rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
 
187
      goto leave;
 
188
#endif /*!ENABLE_CARD_SUPPORT*/
170
189
    }
171
190
  else
172
191
    {
173
 
      rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey);
 
192
      rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
174
193
      if( rc )
175
 
        goto leave;
 
194
        goto leave;
176
195
      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
177
196
        BUG();
178
197
      gcry_mpi_release (plain_dek); plain_dek = NULL;
179
198
    }
180
199
 
181
 
 
182
 
  /* Now get the DEK (data encryption key) from the frame
183
 
   *
184
 
   * Old versions encode the DEK in in this format (msb is left):
185
 
   *
186
 
   *       0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
187
 
   *
188
 
   * Later versions encode the DEK like this:
189
 
   *
190
 
   *       0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
191
 
   *
192
 
   * (mpi_get_buffer already removed the leading zero).
193
 
   *
194
 
   * RND are non-zero randow bytes.
195
 
   * A   is the cipher algorithm
196
 
   * DEK is the encryption key (session key) with length k
197
 
   * CSUM
198
 
   */
199
 
  if( DBG_CIPHER )
200
 
    log_printhex ("DEK frame:", frame, nframe );
201
 
  n=0;
202
 
  if (!card)
 
200
    /* Now get the DEK (data encryption key) from the frame
 
201
     *
 
202
     * Old versions encode the DEK in in this format (msb is left):
 
203
     *
 
204
     *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
 
205
     *
 
206
     * Later versions encode the DEK like this:
 
207
     *
 
208
     *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
 
209
     *
 
210
     * (mpi_get_buffer already removed the leading zero).
 
211
     *
 
212
     * RND are non-zero randow bytes.
 
213
     * A   is the cipher algorithm
 
214
     * DEK is the encryption key (session key) with length k
 
215
     * CSUM
 
216
     */
 
217
    if (DBG_CIPHER)
 
218
      log_printhex ("DEK frame:", frame, nframe );
 
219
    n=0;
 
220
    if (!card)
 
221
      {
 
222
        if( n + 7 > nframe )
 
223
          { rc = G10ERR_WRONG_SECKEY; goto leave; }
 
224
        if( frame[n] == 1 && frame[nframe-1] == 2 ) {
 
225
          log_info(_("old encoding of the DEK is not supported\n"));
 
226
          rc = G10ERR_CIPHER_ALGO;
 
227
          goto leave;
 
228
        }
 
229
        if( frame[n] != 2 )  /* somethink is wrong */
 
230
          { rc = G10ERR_WRONG_SECKEY; goto leave; }
 
231
        for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
 
232
          ;
 
233
        n++; /* and the zero byte */
 
234
      }
 
235
 
 
236
    if( n + 4 > nframe )
 
237
        { rc = G10ERR_WRONG_SECKEY; goto leave; }
 
238
 
 
239
    dek->keylen = nframe - (n+1) - 2;
 
240
    dek->algo = frame[n++];
 
241
    if( dek->algo ==  CIPHER_ALGO_IDEA )
 
242
        write_status(STATUS_RSA_OR_IDEA);
 
243
    rc = openpgp_cipher_test_algo (dek->algo);
 
244
    if( rc ) {
 
245
        if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
 
246
            log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
 
247
                     dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
 
248
            if(dek->algo==CIPHER_ALGO_IDEA)
 
249
              idea_cipher_warn(0);
 
250
        }
 
251
        dek->algo = 0;
 
252
        goto leave;
 
253
    }
 
254
    if ( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
 
255
        rc = GPG_ERR_WRONG_SECKEY;
 
256
        goto leave;
 
257
    }
 
258
 
 
259
    /* copy the key to DEK and compare the checksum */
 
260
    csum  = frame[nframe-2] << 8;
 
261
    csum |= frame[nframe-1];
 
262
    memcpy( dek->key, frame+n, dek->keylen );
 
263
    for( csum2=0, n=0; n < dek->keylen; n++ )
 
264
        csum2 += dek->key[n];
 
265
    if( csum != csum2 ) {
 
266
        rc = G10ERR_WRONG_SECKEY;
 
267
        goto leave;
 
268
    }
 
269
    if( DBG_CIPHER )
 
270
        log_printhex ("DEK is:", dek->key, dek->keylen );
 
271
    /* check that the algo is in the preferences and whether it has expired */
203
272
    {
204
 
      if( n + 7 > nframe )
205
 
        { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
206
 
      if( frame[n] == 1 && frame[nframe-1] == 2 ) {
207
 
        log_info(_("old encoding of the DEK is not supported\n"));
208
 
        rc = GPG_ERR_CIPHER_ALGO;
209
 
        goto leave;
210
 
      }
211
 
      if( frame[n] != 2 )  /* somethink is wrong */
212
 
        { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
213
 
      for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
214
 
        ;
215
 
      n++; /* and the zero byte */
216
 
    }
217
 
 
218
 
  if( n + 4 > nframe )
219
 
    { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
220
 
  dek->keylen = nframe - (n+1) - 2;
221
 
  dek->algo = frame[n++];
222
 
  if( dek->algo ==  CIPHER_ALGO_IDEA )
223
 
    write_status(STATUS_RSA_OR_IDEA);
224
 
  rc = openpgp_cipher_test_algo (dek->algo);
225
 
  if( rc ) {
226
 
    if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
227
 
      log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
228
 
               dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
229
 
      if(dek->algo==CIPHER_ALGO_IDEA)
230
 
        idea_cipher_warn(0);
231
 
    }
232
 
    dek->algo = 0;
233
 
    goto leave;
234
 
  }
235
 
  if( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
236
 
    rc = GPG_ERR_WRONG_SECKEY;
237
 
    goto leave;
238
 
  }
239
 
 
240
 
  /* copy the key to DEK and compare the checksum */
241
 
  csum  = frame[nframe-2] << 8;
242
 
  csum |= frame[nframe-1];
243
 
  memcpy( dek->key, frame+n, dek->keylen );
244
 
  for( csum2=0, n=0; n < dek->keylen; n++ )
245
 
    csum2 += dek->key[n];
246
 
  if( csum != csum2 ) {
247
 
    rc = GPG_ERR_WRONG_SECKEY;
248
 
    goto leave;
249
 
  }
250
 
  if( DBG_CIPHER )
251
 
    log_printhex ("DEK is:", dek->key, dek->keylen );
252
 
  /* check that the algo is in the preferences and whether it has expired */
253
 
  {
254
 
    PKT_public_key *pk = NULL;
255
 
    KBNODE pkb = get_pubkeyblock (keyid);
256
 
 
257
 
    if( !pkb ) {
258
 
      rc = -1;
259
 
      log_error("oops: public key not found for preference check\n");
260
 
    }
261
 
    else if( pkb->pkt->pkt.public_key->selfsigversion > 3
262
 
             && dek->algo != CIPHER_ALGO_3DES
263
 
             && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) {
264
 
      /* Don't print a note while we are not on verbose mode,
265
 
       * the cipher is blowfish and the preferences have twofish
266
 
       * listed */
267
 
      if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
268
 
          || !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH))
269
 
        log_info(_(
270
 
                   "NOTE: cipher algorithm %d not found in preferences\n"),
271
 
                 dek->algo );
272
 
    }
273
 
 
274
 
    if (!rc) {
275
 
      KBNODE k;
 
273
        PKT_public_key *pk = NULL;
 
274
        KBNODE pkb = get_pubkeyblock (keyid);
 
275
 
 
276
        if( !pkb ) {
 
277
            rc = -1;
 
278
            log_error("oops: public key not found for preference check\n");
 
279
        }
 
280
        else if(pkb->pkt->pkt.public_key->selfsigversion > 3
 
281
                && dek->algo != CIPHER_ALGO_3DES
 
282
                && !opt.quiet
 
283
                && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
 
284
          log_info (_("WARNING: cipher algorithm %s not found in recipient"
 
285
                      " preferences\n"), openpgp_cipher_algo_name (dek->algo));
 
286
        if (!rc) {
 
287
            KBNODE k;
276
288
            
277
 
      for (k=pkb; k; k = k->next) {
278
 
        if (k->pkt->pkttype == PKT_PUBLIC_KEY 
279
 
            || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
280
 
          u32 aki[2];
281
 
          keyid_from_pk(k->pkt->pkt.public_key, aki);
282
 
 
283
 
          if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
284
 
            pk = k->pkt->pkt.public_key;
285
 
            break;
286
 
          }
287
 
        }
288
 
      }
289
 
      if (!pk)
290
 
        BUG ();
291
 
      if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
292
 
        log_info(_("NOTE: secret key %08lX expired at %s\n"),
293
 
                 (ulong)keyid[1], asctimestamp( pk->expiredate) );
294
 
      }
295
 
    }
296
 
 
297
 
    if ( pk &&  pk->is_revoked ) {
298
 
      log_info( _("NOTE: key has been revoked") );
299
 
      putc( '\n', log_get_stream() );
300
 
      show_revocation_reason( pk, 1 );
301
 
    }
302
 
 
303
 
    release_kbnode (pkb);
304
 
    rc = 0;
305
 
  }
306
 
 
307
 
 
308
 
 leave:
309
 
  gcry_mpi_release (plain_dek);
310
 
  xfree (frame);
311
 
  return rc;
 
289
            for (k=pkb; k; k = k->next) {
 
290
                if (k->pkt->pkttype == PKT_PUBLIC_KEY 
 
291
                    || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
 
292
                    u32 aki[2];
 
293
                    keyid_from_pk(k->pkt->pkt.public_key, aki);
 
294
 
 
295
                    if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
 
296
                        pk = k->pkt->pkt.public_key;
 
297
                        break;
 
298
                    }
 
299
                }
 
300
            }
 
301
            if (!pk)
 
302
                BUG ();
 
303
            if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
 
304
                log_info(_("NOTE: secret key %s expired at %s\n"),
 
305
                         keystr(keyid), asctimestamp( pk->expiredate) );
 
306
            }
 
307
        }
 
308
 
 
309
        if ( pk &&  pk->is_revoked ) {
 
310
            log_info( _("NOTE: key has been revoked") );
 
311
            log_printf ("\n");
 
312
            show_revocation_reason( pk, 1 );
 
313
        }
 
314
 
 
315
        release_kbnode (pkb);
 
316
        rc = 0;
 
317
    }
 
318
 
 
319
 
 
320
  leave:
 
321
    gcry_mpi_release (plain_dek);
 
322
    xfree (frame);
 
323
    return rc;
312
324
}
313
325
 
314
326
 
324
336
    int i;
325
337
 
326
338
    if ( !string )
327
 
        return GPG_ERR_BAD_KEY;
 
339
        return G10ERR_BAD_KEY;
328
340
    dek->algo = atoi(string);
329
341
    if ( dek->algo < 1 )
330
 
        return GPG_ERR_BAD_KEY;
 
342
        return G10ERR_BAD_KEY;
331
343
    if ( !(s = strchr ( string, ':' )) )
332
 
        return GPG_ERR_BAD_KEY;
 
344
        return G10ERR_BAD_KEY;
333
345
    s++;
334
346
    for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
335
347
        int c = hextobyte ( s );
336
348
        if (c == -1)
337
 
            return GPG_ERR_BAD_KEY;
 
349
            return G10ERR_BAD_KEY;
338
350
        dek->key[i] = c;
339
351
    }
340
352
    if ( *s )
341
 
        return GPG_ERR_BAD_KEY;
 
353
        return G10ERR_BAD_KEY;
342
354
    dek->keylen = i;
343
355
    return 0;
344
356
}