fca19f849855a78e786a914c767dd8f25b516310
[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 n, nframe;
159   u16 csum, csum2;
160   
161   int card = 0;
162
163   if (sk->is_protected && sk->protect.s2k.mode == 1002)
164     { /* Note, that we only support RSA for now. */
165 #ifdef ENABLE_CARD_SUPPORT
166       unsigned char *rbuf;
167       size_t rbuflen;
168       char *snbuf;
169       unsigned char *indata = NULL;
170       unsigned int indatalen;
171
172       snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
173
174       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
175         BUG ();
176
177       rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
178       xfree (snbuf);
179       xfree (indata);
180       if (rc)
181         goto leave;
182
183       frame = rbuf;
184       nframe = rbuflen;
185       card = 1;
186 #else
187       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
188       goto leave;
189 #endif /*!ENABLE_CARD_SUPPORT*/
190     }
191   else
192     {
193       rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
194       if( rc )
195         goto leave;
196       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
197         BUG();
198       gcry_mpi_release (plain_dek); plain_dek = NULL;
199     }
200
201     /* Now get the DEK (data encryption key) from the frame
202      *
203      * Old versions encode the DEK in in this format (msb is left):
204      *
205      *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
206      *
207      * Later versions encode the DEK like this:
208      *
209      *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
210      *
211      * (mpi_get_buffer already removed the leading zero).
212      *
213      * RND are non-zero randow bytes.
214      * A   is the cipher algorithm
215      * DEK is the encryption key (session key) with length k
216      * CSUM
217      */
218     if (DBG_CIPHER)
219       log_printhex ("DEK frame:", frame, nframe );
220     n=0;
221     if (!card)
222       {
223         if( n + 7 > nframe )
224           { rc = G10ERR_WRONG_SECKEY; goto leave; }
225         if( frame[n] == 1 && frame[nframe-1] == 2 ) {
226           log_info(_("old encoding of the DEK is not supported\n"));
227           rc = G10ERR_CIPHER_ALGO;
228           goto leave;
229         }
230         if( frame[n] != 2 )  /* somethink is wrong */
231           { rc = G10ERR_WRONG_SECKEY; goto leave; }
232         for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
233           ;
234         n++; /* and the zero byte */
235       }
236
237     if( n + 4 > nframe )
238         { rc = G10ERR_WRONG_SECKEY; goto leave; }
239
240     dek->keylen = nframe - (n+1) - 2;
241     dek->algo = frame[n++];
242     if( dek->algo ==  CIPHER_ALGO_IDEA )
243         write_status(STATUS_RSA_OR_IDEA);
244     rc = openpgp_cipher_test_algo (dek->algo);
245     if( rc ) {
246         if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
247             log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
248                      dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
249             if(dek->algo==CIPHER_ALGO_IDEA)
250               idea_cipher_warn(0);
251         }
252         dek->algo = 0;
253         goto leave;
254     }
255     if ( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
256         rc = GPG_ERR_WRONG_SECKEY;
257         goto leave;
258     }
259
260     /* copy the key to DEK and compare the checksum */
261     csum  = frame[nframe-2] << 8;
262     csum |= frame[nframe-1];
263     memcpy( dek->key, frame+n, dek->keylen );
264     for( csum2=0, n=0; n < dek->keylen; n++ )
265         csum2 += dek->key[n];
266     if( csum != csum2 ) {
267         rc = G10ERR_WRONG_SECKEY;
268         goto leave;
269     }
270     if( DBG_CIPHER )
271         log_printhex ("DEK is:", dek->key, dek->keylen );
272     /* check that the algo is in the preferences and whether it has expired */
273     {
274         PKT_public_key *pk = NULL;
275         KBNODE pkb = get_pubkeyblock (keyid);
276
277         if( !pkb ) {
278             rc = -1;
279             log_error("oops: public key not found for preference check\n");
280         }
281         else if(pkb->pkt->pkt.public_key->selfsigversion > 3
282                 && dek->algo != CIPHER_ALGO_3DES
283                 && !opt.quiet
284                 && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
285           log_info (_("WARNING: cipher algorithm %s not found in recipient"
286                       " preferences\n"), gcry_cipher_algo_name (dek->algo));
287         if (!rc) {
288             KBNODE k;
289             
290             for (k=pkb; k; k = k->next) {
291                 if (k->pkt->pkttype == PKT_PUBLIC_KEY 
292                     || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
293                     u32 aki[2];
294                     keyid_from_pk(k->pkt->pkt.public_key, aki);
295
296                     if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
297                         pk = k->pkt->pkt.public_key;
298                         break;
299                     }
300                 }
301             }
302             if (!pk)
303                 BUG ();
304             if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
305                 log_info(_("NOTE: secret key %s expired at %s\n"),
306                          keystr(keyid), asctimestamp( pk->expiredate) );
307             }
308         }
309
310         if ( pk &&  pk->is_revoked ) {
311             log_info( _("NOTE: key has been revoked") );
312             log_printf ("\n");
313             show_revocation_reason( pk, 1 );
314         }
315
316         release_kbnode (pkb);
317         rc = 0;
318     }
319
320
321   leave:
322     gcry_mpi_release (plain_dek);
323     xfree (frame);
324     return rc;
325 }
326
327
328 /****************
329  * Get the session key from the given string.
330  * String is supposed to be formatted as this:
331  *  <algo-id>:<even-number-of-hex-digits>
332  */
333 int
334 get_override_session_key( DEK *dek, const char *string )
335 {
336     const char *s;
337     int i;
338
339     if ( !string )
340         return G10ERR_BAD_KEY;
341     dek->algo = atoi(string);
342     if ( dek->algo < 1 )
343         return G10ERR_BAD_KEY;
344     if ( !(s = strchr ( string, ':' )) )
345         return G10ERR_BAD_KEY;
346     s++;
347     for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
348         int c = hextobyte ( s );
349         if (c == -1)
350             return G10ERR_BAD_KEY;
351         dek->key[i] = c;
352     }
353     if ( *s )
354         return G10ERR_BAD_KEY;
355     dek->keylen = i;
356     return 0;
357 }
358