1
/* protect.c - Un/Protect a secret key
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
* 2003, 2007, 2009 Free Software Foundation, Inc.
5
* This file is part of GnuPG.
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.
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.
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/>.
30
#ifdef HAVE_W32_SYSTEM
33
# include <sys/times.h>
38
#include "sexp-parse.h"
40
#define PROT_CIPHER GCRY_CIPHER_AES
41
#define PROT_CIPHER_STRING "aes"
42
#define PROT_CIPHER_KEYLEN (128/8)
45
/* A table containing the information needed to create a protected
50
int prot_from, prot_to;
52
{ "rsa", "nedpqu", 2, 5 },
53
{ "dsa", "pqgyx", 4, 4 },
54
{ "elg", "pgyx", 3, 3 },
59
/* A helper object for time measurement. */
60
struct calibrate_time_s
62
#ifdef HAVE_W32_SYSTEM
63
FILETIME creation_time, exit_time, kernel_time, user_time;
71
hash_passphrase (const char *passphrase, int hashalgo,
73
const unsigned char *s2ksalt, unsigned long s2kcount,
74
unsigned char *key, size_t keylen);
76
/* Get the process time and store it in DATA. */
78
calibrate_get_time (struct calibrate_time_s *data)
80
#ifdef HAVE_W32_SYSTEM
81
GetProcessTimes (GetCurrentProcess (),
82
&data->creation_time, &data->exit_time,
83
&data->kernel_time, &data->user_time);
88
data->ticks = tmp.tms_utime;
94
calibrate_elapsed_time (struct calibrate_time_s *starttime)
96
struct calibrate_time_s stoptime;
98
calibrate_get_time (&stoptime);
99
#ifdef HAVE_W32_SYSTEM
101
unsigned long long t1, t2;
103
t1 = (((unsigned long long)starttime->kernel_time.dwHighDateTime << 32)
104
+ starttime->kernel_time.dwLowDateTime);
105
t1 += (((unsigned long long)starttime->user_time.dwHighDateTime << 32)
106
+ starttime->user_time.dwLowDateTime);
107
t2 = (((unsigned long long)stoptime.kernel_time.dwHighDateTime << 32)
108
+ stoptime.kernel_time.dwLowDateTime);
109
t2 += (((unsigned long long)stoptime.user_time.dwHighDateTime << 32)
110
+ stoptime.user_time.dwLowDateTime);
111
return (unsigned long)((t2 - t1)/10000);
114
return (unsigned long)((((double) (stoptime.ticks - starttime->ticks))
115
/CLOCKS_PER_SEC)*10000000);
120
/* Run a test hashing for COUNT and return the time required in
123
calibrate_s2k_count_one (unsigned long count)
126
char keybuf[PROT_CIPHER_KEYLEN];
127
struct calibrate_time_s starttime;
129
calibrate_get_time (&starttime);
130
rc = hash_passphrase ("123456789abcdef0", GCRY_MD_SHA1,
131
3, "saltsalt", count, keybuf, sizeof keybuf);
134
return calibrate_elapsed_time (&starttime);
138
/* Measure the time we need to do the hash operations and deduce an
139
S2K count which requires about 100ms of time. */
141
calibrate_s2k_count (void)
146
for (count = 65536; count; count *= 2)
148
ms = calibrate_s2k_count_one (count);
150
log_info ("S2K calibration: %lu -> %lums\n", count, ms);
155
count = (unsigned long)(((double)count / ms) * 100);
163
ms = calibrate_s2k_count_one (count);
164
log_info ("S2K calibration: %lu iterations for %lums\n", count, ms);
172
/* Return the standard S2K count. */
174
get_standard_s2k_count (void)
176
static unsigned long count;
179
count = calibrate_s2k_count ();
181
/* Enforce a lower limit. */
182
return count < 65536 ? 65536 : count;
188
/* Calculate the MIC for a private key S-Exp. SHA1HASH should point to
189
a 20 byte buffer. This function is suitable for any algorithms. */
191
calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash)
193
const unsigned char *hash_begin, *hash_end;
194
const unsigned char *s;
199
return gpg_error (GPG_ERR_INV_SEXP);
203
return gpg_error (GPG_ERR_INV_SEXP);
204
if (!smatch (&s, n, "private-key"))
205
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
207
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
212
return gpg_error (GPG_ERR_INV_SEXP);
213
s += n; /* skip over the algorithm name */
220
return gpg_error (GPG_ERR_INV_SEXP);
224
return gpg_error (GPG_ERR_INV_SEXP);
227
return gpg_error (GPG_ERR_INV_SEXP);
231
return gpg_error (GPG_ERR_INV_SEXP);
235
gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash,
236
hash_begin, hash_end - hash_begin);
243
/* Encrypt the parameter block starting at PROTBEGIN with length
244
PROTLEN using the utf8 encoded key PASSPHRASE and return the entire
245
encrypted block in RESULT or return with an error code. SHA1HASH
246
is the 20 byte SHA-1 hash required for the integrity code.
248
The parameter block is expected to be an incomplete S-Expression of
249
the form (example in advanced format):
251
(d #046129F..[some bytes not shown]..81#)
252
(p #00e861b..[some bytes not shown]..f1#)
253
(q #00f7a7c..[some bytes not shown]..61#)
254
(u #304559a..[some bytes not shown]..9b#)
256
the returned block is the S-Expression:
258
(protected mode (parms) encrypted_octet_string)
262
do_encryption (const unsigned char *protbegin, size_t protlen,
263
const char *passphrase, const unsigned char *sha1hash,
264
unsigned char **result, size_t *resultlen)
267
const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
268
int blklen, enclen, outlen;
269
unsigned char *iv = NULL;
273
int saltpos, ivpos, encpos;
278
rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
284
/* We need to work on a copy of the data because this makes it
285
easier to add the trailer and the padding and more important we
286
have to prefix the text with 2 parenthesis, so we have to
287
allocate enough space for:
289
((<parameter_list>)(4:hash4:sha120:<hashvalue>)) + padding
291
We always append a full block of random bytes as padding but
292
encrypt only what is needed for a full blocksize. */
293
blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
294
outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen;
295
enclen = outlen/blklen * blklen;
296
outbuf = gcry_malloc_secure (outlen);
301
/* Allocate random bytes to be used as IV, padding and s2k salt. */
302
iv = xtrymalloc (blklen*2+8);
304
rc = gpg_error (GPG_ERR_ENOMEM);
307
gcry_create_nonce (iv, blklen*2+8);
308
rc = gcry_cipher_setiv (hd, iv, blklen);
314
size_t keylen = PROT_CIPHER_KEYLEN;
316
key = gcry_malloc_secure (keylen);
321
rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
323
get_standard_s2k_count (), key, keylen);
325
rc = gcry_cipher_setkey (hd, key, keylen);
334
memcpy (p, protbegin, protlen);
336
memcpy (p, ")(4:hash4:sha120:", 17);
338
memcpy (p, sha1hash, 20);
342
memcpy (p, iv+blklen, blklen);
344
assert ( p - outbuf == outlen);
345
rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0);
347
gcry_cipher_close (hd);
355
/* Now allocate the buffer we want to return. This is
357
(protected openpgp-s2k3-sha1-aes-cbc
358
((sha1 salt no_of_iterations) 16byte_iv)
359
encrypted_octet_string)
361
in canoncical format of course. We use asprintf and %n modifier
362
and dummy values as placeholders. */
364
("(9:protected%d:%s((4:sha18:%n_8bytes_2:96)%d:%n%*s)%d:%n%*s)",
365
(int)strlen (modestr), modestr,
367
blklen, &ivpos, blklen, "",
368
enclen, &encpos, enclen, "");
371
gpg_error_t tmperr = out_of_core ();
376
*resultlen = strlen (p);
377
*result = (unsigned char*)p;
378
memcpy (p+saltpos, iv+2*blklen, 8);
379
memcpy (p+ivpos, iv, blklen);
380
memcpy (p+encpos, outbuf, enclen);
388
/* Protect the key encoded in canonical format in PLAINKEY. We assume
389
a valid S-Exp here. */
391
agent_protect (const unsigned char *plainkey, const char *passphrase,
392
unsigned char **result, size_t *resultlen)
395
const unsigned char *s;
396
const unsigned char *hash_begin, *hash_end;
397
const unsigned char *prot_begin, *prot_end, *real_end;
400
unsigned char hashvalue[20];
401
char timestamp_exp[35];
402
unsigned char *protected;
408
/* Create an S-expression with the procted-at timestamp. */
409
memcpy (timestamp_exp, "(12:protected-at15:", 19);
410
gnupg_get_isotime (timestamp_exp+19);
411
timestamp_exp[19+15] = ')';
413
/* Parse original key. */
416
return gpg_error (GPG_ERR_INV_SEXP);
421
return gpg_error (GPG_ERR_INV_SEXP);
422
if (!smatch (&s, n, "private-key"))
423
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
425
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
431
return gpg_error (GPG_ERR_INV_SEXP);
433
for (infidx=0; protect_info[infidx].algo
434
&& !smatch (&s, n, protect_info[infidx].algo); infidx++)
436
if (!protect_info[infidx].algo)
437
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
439
prot_begin = prot_end = NULL;
440
for (i=0; (c=protect_info[infidx].parmlist[i]); i++)
442
if (i == protect_info[infidx].prot_from)
445
return gpg_error (GPG_ERR_INV_SEXP);
450
return gpg_error (GPG_ERR_INV_SEXP);
451
if (n != 1 || c != *s)
452
return gpg_error (GPG_ERR_INV_SEXP);
456
return gpg_error (GPG_ERR_INV_SEXP);
457
s +=n; /* skip value */
459
return gpg_error (GPG_ERR_INV_SEXP);
461
if (i == protect_info[infidx].prot_to)
465
if (*s != ')' || !prot_begin || !prot_end )
466
return gpg_error (GPG_ERR_INV_SEXP);
470
/* skip to the end of the S-exp */
472
rc = sskip (&s, &depth);
479
/* Hash the stuff. Because the timestamp_exp won't get protected,
480
we can't simply hash a continuous buffer but need to use several
482
rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 );
485
gcry_md_write (md, hash_begin, hash_end - hash_begin);
486
gcry_md_write (md, timestamp_exp, 35);
487
gcry_md_write (md, ")", 1);
488
memcpy (hashvalue, gcry_md_read (md, GCRY_MD_SHA1), 20);
491
rc = do_encryption (prot_begin, prot_end - prot_begin + 1,
492
passphrase, hashvalue,
493
&protected, &protectedlen);
497
/* Now create the protected version of the key. Note that the 10
498
extra bytes are for for the inserted "protected-" string (the
499
beginning of the plaintext reads: "((11:private-key(" ). The 35
500
term is the space for (12:protected-at15:<timestamp>). */
502
+ (prot_begin-plainkey)
505
+ (real_end-prot_end));
506
*result = p = xtrymalloc (*resultlen);
509
gpg_error_t tmperr = out_of_core ();
513
memcpy (p, "(21:protected-", 14);
515
memcpy (p, plainkey+4, prot_begin - plainkey - 4);
516
p += prot_begin - plainkey - 4;
517
memcpy (p, protected, protectedlen);
520
memcpy (p, timestamp_exp, 35);
523
memcpy (p, prot_end+1, real_end - prot_end);
524
p += real_end - prot_end;
525
assert ( p - *result == *resultlen);
532
/* Do the actual decryption and check the return list for consistency. */
534
do_decryption (const unsigned char *protected, size_t protectedlen,
535
const char *passphrase,
536
const unsigned char *s2ksalt, unsigned long s2kcount,
537
const unsigned char *iv, size_t ivlen,
538
unsigned char **result)
543
unsigned char *outbuf;
546
blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER);
547
if (protectedlen < 4 || (protectedlen%blklen))
548
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
550
rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
555
outbuf = gcry_malloc_secure (protectedlen);
559
rc = gcry_cipher_setiv (hd, iv, ivlen);
563
size_t keylen = PROT_CIPHER_KEYLEN;
565
key = gcry_malloc_secure (keylen);
570
rc = hash_passphrase (passphrase, GCRY_MD_SHA1,
571
3, s2ksalt, s2kcount, key, keylen);
573
rc = gcry_cipher_setkey (hd, key, keylen);
578
rc = gcry_cipher_decrypt (hd, outbuf, protectedlen,
579
protected, protectedlen);
580
gcry_cipher_close (hd);
586
/* Do a quick check first. */
587
if (*outbuf != '(' && outbuf[1] != '(')
590
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
592
/* Check that we have a consistent S-Exp. */
593
reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL);
594
if (!reallen || (reallen + blklen < protectedlen) )
597
return gpg_error (GPG_ERR_BAD_PASSPHRASE);
604
/* Merge the parameter list contained in CLEARTEXT with the original
605
protect lists PROTECTEDKEY by replacing the list at REPLACEPOS.
606
Return the new list in RESULT and the MIC value in the 20 byte
607
buffer SHA1HASH. CUTOFF and CUTLEN will receive the offset and the
608
length of the resulting list which should go into the MIC
609
calculation but then be removed. */
611
merge_lists (const unsigned char *protectedkey,
613
const unsigned char *cleartext,
614
unsigned char *sha1hash,
615
unsigned char **result, size_t *resultlen,
616
size_t *cutoff, size_t *cutlen)
618
size_t n, newlistlen;
619
unsigned char *newlist, *p;
620
const unsigned char *s;
621
const unsigned char *startpos, *endpos;
630
return gpg_error (GPG_ERR_BUG);
632
/* Estimate the required size of the resulting list. We have a large
633
safety margin of >20 bytes (MIC hash from CLEARTEXT and the
634
removed "protected-" */
635
newlistlen = gcry_sexp_canon_len (protectedkey, 0, NULL, NULL);
637
return gpg_error (GPG_ERR_BUG);
638
n = gcry_sexp_canon_len (cleartext, 0, NULL, NULL);
640
return gpg_error (GPG_ERR_BUG);
642
newlist = gcry_malloc_secure (newlistlen);
644
return out_of_core ();
646
/* Copy the initial segment */
647
strcpy ((char*)newlist, "(11:private-key");
649
memcpy (p, protectedkey+15+10, replacepos-15-10);
650
p += replacepos-15-10;
652
/* copy the cleartext */
654
if (*s != '(' && s[1] != '(')
655
return gpg_error (GPG_ERR_BUG); /*we already checked this */
677
/* Intermezzo: Get the MIC */
682
if (!smatch (&s, n, "hash"))
685
if (!smatch (&s, n, "sha1"))
690
memcpy (sha1hash, s, 20);
696
/* append the parameter list */
697
memcpy (p, startpos, endpos - startpos);
698
p += endpos - startpos;
700
/* Skip over the protected list element in the original list. */
701
s = protectedkey + replacepos;
708
/* Record the position of the optional protected-at expression. */
711
const unsigned char *save_s = s;
714
if (smatch (&s, n, "protected-at"))
720
*cutlen = s - save_s;
725
i = 2; /* we are inside this level */
729
assert (s[-1] == ')');
730
endpos = s; /* one behind the end of the list */
732
/* Append the rest. */
734
*cutoff = p - newlist;
735
memcpy (p, startpos, endpos - startpos);
736
p += endpos - startpos;
741
*resultlen = newlistlen;
745
wipememory (newlist, newlistlen);
750
wipememory (newlist, newlistlen);
752
return gpg_error (GPG_ERR_INV_SEXP);
757
/* Unprotect the key encoded in canonical format. We assume a valid
758
S-Exp here. If a protected-at item is available, its value will
759
be stored at protocted_at unless this is NULL. */
761
agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
762
gnupg_isotime_t protected_at,
763
unsigned char **result, size_t *resultlen)
766
const unsigned char *s;
767
const unsigned char *protect_list;
770
unsigned char sha1hash[20], sha1hash2[20];
771
const unsigned char *s2ksalt;
772
unsigned long s2kcount;
773
const unsigned char *iv;
774
const unsigned char *prot_begin;
775
unsigned char *cleartext;
776
unsigned char *final;
778
size_t cutoff, cutlen;
785
return gpg_error (GPG_ERR_INV_SEXP);
789
return gpg_error (GPG_ERR_INV_SEXP);
790
if (!smatch (&s, n, "protected-private-key"))
791
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
793
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
797
return gpg_error (GPG_ERR_INV_SEXP);
799
for (infidx=0; protect_info[infidx].algo
800
&& !smatch (&s, n, protect_info[infidx].algo); infidx++)
802
if (!protect_info[infidx].algo)
803
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
806
/* See wether we have a protected-at timestamp. */
807
protect_list = s; /* Save for later. */
816
return gpg_error (GPG_ERR_INV_SEXP);
817
if (smatch (&s, n, "protected-at"))
821
return gpg_error (GPG_ERR_INV_SEXP);
823
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
824
memcpy (protected_at, s, 15);
825
protected_at[15] = 0;
836
/* Now find the list with the protected information. Here is an
837
example for such a list:
838
(protected openpgp-s2k3-sha1-aes-cbc
839
((sha1 <salt> <count>) <Initialization_Vector>)
846
return gpg_error (GPG_ERR_INV_SEXP);
851
return gpg_error (GPG_ERR_INV_SEXP);
852
if (smatch (&s, n, "protected"))
863
return gpg_error (GPG_ERR_INV_SEXP);
864
if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"))
865
return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
866
if (*s != '(' || s[1] != '(')
867
return gpg_error (GPG_ERR_INV_SEXP);
871
return gpg_error (GPG_ERR_INV_SEXP);
872
if (!smatch (&s, n, "sha1"))
873
return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION);
876
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
881
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
882
/* We expect a list close as next, so we can simply use strtoul()
883
here. We might want to check that we only have digits - but this
884
is nothing we should worry about */
886
return gpg_error (GPG_ERR_INV_SEXP);
888
/* Old versions of gpg-agent used the funny floating point number in
889
a byte encoding as specified by OpenPGP. However this is not
890
needed and thus we now store it as a plain unsigned integer. We
891
can easily distinguish the old format by looking at its value:
892
Less than 256 is an old-style encoded number; other values are
893
plain integers. In any case we check that they are at least
894
65536 because we never used a lower value in the past and we
895
should have a lower limit. */
896
s2kcount = strtoul ((const char*)s, NULL, 10);
898
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
900
s2kcount = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6);
901
if (s2kcount < 65536)
902
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
905
s++; /* skip list end */
908
if (n != 16) /* Wrong blocksize for IV (we support only aes-128). */
909
return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
913
return gpg_error (GPG_ERR_INV_SEXP);
917
return gpg_error (GPG_ERR_INV_SEXP);
919
rc = do_decryption (s, n,
920
passphrase, s2ksalt, s2kcount,
926
rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext,
927
sha1hash, &final, &finallen, &cutoff, &cutlen);
928
/* Albeit cleartext has been allocated in secure memory and thus
929
xfree will wipe it out, we do an extra wipe just in case
930
somethings goes badly wrong. */
931
wipememory (cleartext, n);
936
rc = calculate_mic (final, sha1hash2);
937
if (!rc && memcmp (sha1hash, sha1hash2, 20))
938
rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
941
wipememory (final, finallen);
945
/* Now remove tha part which is included in the MIC but should not
946
go into the final thing. */
949
memmove (final+cutoff, final+cutoff+cutlen, finallen-cutoff-cutlen);
954
*resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL);
958
/* Check the type of the private key, this is one of the constants:
959
PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the
960
value 0), PRIVATE_KEY_CLEAR for an unprotected private key.
961
PRIVATE_KEY_PROTECTED for an protected private key or
962
PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored
965
agent_private_key_type (const unsigned char *privatekey)
967
const unsigned char *s;
972
return PRIVATE_KEY_UNKNOWN;
976
return PRIVATE_KEY_UNKNOWN;
977
if (smatch (&s, n, "protected-private-key"))
978
return PRIVATE_KEY_PROTECTED;
979
if (smatch (&s, n, "shadowed-private-key"))
980
return PRIVATE_KEY_SHADOWED;
981
if (smatch (&s, n, "private-key"))
982
return PRIVATE_KEY_CLEAR;
983
return PRIVATE_KEY_UNKNOWN;
988
/* Transform a passphrase into a suitable key of length KEYLEN and
989
store this key in the caller provided buffer KEY. The caller must
990
provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on
991
that mode an S2KSALT of 8 random bytes and an S2KCOUNT.
993
Returns an error code on failure. */
995
hash_passphrase (const char *passphrase, int hashalgo,
997
const unsigned char *s2ksalt,
998
unsigned long s2kcount,
999
unsigned char *key, size_t keylen)
1005
int pwlen = strlen (passphrase);
1007
if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3)
1008
|| !hashalgo || !keylen || !key || !passphrase)
1009
return gpg_error (GPG_ERR_INV_VALUE);
1010
if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
1011
return gpg_error (GPG_ERR_INV_VALUE);
1013
rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
1017
for (pass=0; used < keylen; pass++)
1022
for (i=0; i < pass; i++) /* preset the hash context */
1023
gcry_md_putc (md, 0);
1026
if (s2kmode == 1 || s2kmode == 3)
1028
int len2 = pwlen + 8;
1029
unsigned long count = len2;
1038
while (count > len2)
1040
gcry_md_write (md, s2ksalt, 8);
1041
gcry_md_write (md, passphrase, pwlen);
1045
gcry_md_write (md, s2ksalt, count);
1048
gcry_md_write (md, s2ksalt, 8);
1050
gcry_md_write (md, passphrase, count);
1054
gcry_md_write (md, passphrase, pwlen);
1057
i = gcry_md_get_algo_dlen (hashalgo);
1058
if (i > keylen - used)
1060
memcpy (key+used, gcry_md_read (md, hashalgo), i);
1070
/* Create an canonical encoded S-expression with the shadow info from
1071
a card's SERIALNO and the IDSTRING. */
1073
make_shadow_info (const char *serialno, const char *idstring)
1080
for (s=serialno, n=0; *s && s[1]; s += 2)
1083
info = p = xtrymalloc (1 + sizeof numbuf + n
1084
+ sizeof numbuf + strlen (idstring) + 1 + 1);
1088
p = stpcpy (p, smklen (numbuf, sizeof numbuf, n, NULL));
1089
for (s=serialno; *s && s[1]; s += 2)
1090
*(unsigned char *)p++ = xtoi_2 (s);
1091
p = stpcpy (p, smklen (numbuf, sizeof numbuf, strlen (idstring), NULL));
1092
p = stpcpy (p, idstring);
1095
return (unsigned char *)info;
1100
/* Create a shadow key from a public key. We use the shadow protocol
1101
"ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting
1102
S-expression is returned in an allocated buffer RESULT will point
1103
to. The input parameters are expected to be valid canonicalized
1106
agent_shadow_key (const unsigned char *pubkey,
1107
const unsigned char *shadow_info,
1108
unsigned char **result)
1110
const unsigned char *s;
1111
const unsigned char *point;
1115
size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL);
1116
size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL);
1118
if (!pubkey_len || !shadow_info_len)
1119
return gpg_error (GPG_ERR_INV_VALUE);
1122
return gpg_error (GPG_ERR_INV_SEXP);
1127
return gpg_error (GPG_ERR_INV_SEXP);
1128
if (!smatch (&s, n, "public-key"))
1129
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1131
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1136
return gpg_error (GPG_ERR_INV_SEXP);
1137
s += n; /* skip over the algorithm name */
1142
return gpg_error (GPG_ERR_INV_SEXP);
1147
return gpg_error (GPG_ERR_INV_SEXP);
1151
return gpg_error (GPG_ERR_INV_SEXP);
1152
s +=n; /* skip value */
1154
return gpg_error (GPG_ERR_INV_SEXP);
1158
point = s; /* insert right before the point */
1161
assert (depth == 1);
1163
/* Calculate required length by taking in account: the "shadowed-"
1164
prefix, the "shadowed", "t1-v1" as well as some parenthesis */
1165
n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1;
1166
*result = xtrymalloc (n);
1169
return out_of_core ();
1170
p = stpcpy (p, "(20:shadowed-private-key");
1171
/* (10:public-key ...)*/
1172
memcpy (p, pubkey+14, point - (pubkey+14));
1173
p += point - (pubkey+14);
1174
p = stpcpy (p, "(8:shadowed5:t1-v1");
1175
memcpy (p, shadow_info, shadow_info_len);
1176
p += shadow_info_len;
1178
memcpy (p, point, pubkey_len - (point - pubkey));
1179
p += pubkey_len - (point - pubkey);
1184
/* Parse a canonical encoded shadowed key and return a pointer to the
1185
inner list with the shadow_info */
1187
agent_get_shadow_info (const unsigned char *shadowkey,
1188
unsigned char const **shadow_info)
1190
const unsigned char *s;
1196
return gpg_error (GPG_ERR_INV_SEXP);
1201
return gpg_error (GPG_ERR_INV_SEXP);
1202
if (!smatch (&s, n, "shadowed-private-key"))
1203
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1205
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1210
return gpg_error (GPG_ERR_INV_SEXP);
1211
s += n; /* skip over the algorithm name */
1216
return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1218
return gpg_error (GPG_ERR_INV_SEXP);
1223
return gpg_error (GPG_ERR_INV_SEXP);
1224
if (smatch (&s, n, "shadowed"))
1229
return gpg_error (GPG_ERR_INV_SEXP);
1230
s +=n; /* skip value */
1232
return gpg_error (GPG_ERR_INV_SEXP);
1236
/* Found the shadowed list, S points to the protocol */
1239
return gpg_error (GPG_ERR_INV_SEXP);
1240
if (smatch (&s, n, "t1-v1"))
1243
return gpg_error (GPG_ERR_INV_SEXP);
1247
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
1252
/* Parse the canonical encoded SHADOW_INFO S-expression. On success
1253
the hex encoded serial number is returned as a malloced strings at
1254
R_HEXSN and the Id string as a malloced string at R_IDSTR. On
1255
error an error code is returned and NULL is stored at the result
1256
parameters addresses. If the serial number or the ID string is not
1257
required, NULL may be passed for them. */
1259
parse_shadow_info (const unsigned char *shadow_info,
1260
char **r_hexsn, char **r_idstr)
1262
const unsigned char *s;
1272
return gpg_error (GPG_ERR_INV_SEXP);
1276
return gpg_error (GPG_ERR_INV_SEXP);
1280
*r_hexsn = bin2hex (s, n, NULL);
1282
return gpg_error_from_syserror ();
1294
return gpg_error (GPG_ERR_INV_SEXP);
1299
*r_idstr = xtrymalloc (n+1);
1307
return gpg_error_from_syserror ();
1309
memcpy (*r_idstr, s, n);