Line data Source code
1 : /* pubkey-enc.c - Process a public key encoded packet.
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009,
3 : * 2010 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 3 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, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 :
26 : #include "gpg.h"
27 : #include "util.h"
28 : #include "packet.h"
29 : #include "keydb.h"
30 : #include "trustdb.h"
31 : #include "status.h"
32 : #include "options.h"
33 : #include "main.h"
34 : #include "i18n.h"
35 : #include "pkglue.h"
36 : #include "call-agent.h"
37 : #include "host2net.h"
38 :
39 :
40 : static gpg_error_t get_it (PKT_pubkey_enc *k,
41 : DEK *dek, PKT_public_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 240 : is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
47 : {
48 : kbnode_t k;
49 :
50 844 : for (k = keyblock; k; k = k->next)
51 : {
52 753 : if (k->pkt->pkttype == PKT_USER_ID)
53 : {
54 240 : PKT_user_id *uid = k->pkt->pkt.user_id;
55 240 : prefitem_t *prefs = uid->prefs;
56 :
57 240 : if (uid->created && prefs && !uid->is_revoked && !uid->is_expired)
58 : {
59 842 : for (; prefs->type; prefs++)
60 751 : if (prefs->type == type && prefs->value == algo)
61 149 : return 1;
62 : }
63 : }
64 : }
65 91 : return 0;
66 : }
67 :
68 :
69 : /*
70 : * Get the session key from a pubkey enc packet and return it in DEK,
71 : * which should have been allocated in secure memory by the caller.
72 : */
73 : gpg_error_t
74 259 : get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
75 : {
76 259 : PKT_public_key *sk = NULL;
77 : int rc;
78 :
79 259 : if (DBG_CLOCK)
80 0 : log_clock ("get_session_key enter");
81 :
82 259 : rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
83 259 : if (rc)
84 0 : goto leave;
85 :
86 259 : if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets)
87 : {
88 259 : sk = xmalloc_clear (sizeof *sk);
89 259 : sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */
90 518 : if (!(rc = get_seckey (sk, k->keyid)))
91 259 : rc = get_it (k, dek, sk, k->keyid);
92 : }
93 0 : else if (opt.skip_hidden_recipients)
94 0 : rc = gpg_error (GPG_ERR_NO_SECKEY);
95 : else /* Anonymous receiver: Try all available secret keys. */
96 : {
97 0 : void *enum_context = NULL;
98 : u32 keyid[2];
99 :
100 : for (;;)
101 : {
102 0 : free_public_key (sk);
103 0 : sk = xmalloc_clear (sizeof *sk);
104 0 : rc = enum_secret_keys (ctrl, &enum_context, sk);
105 0 : if (rc)
106 : {
107 0 : rc = GPG_ERR_NO_SECKEY;
108 0 : break;
109 : }
110 0 : if (sk->pubkey_algo != k->pubkey_algo)
111 0 : continue;
112 0 : if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
113 0 : continue;
114 0 : keyid_from_pk (sk, keyid);
115 0 : if (!opt.quiet)
116 0 : log_info (_("anonymous recipient; trying secret key %s ...\n"),
117 : keystr (keyid));
118 :
119 0 : rc = get_it (k, dek, sk, keyid);
120 0 : if (!rc)
121 : {
122 0 : if (!opt.quiet)
123 0 : log_info (_("okay, we are the anonymous recipient.\n"));
124 0 : break;
125 : }
126 0 : else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
127 0 : break; /* Don't try any more secret keys. */
128 0 : }
129 0 : enum_secret_keys (ctrl, &enum_context, NULL); /* free context */
130 : }
131 :
132 : leave:
133 259 : free_public_key (sk);
134 259 : if (DBG_CLOCK)
135 0 : log_clock ("get_session_key leave");
136 259 : return rc;
137 : }
138 :
139 :
140 : static gpg_error_t
141 259 : get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
142 : {
143 : gpg_error_t err;
144 259 : byte *frame = NULL;
145 : unsigned int n;
146 : size_t nframe;
147 : u16 csum, csum2;
148 : int padding;
149 : gcry_sexp_t s_data;
150 : char *desc;
151 : char *keygrip;
152 : byte fp[MAX_FINGERPRINT_LEN];
153 : size_t fpn;
154 :
155 259 : if (DBG_CLOCK)
156 0 : log_clock ("decryption start");
157 :
158 : /* Get the keygrip. */
159 259 : err = hexkeygrip_from_pk (sk, &keygrip);
160 259 : if (err)
161 0 : goto leave;
162 :
163 : /* Convert the data to an S-expression. */
164 259 : if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
165 259 : || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
166 : {
167 464 : if (!enc->data[0] || !enc->data[1])
168 0 : err = gpg_error (GPG_ERR_BAD_MPI);
169 : else
170 232 : err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
171 : enc->data[0], enc->data[1]);
172 : }
173 27 : else if (sk->pubkey_algo == PUBKEY_ALGO_RSA
174 24 : || sk->pubkey_algo == PUBKEY_ALGO_RSA_E)
175 : {
176 6 : if (!enc->data[0])
177 0 : err = gpg_error (GPG_ERR_BAD_MPI);
178 : else
179 3 : err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
180 : enc->data[0]);
181 : }
182 24 : else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
183 : {
184 24 : if (!enc->data[0] || !enc->data[1])
185 0 : err = gpg_error (GPG_ERR_BAD_MPI);
186 : else
187 24 : err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
188 : enc->data[1], enc->data[0]);
189 : }
190 : else
191 0 : err = gpg_error (GPG_ERR_BUG);
192 :
193 259 : if (err)
194 0 : goto leave;
195 :
196 259 : if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
197 : {
198 24 : fingerprint_from_pk (sk, fp, &fpn);
199 24 : log_assert (fpn == 20);
200 : }
201 :
202 : /* Decrypt. */
203 259 : desc = gpg_format_keydesc (sk, FORMAT_KEYDESC_NORMAL, 1);
204 777 : err = agent_pkdecrypt (NULL, keygrip,
205 518 : desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
206 : s_data, &frame, &nframe, &padding);
207 259 : xfree (desc);
208 259 : gcry_sexp_release (s_data);
209 259 : if (err)
210 0 : goto leave;
211 :
212 : /* Now get the DEK (data encryption key) from the frame
213 : *
214 : * Old versions encode the DEK in in this format (msb is left):
215 : *
216 : * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2
217 : *
218 : * Later versions encode the DEK like this:
219 : *
220 : * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
221 : *
222 : * (mpi_get_buffer already removed the leading zero).
223 : *
224 : * RND are non-zero randow bytes.
225 : * A is the cipher algorithm
226 : * DEK is the encryption key (session key) with length k
227 : * CSUM
228 : */
229 259 : if (DBG_CRYPTO)
230 0 : log_printhex ("DEK frame:", frame, nframe);
231 259 : n = 0;
232 :
233 259 : if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
234 : {
235 : gcry_mpi_t shared_mpi;
236 : gcry_mpi_t decoded;
237 :
238 : /* At the beginning the frame are the bytes of shared point MPI. */
239 24 : err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
240 24 : if (err)
241 : {
242 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
243 0 : goto leave;
244 : }
245 :
246 24 : err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
247 24 : shared_mpi, sk->pkey);
248 24 : mpi_release (shared_mpi);
249 24 : if(err)
250 0 : goto leave;
251 :
252 24 : xfree (frame);
253 24 : err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded);
254 24 : mpi_release (decoded);
255 24 : if (err)
256 0 : goto leave;
257 :
258 : /* Now the frame are the bytes decrypted but padded session key. */
259 :
260 : /* Allow double padding for the benefit of DEK size concealment.
261 : Higher than this is wasteful. */
262 24 : if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8
263 24 : || frame[nframe-1] > nframe)
264 : {
265 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
266 0 : goto leave;
267 : }
268 24 : nframe -= frame[nframe-1]; /* Remove padding. */
269 24 : log_assert (!n); /* (used just below) */
270 : }
271 : else
272 : {
273 235 : if (padding)
274 : {
275 235 : if (n + 7 > nframe)
276 : {
277 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
278 0 : goto leave;
279 : }
280 235 : if (frame[n] == 1 && frame[nframe - 1] == 2)
281 : {
282 0 : log_info (_("old encoding of the DEK is not supported\n"));
283 0 : err = gpg_error (GPG_ERR_CIPHER_ALGO);
284 0 : goto leave;
285 : }
286 235 : if (frame[n] != 2) /* Something went wrong. */
287 : {
288 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
289 0 : goto leave;
290 : }
291 235 : for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */
292 : ;
293 235 : n++; /* Skip the zero byte. */
294 : }
295 : }
296 :
297 259 : if (n + 4 > nframe)
298 : {
299 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
300 0 : goto leave;
301 : }
302 :
303 259 : dek->keylen = nframe - (n + 1) - 2;
304 259 : dek->algo = frame[n++];
305 259 : err = openpgp_cipher_test_algo (dek->algo);
306 259 : if (err)
307 : {
308 0 : if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
309 : {
310 0 : log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
311 : dek->algo,
312 0 : dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
313 : }
314 0 : dek->algo = 0;
315 0 : goto leave;
316 : }
317 259 : if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
318 : {
319 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
320 0 : goto leave;
321 : }
322 :
323 : /* Copy the key to DEK and compare the checksum. */
324 259 : csum = buf16_to_u16 (frame+nframe-2);
325 259 : memcpy (dek->key, frame + n, dek->keylen);
326 6715 : for (csum2 = 0, n = 0; n < dek->keylen; n++)
327 6456 : csum2 += dek->key[n];
328 259 : if (csum != csum2)
329 : {
330 0 : err = gpg_error (GPG_ERR_WRONG_SECKEY);
331 0 : goto leave;
332 : }
333 259 : if (DBG_CLOCK)
334 0 : log_clock ("decryption ready");
335 259 : if (DBG_CRYPTO)
336 0 : log_printhex ("DEK is:", dek->key, dek->keylen);
337 :
338 : /* Check that the algo is in the preferences and whether it has expired. */
339 : {
340 259 : PKT_public_key *pk = NULL;
341 259 : KBNODE pkb = get_pubkeyblock (keyid);
342 :
343 259 : if (!pkb)
344 : {
345 0 : err = -1;
346 0 : log_error ("oops: public key not found for preference check\n");
347 : }
348 259 : else if (pkb->pkt->pkt.public_key->selfsigversion > 3
349 259 : && dek->algo != CIPHER_ALGO_3DES
350 240 : && !opt.quiet
351 240 : && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
352 91 : log_info (_("WARNING: cipher algorithm %s not found in recipient"
353 91 : " preferences\n"), openpgp_cipher_algo_name (dek->algo));
354 259 : if (!err)
355 : {
356 : KBNODE k;
357 :
358 1045 : for (k = pkb; k; k = k->next)
359 : {
360 1045 : if (k->pkt->pkttype == PKT_PUBLIC_KEY
361 786 : || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
362 : {
363 : u32 aki[2];
364 518 : keyid_from_pk (k->pkt->pkt.public_key, aki);
365 :
366 518 : if (aki[0] == keyid[0] && aki[1] == keyid[1])
367 : {
368 259 : pk = k->pkt->pkt.public_key;
369 259 : break;
370 : }
371 : }
372 : }
373 259 : if (!pk)
374 0 : BUG ();
375 259 : if (pk->expiredate && pk->expiredate <= make_timestamp ())
376 : {
377 0 : log_info (_("Note: secret key %s expired at %s\n"),
378 : keystr (keyid), asctimestamp (pk->expiredate));
379 : }
380 : }
381 :
382 259 : if (pk && pk->flags.revoked)
383 : {
384 0 : log_info (_("Note: key has been revoked"));
385 0 : log_printf ("\n");
386 0 : show_revocation_reason (pk, 1);
387 : }
388 :
389 259 : release_kbnode (pkb);
390 259 : err = 0;
391 : }
392 :
393 : leave:
394 259 : xfree (frame);
395 259 : xfree (keygrip);
396 259 : return err;
397 : }
398 :
399 :
400 : /*
401 : * Get the session key from the given string.
402 : * String is supposed to be formatted as this:
403 : * <algo-id>:<even-number-of-hex-digits>
404 : */
405 : gpg_error_t
406 0 : get_override_session_key (DEK *dek, const char *string)
407 : {
408 : const char *s;
409 : int i;
410 :
411 0 : if (!string)
412 0 : return GPG_ERR_BAD_KEY;
413 0 : dek->algo = atoi (string);
414 0 : if (dek->algo < 1)
415 0 : return GPG_ERR_BAD_KEY;
416 0 : if (!(s = strchr (string, ':')))
417 0 : return GPG_ERR_BAD_KEY;
418 0 : s++;
419 0 : for (i = 0; i < DIM (dek->key) && *s; i++, s += 2)
420 : {
421 0 : int c = hextobyte (s);
422 0 : if (c == -1)
423 0 : return GPG_ERR_BAD_KEY;
424 0 : dek->key[i] = c;
425 : }
426 0 : if (*s)
427 0 : return GPG_ERR_BAD_KEY;
428 0 : dek->keylen = i;
429 0 : return 0;
430 : }
|