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