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