Fixed a bunch of little bugs as reported by Fabian Keil.
[gnupg.git] / agent / protect.c
1 /* protect.c - Un/Protect a secret key
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3  *               2003, 2007, 2009 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 <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
31 #include "agent.h"
32
33 #include "sexp-parse.h"
34
35 #define PROT_CIPHER        GCRY_CIPHER_AES
36 #define PROT_CIPHER_STRING "aes"
37 #define PROT_CIPHER_KEYLEN (128/8)
38
39
40 /* A table containing the information needed to create a protected
41    private key */
42 static struct {
43   const char *algo;
44   const char *parmlist;
45   int prot_from, prot_to;
46 } protect_info[] = {
47   { "rsa",  "nedpqu", 2, 5 },
48   { "dsa",  "pqgyx", 4, 4 },
49   { "elg",  "pgyx", 3, 3 },
50   { NULL }
51 };
52
53
54 static int
55 hash_passphrase (const char *passphrase, int hashalgo,
56                  int s2kmode,
57                  const unsigned char *s2ksalt, unsigned long s2kcount,
58                  unsigned char *key, size_t keylen);
59
60
61 \f
62 /* Calculate the MIC for a private key S-Exp. SHA1HASH should point to
63    a 20 byte buffer.  This function is suitable for any algorithms. */
64 static int 
65 calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
66 {
67   const unsigned char *hash_begin, *hash_end;
68   const unsigned char *s;
69   size_t n;
70
71   s = plainkey;
72   if (*s != '(')
73     return gpg_error (GPG_ERR_INV_SEXP);
74   s++;
75   n = snext (&s);
76   if (!n)
77     return gpg_error (GPG_ERR_INV_SEXP); 
78   if (!smatch (&s, n, "private-key"))
79     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
80   if (*s != '(')
81     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
82   hash_begin = s;
83   s++;
84   n = snext (&s);
85   if (!n)
86     return gpg_error (GPG_ERR_INV_SEXP); 
87   s += n; /* skip over the algorithm name */
88
89   while (*s == '(')
90     {
91       s++;
92       n = snext (&s);
93       if (!n)
94         return gpg_error (GPG_ERR_INV_SEXP); 
95       s += n;
96       n = snext (&s);
97       if (!n)
98         return gpg_error (GPG_ERR_INV_SEXP); 
99       s += n;
100       if ( *s != ')' )
101         return gpg_error (GPG_ERR_INV_SEXP); 
102       s++;
103     }
104   if (*s != ')')
105     return gpg_error (GPG_ERR_INV_SEXP); 
106   s++;
107   hash_end = s;
108
109   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash,
110                        hash_begin, hash_end - hash_begin);
111
112   return 0;
113 }
114
115
116 \f
117 /* Encrypt the parameter block starting at PROTBEGIN with length
118    PROTLEN using the utf8 encoded key PASSPHRASE and return the entire
119    encrypted block in RESULT or return with an error code.  SHA1HASH
120    is the 20 byte SHA-1 hash required for the integrity code.
121
122    The parameter block is expected to be an incomplete S-Expression of
123    the form (example in advanced format):
124
125      (d #046129F..[some bytes not shown]..81#)
126      (p #00e861b..[some bytes not shown]..f1#)
127      (q #00f7a7c..[some bytes not shown]..61#)
128      (u #304559a..[some bytes not shown]..9b#) 
129
130    the returned block is the S-Expression:
131
132     (protected mode (parms) encrypted_octet_string)
133
134 */
135 static int
136 do_encryption (const unsigned char *protbegin, size_t protlen, 
137                const char *passphrase,  const unsigned char *sha1hash,
138                unsigned char **result, size_t *resultlen)
139 {
140   gcry_cipher_hd_t hd;
141   const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
142   int blklen, enclen, outlen;
143   unsigned char *iv = NULL;
144   int rc;
145   char *outbuf = NULL;
146   char *p;
147   int saltpos, ivpos, encpos;
148
149   *resultlen = 0;
150   *result = NULL;
151
152   rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
153                          GCRY_CIPHER_SECURE);
154   if (rc)
155     return rc;
156
157
158   /* We need to work on a copy of the data because this makes it
159      easier to add the trailer and the padding and more important we
160      have to prefix the text with 2 parenthesis, so we have to
161      allocate enough space for:
162
163      ((<parameter_list>)(4:hash4:sha120:<hashvalue>)) + padding
164
165      We always append a full block of random bytes as padding but
166      encrypt only what is needed for a full blocksize.  */
167   blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
168   outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen;
169   enclen = outlen/blklen * blklen;
170   outbuf = gcry_malloc_secure (outlen);
171   if (!outbuf)
172     rc = out_of_core ();
173   if (!rc)
174     {
175       /* Allocate random bytes to be used as IV, padding and s2k salt. */
176       iv = xtrymalloc (blklen*2+8);
177       if (!iv)
178         rc = gpg_error (GPG_ERR_ENOMEM);
179       else
180         {
181           gcry_create_nonce (iv, blklen*2+8);
182           rc = gcry_cipher_setiv (hd, iv, blklen);
183         }
184     }
185   if (!rc)
186     {
187       unsigned char *key;
188       size_t keylen = PROT_CIPHER_KEYLEN;
189       
190       key = gcry_malloc_secure (keylen);
191       if (!key)
192         rc = out_of_core ();
193       else
194         {
195           rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
196                                 3, iv+2*blklen, 96, key, keylen);
197           if (!rc)
198             rc = gcry_cipher_setkey (hd, key, keylen);
199           xfree (key);
200         }
201     }
202   if (!rc)
203     {
204       p = outbuf;
205       *p++ = '(';
206       *p++ = '(';
207       memcpy (p, protbegin, protlen);
208       p += protlen;
209       memcpy (p, ")(4:hash4:sha120:", 17);
210       p += 17;
211       memcpy (p, sha1hash, 20);
212       p += 20;
213       *p++ = ')';
214       *p++ = ')';
215       memcpy (p, iv+blklen, blklen); 
216       p += blklen;
217       assert ( p - outbuf == outlen);
218       rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0);
219     }
220   gcry_cipher_close (hd);
221   if (rc)
222     {
223       xfree (iv);
224       xfree (outbuf);
225       return rc;
226     }
227
228   /* Now allocate the buffer we want to return.  This is
229
230      (protected openpgp-s2k3-sha1-aes-cbc
231        ((sha1 salt no_of_iterations) 16byte_iv)
232        encrypted_octet_string)
233        
234      in canoncical format of course.  We use asprintf and %n modifier
235      and dummy values as placeholders.  */
236   p = xtryasprintf
237     ("(9:protected%d:%s((4:sha18:%n_8bytes_2:96)%d:%n%*s)%d:%n%*s)",
238      (int)strlen (modestr), modestr,
239      &saltpos, 
240      blklen, &ivpos, blklen, "",
241      enclen, &encpos, enclen, "");
242   if (!p)
243     {
244       gpg_error_t tmperr = out_of_core ();
245       xfree (iv);
246       xfree (outbuf);
247       return tmperr;
248     }
249   *resultlen = strlen (p);
250   *result = (unsigned char*)p;
251   memcpy (p+saltpos, iv+2*blklen, 8);
252   memcpy (p+ivpos, iv, blklen);
253   memcpy (p+encpos, outbuf, enclen);
254   xfree (iv);
255   xfree (outbuf);
256   return 0;
257 }
258
259
260
261 /* Protect the key encoded in canonical format in PLAINKEY.  We assume
262    a valid S-Exp here. */
263 int 
264 agent_protect (const unsigned char *plainkey, const char *passphrase,
265                unsigned char **result, size_t *resultlen)
266 {
267   int rc;
268   const unsigned char *s;
269   const unsigned char *hash_begin, *hash_end;
270   const unsigned char *prot_begin, *prot_end, *real_end;
271   size_t n;
272   int c, infidx, i;
273   unsigned char hashvalue[20];
274   char timestamp_exp[35];
275   unsigned char *protected;
276   size_t protectedlen;
277   int depth = 0;
278   unsigned char *p;
279   gcry_md_hd_t md;
280
281   /* Create an S-expression with the procted-at timestamp.  */
282   memcpy (timestamp_exp, "(12:protected-at15:", 19);
283   gnupg_get_isotime (timestamp_exp+19);
284   timestamp_exp[19+15] = ')';
285
286   /* Parse original key.  */
287   s = plainkey;
288   if (*s != '(')
289     return gpg_error (GPG_ERR_INV_SEXP);
290   depth++;
291   s++;
292   n = snext (&s);
293   if (!n)
294     return gpg_error (GPG_ERR_INV_SEXP); 
295   if (!smatch (&s, n, "private-key"))
296     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
297   if (*s != '(')
298     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
299   depth++;
300   hash_begin = s;
301   s++;
302   n = snext (&s);
303   if (!n)
304     return gpg_error (GPG_ERR_INV_SEXP); 
305
306   for (infidx=0; protect_info[infidx].algo
307               && !smatch (&s, n, protect_info[infidx].algo); infidx++)
308     ;
309   if (!protect_info[infidx].algo)
310     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); 
311
312   prot_begin = prot_end = NULL;
313   for (i=0; (c=protect_info[infidx].parmlist[i]); i++)
314     {
315       if (i == protect_info[infidx].prot_from)
316         prot_begin = s;
317       if (*s != '(')
318         return gpg_error (GPG_ERR_INV_SEXP);
319       depth++;
320       s++;
321       n = snext (&s);
322       if (!n)
323         return gpg_error (GPG_ERR_INV_SEXP); 
324       if (n != 1 || c != *s)
325         return gpg_error (GPG_ERR_INV_SEXP); 
326       s += n;
327       n = snext (&s);
328       if (!n)
329         return gpg_error (GPG_ERR_INV_SEXP); 
330       s +=n; /* skip value */
331       if (*s != ')')
332         return gpg_error (GPG_ERR_INV_SEXP); 
333       depth--;
334       if (i == protect_info[infidx].prot_to)
335         prot_end = s;
336       s++;
337     }
338   if (*s != ')' || !prot_begin || !prot_end )
339     return gpg_error (GPG_ERR_INV_SEXP); 
340   depth--;
341   hash_end = s;
342   s++;
343   /* skip to the end of the S-exp */
344   assert (depth == 1);
345   rc = sskip (&s, &depth);
346   if (rc)
347     return rc;
348   assert (!depth);
349   real_end = s-1;
350
351   
352   /* Hash the stuff.  Because the timestamp_exp won't get protected,
353      we can't simply hash a continuous buffer but need to use several
354      md_writes.  */ 
355   rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 );
356   if (rc)
357     return rc;
358   gcry_md_write (md, hash_begin, hash_end - hash_begin);
359   gcry_md_write (md, timestamp_exp, 35);
360   gcry_md_write (md, ")", 1);
361   memcpy (hashvalue, gcry_md_read (md, GCRY_MD_SHA1), 20);
362   gcry_md_close (md);
363
364   rc = do_encryption (prot_begin, prot_end - prot_begin + 1,
365                       passphrase,  hashvalue,
366                       &protected, &protectedlen);
367   if (rc)
368     return rc;
369
370   /* Now create the protected version of the key.  Note that the 10
371      extra bytes are for for the inserted "protected-" string (the
372      beginning of the plaintext reads: "((11:private-key(" ).  The 35
373      term is the space for (12:protected-at15:<timestamp>).  */
374   *resultlen = (10
375                 + (prot_begin-plainkey)
376                 + protectedlen
377                 + 35
378                 + (real_end-prot_end));
379   *result = p = xtrymalloc (*resultlen);
380   if (!p)
381     {
382       gpg_error_t tmperr = out_of_core ();
383       xfree (protected);
384       return tmperr;
385     }
386   memcpy (p, "(21:protected-", 14);
387   p += 14;
388   memcpy (p, plainkey+4, prot_begin - plainkey - 4);
389   p += prot_begin - plainkey - 4;
390   memcpy (p, protected, protectedlen);
391   p += protectedlen;
392
393   memcpy (p, timestamp_exp, 35);
394   p += 35;
395
396   memcpy (p, prot_end+1, real_end - prot_end);
397   p += real_end - prot_end;
398   assert ( p - *result == *resultlen);
399   xfree (protected);
400
401   return 0;
402 }
403
404 \f
405 /* Do the actual decryption and check the return list for consistency.  */
406 static int
407 do_decryption (const unsigned char *protected, size_t protectedlen, 
408                const char *passphrase, 
409                const unsigned char *s2ksalt, unsigned long s2kcount,
410                const unsigned char *iv, size_t ivlen,
411                unsigned char **result)
412 {
413   int rc = 0;
414   int blklen;
415   gcry_cipher_hd_t hd;
416   unsigned char *outbuf;
417   size_t reallen;
418
419   blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
420   if (protectedlen < 4 || (protectedlen%blklen))
421     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
422
423   rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
424                          GCRY_CIPHER_SECURE);
425   if (rc)
426     return rc;
427
428   outbuf = gcry_malloc_secure (protectedlen);
429   if (!outbuf)
430     rc = out_of_core ();
431   if (!rc)
432     rc = gcry_cipher_setiv (hd, iv, ivlen);
433   if (!rc)
434     {
435       unsigned char *key;
436       size_t keylen = PROT_CIPHER_KEYLEN;
437       
438       key = gcry_malloc_secure (keylen);
439       if (!key)
440         rc = out_of_core ();
441       else
442         {
443           rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
444                                 3, s2ksalt, s2kcount, key, keylen);
445           if (!rc)
446             rc = gcry_cipher_setkey (hd, key, keylen);
447           xfree (key);
448         }
449     }
450   if (!rc)
451     rc = gcry_cipher_decrypt (hd, outbuf, protectedlen,
452                               protected, protectedlen);
453   gcry_cipher_close (hd);
454   if (rc)
455     {
456       xfree (outbuf);
457       return rc;
458     }
459   /* Do a quick check first. */
460   if (*outbuf != '(' && outbuf[1] != '(')
461     {
462       xfree (outbuf);
463       return gpg_error (GPG_ERR_BAD_PASSPHRASE);
464     }
465   /* Check that we have a consistent S-Exp. */
466   reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL);
467   if (!reallen || (reallen + blklen < protectedlen) )
468     {
469       xfree (outbuf);
470       return gpg_error (GPG_ERR_BAD_PASSPHRASE);
471     }
472   *result = outbuf;
473   return 0;
474 }
475
476
477 /* Merge the parameter list contained in CLEARTEXT with the original
478    protect lists PROTECTEDKEY by replacing the list at REPLACEPOS.
479    Return the new list in RESULT and the MIC value in the 20 byte
480    buffer SHA1HASH.  CUTOFF and CUTLEN will receive the offset and the
481    length of the resulting list which should go into the MIC
482    calculation but then be removed.  */
483 static int
484 merge_lists (const unsigned char *protectedkey,
485              size_t replacepos, 
486              const unsigned char *cleartext,
487              unsigned char *sha1hash,
488              unsigned char **result, size_t *resultlen,
489              size_t *cutoff, size_t *cutlen)
490 {
491   size_t n, newlistlen;
492   unsigned char *newlist, *p;
493   const unsigned char *s;
494   const unsigned char *startpos, *endpos;
495   int i, rc;
496   
497   *result = NULL;
498   *resultlen = 0;
499   *cutoff = 0;
500   *cutlen = 0;
501
502   if (replacepos < 26)
503     return gpg_error (GPG_ERR_BUG);
504
505   /* Estimate the required size of the resulting list.  We have a large
506      safety margin of >20 bytes (MIC hash from CLEARTEXT and the
507      removed "protected-" */
508   newlistlen = gcry_sexp_canon_len (protectedkey, 0, NULL, NULL);
509   if (!newlistlen)
510     return gpg_error (GPG_ERR_BUG);
511   n = gcry_sexp_canon_len (cleartext, 0, NULL, NULL);
512   if (!n)
513     return gpg_error (GPG_ERR_BUG);
514   newlistlen += n;
515   newlist = gcry_malloc_secure (newlistlen);
516   if (!newlist)
517     return out_of_core ();
518
519   /* Copy the initial segment */
520   strcpy ((char*)newlist, "(11:private-key");
521   p = newlist + 15;
522   memcpy (p, protectedkey+15+10, replacepos-15-10);
523   p += replacepos-15-10;
524
525   /* copy the cleartext */
526   s = cleartext;
527   if (*s != '(' && s[1] != '(')
528     return gpg_error (GPG_ERR_BUG);  /*we already checked this */
529   s += 2;
530   startpos = s;
531   while ( *s == '(' )
532     {
533       s++;
534       n = snext (&s);
535       if (!n)
536         goto invalid_sexp;
537       s += n;
538       n = snext (&s);
539       if (!n)
540         goto invalid_sexp;
541       s += n;
542       if ( *s != ')' )
543         goto invalid_sexp;
544       s++;
545     }
546   if ( *s != ')' )
547     goto invalid_sexp;
548   endpos = s;
549   s++;
550   /* Intermezzo: Get the MIC */
551   if (*s != '(')
552     goto invalid_sexp;
553   s++;
554   n = snext (&s);
555   if (!smatch (&s, n, "hash"))
556     goto invalid_sexp;
557   n = snext (&s);
558   if (!smatch (&s, n, "sha1"))
559     goto invalid_sexp; 
560   n = snext (&s);
561   if (n != 20)
562     goto invalid_sexp;
563   memcpy (sha1hash, s, 20);
564   s += n;
565   if (*s != ')')
566     goto invalid_sexp;
567   /* End intermezzo */
568
569   /* append the parameter list */
570   memcpy (p, startpos, endpos - startpos);
571   p += endpos - startpos;
572   
573   /* Skip over the protected list element in the original list.  */
574   s = protectedkey + replacepos;
575   assert (*s == '(');
576   s++;
577   i = 1;
578   rc = sskip (&s, &i);
579   if (rc)
580     goto failure;
581   /* Record the position of the optional protected-at expression.  */
582   if (*s == '(')
583     {
584       const unsigned char *save_s = s;
585       s++;
586       n = snext (&s);
587       if (smatch (&s, n, "protected-at"))
588         {
589           i = 1;
590           rc = sskip (&s, &i);
591           if (rc)
592             goto failure;
593           *cutlen = s - save_s;
594         }
595       s = save_s;
596     }
597   startpos = s;
598   i = 2; /* we are inside this level */
599   rc = sskip (&s, &i);
600   if (rc)
601     goto failure;
602   assert (s[-1] == ')');
603   endpos = s; /* one behind the end of the list */
604
605   /* Append the rest. */
606   if (*cutlen)
607     *cutoff = p - newlist;
608   memcpy (p, startpos, endpos - startpos);
609   p += endpos - startpos;
610   
611
612   /* ready */
613   *result = newlist;
614   *resultlen = newlistlen;
615   return 0;
616
617  failure:
618   wipememory (newlist, newlistlen);
619   xfree (newlist);
620   return rc;
621
622  invalid_sexp:
623   wipememory (newlist, newlistlen);
624   xfree (newlist);
625   return gpg_error (GPG_ERR_INV_SEXP);
626 }
627
628
629
630 /* Unprotect the key encoded in canonical format.  We assume a valid
631    S-Exp here.  If a protected-at item is available, its value will
632    be stored at protocted_at unless this is NULL.  */
633 int 
634 agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
635                  gnupg_isotime_t protected_at, 
636                  unsigned char **result, size_t *resultlen)
637 {
638   int rc;
639   const unsigned char *s;
640   const unsigned char *protect_list; 
641   size_t n;
642   int infidx, i;
643   unsigned char sha1hash[20], sha1hash2[20];
644   const unsigned char *s2ksalt;
645   unsigned long s2kcount;
646   const unsigned char *iv;
647   const unsigned char *prot_begin;
648   unsigned char *cleartext;
649   unsigned char *final;
650   size_t finallen;
651   size_t cutoff, cutlen;
652
653   if (protected_at)
654     *protected_at = 0;
655
656   s = protectedkey;
657   if (*s != '(')
658     return gpg_error (GPG_ERR_INV_SEXP);
659   s++;
660   n = snext (&s);
661   if (!n)
662     return gpg_error (GPG_ERR_INV_SEXP); 
663   if (!smatch (&s, n, "protected-private-key"))
664     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
665   if (*s != '(')
666     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
667   s++;
668   n = snext (&s);
669   if (!n)
670     return gpg_error (GPG_ERR_INV_SEXP); 
671
672   for (infidx=0; protect_info[infidx].algo
673               && !smatch (&s, n, protect_info[infidx].algo); infidx++)
674     ;
675   if (!protect_info[infidx].algo)
676     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); 
677
678
679   /* See wether we have a protected-at timestamp.  */
680   protect_list = s;  /* Save for later.  */
681   if (protected_at)
682     {
683       while (*s == '(')
684         {
685           prot_begin = s;
686           s++;
687           n = snext (&s);
688           if (!n)
689             return gpg_error (GPG_ERR_INV_SEXP);
690           if (smatch (&s, n, "protected-at"))
691             {
692               n = snext (&s);
693               if (!n)
694                 return gpg_error (GPG_ERR_INV_SEXP);
695               if (n != 15)
696                 return gpg_error (GPG_ERR_UNKNOWN_SEXP);
697               memcpy (protected_at, s, 15);
698               protected_at[15] = 0;
699               break;
700             }
701           s += n;
702           i = 1;
703           rc = sskip (&s, &i);
704           if (rc)
705             return rc;
706         }
707     }
708
709   /* Now find the list with the protected information.  Here is an
710      example for such a list:
711      (protected openpgp-s2k3-sha1-aes-cbc 
712         ((sha1 <salt> <count>) <Initialization_Vector>)
713         <encrypted_data>)
714    */
715   s = protect_list;
716   for (;;)
717     {
718       if (*s != '(')
719         return gpg_error (GPG_ERR_INV_SEXP);
720       prot_begin = s;
721       s++;
722       n = snext (&s);
723       if (!n)
724         return gpg_error (GPG_ERR_INV_SEXP); 
725       if (smatch (&s, n, "protected"))
726         break;
727       s += n;
728       i = 1;
729       rc = sskip (&s, &i);
730       if (rc)
731         return rc;
732     }
733   /* found */
734   n = snext (&s);
735   if (!n)
736     return gpg_error (GPG_ERR_INV_SEXP); 
737   if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"))
738     return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
739   if (*s != '(' || s[1] != '(')
740     return gpg_error (GPG_ERR_INV_SEXP);
741   s += 2;
742   n = snext (&s);
743   if (!n)
744     return gpg_error (GPG_ERR_INV_SEXP); 
745   if (!smatch (&s, n, "sha1"))
746     return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
747   n = snext (&s);
748   if (n != 8)
749     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
750   s2ksalt = s;
751   s += n;
752   n = snext (&s);
753   if (!n)
754     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
755   /* We expect a list close as next, so we can simply use strtoul()
756      here.  We might want to check that we only have digits - but this
757      is nothing we should worry about */
758   if (s[n] != ')' )
759     return gpg_error (GPG_ERR_INV_SEXP);
760   s2kcount = strtoul ((const char*)s, NULL, 10);
761   if (!s2kcount)
762     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
763   s += n;
764   s++; /* skip list end */
765
766   n = snext (&s);
767   if (n != 16) /* Wrong blocksize for IV (we support only aes-128). */
768     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
769   iv = s;
770   s += n;
771   if (*s != ')' )
772     return gpg_error (GPG_ERR_INV_SEXP);
773   s++;
774   n = snext (&s);
775   if (!n)
776     return gpg_error (GPG_ERR_INV_SEXP); 
777   
778   rc = do_decryption (s, n,
779                       passphrase, s2ksalt, s2kcount,
780                       iv, 16,
781                       &cleartext);
782   if (rc)
783     return rc;
784
785   rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext,
786                     sha1hash, &final, &finallen, &cutoff, &cutlen);
787   /* Albeit cleartext has been allocated in secure memory and thus
788      xfree will wipe it out, we do an extra wipe just in case
789      somethings goes badly wrong. */
790   wipememory (cleartext, n);
791   xfree (cleartext);
792   if (rc)
793     return rc;
794
795   rc = calculate_mic (final, sha1hash2);
796   if (!rc && memcmp (sha1hash, sha1hash2, 20))
797     rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
798   if (rc)
799     {
800       wipememory (final, finallen);
801       xfree (final);
802       return rc;
803     }
804   /* Now remove tha part which is included in the MIC but should not
805      go into the final thing.  */
806   if (cutlen)
807     {
808       memmove (final+cutoff, final+cutoff+cutlen, finallen-cutoff-cutlen);
809       finallen -= cutlen;
810     }
811
812   *result = final;
813   *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
814   return 0;
815 }
816
817 /* Check the type of the private key, this is one of the constants:
818    PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
819    value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
820    PRIVATE_KEY_PROTECTED for an protected private key or
821    PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored
822    elsewhere. */
823 int
824 agent_private_key_type (const unsigned char *privatekey)
825 {
826   const unsigned char *s;
827   size_t n;
828
829   s = privatekey;
830   if (*s != '(')
831     return PRIVATE_KEY_UNKNOWN;
832   s++;
833   n = snext (&s);
834   if (!n)
835     return PRIVATE_KEY_UNKNOWN;
836   if (smatch (&s, n, "protected-private-key"))
837     return PRIVATE_KEY_PROTECTED;
838   if (smatch (&s, n, "shadowed-private-key"))
839     return PRIVATE_KEY_SHADOWED;
840   if (smatch (&s, n, "private-key"))
841     return PRIVATE_KEY_CLEAR;
842   return PRIVATE_KEY_UNKNOWN;
843 }
844
845
846 \f
847 /* Transform a passphrase into a suitable key of length KEYLEN and
848    store this key in the caller provided buffer KEY.  The caller must
849    provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on
850    that mode an S2KSALT of 8 random bytes and an S2KCOUNT (a suitable
851    value is 96).
852   
853    Returns an error code on failure.  */
854 static int
855 hash_passphrase (const char *passphrase, int hashalgo,
856                  int s2kmode,
857                  const unsigned char *s2ksalt,
858                  unsigned long s2kcount,
859                  unsigned char *key, size_t keylen)
860 {
861   int rc;
862   gcry_md_hd_t md;
863   int pass, i;
864   int used = 0;
865   int pwlen = strlen (passphrase);
866
867   if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3)
868       || !hashalgo || !keylen || !key || !passphrase)
869     return gpg_error (GPG_ERR_INV_VALUE);
870   if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
871     return gpg_error (GPG_ERR_INV_VALUE);
872   
873   rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
874   if (rc)
875     return rc;
876
877   for (pass=0; used < keylen; pass++)
878     {
879       if (pass)
880         {
881           gcry_md_reset (md);
882           for (i=0; i < pass; i++) /* preset the hash context */
883             gcry_md_putc (md, 0);
884         }
885
886       if (s2kmode == 1 || s2kmode == 3)
887         {
888           int len2 = pwlen + 8;
889           unsigned long count = len2;
890
891           if (s2kmode == 3)
892             {
893               count = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6);
894               if (count < len2)
895                 count = len2;
896             }
897
898           while (count > len2)
899             {
900               gcry_md_write (md, s2ksalt, 8);
901               gcry_md_write (md, passphrase, pwlen);
902               count -= len2;
903             }
904           if (count < 8)
905             gcry_md_write (md, s2ksalt, count);
906           else 
907             {
908               gcry_md_write (md, s2ksalt, 8);
909               count -= 8;
910               gcry_md_write (md, passphrase, count);
911             }
912         }
913       else
914         gcry_md_write (md, passphrase, pwlen);
915       
916       gcry_md_final (md);
917       i = gcry_md_get_algo_dlen (hashalgo);
918       if (i > keylen - used)
919         i = keylen - used;
920       memcpy  (key+used, gcry_md_read (md, hashalgo), i);
921       used += i;
922     }
923   gcry_md_close(md);
924   return 0;
925 }
926
927
928 \f
929
930 /* Create an canonical encoded S-expression with the shadow info from
931    a card's SERIALNO and the IDSTRING.  */
932 unsigned char *
933 make_shadow_info (const char *serialno, const char *idstring)
934 {
935   const char *s;
936   char *info, *p;
937   char numbuf[20];
938   size_t n;
939
940   for (s=serialno, n=0; *s && s[1]; s += 2)
941     n++;
942
943   info = p = xtrymalloc (1 + sizeof numbuf + n
944                            + sizeof numbuf + strlen (idstring) + 1 + 1);
945   if (!info)
946     return NULL;
947   *p++ = '(';
948   p = stpcpy (p, smklen (numbuf, sizeof numbuf, n, NULL));
949   for (s=serialno; *s && s[1]; s += 2)
950     *(unsigned char *)p++ = xtoi_2 (s);
951   p = stpcpy (p, smklen (numbuf, sizeof numbuf, strlen (idstring), NULL));
952   p = stpcpy (p, idstring);
953   *p++ = ')';
954   *p = 0;
955   return (unsigned char *)info;
956 }
957
958
959
960 /* Create a shadow key from a public key.  We use the shadow protocol
961   "ti-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
962   S-expression is returned in an allocated buffer RESULT will point
963   to. The input parameters are expected to be valid canonicalized
964   S-expressions */
965 int 
966 agent_shadow_key (const unsigned char *pubkey,
967                   const unsigned char *shadow_info,
968                   unsigned char **result)
969 {
970   const unsigned char *s;
971   const unsigned char *point;
972   size_t n;
973   int depth = 0;
974   char *p;
975   size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
976   size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
977
978   if (!pubkey_len || !shadow_info_len)
979     return gpg_error (GPG_ERR_INV_VALUE);
980   s = pubkey;
981   if (*s != '(')
982     return gpg_error (GPG_ERR_INV_SEXP);
983   depth++;
984   s++;
985   n = snext (&s);
986   if (!n)
987     return gpg_error (GPG_ERR_INV_SEXP); 
988   if (!smatch (&s, n, "public-key"))
989     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
990   if (*s != '(')
991     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
992   depth++;
993   s++;
994   n = snext (&s); 
995   if (!n)
996     return gpg_error (GPG_ERR_INV_SEXP); 
997   s += n; /* skip over the algorithm name */
998
999   while (*s != ')')
1000     {
1001       if (*s != '(')
1002         return gpg_error (GPG_ERR_INV_SEXP);
1003       depth++;
1004       s++;
1005       n = snext (&s);
1006       if (!n) 
1007         return gpg_error (GPG_ERR_INV_SEXP); 
1008       s += n;
1009       n = snext (&s);
1010       if (!n)
1011         return gpg_error (GPG_ERR_INV_SEXP); 
1012       s +=n; /* skip value */
1013       if (*s != ')')
1014         return gpg_error (GPG_ERR_INV_SEXP); 
1015       depth--;
1016       s++;
1017     }
1018   point = s; /* insert right before the point */
1019   depth--;
1020   s++;
1021   assert (depth == 1);
1022
1023   /* Calculate required length by taking in account: the "shadowed-"
1024      prefix, the "shadowed", "t1-v1" as well as some parenthesis */
1025   n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1;
1026   *result = xtrymalloc (n);
1027   p = (char*)*result;
1028   if (!p)
1029       return out_of_core ();
1030   p = stpcpy (p, "(20:shadowed-private-key");
1031   /* (10:public-key ...)*/
1032   memcpy (p, pubkey+14, point - (pubkey+14));
1033   p += point - (pubkey+14);
1034   p = stpcpy (p, "(8:shadowed5:t1-v1");
1035   memcpy (p, shadow_info, shadow_info_len);
1036   p += shadow_info_len;
1037   *p++ = ')';
1038   memcpy (p, point, pubkey_len - (point - pubkey));
1039   p += pubkey_len - (point - pubkey);
1040
1041   return 0;
1042 }
1043
1044 /* Parse a canonical encoded shadowed key and return a pointer to the
1045    inner list with the shadow_info */
1046 int 
1047 agent_get_shadow_info (const unsigned char *shadowkey,
1048                        unsigned char const **shadow_info)
1049 {
1050   const unsigned char *s;
1051   size_t n;
1052   int depth = 0;
1053
1054   s = shadowkey;
1055   if (*s != '(')
1056     return gpg_error (GPG_ERR_INV_SEXP);
1057   depth++;
1058   s++;
1059   n = snext (&s);
1060   if (!n)
1061     return gpg_error (GPG_ERR_INV_SEXP); 
1062   if (!smatch (&s, n, "shadowed-private-key"))
1063     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
1064   if (*s != '(')
1065     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1066   depth++;
1067   s++;
1068   n = snext (&s); 
1069   if (!n)
1070     return gpg_error (GPG_ERR_INV_SEXP); 
1071   s += n; /* skip over the algorithm name */
1072
1073   for (;;)
1074     {
1075       if (*s == ')')
1076         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1077       if (*s != '(')
1078         return gpg_error (GPG_ERR_INV_SEXP);
1079       depth++;
1080       s++;
1081       n = snext (&s);
1082       if (!n) 
1083         return gpg_error (GPG_ERR_INV_SEXP); 
1084       if (smatch (&s, n, "shadowed"))
1085         break;
1086       s += n;
1087       n = snext (&s);
1088       if (!n)
1089         return gpg_error (GPG_ERR_INV_SEXP); 
1090       s +=n; /* skip value */
1091       if (*s != ')')
1092         return gpg_error (GPG_ERR_INV_SEXP); 
1093       depth--;
1094       s++;
1095     }
1096   /* Found the shadowed list, S points to the protocol */
1097   n = snext (&s);
1098   if (!n) 
1099     return gpg_error (GPG_ERR_INV_SEXP); 
1100   if (smatch (&s, n, "t1-v1"))
1101     {
1102       if (*s != '(')
1103         return gpg_error (GPG_ERR_INV_SEXP);
1104       *shadow_info = s;
1105     }
1106   else
1107     return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
1108   return 0;
1109 }
1110
1111
1112 /* Parse the canonical encoded SHADOW_INFO S-expression.  On success
1113    the hex encoded serial number is returned as a malloced strings at
1114    R_HEXSN and the Id string as a malloced string at R_IDSTR.  On
1115    error an error code is returned and NULL is stored at the result
1116    parameters addresses.  If the serial number or the ID string is not
1117    required, NULL may be passed for them.  */
1118 gpg_error_t
1119 parse_shadow_info (const unsigned char *shadow_info, 
1120                    char **r_hexsn, char **r_idstr)
1121 {
1122   const unsigned char *s;
1123   size_t n;
1124
1125   if (r_hexsn)
1126     *r_hexsn = NULL;
1127   if (r_idstr)
1128     *r_idstr = NULL;
1129
1130   s = shadow_info;
1131   if (*s != '(')
1132     return gpg_error (GPG_ERR_INV_SEXP);
1133   s++;
1134   n = snext (&s);
1135   if (!n)
1136     return gpg_error (GPG_ERR_INV_SEXP);
1137
1138   if (r_hexsn)
1139     {
1140       *r_hexsn = bin2hex (s, n, NULL);
1141       if (!*r_hexsn)
1142         return gpg_error_from_syserror ();
1143     }
1144   s += n;
1145
1146   n = snext (&s);
1147   if (!n)
1148     {
1149       if (r_hexsn)
1150         {
1151           xfree (*r_hexsn);
1152           *r_hexsn = NULL;
1153         }
1154       return gpg_error (GPG_ERR_INV_SEXP);
1155     }
1156   
1157   if (r_idstr)
1158     {
1159       *r_idstr = xtrymalloc (n+1);
1160       if (!*r_idstr)
1161         {
1162           if (r_hexsn)
1163             {
1164               xfree (*r_hexsn);
1165               *r_hexsn = NULL;
1166             }
1167           return gpg_error_from_syserror ();
1168         }
1169       memcpy (*r_idstr, s, n);
1170       (*r_idstr)[n] = 0;
1171     }
1172
1173   return 0;
1174 }
1175