5af0d5f1d48e1a2971fcf885a9fcb0f13c06d9e9
[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
41
42 static int get_it( PKT_pubkey_enc *k,
43                    DEK *dek, PKT_secret_key *sk, u32 *keyid );
44
45
46 /* check that the given algo is mentioned in one of the valid user IDs */
47 static int
48 is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo )
49 {
50     KBNODE k;
51
52     for (k=keyblock; k; k=k->next) {
53         if (k->pkt->pkttype == PKT_USER_ID) {
54             PKT_user_id *uid = k->pkt->pkt.user_id;
55             prefitem_t *prefs = uid->prefs;
56             
57             if (uid->created && prefs &&
58                 !uid->is_revoked && !uid->is_expired ) {
59                 for (; prefs->type; prefs++ )
60                     if (prefs->type == type && prefs->value == algo)
61                         return 1;
62             }
63         }
64     }
65     return 0;
66 }
67
68
69 /****************
70  * Get the session key from a pubkey enc packet and return
71  * it in DEK, which should have been allocated in secure memory.
72  */
73 int
74 get_session_key( PKT_pubkey_enc *k, DEK *dek )
75 {
76     PKT_secret_key *sk = NULL;
77     int rc;
78
79     rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
80     if( rc )
81         goto leave;
82
83     if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
84         sk = xmalloc_clear( sizeof *sk );
85         sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
86         if( !(rc = get_seckey( sk, k->keyid )) )
87             rc = get_it( k, dek, sk, k->keyid );
88     }
89     else { /* anonymous receiver: Try all available secret keys */
90         void *enum_context = NULL;
91         u32 keyid[2];
92         char *p;
93
94         for(;;) {
95             if( sk )
96                 free_secret_key( sk );
97             sk = xmalloc_clear( sizeof *sk );
98             rc=enum_secret_keys( &enum_context, sk, 1, 0);
99             if( rc ) {
100                 rc = G10ERR_NO_SECKEY;
101                 break;
102             }
103             if( sk->pubkey_algo != k->pubkey_algo )
104                 continue;
105             keyid_from_sk( sk, keyid );
106             log_info(_("anonymous recipient; trying secret key %s ...\n"),
107                      keystr(keyid));
108
109             if(!opt.try_all_secrets && !is_status_enabled())
110               {
111                 p=get_last_passphrase();
112                 set_next_passphrase(p);
113                 xfree(p);
114               }
115
116             rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
117                                                                       only
118                                                                       once */
119             if( !rc )
120               {
121                 rc = get_it( k, dek, sk, keyid );
122                 /* Successfully checked the secret key (either it was
123                    a card, had no passphrase, or had the right
124                    passphrase) but couldn't decrypt the session key,
125                    so thus that key is not the anonymous recipient.
126                    Move the next passphrase into last for the next
127                    round.  We only do this if the secret key was
128                    successfully checked as in the normal case,
129                    check_secret_key handles this for us via
130                    passphrase_to_dek */
131                 if(rc)
132                   next_to_last_passphrase();
133               }
134
135             if( !rc )
136               {
137                 log_info(_("okay, we are the anonymous recipient.\n") );
138                 break;
139               }
140         }
141         enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
142     }
143
144   leave:
145     if( sk )
146         free_secret_key( sk );
147     return rc;
148 }
149
150
151 static int
152 get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
153 {
154   int rc;
155   gcry_mpi_t plain_dek  = NULL;
156   byte *frame = NULL;
157   unsigned n, nframe;
158   u16 csum, csum2;
159   
160   int card = 0;
161
162   if (sk->is_protected && sk->protect.s2k.mode == 1002)
163     { /* Note, that we only support RSA for now. */
164 #ifdef ENABLE_CARD_SUPPORT
165       unsigned char *rbuf;
166       size_t rbuflen;
167       char *snbuf;
168       unsigned char *indata = NULL;
169       unsigned int indatalen;
170
171       snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
172
173       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
174         BUG ();
175
176       rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
177       xfree (snbuf);
178       xfree (indata);
179       if (rc)
180         goto leave;
181
182       frame = rbuf;
183       nframe = rbuflen;
184       card = 1;
185 #else
186       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
187       goto leave;
188 #endif /*!ENABLE_CARD_SUPPORT*/
189     }
190   else
191     {
192       rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
193       if( rc )
194         goto leave;
195       if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
196         BUG();
197       gcry_mpi_release (plain_dek); plain_dek = NULL;
198     }
199
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_hexdump("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_hexdump("DEK is:", dek->key, dek->keylen );
271     /* check that the algo is in the preferences and whether it has expired */
272     {
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"), gcry_cipher_algo_name (dek->algo));
286         if (!rc) {
287             KBNODE k;
288             
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             putc( '\n', log_get_stream() );
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;
324 }
325
326
327 /****************
328  * Get the session key from the given string.
329  * String is supposed to be formatted as this:
330  *  <algo-id>:<even-number-of-hex-digits>
331  */
332 int
333 get_override_session_key( DEK *dek, const char *string )
334 {
335     const char *s;
336     int i;
337
338     if ( !string )
339         return G10ERR_BAD_KEY;
340     dek->algo = atoi(string);
341     if ( dek->algo < 1 )
342         return G10ERR_BAD_KEY;
343     if ( !(s = strchr ( string, ':' )) )
344         return G10ERR_BAD_KEY;
345     s++;
346     for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
347         int c = hextobyte ( s );
348         if (c == -1)
349             return G10ERR_BAD_KEY;
350         dek->key[i] = c;
351     }
352     if ( *s )
353         return G10ERR_BAD_KEY;
354     dek->keylen = i;
355     return 0;
356 }
357