Line data Source code
1 : /* protect.c - Un/Protect a secret key
2 : * Copyright (C) 1998-2003, 2007, 2009, 2011 Free Software Foundation, Inc.
3 : * Copyright (C) 1998-2003, 2007, 2009, 2011, 2013-2015 Werner Koch
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 <https://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <errno.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <ctype.h>
27 : #include <assert.h>
28 : #include <unistd.h>
29 : #include <sys/stat.h>
30 : #ifdef HAVE_W32_SYSTEM
31 : # ifdef HAVE_WINSOCK2_H
32 : # include <winsock2.h>
33 : # endif
34 : # include <windows.h>
35 : #else
36 : # include <sys/times.h>
37 : #endif
38 :
39 : #include "agent.h"
40 :
41 : #include "cvt-openpgp.h"
42 : #include "sexp-parse.h"
43 :
44 :
45 : /* To use the openpgp-s2k3-ocb-aes scheme by default set the value of
46 : * this macro to 1. Note that the caller of agent_protect may
47 : * override this default. */
48 : #define PROT_DEFAULT_TO_OCB 0
49 :
50 : /* The protection mode for encryption. The supported modes for
51 : decryption are listed in agent_unprotect(). */
52 : #define PROT_CIPHER GCRY_CIPHER_AES128
53 : #define PROT_CIPHER_STRING "aes"
54 : #define PROT_CIPHER_KEYLEN (128/8)
55 :
56 : /* Decode an rfc4880 encoded S2K count. */
57 : #define S2K_DECODE_COUNT(_val) ((16ul + ((_val) & 15)) << (((_val) >> 4) + 6))
58 :
59 :
60 : /* A table containing the information needed to create a protected
61 : private key. */
62 : static struct {
63 : const char *algo;
64 : const char *parmlist;
65 : int prot_from, prot_to;
66 : int ecc_hack;
67 : } protect_info[] = {
68 : { "rsa", "nedpqu", 2, 5 },
69 : { "dsa", "pqgyx", 4, 4 },
70 : { "elg", "pgyx", 3, 3 },
71 : { "ecdsa","pabgnqd", 6, 6, 1 },
72 : { "ecdh", "pabgnqd", 6, 6, 1 },
73 : { "ecc", "pabgnqd", 6, 6, 1 },
74 : { NULL }
75 : };
76 :
77 :
78 : /* A helper object for time measurement. */
79 : struct calibrate_time_s
80 : {
81 : #ifdef HAVE_W32_SYSTEM
82 : FILETIME creation_time, exit_time, kernel_time, user_time;
83 : #else
84 : clock_t ticks;
85 : #endif
86 : };
87 :
88 :
89 : static int
90 : hash_passphrase (const char *passphrase, int hashalgo,
91 : int s2kmode,
92 : const unsigned char *s2ksalt, unsigned long s2kcount,
93 : unsigned char *key, size_t keylen);
94 :
95 :
96 :
97 :
98 : /* Get the process time and store it in DATA. */
99 : static void
100 120 : calibrate_get_time (struct calibrate_time_s *data)
101 : {
102 : #ifdef HAVE_W32_SYSTEM
103 : # ifdef HAVE_W32CE_SYSTEM
104 : GetThreadTimes (GetCurrentThread (),
105 : &data->creation_time, &data->exit_time,
106 : &data->kernel_time, &data->user_time);
107 : # else
108 : GetProcessTimes (GetCurrentProcess (),
109 : &data->creation_time, &data->exit_time,
110 : &data->kernel_time, &data->user_time);
111 : # endif
112 : #else
113 : struct tms tmp;
114 :
115 120 : times (&tmp);
116 120 : data->ticks = tmp.tms_utime;
117 : #endif
118 120 : }
119 :
120 :
121 : static unsigned long
122 60 : calibrate_elapsed_time (struct calibrate_time_s *starttime)
123 : {
124 : struct calibrate_time_s stoptime;
125 :
126 60 : calibrate_get_time (&stoptime);
127 : #ifdef HAVE_W32_SYSTEM
128 : {
129 : unsigned long long t1, t2;
130 :
131 : t1 = (((unsigned long long)starttime->kernel_time.dwHighDateTime << 32)
132 : + starttime->kernel_time.dwLowDateTime);
133 : t1 += (((unsigned long long)starttime->user_time.dwHighDateTime << 32)
134 : + starttime->user_time.dwLowDateTime);
135 : t2 = (((unsigned long long)stoptime.kernel_time.dwHighDateTime << 32)
136 : + stoptime.kernel_time.dwLowDateTime);
137 : t2 += (((unsigned long long)stoptime.user_time.dwHighDateTime << 32)
138 : + stoptime.user_time.dwLowDateTime);
139 : return (unsigned long)((t2 - t1)/10000);
140 : }
141 : #else
142 120 : return (unsigned long)((((double) (stoptime.ticks - starttime->ticks))
143 60 : /CLOCKS_PER_SEC)*10000000);
144 : #endif
145 : }
146 :
147 :
148 : /* Run a test hashing for COUNT and return the time required in
149 : milliseconds. */
150 : static unsigned long
151 60 : calibrate_s2k_count_one (unsigned long count)
152 : {
153 : int rc;
154 : char keybuf[PROT_CIPHER_KEYLEN];
155 : struct calibrate_time_s starttime;
156 :
157 60 : calibrate_get_time (&starttime);
158 60 : rc = hash_passphrase ("123456789abcdef0", GCRY_MD_SHA1,
159 : 3, "saltsalt", count, keybuf, sizeof keybuf);
160 60 : if (rc)
161 0 : BUG ();
162 60 : return calibrate_elapsed_time (&starttime);
163 : }
164 :
165 :
166 : /* Measure the time we need to do the hash operations and deduce an
167 : S2K count which requires about 100ms of time. */
168 : static unsigned long
169 6 : calibrate_s2k_count (void)
170 : {
171 : unsigned long count;
172 : unsigned long ms;
173 :
174 60 : for (count = 65536; count; count *= 2)
175 : {
176 60 : ms = calibrate_s2k_count_one (count);
177 60 : if (opt.verbose > 1)
178 0 : log_info ("S2K calibration: %lu -> %lums\n", count, ms);
179 60 : if (ms > 100)
180 6 : break;
181 : }
182 :
183 6 : count = (unsigned long)(((double)count / ms) * 100);
184 6 : count /= 1024;
185 6 : count *= 1024;
186 6 : if (count < 65536)
187 0 : count = 65536;
188 :
189 6 : if (opt.verbose)
190 : {
191 0 : ms = calibrate_s2k_count_one (count);
192 0 : log_info ("S2K calibration: %lu -> %lums\n", count, ms);
193 : }
194 :
195 6 : return count;
196 : }
197 :
198 :
199 :
200 : /* Return the standard S2K count. */
201 : unsigned long
202 33 : get_standard_s2k_count (void)
203 : {
204 : static unsigned long count;
205 :
206 33 : if (!count)
207 6 : count = calibrate_s2k_count ();
208 :
209 : /* Enforce a lower limit. */
210 33 : return count < 65536 ? 65536 : count;
211 : }
212 :
213 :
214 : /* Same as get_standard_s2k_count but return the count in the encoding
215 : as described by rfc4880. */
216 : unsigned char
217 2 : get_standard_s2k_count_rfc4880 (void)
218 : {
219 : unsigned long iterations;
220 : unsigned int count;
221 : unsigned char result;
222 2 : unsigned char c=0;
223 :
224 2 : iterations = get_standard_s2k_count ();
225 2 : if (iterations >= 65011712)
226 0 : return 255;
227 :
228 : /* Need count to be in the range 16-31 */
229 30 : for (count=iterations>>6; count>=32; count>>=1)
230 28 : c++;
231 :
232 2 : result = (c<<4)|(count-16);
233 :
234 2 : if (S2K_DECODE_COUNT(result) < iterations)
235 2 : result++;
236 :
237 2 : return result;
238 :
239 : }
240 :
241 :
242 :
243 : /* Calculate the MIC for a private key or shared secret S-expression.
244 : SHA1HASH should point to a 20 byte buffer. This function is
245 : suitable for all algorithms. */
246 : static int
247 139 : calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
248 : {
249 : const unsigned char *hash_begin, *hash_end;
250 : const unsigned char *s;
251 : size_t n;
252 : int is_shared_secret;
253 :
254 139 : s = plainkey;
255 139 : if (*s != '(')
256 0 : return gpg_error (GPG_ERR_INV_SEXP);
257 139 : s++;
258 139 : n = snext (&s);
259 139 : if (!n)
260 0 : return gpg_error (GPG_ERR_INV_SEXP);
261 139 : if (smatch (&s, n, "private-key"))
262 139 : is_shared_secret = 0;
263 0 : else if (smatch (&s, n, "shared-secret"))
264 0 : is_shared_secret = 1;
265 : else
266 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
267 139 : if (*s != '(')
268 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
269 139 : hash_begin = s;
270 139 : if (!is_shared_secret)
271 : {
272 139 : s++;
273 139 : n = snext (&s);
274 139 : if (!n)
275 0 : return gpg_error (GPG_ERR_INV_SEXP);
276 139 : s += n; /* Skip the algorithm name. */
277 : }
278 :
279 1030 : while (*s == '(')
280 : {
281 752 : s++;
282 752 : n = snext (&s);
283 752 : if (!n)
284 0 : return gpg_error (GPG_ERR_INV_SEXP);
285 752 : s += n;
286 752 : n = snext (&s);
287 752 : if (!n)
288 0 : return gpg_error (GPG_ERR_INV_SEXP);
289 752 : s += n;
290 752 : if ( *s != ')' )
291 0 : return gpg_error (GPG_ERR_INV_SEXP);
292 752 : s++;
293 : }
294 139 : if (*s != ')')
295 0 : return gpg_error (GPG_ERR_INV_SEXP);
296 139 : s++;
297 139 : hash_end = s;
298 :
299 139 : gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash,
300 139 : hash_begin, hash_end - hash_begin);
301 :
302 139 : return 0;
303 : }
304 :
305 :
306 :
307 : /* Encrypt the parameter block starting at PROTBEGIN with length
308 : PROTLEN using the utf8 encoded key PASSPHRASE and return the entire
309 : encrypted block in RESULT or return with an error code. SHA1HASH
310 : is the 20 byte SHA-1 hash required for the integrity code.
311 :
312 : The parameter block is expected to be an incomplete canonical
313 : encoded S-Expression of the form (example in advanced format):
314 :
315 : (d #046129F..[some bytes not shown]..81#)
316 : (p #00e861b..[some bytes not shown]..f1#)
317 : (q #00f7a7c..[some bytes not shown]..61#)
318 : (u #304559a..[some bytes not shown]..9b#)
319 :
320 : the returned block is the S-Expression:
321 :
322 : (protected mode (parms) encrypted_octet_string)
323 :
324 : */
325 : static int
326 14 : do_encryption (const unsigned char *hashbegin, size_t hashlen,
327 : const unsigned char *protbegin, size_t protlen,
328 : const char *passphrase,
329 : const char *timestamp_exp, size_t timestamp_exp_len,
330 : unsigned char **result, size_t *resultlen,
331 : unsigned long s2k_count, int use_ocb)
332 : {
333 : gcry_cipher_hd_t hd;
334 : const char *modestr;
335 : unsigned char hashvalue[20];
336 : int blklen, enclen, outlen;
337 14 : unsigned char *iv = NULL;
338 : unsigned int ivsize; /* Size of the buffer allocated for IV. */
339 : const unsigned char *s2ksalt; /* Points into IV. */
340 : int rc;
341 14 : char *outbuf = NULL;
342 : char *p;
343 : int saltpos, ivpos, encpos;
344 :
345 14 : s2ksalt = iv; /* Silence compiler warning. */
346 :
347 14 : *resultlen = 0;
348 14 : *result = NULL;
349 :
350 14 : modestr = (use_ocb? "openpgp-s2k3-ocb-aes"
351 14 : /* */: "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc");
352 :
353 14 : rc = gcry_cipher_open (&hd, PROT_CIPHER,
354 : use_ocb? GCRY_CIPHER_MODE_OCB :
355 : GCRY_CIPHER_MODE_CBC,
356 : GCRY_CIPHER_SECURE);
357 14 : if (rc)
358 0 : return rc;
359 :
360 : /* We need to work on a copy of the data because this makes it
361 : * easier to add the trailer and the padding and more important we
362 : * have to prefix the text with 2 parenthesis. In CBC mode we
363 : * have to allocate enough space for:
364 : *
365 : * ((<parameter_list>)(4:hash4:sha120:<hashvalue>)) + padding
366 : *
367 : * we always append a full block of random bytes as padding but
368 : * encrypt only what is needed for a full blocksize. In OCB mode we
369 : * have to allocate enough space for just:
370 : *
371 : * ((<parameter_list>))
372 : */
373 14 : blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
374 14 : if (use_ocb)
375 : {
376 : /* (( )) */
377 0 : outlen = 2 + protlen + 2 ;
378 0 : enclen = outlen + 16 /* taglen */;
379 0 : outbuf = gcry_malloc_secure (enclen);
380 : }
381 : else
382 : {
383 : /* (( )( 4:hash 4:sha1 20:<hash> )) <padding> */
384 14 : outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen;
385 14 : enclen = outlen/blklen * blklen;
386 14 : outbuf = gcry_malloc_secure (outlen);
387 : }
388 14 : if (!outbuf)
389 0 : rc = out_of_core ();
390 :
391 : /* Allocate a buffer for the nonce and the salt. */
392 14 : if (!rc)
393 : {
394 : /* Allocate random bytes to be used as IV, padding and s2k salt
395 : * or in OCB mode for a nonce and the s2k salt. The IV/nonce is
396 : * set later because for OCB we need to set the key first. */
397 14 : ivsize = (use_ocb? 12 : (blklen*2)) + 8;
398 14 : iv = xtrymalloc (ivsize);
399 14 : if (!iv)
400 0 : rc = gpg_error_from_syserror ();
401 : else
402 : {
403 14 : gcry_create_nonce (iv, ivsize);
404 14 : s2ksalt = iv + ivsize - 8;
405 : }
406 : }
407 :
408 : /* Hash the passphrase and set the key. */
409 14 : if (!rc)
410 : {
411 : unsigned char *key;
412 14 : size_t keylen = PROT_CIPHER_KEYLEN;
413 :
414 14 : key = gcry_malloc_secure (keylen);
415 14 : if (!key)
416 0 : rc = out_of_core ();
417 : else
418 : {
419 14 : rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
420 : 3, s2ksalt,
421 : s2k_count? s2k_count:get_standard_s2k_count(),
422 : key, keylen);
423 14 : if (!rc)
424 14 : rc = gcry_cipher_setkey (hd, key, keylen);
425 14 : xfree (key);
426 : }
427 : }
428 :
429 : /* Set the IV/nonce. */
430 14 : if (!rc)
431 : {
432 14 : rc = gcry_cipher_setiv (hd, iv, use_ocb? 12 : blklen);
433 : }
434 :
435 14 : if (use_ocb)
436 : {
437 : /* In OCB Mode we use only the public key parameters as AAD. */
438 0 : rc = gcry_cipher_authenticate (hd, hashbegin, protbegin - hashbegin);
439 0 : if (!rc)
440 0 : rc = gcry_cipher_authenticate (hd, timestamp_exp, timestamp_exp_len);
441 0 : if (!rc)
442 0 : rc = gcry_cipher_authenticate
443 0 : (hd, protbegin+protlen, hashlen - (protbegin+protlen - hashbegin));
444 :
445 : }
446 : else
447 : {
448 : /* Hash the entire expression for CBC mode. Because
449 : * TIMESTAMP_EXP won't get protected, we can't simply hash a
450 : * continuous buffer but need to call md_write several times. */
451 : gcry_md_hd_t md;
452 :
453 14 : rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 );
454 14 : if (!rc)
455 : {
456 14 : gcry_md_write (md, hashbegin, protbegin - hashbegin);
457 14 : gcry_md_write (md, protbegin, protlen);
458 14 : gcry_md_write (md, timestamp_exp, timestamp_exp_len);
459 14 : gcry_md_write (md, protbegin+protlen,
460 14 : hashlen - (protbegin+protlen - hashbegin));
461 14 : memcpy (hashvalue, gcry_md_read (md, GCRY_MD_SHA1), 20);
462 14 : gcry_md_close (md);
463 : }
464 : }
465 :
466 :
467 : /* Encrypt. */
468 14 : if (!rc)
469 : {
470 14 : p = outbuf;
471 14 : *p++ = '(';
472 14 : *p++ = '(';
473 14 : memcpy (p, protbegin, protlen);
474 14 : p += protlen;
475 14 : if (use_ocb)
476 : {
477 0 : *p++ = ')';
478 0 : *p++ = ')';
479 : }
480 : else
481 : {
482 14 : memcpy (p, ")(4:hash4:sha120:", 17);
483 14 : p += 17;
484 14 : memcpy (p, hashvalue, 20);
485 14 : p += 20;
486 14 : *p++ = ')';
487 14 : *p++ = ')';
488 14 : memcpy (p, iv+blklen, blklen); /* Add padding. */
489 14 : p += blklen;
490 : }
491 14 : assert ( p - outbuf == outlen);
492 14 : if (use_ocb)
493 : {
494 0 : gcry_cipher_final (hd);
495 0 : rc = gcry_cipher_encrypt (hd, outbuf, outlen, NULL, 0);
496 0 : if (!rc)
497 : {
498 0 : log_assert (outlen + 16 == enclen);
499 0 : rc = gcry_cipher_gettag (hd, outbuf + outlen, 16);
500 : }
501 : }
502 : else
503 : {
504 14 : rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0);
505 : }
506 : }
507 :
508 : /* Release cipher handle and check for errors. */
509 14 : gcry_cipher_close (hd);
510 14 : if (rc)
511 : {
512 0 : xfree (iv);
513 0 : xfree (outbuf);
514 0 : return rc;
515 : }
516 :
517 : /* Now allocate the buffer we want to return. This is
518 :
519 : (protected openpgp-s2k3-sha1-aes-cbc
520 : ((sha1 salt no_of_iterations) 16byte_iv)
521 : encrypted_octet_string)
522 :
523 : in canoncical format of course. We use asprintf and %n modifier
524 : and dummy values as placeholders. */
525 : {
526 : char countbuf[35];
527 :
528 14 : snprintf (countbuf, sizeof countbuf, "%lu",
529 : s2k_count ? s2k_count : get_standard_s2k_count ());
530 42 : p = xtryasprintf
531 : ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)",
532 14 : (int)strlen (modestr), modestr,
533 : &saltpos,
534 14 : (unsigned int)strlen (countbuf), countbuf,
535 : use_ocb? 12 : blklen, &ivpos, use_ocb? 12 : blklen, "",
536 : enclen, &encpos, enclen, "");
537 14 : if (!p)
538 : {
539 0 : gpg_error_t tmperr = out_of_core ();
540 0 : xfree (iv);
541 0 : xfree (outbuf);
542 0 : return tmperr;
543 : }
544 :
545 : }
546 14 : *resultlen = strlen (p);
547 14 : *result = (unsigned char*)p;
548 14 : memcpy (p+saltpos, s2ksalt, 8);
549 14 : memcpy (p+ivpos, iv, use_ocb? 12 : blklen);
550 14 : memcpy (p+encpos, outbuf, enclen);
551 14 : xfree (iv);
552 14 : xfree (outbuf);
553 14 : return 0;
554 : }
555 :
556 :
557 :
558 : /* Protect the key encoded in canonical format in PLAINKEY. We assume
559 : a valid S-Exp here. With USE_UCB set to -1 the default scheme is
560 : used (ie. either CBC or OCB), set to 0 the old CBC mode is used,
561 : and set to 1 OCB is used. */
562 : int
563 17 : agent_protect (const unsigned char *plainkey, const char *passphrase,
564 : unsigned char **result, size_t *resultlen,
565 : unsigned long s2k_count, int use_ocb)
566 : {
567 : int rc;
568 : const char *parmlist;
569 : int prot_from_idx, prot_to_idx;
570 : const unsigned char *s;
571 : const unsigned char *hash_begin, *hash_end;
572 : const unsigned char *prot_begin, *prot_end, *real_end;
573 : size_t n;
574 : int c, infidx, i;
575 : char timestamp_exp[35];
576 : unsigned char *protected;
577 : size_t protectedlen;
578 17 : int depth = 0;
579 : unsigned char *p;
580 17 : int have_curve = 0;
581 :
582 17 : if (use_ocb == -1)
583 17 : use_ocb = PROT_DEFAULT_TO_OCB;
584 :
585 : /* Create an S-expression with the protected-at timestamp. */
586 17 : memcpy (timestamp_exp, "(12:protected-at15:", 19);
587 17 : gnupg_get_isotime (timestamp_exp+19);
588 17 : timestamp_exp[19+15] = ')';
589 :
590 : /* Parse original key. */
591 17 : s = plainkey;
592 17 : if (*s != '(')
593 1 : return gpg_error (GPG_ERR_INV_SEXP);
594 16 : depth++;
595 16 : s++;
596 16 : n = snext (&s);
597 16 : if (!n)
598 0 : return gpg_error (GPG_ERR_INV_SEXP);
599 16 : if (!smatch (&s, n, "private-key"))
600 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
601 16 : if (*s != '(')
602 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
603 16 : depth++;
604 16 : hash_begin = s;
605 16 : s++;
606 16 : n = snext (&s);
607 16 : if (!n)
608 0 : return gpg_error (GPG_ERR_INV_SEXP);
609 :
610 76 : for (infidx=0; protect_info[infidx].algo
611 104 : && !smatch (&s, n, protect_info[infidx].algo); infidx++)
612 : ;
613 16 : if (!protect_info[infidx].algo)
614 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
615 :
616 : /* The parser below is a complete mess: To make it robust for ECC
617 : use we should reorder the s-expression to include only what we
618 : really need and thus guarantee the right order for saving stuff.
619 : This should be done before calling this function and maybe with
620 : the help of the new gcry_sexp_extract_param. */
621 16 : parmlist = protect_info[infidx].parmlist;
622 16 : prot_from_idx = protect_info[infidx].prot_from;
623 16 : prot_to_idx = protect_info[infidx].prot_to;
624 16 : prot_begin = prot_end = NULL;
625 80 : for (i=0; (c=parmlist[i]); i++)
626 : {
627 65 : if (i == prot_from_idx)
628 15 : prot_begin = s;
629 65 : if (*s != '(')
630 0 : return gpg_error (GPG_ERR_INV_SEXP);
631 65 : depth++;
632 65 : s++;
633 65 : n = snext (&s);
634 65 : if (!n)
635 0 : return gpg_error (GPG_ERR_INV_SEXP);
636 65 : if (n != 1 || c != *s)
637 : {
638 11 : if (n == 5 && !memcmp (s, "curve", 5)
639 9 : && !i && protect_info[infidx].ecc_hack)
640 : {
641 : /* This is a private ECC key but the first parameter is
642 : the name of the curve. We change the parameter list
643 : here to the one we expect in this case. */
644 9 : have_curve = 1;
645 9 : parmlist = "?qd";
646 9 : prot_from_idx = 2;
647 9 : prot_to_idx = 2;
648 : }
649 2 : else if (n == 5 && !memcmp (s, "flags", 5)
650 1 : && i == 1 && have_curve)
651 : {
652 : /* "curve" followed by "flags": Change again. */
653 1 : parmlist = "??qd";
654 1 : prot_from_idx = 3;
655 1 : prot_to_idx = 3;
656 : }
657 : else
658 1 : return gpg_error (GPG_ERR_INV_SEXP);
659 : }
660 64 : s += n;
661 64 : n = snext (&s);
662 64 : if (!n)
663 0 : return gpg_error (GPG_ERR_INV_SEXP);
664 64 : s +=n; /* skip value */
665 64 : if (*s != ')')
666 0 : return gpg_error (GPG_ERR_INV_SEXP);
667 64 : depth--;
668 64 : if (i == prot_to_idx)
669 15 : prot_end = s;
670 64 : s++;
671 : }
672 15 : if (*s != ')' || !prot_begin || !prot_end )
673 0 : return gpg_error (GPG_ERR_INV_SEXP);
674 15 : depth--;
675 15 : hash_end = s;
676 15 : s++;
677 : /* Skip to the end of the S-expression. */
678 15 : assert (depth == 1);
679 15 : rc = sskip (&s, &depth);
680 15 : if (rc)
681 1 : return rc;
682 14 : assert (!depth);
683 14 : real_end = s-1;
684 :
685 14 : rc = do_encryption (hash_begin, hash_end - hash_begin + 1,
686 14 : prot_begin, prot_end - prot_begin + 1,
687 : passphrase, timestamp_exp, sizeof (timestamp_exp),
688 : &protected, &protectedlen, s2k_count, use_ocb);
689 14 : if (rc)
690 0 : return rc;
691 :
692 : /* Now create the protected version of the key. Note that the 10
693 : extra bytes are for for the inserted "protected-" string (the
694 : beginning of the plaintext reads: "((11:private-key(" ). The 35
695 : term is the space for (12:protected-at15:<timestamp>). */
696 14 : *resultlen = (10
697 14 : + (prot_begin-plainkey)
698 14 : + protectedlen
699 : + 35
700 14 : + (real_end-prot_end));
701 14 : *result = p = xtrymalloc (*resultlen);
702 14 : if (!p)
703 : {
704 0 : gpg_error_t tmperr = out_of_core ();
705 0 : xfree (protected);
706 0 : return tmperr;
707 : }
708 14 : memcpy (p, "(21:protected-", 14);
709 14 : p += 14;
710 14 : memcpy (p, plainkey+4, prot_begin - plainkey - 4);
711 14 : p += prot_begin - plainkey - 4;
712 14 : memcpy (p, protected, protectedlen);
713 14 : p += protectedlen;
714 :
715 14 : memcpy (p, timestamp_exp, 35);
716 14 : p += 35;
717 :
718 14 : memcpy (p, prot_end+1, real_end - prot_end);
719 14 : p += real_end - prot_end;
720 14 : assert ( p - *result == *resultlen);
721 14 : xfree (protected);
722 :
723 14 : return 0;
724 : }
725 :
726 :
727 :
728 : /* Do the actual decryption and check the return list for consistency. */
729 : static int
730 139 : do_decryption (const unsigned char *aad_begin, size_t aad_len,
731 : const unsigned char *aadhole_begin, size_t aadhole_len,
732 : const unsigned char *protected, size_t protectedlen,
733 : const char *passphrase,
734 : const unsigned char *s2ksalt, unsigned long s2kcount,
735 : const unsigned char *iv, size_t ivlen,
736 : int prot_cipher, int prot_cipher_keylen, int is_ocb,
737 : unsigned char **result)
738 : {
739 139 : int rc = 0;
740 : int blklen;
741 : gcry_cipher_hd_t hd;
742 : unsigned char *outbuf;
743 : size_t reallen;
744 :
745 139 : blklen = gcry_cipher_get_algo_blklen (prot_cipher);
746 139 : if (is_ocb)
747 : {
748 : /* OCB does not require a multiple of the block length but we
749 : * check that it is long enough for the 128 bit tag and that we
750 : * have the 96 bit nonce. */
751 0 : if (protectedlen < (4 + 16) || ivlen != 12)
752 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
753 : }
754 : else
755 : {
756 139 : if (protectedlen < 4 || (protectedlen%blklen))
757 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
758 : }
759 :
760 139 : rc = gcry_cipher_open (&hd, prot_cipher,
761 : is_ocb? GCRY_CIPHER_MODE_OCB :
762 : GCRY_CIPHER_MODE_CBC,
763 : GCRY_CIPHER_SECURE);
764 139 : if (rc)
765 0 : return rc;
766 :
767 139 : outbuf = gcry_malloc_secure (protectedlen);
768 139 : if (!outbuf)
769 0 : rc = out_of_core ();
770 :
771 : /* Hash the passphrase and set the key. */
772 139 : if (!rc)
773 : {
774 : unsigned char *key;
775 :
776 139 : key = gcry_malloc_secure (prot_cipher_keylen);
777 139 : if (!key)
778 0 : rc = out_of_core ();
779 : else
780 : {
781 139 : rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
782 : 3, s2ksalt, s2kcount, key, prot_cipher_keylen);
783 139 : if (!rc)
784 139 : rc = gcry_cipher_setkey (hd, key, prot_cipher_keylen);
785 139 : xfree (key);
786 : }
787 : }
788 :
789 : /* Set the IV/nonce. */
790 139 : if (!rc)
791 : {
792 139 : rc = gcry_cipher_setiv (hd, iv, ivlen);
793 : }
794 :
795 : /* Decrypt. */
796 139 : if (!rc)
797 : {
798 139 : if (is_ocb)
799 : {
800 0 : rc = gcry_cipher_authenticate (hd, aad_begin,
801 0 : aadhole_begin - aad_begin);
802 0 : if (!rc)
803 0 : rc = gcry_cipher_authenticate
804 : (hd, aadhole_begin + aadhole_len,
805 0 : aad_len - (aadhole_begin+aadhole_len - aad_begin));
806 :
807 0 : if (!rc)
808 : {
809 0 : gcry_cipher_final (hd);
810 0 : rc = gcry_cipher_decrypt (hd, outbuf, protectedlen - 16,
811 : protected, protectedlen - 16);
812 : }
813 0 : if (!rc)
814 0 : rc = gcry_cipher_checktag (hd, protected + protectedlen - 16, 16);
815 : }
816 : else
817 : {
818 139 : rc = gcry_cipher_decrypt (hd, outbuf, protectedlen,
819 : protected, protectedlen);
820 : }
821 : }
822 :
823 : /* Release cipher handle and check for errors. */
824 139 : gcry_cipher_close (hd);
825 139 : if (rc)
826 : {
827 0 : xfree (outbuf);
828 0 : return rc;
829 : }
830 :
831 : /* Do a quick check on the data structure. */
832 139 : if (*outbuf != '(' && outbuf[1] != '(')
833 : {
834 : /* Note that in OCB mode this is actually invalid _encrypted_
835 : * data and not a bad passphrase. */
836 0 : xfree (outbuf);
837 0 : return gpg_error (GPG_ERR_BAD_PASSPHRASE);
838 : }
839 :
840 : /* Check that we have a consistent S-Exp. */
841 139 : reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL);
842 139 : if (!reallen || (reallen + blklen < protectedlen) )
843 : {
844 0 : xfree (outbuf);
845 0 : return gpg_error (GPG_ERR_BAD_PASSPHRASE);
846 : }
847 139 : *result = outbuf;
848 139 : return 0;
849 : }
850 :
851 :
852 : /* Merge the parameter list contained in CLEARTEXT with the original
853 : * protect lists PROTECTEDKEY by replacing the list at REPLACEPOS.
854 : * Return the new list in RESULT and the MIC value in the 20 byte
855 : * buffer SHA1HASH; if SHA1HASH is NULL no MIC will be computed.
856 : * CUTOFF and CUTLEN will receive the offset and the length of the
857 : * resulting list which should go into the MIC calculation but then be
858 : * removed. */
859 : static int
860 139 : merge_lists (const unsigned char *protectedkey,
861 : size_t replacepos,
862 : const unsigned char *cleartext,
863 : unsigned char *sha1hash,
864 : unsigned char **result, size_t *resultlen,
865 : size_t *cutoff, size_t *cutlen)
866 : {
867 : size_t n, newlistlen;
868 : unsigned char *newlist, *p;
869 : const unsigned char *s;
870 : const unsigned char *startpos, *endpos;
871 : int i, rc;
872 :
873 139 : *result = NULL;
874 139 : *resultlen = 0;
875 139 : *cutoff = 0;
876 139 : *cutlen = 0;
877 :
878 139 : if (replacepos < 26)
879 0 : return gpg_error (GPG_ERR_BUG);
880 :
881 : /* Estimate the required size of the resulting list. We have a large
882 : safety margin of >20 bytes (FIXME: MIC hash from CLEARTEXT and the
883 : removed "protected-" */
884 139 : newlistlen = gcry_sexp_canon_len (protectedkey, 0, NULL, NULL);
885 139 : if (!newlistlen)
886 0 : return gpg_error (GPG_ERR_BUG);
887 139 : n = gcry_sexp_canon_len (cleartext, 0, NULL, NULL);
888 139 : if (!n)
889 0 : return gpg_error (GPG_ERR_BUG);
890 139 : newlistlen += n;
891 139 : newlist = gcry_malloc_secure (newlistlen);
892 139 : if (!newlist)
893 0 : return out_of_core ();
894 :
895 : /* Copy the initial segment */
896 139 : strcpy ((char*)newlist, "(11:private-key");
897 139 : p = newlist + 15;
898 139 : memcpy (p, protectedkey+15+10, replacepos-15-10);
899 139 : p += replacepos-15-10;
900 :
901 : /* Copy the cleartext. */
902 139 : s = cleartext;
903 139 : if (*s != '(' && s[1] != '(')
904 0 : return gpg_error (GPG_ERR_BUG); /*we already checked this */
905 139 : s += 2;
906 139 : startpos = s;
907 432 : while ( *s == '(' )
908 : {
909 154 : s++;
910 154 : n = snext (&s);
911 154 : if (!n)
912 0 : goto invalid_sexp;
913 154 : s += n;
914 154 : n = snext (&s);
915 154 : if (!n)
916 0 : goto invalid_sexp;
917 154 : s += n;
918 154 : if ( *s != ')' )
919 0 : goto invalid_sexp;
920 154 : s++;
921 : }
922 139 : if ( *s != ')' )
923 0 : goto invalid_sexp;
924 139 : endpos = s;
925 139 : s++;
926 :
927 : /* Intermezzo: Get the MIC if requested. */
928 139 : if (sha1hash)
929 : {
930 139 : if (*s != '(')
931 0 : goto invalid_sexp;
932 139 : s++;
933 139 : n = snext (&s);
934 139 : if (!smatch (&s, n, "hash"))
935 0 : goto invalid_sexp;
936 139 : n = snext (&s);
937 139 : if (!smatch (&s, n, "sha1"))
938 0 : goto invalid_sexp;
939 139 : n = snext (&s);
940 139 : if (n != 20)
941 0 : goto invalid_sexp;
942 139 : memcpy (sha1hash, s, 20);
943 139 : s += n;
944 139 : if (*s != ')')
945 0 : goto invalid_sexp;
946 : }
947 :
948 : /* Append the parameter list. */
949 139 : memcpy (p, startpos, endpos - startpos);
950 139 : p += endpos - startpos;
951 :
952 : /* Skip over the protected list element in the original list. */
953 139 : s = protectedkey + replacepos;
954 139 : assert (*s == '(');
955 139 : s++;
956 139 : i = 1;
957 139 : rc = sskip (&s, &i);
958 139 : if (rc)
959 0 : goto failure;
960 : /* Record the position of the optional protected-at expression. */
961 139 : if (*s == '(')
962 : {
963 139 : const unsigned char *save_s = s;
964 139 : s++;
965 139 : n = snext (&s);
966 139 : if (smatch (&s, n, "protected-at"))
967 : {
968 139 : i = 1;
969 139 : rc = sskip (&s, &i);
970 139 : if (rc)
971 0 : goto failure;
972 139 : *cutlen = s - save_s;
973 : }
974 139 : s = save_s;
975 : }
976 139 : startpos = s;
977 139 : i = 2; /* we are inside this level */
978 139 : rc = sskip (&s, &i);
979 139 : if (rc)
980 0 : goto failure;
981 139 : assert (s[-1] == ')');
982 139 : endpos = s; /* one behind the end of the list */
983 :
984 : /* Append the rest. */
985 139 : if (*cutlen)
986 139 : *cutoff = p - newlist;
987 139 : memcpy (p, startpos, endpos - startpos);
988 139 : p += endpos - startpos;
989 :
990 :
991 : /* ready */
992 139 : *result = newlist;
993 139 : *resultlen = newlistlen;
994 139 : return 0;
995 :
996 : failure:
997 0 : wipememory (newlist, newlistlen);
998 0 : xfree (newlist);
999 0 : return rc;
1000 :
1001 : invalid_sexp:
1002 0 : wipememory (newlist, newlistlen);
1003 0 : xfree (newlist);
1004 0 : return gpg_error (GPG_ERR_INV_SEXP);
1005 : }
1006 :
1007 :
1008 :
1009 : /* Unprotect the key encoded in canonical format. We assume a valid
1010 : S-Exp here. If a protected-at item is available, its value will
1011 : be stored at protected_at unless this is NULL. */
1012 : int
1013 147 : agent_unprotect (ctrl_t ctrl,
1014 : const unsigned char *protectedkey, const char *passphrase,
1015 : gnupg_isotime_t protected_at,
1016 : unsigned char **result, size_t *resultlen)
1017 : {
1018 : static struct {
1019 : const char *name; /* Name of the protection method. */
1020 : int algo; /* (A zero indicates the "openpgp-native" hack.) */
1021 : int keylen; /* Used key length in bytes. */
1022 : unsigned int is_ocb:1;
1023 : } algotable[] = {
1024 : { "openpgp-s2k3-sha1-aes-cbc", GCRY_CIPHER_AES128, (128/8)},
1025 : { "openpgp-s2k3-sha1-aes256-cbc", GCRY_CIPHER_AES256, (256/8)},
1026 : { "openpgp-s2k3-ocb-aes", GCRY_CIPHER_AES128, (128/8), 1},
1027 : { "openpgp-native", 0, 0 }
1028 : };
1029 : int rc;
1030 : const unsigned char *s;
1031 : const unsigned char *protect_list;
1032 : size_t n;
1033 : int infidx, i;
1034 : unsigned char sha1hash[20], sha1hash2[20];
1035 : const unsigned char *s2ksalt;
1036 : unsigned long s2kcount;
1037 : const unsigned char *iv;
1038 : int prot_cipher, prot_cipher_keylen;
1039 : int is_ocb;
1040 : const unsigned char *aad_begin, *aad_end, *aadhole_begin, *aadhole_end;
1041 : const unsigned char *prot_begin;
1042 : unsigned char *cleartext;
1043 : unsigned char *final;
1044 : size_t finallen;
1045 : size_t cutoff, cutlen;
1046 :
1047 147 : if (protected_at)
1048 2 : *protected_at = 0;
1049 :
1050 147 : s = protectedkey;
1051 147 : if (*s != '(')
1052 0 : return gpg_error (GPG_ERR_INV_SEXP);
1053 147 : s++;
1054 147 : n = snext (&s);
1055 147 : if (!n)
1056 0 : return gpg_error (GPG_ERR_INV_SEXP);
1057 147 : if (!smatch (&s, n, "protected-private-key"))
1058 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1059 147 : if (*s != '(')
1060 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1061 : {
1062 147 : aad_begin = aad_end = s;
1063 147 : aad_end++;
1064 147 : i = 1;
1065 147 : rc = sskip (&aad_end, &i);
1066 147 : if (rc)
1067 0 : return rc;
1068 : }
1069 :
1070 147 : s++;
1071 147 : n = snext (&s);
1072 147 : if (!n)
1073 0 : return gpg_error (GPG_ERR_INV_SEXP);
1074 :
1075 623 : for (infidx=0; protect_info[infidx].algo
1076 805 : && !smatch (&s, n, protect_info[infidx].algo); infidx++)
1077 : ;
1078 147 : if (!protect_info[infidx].algo)
1079 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
1080 :
1081 : /* See wether we have a protected-at timestamp. */
1082 147 : protect_list = s; /* Save for later. */
1083 147 : if (protected_at)
1084 : {
1085 12 : while (*s == '(')
1086 : {
1087 10 : prot_begin = s;
1088 10 : s++;
1089 10 : n = snext (&s);
1090 10 : if (!n)
1091 0 : return gpg_error (GPG_ERR_INV_SEXP);
1092 10 : if (smatch (&s, n, "protected-at"))
1093 : {
1094 2 : n = snext (&s);
1095 2 : if (!n)
1096 0 : return gpg_error (GPG_ERR_INV_SEXP);
1097 2 : if (n != 15)
1098 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1099 2 : memcpy (protected_at, s, 15);
1100 2 : protected_at[15] = 0;
1101 2 : break;
1102 : }
1103 8 : s += n;
1104 8 : i = 1;
1105 8 : rc = sskip (&s, &i);
1106 8 : if (rc)
1107 0 : return rc;
1108 : }
1109 : }
1110 :
1111 : /* Now find the list with the protected information. Here is an
1112 : example for such a list:
1113 : (protected openpgp-s2k3-sha1-aes-cbc
1114 : ((sha1 <salt> <count>) <Initialization_Vector>)
1115 : <encrypted_data>)
1116 : */
1117 147 : s = protect_list;
1118 : for (;;)
1119 : {
1120 622 : if (*s != '(')
1121 0 : return gpg_error (GPG_ERR_INV_SEXP);
1122 622 : prot_begin = s;
1123 622 : s++;
1124 622 : n = snext (&s);
1125 622 : if (!n)
1126 0 : return gpg_error (GPG_ERR_INV_SEXP);
1127 622 : if (smatch (&s, n, "protected"))
1128 147 : break;
1129 475 : s += n;
1130 475 : i = 1;
1131 475 : rc = sskip (&s, &i);
1132 475 : if (rc)
1133 0 : return rc;
1134 475 : }
1135 : /* found */
1136 : {
1137 147 : aadhole_begin = aadhole_end = prot_begin;
1138 147 : aadhole_end++;
1139 147 : i = 1;
1140 147 : rc = sskip (&aadhole_end, &i);
1141 147 : if (rc)
1142 0 : return rc;
1143 : }
1144 147 : n = snext (&s);
1145 147 : if (!n)
1146 0 : return gpg_error (GPG_ERR_INV_SEXP);
1147 :
1148 : /* Lookup the protection algo. */
1149 147 : prot_cipher = 0; /* (avoid gcc warning) */
1150 147 : prot_cipher_keylen = 0; /* (avoid gcc warning) */
1151 147 : is_ocb = 0;
1152 171 : for (i=0; i < DIM (algotable); i++)
1153 171 : if (smatch (&s, n, algotable[i].name))
1154 : {
1155 147 : prot_cipher = algotable[i].algo;
1156 147 : prot_cipher_keylen = algotable[i].keylen;
1157 147 : is_ocb = algotable[i].is_ocb;
1158 147 : break;
1159 : }
1160 147 : if (i == DIM (algotable))
1161 0 : return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
1162 :
1163 147 : if (!prot_cipher) /* This is "openpgp-native". */
1164 : {
1165 : gcry_sexp_t s_prot_begin;
1166 :
1167 8 : rc = gcry_sexp_sscan (&s_prot_begin, NULL,
1168 : prot_begin,
1169 : gcry_sexp_canon_len (prot_begin, 0,NULL,NULL));
1170 8 : if (rc)
1171 0 : return rc;
1172 :
1173 8 : rc = convert_from_openpgp_native (ctrl, s_prot_begin, passphrase, &final);
1174 8 : gcry_sexp_release (s_prot_begin);
1175 8 : if (!rc)
1176 : {
1177 8 : *result = final;
1178 8 : *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
1179 : }
1180 8 : return rc;
1181 : }
1182 :
1183 139 : if (*s != '(' || s[1] != '(')
1184 0 : return gpg_error (GPG_ERR_INV_SEXP);
1185 139 : s += 2;
1186 139 : n = snext (&s);
1187 139 : if (!n)
1188 0 : return gpg_error (GPG_ERR_INV_SEXP);
1189 139 : if (!smatch (&s, n, "sha1"))
1190 0 : return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
1191 139 : n = snext (&s);
1192 139 : if (n != 8)
1193 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1194 139 : s2ksalt = s;
1195 139 : s += n;
1196 139 : n = snext (&s);
1197 139 : if (!n)
1198 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1199 : /* We expect a list close as next, so we can simply use strtoul()
1200 : here. We might want to check that we only have digits - but this
1201 : is nothing we should worry about */
1202 139 : if (s[n] != ')' )
1203 0 : return gpg_error (GPG_ERR_INV_SEXP);
1204 :
1205 : /* Old versions of gpg-agent used the funny floating point number in
1206 : a byte encoding as specified by OpenPGP. However this is not
1207 : needed and thus we now store it as a plain unsigned integer. We
1208 : can easily distinguish the old format by looking at its value:
1209 : Less than 256 is an old-style encoded number; other values are
1210 : plain integers. In any case we check that they are at least
1211 : 65536 because we never used a lower value in the past and we
1212 : should have a lower limit. */
1213 139 : s2kcount = strtoul ((const char*)s, NULL, 10);
1214 139 : if (!s2kcount)
1215 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1216 139 : if (s2kcount < 256)
1217 0 : s2kcount = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6);
1218 139 : if (s2kcount < 65536)
1219 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1220 :
1221 139 : s += n;
1222 139 : s++; /* skip list end */
1223 :
1224 139 : n = snext (&s);
1225 139 : if (is_ocb)
1226 : {
1227 0 : if (n != 12) /* Wrong size of the nonce. */
1228 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1229 : }
1230 : else
1231 : {
1232 139 : if (n != 16) /* Wrong blocksize for IV (we support only 128 bit). */
1233 0 : return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1234 : }
1235 139 : iv = s;
1236 139 : s += n;
1237 139 : if (*s != ')' )
1238 0 : return gpg_error (GPG_ERR_INV_SEXP);
1239 139 : s++;
1240 139 : n = snext (&s);
1241 139 : if (!n)
1242 0 : return gpg_error (GPG_ERR_INV_SEXP);
1243 :
1244 139 : cleartext = NULL; /* Avoid cc warning. */
1245 278 : rc = do_decryption (aad_begin, aad_end - aad_begin,
1246 139 : aadhole_begin, aadhole_end - aadhole_begin,
1247 : s, n,
1248 : passphrase, s2ksalt, s2kcount,
1249 : iv, is_ocb? 12:16,
1250 : prot_cipher, prot_cipher_keylen, is_ocb,
1251 : &cleartext);
1252 139 : if (rc)
1253 0 : return rc;
1254 :
1255 139 : rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext,
1256 : is_ocb? NULL : sha1hash,
1257 : &final, &finallen, &cutoff, &cutlen);
1258 : /* Albeit cleartext has been allocated in secure memory and thus
1259 : xfree will wipe it out, we do an extra wipe just in case
1260 : somethings goes badly wrong. */
1261 139 : wipememory (cleartext, n);
1262 139 : xfree (cleartext);
1263 139 : if (rc)
1264 0 : return rc;
1265 :
1266 139 : if (!is_ocb)
1267 : {
1268 139 : rc = calculate_mic (final, sha1hash2);
1269 139 : if (!rc && memcmp (sha1hash, sha1hash2, 20))
1270 0 : rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
1271 139 : if (rc)
1272 : {
1273 0 : wipememory (final, finallen);
1274 0 : xfree (final);
1275 0 : return rc;
1276 : }
1277 : }
1278 :
1279 : /* Now remove the part which is included in the MIC but should not
1280 : go into the final thing. */
1281 139 : if (cutlen)
1282 : {
1283 139 : memmove (final+cutoff, final+cutoff+cutlen, finallen-cutoff-cutlen);
1284 139 : finallen -= cutlen;
1285 : }
1286 :
1287 139 : *result = final;
1288 139 : *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
1289 139 : return 0;
1290 : }
1291 :
1292 : /* Check the type of the private key, this is one of the constants:
1293 : PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
1294 : value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
1295 : PRIVATE_KEY_PROTECTED for an protected private key or
1296 : PRIVATE_KEY_SHADOWED for a sub key where the secret parts are
1297 : stored elsewhere. Finally PRIVATE_KEY_OPENPGP_NONE may be returned
1298 : is the key is still in the openpgp-native format but without
1299 : protection. */
1300 : int
1301 468 : agent_private_key_type (const unsigned char *privatekey)
1302 : {
1303 : const unsigned char *s;
1304 : size_t n;
1305 : int i;
1306 :
1307 468 : s = privatekey;
1308 468 : if (*s != '(')
1309 0 : return PRIVATE_KEY_UNKNOWN;
1310 468 : s++;
1311 468 : n = snext (&s);
1312 468 : if (!n)
1313 0 : return PRIVATE_KEY_UNKNOWN;
1314 468 : if (smatch (&s, n, "protected-private-key"))
1315 : {
1316 : /* We need to check whether this is openpgp-native protected
1317 : with the protection method "none". In that case we return a
1318 : different key type so that the caller knows that there is no
1319 : need to ask for a passphrase. */
1320 189 : if (*s != '(')
1321 0 : return PRIVATE_KEY_PROTECTED; /* Unknown sexp - assume protected. */
1322 189 : s++;
1323 189 : n = snext (&s);
1324 189 : if (!n)
1325 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1326 189 : s += n; /* Skip over the algo */
1327 :
1328 : /* Find the (protected ...) list. */
1329 : for (;;)
1330 : {
1331 787 : if (*s != '(')
1332 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1333 787 : s++;
1334 787 : n = snext (&s);
1335 787 : if (!n)
1336 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1337 787 : if (smatch (&s, n, "protected"))
1338 189 : break;
1339 598 : s += n;
1340 598 : i = 1;
1341 598 : if (sskip (&s, &i))
1342 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1343 598 : }
1344 : /* Found - Is this openpgp-native? */
1345 189 : n = snext (&s);
1346 189 : if (!n)
1347 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1348 189 : if (smatch (&s, n, "openpgp-native")) /* Yes. */
1349 : {
1350 40 : if (*s != '(')
1351 0 : return PRIVATE_KEY_UNKNOWN; /* Unknown sexp. */
1352 40 : s++;
1353 40 : n = snext (&s);
1354 40 : if (!n)
1355 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1356 40 : s += n; /* Skip over "openpgp-private-key". */
1357 : /* Find the (protection ...) list. */
1358 : for (;;)
1359 : {
1360 206 : if (*s != '(')
1361 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1362 206 : s++;
1363 206 : n = snext (&s);
1364 206 : if (!n)
1365 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1366 206 : if (smatch (&s, n, "protection"))
1367 40 : break;
1368 166 : s += n;
1369 166 : i = 1;
1370 166 : if (sskip (&s, &i))
1371 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1372 166 : }
1373 : /* Found - Is the mode "none"? */
1374 40 : n = snext (&s);
1375 40 : if (!n)
1376 0 : return PRIVATE_KEY_UNKNOWN; /* Invalid sexp. */
1377 40 : if (smatch (&s, n, "none"))
1378 4 : return PRIVATE_KEY_OPENPGP_NONE; /* Yes. */
1379 : }
1380 :
1381 185 : return PRIVATE_KEY_PROTECTED;
1382 : }
1383 279 : if (smatch (&s, n, "shadowed-private-key"))
1384 0 : return PRIVATE_KEY_SHADOWED;
1385 279 : if (smatch (&s, n, "private-key"))
1386 279 : return PRIVATE_KEY_CLEAR;
1387 0 : return PRIVATE_KEY_UNKNOWN;
1388 : }
1389 :
1390 :
1391 :
1392 : /* Transform a passphrase into a suitable key of length KEYLEN and
1393 : store this key in the caller provided buffer KEY. The caller must
1394 : provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on
1395 : that mode an S2KSALT of 8 random bytes and an S2KCOUNT.
1396 :
1397 : Returns an error code on failure. */
1398 : static int
1399 221 : hash_passphrase (const char *passphrase, int hashalgo,
1400 : int s2kmode,
1401 : const unsigned char *s2ksalt,
1402 : unsigned long s2kcount,
1403 : unsigned char *key, size_t keylen)
1404 : {
1405 : /* The key derive function does not support a zero length string for
1406 : the passphrase in the S2K modes. Return a better suited error
1407 : code than GPG_ERR_INV_DATA. */
1408 221 : if (!passphrase || !*passphrase)
1409 0 : return gpg_error (GPG_ERR_NO_PASSPHRASE);
1410 221 : return gcry_kdf_derive (passphrase, strlen (passphrase),
1411 : s2kmode == 3? GCRY_KDF_ITERSALTED_S2K :
1412 0 : s2kmode == 1? GCRY_KDF_SALTED_S2K :
1413 0 : s2kmode == 0? GCRY_KDF_SIMPLE_S2K : GCRY_KDF_NONE,
1414 : hashalgo, s2ksalt, 8, s2kcount,
1415 : keylen, key);
1416 : }
1417 :
1418 :
1419 : gpg_error_t
1420 8 : s2k_hash_passphrase (const char *passphrase, int hashalgo,
1421 : int s2kmode,
1422 : const unsigned char *s2ksalt,
1423 : unsigned int s2kcount,
1424 : unsigned char *key, size_t keylen)
1425 : {
1426 8 : return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt,
1427 8 : S2K_DECODE_COUNT (s2kcount),
1428 : key, keylen);
1429 : }
1430 :
1431 :
1432 :
1433 :
1434 : /* Create an canonical encoded S-expression with the shadow info from
1435 : a card's SERIALNO and the IDSTRING. */
1436 : unsigned char *
1437 0 : make_shadow_info (const char *serialno, const char *idstring)
1438 : {
1439 : const char *s;
1440 : char *info, *p;
1441 : char numbuf[20];
1442 : size_t n;
1443 :
1444 0 : for (s=serialno, n=0; *s && s[1]; s += 2)
1445 0 : n++;
1446 :
1447 0 : info = p = xtrymalloc (1 + sizeof numbuf + n
1448 : + sizeof numbuf + strlen (idstring) + 1 + 1);
1449 0 : if (!info)
1450 0 : return NULL;
1451 0 : *p++ = '(';
1452 0 : p = stpcpy (p, smklen (numbuf, sizeof numbuf, n, NULL));
1453 0 : for (s=serialno; *s && s[1]; s += 2)
1454 0 : *(unsigned char *)p++ = xtoi_2 (s);
1455 0 : p = stpcpy (p, smklen (numbuf, sizeof numbuf, strlen (idstring), NULL));
1456 0 : p = stpcpy (p, idstring);
1457 0 : *p++ = ')';
1458 0 : *p = 0;
1459 0 : return (unsigned char *)info;
1460 : }
1461 :
1462 :
1463 :
1464 : /* Create a shadow key from a public key. We use the shadow protocol
1465 : "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting
1466 : S-expression is returned in an allocated buffer RESULT will point
1467 : to. The input parameters are expected to be valid canonicalized
1468 : S-expressions */
1469 : int
1470 0 : agent_shadow_key (const unsigned char *pubkey,
1471 : const unsigned char *shadow_info,
1472 : unsigned char **result)
1473 : {
1474 : const unsigned char *s;
1475 : const unsigned char *point;
1476 : size_t n;
1477 0 : int depth = 0;
1478 : char *p;
1479 0 : size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
1480 0 : size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
1481 :
1482 0 : if (!pubkey_len || !shadow_info_len)
1483 0 : return gpg_error (GPG_ERR_INV_VALUE);
1484 0 : s = pubkey;
1485 0 : if (*s != '(')
1486 0 : return gpg_error (GPG_ERR_INV_SEXP);
1487 0 : depth++;
1488 0 : s++;
1489 0 : n = snext (&s);
1490 0 : if (!n)
1491 0 : return gpg_error (GPG_ERR_INV_SEXP);
1492 0 : if (!smatch (&s, n, "public-key"))
1493 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1494 0 : if (*s != '(')
1495 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1496 0 : depth++;
1497 0 : s++;
1498 0 : n = snext (&s);
1499 0 : if (!n)
1500 0 : return gpg_error (GPG_ERR_INV_SEXP);
1501 0 : s += n; /* skip over the algorithm name */
1502 :
1503 0 : while (*s != ')')
1504 : {
1505 0 : if (*s != '(')
1506 0 : return gpg_error (GPG_ERR_INV_SEXP);
1507 0 : depth++;
1508 0 : s++;
1509 0 : n = snext (&s);
1510 0 : if (!n)
1511 0 : return gpg_error (GPG_ERR_INV_SEXP);
1512 0 : s += n;
1513 0 : n = snext (&s);
1514 0 : if (!n)
1515 0 : return gpg_error (GPG_ERR_INV_SEXP);
1516 0 : s +=n; /* skip value */
1517 0 : if (*s != ')')
1518 0 : return gpg_error (GPG_ERR_INV_SEXP);
1519 0 : depth--;
1520 0 : s++;
1521 : }
1522 0 : point = s; /* insert right before the point */
1523 0 : depth--;
1524 0 : s++;
1525 0 : assert (depth == 1);
1526 :
1527 : /* Calculate required length by taking in account: the "shadowed-"
1528 : prefix, the "shadowed", "t1-v1" as well as some parenthesis */
1529 0 : n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1;
1530 0 : *result = xtrymalloc (n);
1531 0 : p = (char*)*result;
1532 0 : if (!p)
1533 0 : return out_of_core ();
1534 0 : p = stpcpy (p, "(20:shadowed-private-key");
1535 : /* (10:public-key ...)*/
1536 0 : memcpy (p, pubkey+14, point - (pubkey+14));
1537 0 : p += point - (pubkey+14);
1538 0 : p = stpcpy (p, "(8:shadowed5:t1-v1");
1539 0 : memcpy (p, shadow_info, shadow_info_len);
1540 0 : p += shadow_info_len;
1541 0 : *p++ = ')';
1542 0 : memcpy (p, point, pubkey_len - (point - pubkey));
1543 0 : p += pubkey_len - (point - pubkey);
1544 :
1545 0 : return 0;
1546 : }
1547 :
1548 : /* Parse a canonical encoded shadowed key and return a pointer to the
1549 : inner list with the shadow_info */
1550 : int
1551 0 : agent_get_shadow_info (const unsigned char *shadowkey,
1552 : unsigned char const **shadow_info)
1553 : {
1554 : const unsigned char *s;
1555 : size_t n;
1556 0 : int depth = 0;
1557 :
1558 0 : s = shadowkey;
1559 0 : if (*s != '(')
1560 0 : return gpg_error (GPG_ERR_INV_SEXP);
1561 0 : depth++;
1562 0 : s++;
1563 0 : n = snext (&s);
1564 0 : if (!n)
1565 0 : return gpg_error (GPG_ERR_INV_SEXP);
1566 0 : if (!smatch (&s, n, "shadowed-private-key"))
1567 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1568 0 : if (*s != '(')
1569 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1570 0 : depth++;
1571 0 : s++;
1572 0 : n = snext (&s);
1573 0 : if (!n)
1574 0 : return gpg_error (GPG_ERR_INV_SEXP);
1575 0 : s += n; /* skip over the algorithm name */
1576 :
1577 : for (;;)
1578 : {
1579 0 : if (*s == ')')
1580 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1581 0 : if (*s != '(')
1582 0 : return gpg_error (GPG_ERR_INV_SEXP);
1583 0 : depth++;
1584 0 : s++;
1585 0 : n = snext (&s);
1586 0 : if (!n)
1587 0 : return gpg_error (GPG_ERR_INV_SEXP);
1588 0 : if (smatch (&s, n, "shadowed"))
1589 0 : break;
1590 0 : s += n;
1591 0 : n = snext (&s);
1592 0 : if (!n)
1593 0 : return gpg_error (GPG_ERR_INV_SEXP);
1594 0 : s +=n; /* skip value */
1595 0 : if (*s != ')')
1596 0 : return gpg_error (GPG_ERR_INV_SEXP);
1597 0 : depth--;
1598 0 : s++;
1599 0 : }
1600 : /* Found the shadowed list, S points to the protocol */
1601 0 : n = snext (&s);
1602 0 : if (!n)
1603 0 : return gpg_error (GPG_ERR_INV_SEXP);
1604 0 : if (smatch (&s, n, "t1-v1"))
1605 : {
1606 0 : if (*s != '(')
1607 0 : return gpg_error (GPG_ERR_INV_SEXP);
1608 0 : *shadow_info = s;
1609 : }
1610 : else
1611 0 : return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
1612 0 : return 0;
1613 : }
1614 :
1615 :
1616 : /* Parse the canonical encoded SHADOW_INFO S-expression. On success
1617 : the hex encoded serial number is returned as a malloced strings at
1618 : R_HEXSN and the Id string as a malloced string at R_IDSTR. On
1619 : error an error code is returned and NULL is stored at the result
1620 : parameters addresses. If the serial number or the ID string is not
1621 : required, NULL may be passed for them. */
1622 : gpg_error_t
1623 0 : parse_shadow_info (const unsigned char *shadow_info,
1624 : char **r_hexsn, char **r_idstr, int *r_pinlen)
1625 : {
1626 : const unsigned char *s;
1627 : size_t n;
1628 :
1629 0 : if (r_hexsn)
1630 0 : *r_hexsn = NULL;
1631 0 : if (r_idstr)
1632 0 : *r_idstr = NULL;
1633 0 : if (r_pinlen)
1634 0 : *r_pinlen = 0;
1635 :
1636 0 : s = shadow_info;
1637 0 : if (*s != '(')
1638 0 : return gpg_error (GPG_ERR_INV_SEXP);
1639 0 : s++;
1640 0 : n = snext (&s);
1641 0 : if (!n)
1642 0 : return gpg_error (GPG_ERR_INV_SEXP);
1643 :
1644 0 : if (r_hexsn)
1645 : {
1646 0 : *r_hexsn = bin2hex (s, n, NULL);
1647 0 : if (!*r_hexsn)
1648 0 : return gpg_error_from_syserror ();
1649 : }
1650 0 : s += n;
1651 :
1652 0 : n = snext (&s);
1653 0 : if (!n)
1654 : {
1655 0 : if (r_hexsn)
1656 : {
1657 0 : xfree (*r_hexsn);
1658 0 : *r_hexsn = NULL;
1659 : }
1660 0 : return gpg_error (GPG_ERR_INV_SEXP);
1661 : }
1662 :
1663 0 : if (r_idstr)
1664 : {
1665 0 : *r_idstr = xtrymalloc (n+1);
1666 0 : if (!*r_idstr)
1667 : {
1668 0 : if (r_hexsn)
1669 : {
1670 0 : xfree (*r_hexsn);
1671 0 : *r_hexsn = NULL;
1672 : }
1673 0 : return gpg_error_from_syserror ();
1674 : }
1675 0 : memcpy (*r_idstr, s, n);
1676 0 : (*r_idstr)[n] = 0;
1677 : }
1678 :
1679 : /* Parse the optional PINLEN. */
1680 0 : n = snext (&s);
1681 0 : if (!n)
1682 0 : return 0;
1683 :
1684 0 : if (r_pinlen)
1685 : {
1686 0 : char *tmpstr = xtrymalloc (n+1);
1687 0 : if (!tmpstr)
1688 : {
1689 0 : if (r_hexsn)
1690 : {
1691 0 : xfree (*r_hexsn);
1692 0 : *r_hexsn = NULL;
1693 : }
1694 0 : if (r_idstr)
1695 : {
1696 0 : xfree (*r_idstr);
1697 0 : *r_idstr = NULL;
1698 : }
1699 0 : return gpg_error_from_syserror ();
1700 : }
1701 0 : memcpy (tmpstr, s, n);
1702 0 : tmpstr[n] = 0;
1703 :
1704 0 : *r_pinlen = (int)strtol (tmpstr, NULL, 10);
1705 0 : xfree (tmpstr);
1706 : }
1707 :
1708 0 : return 0;
1709 : }
|