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