* gpg.texi (GPG Configuration Options): Make http_proxy option
[gnupg.git] / g10 / pubkey-enc.c
blob777e5f7883825c6515160b88627b9c7663e1e3b5
1 /* pubkey-enc.c - public key encoded packet handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2006 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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.
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
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"
43 static int get_it( PKT_pubkey_enc *k,
44 DEK *dek, PKT_secret_key *sk, u32 *keyid );
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 )
51 KBNODE k;
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;
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;
66 return 0;
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.
74 int
75 get_session_key( PKT_pubkey_enc *k, DEK *dek )
77 PKT_secret_key *sk = NULL;
78 int rc;
80 rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
81 if( rc )
82 goto leave;
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 );
90 else { /* anonymous receiver: Try all available secret keys */
91 void *enum_context = NULL;
92 u32 keyid[2];
93 char *p;
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;
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));
110 if(!opt.try_all_secrets && !is_status_enabled())
112 p=get_last_passphrase();
113 set_next_passphrase(p);
114 xfree(p);
117 rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
118 only
119 once */
120 if( !rc )
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();
136 if( !rc )
138 log_info(_("okay, we are the anonymous recipient.\n") );
139 break;
142 enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
145 leave:
146 if( sk )
147 free_secret_key( sk );
148 return rc;
152 static int
153 get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
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;
162 int card = 0;
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;
173 snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
175 if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
176 BUG ();
178 rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
179 xfree (snbuf);
180 xfree (indata);
181 if (rc)
182 goto leave;
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*/
192 else
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;
202 /* Now get the DEK (data encryption key) from the frame
204 * Old versions encode the DEK in in this format (msb is left):
206 * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2
208 * Later versions encode the DEK like this:
210 * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
212 * (mpi_get_buffer already removed the leading zero).
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
219 if (DBG_CIPHER)
220 log_printhex ("DEK frame:", frame, nframe );
221 n=0;
222 if (!card)
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;
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 */
235 n++; /* and the zero byte */
238 if( n + 4 > nframe )
239 { rc = G10ERR_WRONG_SECKEY; goto leave; }
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);
253 dek->algo = 0;
254 goto leave;
256 if ( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
257 rc = GPG_ERR_WRONG_SECKEY;
258 goto leave;
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;
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 */
275 PKT_public_key *pk = NULL;
276 KBNODE pkb = get_pubkeyblock (keyid);
278 if( !pkb ) {
279 rc = -1;
280 log_error("oops: public key not found for preference check\n");
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;
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);
297 if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
298 pk = k->pkt->pkt.public_key;
299 break;
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) );
311 if ( pk && pk->is_revoked ) {
312 log_info( _("NOTE: key has been revoked") );
313 log_printf ("\n");
314 show_revocation_reason( pk, 1 );
317 release_kbnode (pkb);
318 rc = 0;
322 leave:
323 gcry_mpi_release (plain_dek);
324 xfree (frame);
325 return rc;
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>
335 get_override_session_key( DEK *dek, const char *string )
337 const char *s;
338 int i;
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;
354 if ( *s )
355 return G10ERR_BAD_KEY;
356 dek->keylen = i;
357 return 0;