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