Re-indent and changed return type.
[gnupg.git] / g10 / pubkey-enc.c
1 /* pubkey-enc.c - Process a public key encoded packet.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009,
3  *               2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "gpg.h"
28 #include "util.h"
29 #include "packet.h"
30 #include "keydb.h"
31 #include "trustdb.h"
32 #include "cipher.h"
33 #include "status.h"
34 #include "options.h"
35 #include "main.h"
36 #include "i18n.h"
37 #include "pkglue.h"
38 #include "call-agent.h"
39
40
41 static gpg_error_t get_it (PKT_pubkey_enc *k,
42                            DEK *dek, PKT_secret_key *sk, u32 *keyid);
43
44
45 /* Check that the given algo is mentioned in one of the valid user-ids. */
46 static int
47 is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
48 {
49   kbnode_t k;
50
51   for (k = keyblock; k; k = k->next)
52     {
53       if (k->pkt->pkttype == PKT_USER_ID)
54         {
55           PKT_user_id *uid = k->pkt->pkt.user_id;
56           prefitem_t *prefs = uid->prefs;
57
58           if (uid->created && prefs && !uid->is_revoked && !uid->is_expired)
59             {
60               for (; prefs->type; prefs++)
61                 if (prefs->type == type && prefs->value == algo)
62                   return 1;
63             }
64         }
65     }
66   return 0;
67 }
68
69
70 /*
71  * Get the session key from a pubkey enc packet and return it in DEK,
72  * which should have been allocated in secure memory by the caller.
73  */
74 gpg_error_t
75 get_session_key (PKT_pubkey_enc * k, DEK * dek)
76 {
77   PKT_secret_key *sk = NULL;
78   int rc;
79
80   rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
81   if (rc)
82     goto leave;
83
84   if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets)
85     {
86       sk = xmalloc_clear (sizeof *sk);
87       sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo */
88       if (!(rc = get_seckey (sk, k->keyid)))
89         rc = get_it (k, dek, sk, k->keyid);
90     }
91   else if (opt.skip_hidden_recipients)
92     rc = gpg_error (GPG_ERR_NO_SECKEY);
93   else  /* Anonymous receiver: Try all available secret keys.  */
94     {
95       void *enum_context = NULL;
96       u32 keyid[2];
97       char *p;
98
99       for (;;)
100         {
101           if (sk)
102             free_secret_key (sk);
103           sk = xmalloc_clear (sizeof *sk);
104           rc = enum_secret_keys (&enum_context, sk, 1, 0);
105           if (rc)
106             {
107               rc = G10ERR_NO_SECKEY;
108               break;
109             }
110           if (sk->pubkey_algo != k->pubkey_algo)
111             continue;
112           keyid_from_sk (sk, keyid);
113           log_info (_("anonymous recipient; trying secret key %s ...\n"),
114                     keystr (keyid));
115
116           if (!opt.try_all_secrets && !is_status_enabled ())
117             {
118               p = get_last_passphrase ();
119               set_next_passphrase (p);
120               xfree (p);
121             }
122
123           /* rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /\* ask */
124           /*                                                        only */
125           /*                                                        once *\/ */
126           /* if( !rc ) */
127           {
128             rc = get_it (k, dek, sk, keyid);
129             /* Successfully checked the secret key (either it was a
130                card, had no passphrase, or had the right passphrase)
131                but couldn't decrypt the session key, so thus that key
132                is not the anonymous recipient.  Move the next
133                passphrase into last for the next round.  We only do
134                this if the secret key was successfully checked as in
135                the normal case, check_secret_key handles this for us
136                via passphrase_to_dek.  */
137             if (rc)
138               next_to_last_passphrase ();
139           }
140
141           if (!rc)
142             {
143               log_info (_("okay, we are the anonymous recipient.\n"));
144               break;
145             }
146         }
147       enum_secret_keys (&enum_context, NULL, 0, 0);     /* free context */
148     }
149
150 leave:
151   if (sk)
152     free_secret_key (sk);
153   return rc;
154 }
155
156
157 static gpg_error_t
158 get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
159 {
160   int rc;
161   gcry_mpi_t plain_dek = NULL;
162   byte *frame = NULL;
163   unsigned int n;
164   size_t nframe;
165   u16 csum, csum2;
166
167   int card = 0;
168
169   if (sk->is_protected && sk->protect.s2k.mode == 1002)
170     {   /* Note, that we only support RSA for now. */
171 #ifdef ENABLE_CARD_SUPPORT
172       unsigned char *rbuf;
173       size_t rbuflen;
174       char *snbuf;
175       unsigned char *indata = NULL;
176       size_t indatalen;
177
178       snbuf =
179         serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
180
181       if (gcry_mpi_aprint
182           (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
183         BUG ();
184
185       rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
186       xfree (snbuf);
187       xfree (indata);
188       if (rc)
189         goto leave;
190
191       frame = rbuf;
192       nframe = rbuflen;
193       card = 1;
194 #else
195       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
196       goto leave;
197 #endif /*!ENABLE_CARD_SUPPORT */
198     }
199   else
200     {
201       rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey);
202       if (rc)
203         goto leave;
204       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
205         BUG ();
206       gcry_mpi_release (plain_dek);
207       plain_dek = NULL;
208     }
209
210   /* Now get the DEK (data encryption key) from the frame
211    *
212    * Old versions encode the DEK in in this format (msb is left):
213    *
214    *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
215    *
216    * Later versions encode the DEK like this:
217    *
218    *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
219    *
220    * (mpi_get_buffer already removed the leading zero).
221    *
222    * RND are non-zero randow bytes.
223    * A   is the cipher algorithm
224    * DEK is the encryption key (session key) with length k
225    * CSUM
226    */
227   if (DBG_CIPHER)
228     log_printhex ("DEK frame:", frame, nframe);
229   n = 0;
230   if (!card)
231     {
232       if (n + 7 > nframe)
233         {
234           rc = G10ERR_WRONG_SECKEY;
235           goto leave;
236         }
237       if (frame[n] == 1 && frame[nframe - 1] == 2)
238         {
239           log_info (_("old encoding of the DEK is not supported\n"));
240           rc = G10ERR_CIPHER_ALGO;
241           goto leave;
242         }
243       if (frame[n] != 2) /* Somethink is wrong.  */
244         {
245           rc = G10ERR_WRONG_SECKEY;
246           goto leave;
247         }
248       for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
249         ;
250       n++; /* Skip the zero byte.  */
251     }
252
253   if (n + 4 > nframe)
254     {
255       rc = G10ERR_WRONG_SECKEY;
256       goto leave;
257     }
258
259   dek->keylen = nframe - (n + 1) - 2;
260   dek->algo = frame[n++];
261   if (dek->algo == CIPHER_ALGO_IDEA)
262     write_status (STATUS_RSA_OR_IDEA);
263   rc = openpgp_cipher_test_algo (dek->algo);
264   if (rc)
265     {
266       if (!opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO)
267         {
268           log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
269                     dek->algo,
270                     dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
271           if (dek->algo == CIPHER_ALGO_IDEA)
272             idea_cipher_warn (0);
273         }
274       dek->algo = 0;
275       goto leave;
276     }
277   if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
278     {
279       rc = GPG_ERR_WRONG_SECKEY;
280       goto leave;
281     }
282
283   /* Copy the key to DEK and compare the checksum.  */
284   csum = frame[nframe - 2] << 8;
285   csum |= frame[nframe - 1];
286   memcpy (dek->key, frame + n, dek->keylen);
287   for (csum2 = 0, n = 0; n < dek->keylen; n++)
288     csum2 += dek->key[n];
289   if (csum != csum2)
290     {
291       rc = G10ERR_WRONG_SECKEY;
292       goto leave;
293     }
294   if (DBG_CIPHER)
295     log_printhex ("DEK is:", dek->key, dek->keylen);
296
297   /* Check that the algo is in the preferences and whether it has expired.  */
298   {
299     PKT_public_key *pk = NULL;
300     KBNODE pkb = get_pubkeyblock (keyid);
301
302     if (!pkb)
303       {
304         rc = -1;
305         log_error ("oops: public key not found for preference check\n");
306       }
307     else if (pkb->pkt->pkt.public_key->selfsigversion > 3
308              && dek->algo != CIPHER_ALGO_3DES
309              && !opt.quiet
310              && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
311       log_info (_("WARNING: cipher algorithm %s not found in recipient"
312                   " preferences\n"), openpgp_cipher_algo_name (dek->algo));
313     if (!rc)
314       {
315         KBNODE k;
316
317         for (k = pkb; k; k = k->next)
318           {
319             if (k->pkt->pkttype == PKT_PUBLIC_KEY
320                 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
321               {
322                 u32 aki[2];
323                 keyid_from_pk (k->pkt->pkt.public_key, aki);
324
325                 if (aki[0] == keyid[0] && aki[1] == keyid[1])
326                   {
327                     pk = k->pkt->pkt.public_key;
328                     break;
329                   }
330               }
331           }
332         if (!pk)
333           BUG ();
334         if (pk->expiredate && pk->expiredate <= make_timestamp ())
335           {
336             log_info (_("NOTE: secret key %s expired at %s\n"),
337                       keystr (keyid), asctimestamp (pk->expiredate));
338           }
339       }
340
341     if (pk && pk->is_revoked)
342       {
343         log_info (_("NOTE: key has been revoked"));
344         log_printf ("\n");
345         show_revocation_reason (pk, 1);
346       }
347
348     release_kbnode (pkb);
349     rc = 0;
350   }
351
352
353 leave:
354   gcry_mpi_release (plain_dek);
355   xfree (frame);
356   return rc;
357 }
358
359
360 /*
361  * Get the session key from the given string.
362  * String is supposed to be formatted as this:
363  *  <algo-id>:<even-number-of-hex-digits>
364  */
365 gpg_error_t
366 get_override_session_key (DEK *dek, const char *string)
367 {
368   const char *s;
369   int i;
370
371   if (!string)
372     return G10ERR_BAD_KEY;
373   dek->algo = atoi (string);
374   if (dek->algo < 1)
375     return G10ERR_BAD_KEY;
376   if (!(s = strchr (string, ':')))
377     return G10ERR_BAD_KEY;
378   s++;
379   for (i = 0; i < DIM (dek->key) && *s; i++, s += 2)
380     {
381       int c = hextobyte (s);
382       if (c == -1)
383         return G10ERR_BAD_KEY;
384       dek->key[i] = c;
385     }
386   if (*s)
387     return G10ERR_BAD_KEY;
388   dek->keylen = i;
389   return 0;
390 }