Unification of the search descriptor usage.
[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   cleartext = NULL; /* Avoid cc warning. */
779   rc = do_decryption (s, n,
780                       passphrase, s2ksalt, s2kcount,
781                       iv, 16,
782                       &cleartext);
783   if (rc)
784     return rc;
785
786   rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext,
787                     sha1hash, &final, &finallen, &cutoff, &cutlen);
788   /* Albeit cleartext has been allocated in secure memory and thus
789      xfree will wipe it out, we do an extra wipe just in case
790      somethings goes badly wrong. */
791   wipememory (cleartext, n);
792   xfree (cleartext);
793   if (rc)
794     return rc;
795
796   rc = calculate_mic (final, sha1hash2);
797   if (!rc && memcmp (sha1hash, sha1hash2, 20))
798     rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
799   if (rc)
800     {
801       wipememory (final, finallen);
802       xfree (final);
803       return rc;
804     }
805   /* Now remove tha part which is included in the MIC but should not
806      go into the final thing.  */
807   if (cutlen)
808     {
809       memmove (final+cutoff, final+cutoff+cutlen, finallen-cutoff-cutlen);
810       finallen -= cutlen;
811     }
812
813   *result = final;
814   *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
815   return 0;
816 }
817
818 /* Check the type of the private key, this is one of the constants:
819    PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
820    value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
821    PRIVATE_KEY_PROTECTED for an protected private key or
822    PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored
823    elsewhere. */
824 int
825 agent_private_key_type (const unsigned char *privatekey)
826 {
827   const unsigned char *s;
828   size_t n;
829
830   s = privatekey;
831   if (*s != '(')
832     return PRIVATE_KEY_UNKNOWN;
833   s++;
834   n = snext (&s);
835   if (!n)
836     return PRIVATE_KEY_UNKNOWN;
837   if (smatch (&s, n, "protected-private-key"))
838     return PRIVATE_KEY_PROTECTED;
839   if (smatch (&s, n, "shadowed-private-key"))
840     return PRIVATE_KEY_SHADOWED;
841   if (smatch (&s, n, "private-key"))
842     return PRIVATE_KEY_CLEAR;
843   return PRIVATE_KEY_UNKNOWN;
844 }
845
846
847 \f
848 /* Transform a passphrase into a suitable key of length KEYLEN and
849    store this key in the caller provided buffer KEY.  The caller must
850    provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on
851    that mode an S2KSALT of 8 random bytes and an S2KCOUNT (a suitable
852    value is 96).
853   
854    Returns an error code on failure.  */
855 static int
856 hash_passphrase (const char *passphrase, int hashalgo,
857                  int s2kmode,
858                  const unsigned char *s2ksalt,
859                  unsigned long s2kcount,
860                  unsigned char *key, size_t keylen)
861 {
862   int rc;
863   gcry_md_hd_t md;
864   int pass, i;
865   int used = 0;
866   int pwlen = strlen (passphrase);
867
868   if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3)
869       || !hashalgo || !keylen || !key || !passphrase)
870     return gpg_error (GPG_ERR_INV_VALUE);
871   if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
872     return gpg_error (GPG_ERR_INV_VALUE);
873   
874   rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
875   if (rc)
876     return rc;
877
878   for (pass=0; used < keylen; pass++)
879     {
880       if (pass)
881         {
882           gcry_md_reset (md);
883           for (i=0; i < pass; i++) /* preset the hash context */
884             gcry_md_putc (md, 0);
885         }
886
887       if (s2kmode == 1 || s2kmode == 3)
888         {
889           int len2 = pwlen + 8;
890           unsigned long count = len2;
891
892           if (s2kmode == 3)
893             {
894               count = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6);
895               if (count < len2)
896                 count = len2;
897             }
898
899           while (count > len2)
900             {
901               gcry_md_write (md, s2ksalt, 8);
902               gcry_md_write (md, passphrase, pwlen);
903               count -= len2;
904             }
905           if (count < 8)
906             gcry_md_write (md, s2ksalt, count);
907           else 
908             {
909               gcry_md_write (md, s2ksalt, 8);
910               count -= 8;
911               gcry_md_write (md, passphrase, count);
912             }
913         }
914       else
915         gcry_md_write (md, passphrase, pwlen);
916       
917       gcry_md_final (md);
918       i = gcry_md_get_algo_dlen (hashalgo);
919       if (i > keylen - used)
920         i = keylen - used;
921       memcpy  (key+used, gcry_md_read (md, hashalgo), i);
922       used += i;
923     }
924   gcry_md_close(md);
925   return 0;
926 }
927
928
929 \f
930
931 /* Create an canonical encoded S-expression with the shadow info from
932    a card's SERIALNO and the IDSTRING.  */
933 unsigned char *
934 make_shadow_info (const char *serialno, const char *idstring)
935 {
936   const char *s;
937   char *info, *p;
938   char numbuf[20];
939   size_t n;
940
941   for (s=serialno, n=0; *s && s[1]; s += 2)
942     n++;
943
944   info = p = xtrymalloc (1 + sizeof numbuf + n
945                            + sizeof numbuf + strlen (idstring) + 1 + 1);
946   if (!info)
947     return NULL;
948   *p++ = '(';
949   p = stpcpy (p, smklen (numbuf, sizeof numbuf, n, NULL));
950   for (s=serialno; *s && s[1]; s += 2)
951     *(unsigned char *)p++ = xtoi_2 (s);
952   p = stpcpy (p, smklen (numbuf, sizeof numbuf, strlen (idstring), NULL));
953   p = stpcpy (p, idstring);
954   *p++ = ')';
955   *p = 0;
956   return (unsigned char *)info;
957 }
958
959
960
961 /* Create a shadow key from a public key.  We use the shadow protocol
962   "ti-v1" and insert the S-expressionn SHADOW_INFO.  The resulting
963   S-expression is returned in an allocated buffer RESULT will point
964   to. The input parameters are expected to be valid canonicalized
965   S-expressions */
966 int 
967 agent_shadow_key (const unsigned char *pubkey,
968                   const unsigned char *shadow_info,
969                   unsigned char **result)
970 {
971   const unsigned char *s;
972   const unsigned char *point;
973   size_t n;
974   int depth = 0;
975   char *p;
976   size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
977   size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
978
979   if (!pubkey_len || !shadow_info_len)
980     return gpg_error (GPG_ERR_INV_VALUE);
981   s = pubkey;
982   if (*s != '(')
983     return gpg_error (GPG_ERR_INV_SEXP);
984   depth++;
985   s++;
986   n = snext (&s);
987   if (!n)
988     return gpg_error (GPG_ERR_INV_SEXP); 
989   if (!smatch (&s, n, "public-key"))
990     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
991   if (*s != '(')
992     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
993   depth++;
994   s++;
995   n = snext (&s); 
996   if (!n)
997     return gpg_error (GPG_ERR_INV_SEXP); 
998   s += n; /* skip over the algorithm name */
999
1000   while (*s != ')')
1001     {
1002       if (*s != '(')
1003         return gpg_error (GPG_ERR_INV_SEXP);
1004       depth++;
1005       s++;
1006       n = snext (&s);
1007       if (!n) 
1008         return gpg_error (GPG_ERR_INV_SEXP); 
1009       s += n;
1010       n = snext (&s);
1011       if (!n)
1012         return gpg_error (GPG_ERR_INV_SEXP); 
1013       s +=n; /* skip value */
1014       if (*s != ')')
1015         return gpg_error (GPG_ERR_INV_SEXP); 
1016       depth--;
1017       s++;
1018     }
1019   point = s; /* insert right before the point */
1020   depth--;
1021   s++;
1022   assert (depth == 1);
1023
1024   /* Calculate required length by taking in account: the "shadowed-"
1025      prefix, the "shadowed", "t1-v1" as well as some parenthesis */
1026   n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1;
1027   *result = xtrymalloc (n);
1028   p = (char*)*result;
1029   if (!p)
1030       return out_of_core ();
1031   p = stpcpy (p, "(20:shadowed-private-key");
1032   /* (10:public-key ...)*/
1033   memcpy (p, pubkey+14, point - (pubkey+14));
1034   p += point - (pubkey+14);
1035   p = stpcpy (p, "(8:shadowed5:t1-v1");
1036   memcpy (p, shadow_info, shadow_info_len);
1037   p += shadow_info_len;
1038   *p++ = ')';
1039   memcpy (p, point, pubkey_len - (point - pubkey));
1040   p += pubkey_len - (point - pubkey);
1041
1042   return 0;
1043 }
1044
1045 /* Parse a canonical encoded shadowed key and return a pointer to the
1046    inner list with the shadow_info */
1047 int 
1048 agent_get_shadow_info (const unsigned char *shadowkey,
1049                        unsigned char const **shadow_info)
1050 {
1051   const unsigned char *s;
1052   size_t n;
1053   int depth = 0;
1054
1055   s = shadowkey;
1056   if (*s != '(')
1057     return gpg_error (GPG_ERR_INV_SEXP);
1058   depth++;
1059   s++;
1060   n = snext (&s);
1061   if (!n)
1062     return gpg_error (GPG_ERR_INV_SEXP); 
1063   if (!smatch (&s, n, "shadowed-private-key"))
1064     return gpg_error (GPG_ERR_UNKNOWN_SEXP); 
1065   if (*s != '(')
1066     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1067   depth++;
1068   s++;
1069   n = snext (&s); 
1070   if (!n)
1071     return gpg_error (GPG_ERR_INV_SEXP); 
1072   s += n; /* skip over the algorithm name */
1073
1074   for (;;)
1075     {
1076       if (*s == ')')
1077         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1078       if (*s != '(')
1079         return gpg_error (GPG_ERR_INV_SEXP);
1080       depth++;
1081       s++;
1082       n = snext (&s);
1083       if (!n) 
1084         return gpg_error (GPG_ERR_INV_SEXP); 
1085       if (smatch (&s, n, "shadowed"))
1086         break;
1087       s += n;
1088       n = snext (&s);
1089       if (!n)
1090         return gpg_error (GPG_ERR_INV_SEXP); 
1091       s +=n; /* skip value */
1092       if (*s != ')')
1093         return gpg_error (GPG_ERR_INV_SEXP); 
1094       depth--;
1095       s++;
1096     }
1097   /* Found the shadowed list, S points to the protocol */
1098   n = snext (&s);
1099   if (!n) 
1100     return gpg_error (GPG_ERR_INV_SEXP); 
1101   if (smatch (&s, n, "t1-v1"))
1102     {
1103       if (*s != '(')
1104         return gpg_error (GPG_ERR_INV_SEXP);
1105       *shadow_info = s;
1106     }
1107   else
1108     return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
1109   return 0;
1110 }
1111
1112
1113 /* Parse the canonical encoded SHADOW_INFO S-expression.  On success
1114    the hex encoded serial number is returned as a malloced strings at
1115    R_HEXSN and the Id string as a malloced string at R_IDSTR.  On
1116    error an error code is returned and NULL is stored at the result
1117    parameters addresses.  If the serial number or the ID string is not
1118    required, NULL may be passed for them.  */
1119 gpg_error_t
1120 parse_shadow_info (const unsigned char *shadow_info, 
1121                    char **r_hexsn, char **r_idstr)
1122 {
1123   const unsigned char *s;
1124   size_t n;
1125
1126   if (r_hexsn)
1127     *r_hexsn = NULL;
1128   if (r_idstr)
1129     *r_idstr = NULL;
1130
1131   s = shadow_info;
1132   if (*s != '(')
1133     return gpg_error (GPG_ERR_INV_SEXP);
1134   s++;
1135   n = snext (&s);
1136   if (!n)
1137     return gpg_error (GPG_ERR_INV_SEXP);
1138
1139   if (r_hexsn)
1140     {
1141       *r_hexsn = bin2hex (s, n, NULL);
1142       if (!*r_hexsn)
1143         return gpg_error_from_syserror ();
1144     }
1145   s += n;
1146
1147   n = snext (&s);
1148   if (!n)
1149     {
1150       if (r_hexsn)
1151         {
1152           xfree (*r_hexsn);
1153           *r_hexsn = NULL;
1154         }
1155       return gpg_error (GPG_ERR_INV_SEXP);
1156     }
1157   
1158   if (r_idstr)
1159     {
1160       *r_idstr = xtrymalloc (n+1);
1161       if (!*r_idstr)
1162         {
1163           if (r_hexsn)
1164             {
1165               xfree (*r_hexsn);
1166               *r_hexsn = NULL;
1167             }
1168           return gpg_error_from_syserror ();
1169         }
1170       memcpy (*r_idstr, s, n);
1171       (*r_idstr)[n] = 0;
1172     }
1173
1174   return 0;
1175 }
1176