Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "egg-asn1-defs.h"
24 : #include "egg-asn1x.h"
25 : #include "egg-secure-memory.h"
26 : #include "egg-symkey.h"
27 :
28 354 : EGG_SECURE_DECLARE (symkey);
29 :
30 : /* -----------------------------------------------------------------------------
31 : * QUARKS
32 : */
33 :
34 : static GQuark OID_PBE_MD2_DES_CBC;
35 : static GQuark OID_PBE_MD5_DES_CBC;
36 : static GQuark OID_PBE_MD2_RC2_CBC;
37 : static GQuark OID_PBE_MD5_RC2_CBC;
38 : static GQuark OID_PBE_SHA1_DES_CBC;
39 : static GQuark OID_PBE_SHA1_RC2_CBC;
40 : static GQuark OID_PBES2;
41 : static GQuark OID_PBKDF2;
42 :
43 : static GQuark OID_DES_CBC;
44 : static GQuark OID_DES_RC2_CBC;
45 : static GQuark OID_DES_EDE3_CBC;
46 : static GQuark OID_DES_RC5_CBC;
47 :
48 : static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
49 : static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
50 : static GQuark OID_PKCS12_PBE_3DES_SHA1;
51 : static GQuark OID_PKCS12_PBE_2DES_SHA1;
52 : static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
53 : static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
54 :
55 : static GQuark OID_SHA1;
56 :
57 : static void
58 51 : init_quarks (void)
59 : {
60 : static gsize quarks_inited = 0;
61 :
62 51 : if (g_once_init_enter (&quarks_inited)) {
63 :
64 : #define QUARK(name, value) \
65 : name = g_quark_from_static_string(value)
66 :
67 3 : QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
68 3 : QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
69 3 : QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
70 3 : QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
71 3 : QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
72 3 : QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
73 :
74 3 : QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
75 :
76 3 : QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
77 :
78 3 : QUARK (OID_DES_CBC, "1.3.14.3.2.7");
79 3 : QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
80 3 : QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
81 3 : QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
82 :
83 3 : QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
84 3 : QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
85 3 : QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
86 3 : QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
87 3 : QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
88 3 : QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
89 :
90 3 : QUARK (OID_SHA1, "1.3.14.3.2.26");
91 :
92 : #undef QUARK
93 :
94 3 : g_once_init_leave (&quarks_inited, 1);
95 : }
96 51 : }
97 :
98 : /* -----------------------------------------------------------------------------
99 : * PASSWORD TO KEY/IV
100 : */
101 :
102 : gboolean
103 91 : egg_symkey_generate_simple (int cipher_algo, int hash_algo,
104 : const gchar *password, gssize n_password,
105 : const guchar *salt, gsize n_salt, int iterations,
106 : guchar **key, guchar **iv)
107 : {
108 : gcry_md_hd_t mdh;
109 : gcry_error_t gcry;
110 : guchar *digest;
111 : guchar *digested;
112 : guint n_digest;
113 : gint pass, i;
114 : gint needed_iv, needed_key;
115 : guchar *at_iv, *at_key;
116 :
117 91 : g_assert (cipher_algo);
118 91 : g_assert (hash_algo);
119 :
120 91 : g_return_val_if_fail (iterations >= 1, FALSE);
121 :
122 91 : if (!password)
123 3 : n_password = 0;
124 91 : if (n_password == -1)
125 2 : n_password = strlen (password);
126 :
127 : /*
128 : * If cipher algo needs more bytes than hash algo has available
129 : * then the entire hashing process is done again (with the previous
130 : * hash bytes as extra input), and so on until satisfied.
131 : */
132 :
133 91 : needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
134 91 : needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
135 :
136 91 : gcry = gcry_md_open (&mdh, hash_algo, 0);
137 91 : if (gcry) {
138 0 : g_warning ("couldn't create '%s' hash context: %s",
139 : gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
140 0 : return FALSE;
141 : }
142 :
143 91 : n_digest = gcry_md_get_algo_dlen (hash_algo);
144 91 : g_return_val_if_fail (n_digest > 0, FALSE);
145 :
146 91 : digest = egg_secure_alloc (n_digest);
147 91 : g_return_val_if_fail (digest, FALSE);
148 91 : if (key) {
149 91 : *key = egg_secure_alloc (needed_key);
150 91 : g_return_val_if_fail (*key, FALSE);
151 : }
152 91 : if (iv)
153 71 : *iv = g_new0 (guchar, needed_iv);
154 :
155 91 : at_key = key ? *key : NULL;
156 91 : at_iv = iv ? *iv : NULL;
157 :
158 111 : for (pass = 0; TRUE; ++pass) {
159 111 : gcry_md_reset (mdh);
160 :
161 : /* Hash in the previous buffer on later passes */
162 111 : if (pass > 0)
163 20 : gcry_md_write (mdh, digest, n_digest);
164 :
165 111 : if (password)
166 108 : gcry_md_write (mdh, password, n_password);
167 111 : if (salt && n_salt)
168 111 : gcry_md_write (mdh, salt, n_salt);
169 111 : gcry_md_final (mdh);
170 111 : digested = gcry_md_read (mdh, 0);
171 111 : g_return_val_if_fail (digested, FALSE);
172 111 : memcpy (digest, digested, n_digest);
173 :
174 135077 : for (i = 1; i < iterations; ++i) {
175 134966 : gcry_md_reset (mdh);
176 134966 : gcry_md_write (mdh, digest, n_digest);
177 134966 : gcry_md_final (mdh);
178 134966 : digested = gcry_md_read (mdh, 0);
179 134966 : g_return_val_if_fail (digested, FALSE);
180 134966 : memcpy (digest, digested, n_digest);
181 : }
182 :
183 : /* Copy as much as possible into the destinations */
184 111 : i = 0;
185 1695 : while (needed_key && i < n_digest) {
186 1584 : if (at_key)
187 1584 : *(at_key++) = digest[i];
188 1584 : needed_key--;
189 1584 : i++;
190 : }
191 1439 : while (needed_iv && i < n_digest) {
192 1328 : if (at_iv)
193 1136 : *(at_iv++) = digest[i];
194 1328 : needed_iv--;
195 1328 : i++;
196 : }
197 :
198 111 : if (needed_key == 0 && needed_iv == 0)
199 91 : break;
200 : }
201 :
202 91 : egg_secure_free (digest);
203 91 : gcry_md_close (mdh);
204 :
205 91 : return TRUE;
206 : }
207 :
208 : gboolean
209 6 : egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
210 : gssize n_password, const guchar *salt, gsize n_salt, int iterations,
211 : guchar **key, guchar **iv)
212 : {
213 : gcry_md_hd_t mdh;
214 : gcry_error_t gcry;
215 : guchar *digest;
216 : guchar *digested;
217 : guint i, n_digest;
218 : gint needed_iv, needed_key;
219 :
220 6 : g_assert (cipher_algo);
221 6 : g_assert (hash_algo);
222 :
223 6 : g_return_val_if_fail (iterations >= 1, FALSE);
224 :
225 6 : if (!password)
226 0 : n_password = 0;
227 6 : if (n_password == -1)
228 1 : n_password = strlen (password);
229 :
230 : /*
231 : * We only do one pass here.
232 : *
233 : * The key ends up as the first needed_key bytes of the hash buffer.
234 : * The iv ends up as the last needed_iv bytes of the hash buffer.
235 : *
236 : * The IV may overlap the key (which is stupid) if the wrong pair of
237 : * hash/cipher algorithms are chosen.
238 : */
239 :
240 6 : n_digest = gcry_md_get_algo_dlen (hash_algo);
241 6 : g_return_val_if_fail (n_digest > 0, FALSE);
242 :
243 6 : needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
244 6 : needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
245 6 : if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) {
246 0 : g_warning ("using PBE symkey generation with %s using an algorithm that needs "
247 : "too many bytes of key and/or IV: %s",
248 : gcry_cipher_algo_name (hash_algo),
249 : gcry_cipher_algo_name (cipher_algo));
250 0 : return FALSE;
251 : }
252 :
253 6 : gcry = gcry_md_open (&mdh, hash_algo, 0);
254 6 : if (gcry) {
255 0 : g_warning ("couldn't create '%s' hash context: %s",
256 : gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
257 0 : return FALSE;
258 : }
259 :
260 6 : digest = egg_secure_alloc (n_digest);
261 6 : g_return_val_if_fail (digest, FALSE);
262 6 : if (key) {
263 6 : *key = egg_secure_alloc (needed_key);
264 6 : g_return_val_if_fail (*key, FALSE);
265 : }
266 6 : if (iv)
267 5 : *iv = g_new0 (guchar, needed_iv);
268 :
269 6 : if (password)
270 6 : gcry_md_write (mdh, password, n_password);
271 6 : if (salt && n_salt)
272 6 : gcry_md_write (mdh, salt, n_salt);
273 6 : gcry_md_final (mdh);
274 6 : digested = gcry_md_read (mdh, 0);
275 6 : g_return_val_if_fail (digested, FALSE);
276 6 : memcpy (digest, digested, n_digest);
277 :
278 10282 : for (i = 1; i < iterations; ++i)
279 10276 : gcry_md_hash_buffer (hash_algo, digest, digest, n_digest);
280 :
281 : /* The first x bytes are the key */
282 6 : if (key) {
283 6 : g_assert (needed_key <= n_digest);
284 6 : memcpy (*key, digest, needed_key);
285 : }
286 :
287 : /* The last 16 - x bytes are the iv */
288 6 : if (iv) {
289 5 : g_assert (needed_iv <= n_digest && n_digest >= 16);
290 5 : memcpy (*iv, digest + (16 - needed_iv), needed_iv);
291 : }
292 :
293 6 : egg_secure_free (digest);
294 6 : gcry_md_close (mdh);
295 :
296 6 : return TRUE;
297 : }
298 :
299 : static gboolean
300 30 : generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
301 : gssize n_password, const guchar *salt, gsize n_salt,
302 : int iterations, guchar *output, gsize n_output)
303 : {
304 : gcry_mpi_t num_b1, num_ij;
305 : guchar *hash, *buf_i, *buf_b;
306 : const gchar *end_password;
307 : gcry_md_hd_t mdh;
308 : const gchar *p2;
309 : guchar *p;
310 : gsize n_hash, i;
311 : gunichar unich;
312 : gcry_error_t gcry;
313 : gsize length;
314 :
315 30 : num_b1 = num_ij = NULL;
316 :
317 30 : n_hash = gcry_md_get_algo_dlen (hash_algo);
318 30 : g_return_val_if_fail (n_hash > 0, FALSE);
319 :
320 30 : if (!utf8_password)
321 1 : n_password = 0;
322 30 : if (n_password == -1)
323 3 : end_password = utf8_password + strlen (utf8_password);
324 : else
325 27 : end_password = utf8_password + n_password;
326 :
327 30 : gcry = gcry_md_open (&mdh, hash_algo, 0);
328 30 : if (gcry) {
329 0 : g_warning ("couldn't create '%s' hash context: %s",
330 : gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
331 0 : return FALSE;
332 : }
333 :
334 : /* Reqisition me a buffer */
335 30 : hash = egg_secure_alloc (n_hash);
336 30 : buf_i = egg_secure_alloc (128);
337 30 : buf_b = egg_secure_alloc (64);
338 30 : g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
339 :
340 : /* Bring in the salt */
341 30 : p = buf_i;
342 30 : if (salt) {
343 1950 : for (i = 0; i < 64; ++i)
344 1920 : *(p++) = salt[i % n_salt];
345 : } else {
346 0 : memset (p, 0, 64);
347 0 : p += 64;
348 : }
349 :
350 : /* Bring in the password, as 16bits per character BMP string, ie: UCS2 */
351 30 : if (utf8_password) {
352 29 : p2 = utf8_password;
353 957 : for (i = 0; i < 64; i += 2) {
354 :
355 : /* Get a character from the string */
356 928 : if (p2 < end_password) {
357 751 : unich = g_utf8_get_char (p2);
358 751 : p2 = g_utf8_next_char (p2);
359 :
360 : /* Get zero null terminator, and loop back to beginning */
361 : } else {
362 177 : unich = 0;
363 177 : p2 = utf8_password;
364 : }
365 :
366 : /* Encode the bytes received */
367 928 : *(p++) = (unich & 0xFF00) >> 8;
368 928 : *(p++) = (unich & 0xFF);
369 : }
370 : } else {
371 1 : memset (p, 0, 64);
372 : }
373 :
374 : /* Hash and bash */
375 : for (;;) {
376 43 : gcry_md_reset (mdh);
377 :
378 : /* Put in the PKCS#12 type of key */
379 2795 : for (i = 0; i < 64; ++i)
380 2752 : gcry_md_putc (mdh, type);
381 :
382 : /* Bring in the password */
383 43 : gcry_md_write (mdh, buf_i, utf8_password ? 128 : 64);
384 :
385 : /* First iteration done */
386 43 : memcpy (hash, gcry_md_read (mdh, hash_algo), n_hash);
387 :
388 : /* All the other iterations */
389 106992 : for (i = 1; i < iterations; i++)
390 106949 : gcry_md_hash_buffer (hash_algo, hash, hash, n_hash);
391 :
392 : /* Take out as much as we need */
393 502 : for (i = 0; i < n_hash && n_output; ++i) {
394 459 : *(output++) = hash[i];
395 459 : --n_output;
396 : }
397 :
398 : /* Is that enough generated keying material? */
399 43 : if (!n_output)
400 30 : break;
401 :
402 : /* Need more bytes, do some voodoo */
403 845 : for (i = 0; i < 64; ++i)
404 832 : buf_b[i] = hash[i % n_hash];
405 13 : gcry = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, NULL);
406 13 : g_return_val_if_fail (gcry == 0, FALSE);
407 13 : gcry_mpi_add_ui (num_b1, num_b1, 1);
408 39 : for (i = 0; i < 128; i += 64) {
409 26 : gcry = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, NULL);
410 26 : g_return_val_if_fail (gcry == 0, FALSE);
411 26 : gcry_mpi_add (num_ij, num_ij, num_b1);
412 26 : gcry_mpi_clear_highbit (num_ij, 64 * 8);
413 : /* We take special care to right align the number in the buffer */
414 26 : gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &length, num_ij);
415 26 : g_return_val_if_fail (gcry == 0 && length <= 64, FALSE);
416 26 : memset (buf_i + i, 0, 64 - length);
417 26 : gcry = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i + (64 - length), 64, NULL, num_ij);
418 26 : g_return_val_if_fail (gcry == 0, FALSE);
419 26 : gcry_mpi_release (num_ij);
420 : }
421 : }
422 :
423 30 : egg_secure_free (buf_i);
424 30 : egg_secure_free (buf_b);
425 30 : egg_secure_free (hash);
426 30 : gcry_mpi_release (num_b1);
427 30 : gcry_md_close (mdh);
428 :
429 30 : return TRUE;
430 : }
431 :
432 : gboolean
433 17 : egg_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
434 : gssize n_password, const guchar *salt, gsize n_salt,
435 : int iterations, guchar **key, guchar **iv)
436 : {
437 : gsize n_block, n_key;
438 17 : gboolean ret = TRUE;
439 :
440 17 : g_return_val_if_fail (cipher_algo, FALSE);
441 17 : g_return_val_if_fail (hash_algo, FALSE);
442 17 : g_return_val_if_fail (iterations > 0, FALSE);
443 :
444 17 : n_key = gcry_cipher_get_algo_keylen (cipher_algo);
445 17 : n_block = gcry_cipher_get_algo_blklen (cipher_algo);
446 :
447 17 : if (password && !g_utf8_validate (password, n_password, NULL)) {
448 0 : g_warning ("invalid non-UTF8 password");
449 0 : g_return_val_if_reached (FALSE);
450 : }
451 :
452 17 : if (key)
453 17 : *key = NULL;
454 17 : if (iv)
455 12 : *iv = NULL;
456 :
457 : /* Generate us an key */
458 17 : if (key) {
459 17 : *key = egg_secure_alloc (n_key);
460 17 : g_return_val_if_fail (*key != NULL, FALSE);
461 17 : ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt,
462 : iterations, *key, n_key);
463 : }
464 :
465 : /* Generate us an iv */
466 17 : if (ret && iv) {
467 12 : if (n_block > 1) {
468 12 : *iv = g_malloc (n_block);
469 12 : ret = generate_pkcs12 (hash_algo, 2, password, n_password, salt, n_salt,
470 : iterations, *iv, n_block);
471 : } else {
472 0 : *iv = NULL;
473 : }
474 : }
475 :
476 : /* Cleanup in case of failure */
477 17 : if (!ret) {
478 0 : g_free (iv ? *iv : NULL);
479 0 : egg_secure_free (key ? *key : NULL);
480 : }
481 :
482 17 : return ret;
483 : }
484 :
485 : gboolean
486 1 : egg_symkey_generate_pkcs12_mac (int hash_algo,
487 : const gchar *password,
488 : gssize n_password,
489 : const guchar *salt,
490 : gsize n_salt,
491 : int iterations,
492 : guchar **key)
493 : {
494 : gsize n_key;
495 1 : gboolean ret = TRUE;
496 :
497 1 : g_return_val_if_fail (hash_algo, FALSE);
498 1 : g_return_val_if_fail (iterations > 0, FALSE);
499 :
500 1 : n_key = gcry_md_get_algo_dlen (hash_algo);
501 :
502 1 : if (password && !g_utf8_validate (password, n_password, NULL)) {
503 0 : g_warning ("invalid non-UTF8 password");
504 0 : g_return_val_if_reached (FALSE);
505 : }
506 :
507 : /* Generate us an key */
508 1 : if (key) {
509 1 : *key = egg_secure_alloc (n_key);
510 1 : g_return_val_if_fail (*key != NULL, FALSE);
511 1 : ret = generate_pkcs12 (hash_algo, 3, password, n_password, salt, n_salt,
512 : iterations, *key, n_key);
513 : }
514 :
515 : /* Cleanup in case of failure */
516 1 : if (!key)
517 0 : egg_secure_free (key ? *key : NULL);
518 :
519 1 : return ret;
520 : }
521 :
522 : static gboolean
523 13 : generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
524 : const guchar *salt, gsize n_salt, guint iterations,
525 : guchar *output, gsize n_output)
526 : {
527 : gcry_md_hd_t mdh;
528 : guint u, l, r, i, k;
529 : gcry_error_t gcry;
530 : guchar *U, *T, *buf;
531 : gsize n_buf, n_hash;
532 :
533 13 : g_return_val_if_fail (hash_algo > 0, FALSE);
534 13 : g_return_val_if_fail (iterations > 0, FALSE);
535 13 : g_return_val_if_fail (n_output > 0, FALSE);
536 13 : g_return_val_if_fail (n_output < G_MAXUINT32, FALSE);
537 :
538 13 : n_hash = gcry_md_get_algo_dlen (hash_algo);
539 13 : g_return_val_if_fail (n_hash > 0, FALSE);
540 :
541 13 : gcry = gcry_md_open (&mdh, hash_algo, GCRY_MD_FLAG_HMAC);
542 13 : if (gcry != 0) {
543 0 : g_warning ("couldn't create '%s' hash context: %s",
544 : gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
545 0 : return FALSE;
546 : }
547 :
548 : /* Get us a temporary buffers */
549 13 : T = egg_secure_alloc (n_hash);
550 13 : U = egg_secure_alloc (n_hash);
551 13 : n_buf = n_salt + 4;
552 13 : buf = egg_secure_alloc (n_buf);
553 13 : g_return_val_if_fail (buf && T && U, FALSE);
554 :
555 : /* n_hash blocks in output, rounding up */
556 13 : l = ((n_output - 1) / n_hash) + 1;
557 :
558 : /* number of bytes in last, rounded up, n_hash block */
559 13 : r = n_output - (l - 1) * n_hash;
560 :
561 13 : memcpy (buf, salt, n_salt);
562 37 : for (i = 1; i <= l; i++) {
563 24 : memset (T, 0, n_hash);
564 43131 : for (u = 1; u <= iterations; u++) {
565 43107 : gcry_md_reset (mdh);
566 :
567 43107 : gcry = gcry_md_setkey (mdh, password, n_password);
568 43107 : g_return_val_if_fail (gcry == 0, FALSE);
569 :
570 : /* For first iteration on each block add 4 extra bytes */
571 43107 : if (u == 1) {
572 24 : buf[n_salt + 0] = (i & 0xff000000) >> 24;
573 24 : buf[n_salt + 1] = (i & 0x00ff0000) >> 16;
574 24 : buf[n_salt + 2] = (i & 0x0000ff00) >> 8;
575 24 : buf[n_salt + 3] = (i & 0x000000ff) >> 0;
576 :
577 24 : gcry_md_write (mdh, buf, n_buf);
578 :
579 : /* Other iterations, any block */
580 : } else {
581 43083 : gcry_md_write (mdh, U, n_hash);
582 : }
583 :
584 43107 : memcpy (U, gcry_md_read (mdh, hash_algo), n_hash);
585 :
586 905247 : for (k = 0; k < n_hash; k++)
587 862140 : T[k] ^= U[k];
588 : }
589 :
590 24 : memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
591 : }
592 :
593 13 : egg_secure_free (T);
594 13 : egg_secure_free (U);
595 13 : egg_secure_free (buf);
596 13 : gcry_md_close (mdh);
597 13 : return TRUE;
598 : }
599 :
600 : gboolean
601 13 : egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
602 : const gchar *password, gssize n_password,
603 : const guchar *salt, gsize n_salt, int iterations,
604 : guchar **key, guchar **iv)
605 : {
606 : gsize n_key, n_block;
607 13 : gboolean ret = TRUE;
608 :
609 13 : g_return_val_if_fail (hash_algo, FALSE);
610 13 : g_return_val_if_fail (cipher_algo, FALSE);
611 13 : g_return_val_if_fail (iterations > 0, FALSE);
612 :
613 13 : n_key = gcry_cipher_get_algo_keylen (cipher_algo);
614 13 : n_block = gcry_cipher_get_algo_blklen (cipher_algo);
615 :
616 13 : if (key)
617 13 : *key = NULL;
618 13 : if (iv)
619 0 : *iv = NULL;
620 :
621 13 : if (!password)
622 3 : n_password = 0;
623 13 : if (n_password == -1)
624 2 : n_password = strlen (password);
625 :
626 : /* Generate us an key */
627 13 : if (key) {
628 13 : *key = egg_secure_alloc (n_key);
629 13 : g_return_val_if_fail (*key != NULL, FALSE);
630 13 : ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt,
631 : iterations, *key, n_key);
632 : }
633 :
634 : /* Generate us an iv */
635 13 : if (ret && iv) {
636 0 : if (n_block > 1) {
637 0 : *iv = g_malloc (n_block);
638 0 : gcry_create_nonce (*iv, n_block);
639 : } else {
640 0 : *iv = NULL;
641 : }
642 : }
643 :
644 : /* Cleanup in case of failure */
645 13 : if (!ret) {
646 0 : g_free (iv ? *iv : NULL);
647 0 : egg_secure_free (key ? *key : NULL);
648 : }
649 :
650 13 : return ret;
651 : }
652 :
653 : /* ----------------------------------------------------------------------------
654 : * DER encoded cipher params
655 : */
656 :
657 :
658 : static gboolean
659 6 : read_cipher_pkcs5_pbe (int cipher_algo,
660 : int cipher_mode,
661 : int hash_algo,
662 : const gchar *password,
663 : gsize n_password,
664 : GNode *data,
665 : gcry_cipher_hd_t *cih)
666 : {
667 6 : GNode *asn = NULL;
668 : gcry_error_t gcry;
669 6 : GBytes *salt = NULL;
670 : gsize n_block, n_key;
671 : gulong iterations;
672 6 : guchar *key = NULL;
673 6 : guchar *iv = NULL;
674 : gboolean ret;
675 :
676 6 : g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
677 6 : g_return_val_if_fail (cih != NULL, FALSE);
678 6 : g_return_val_if_fail (data != NULL, FALSE);
679 :
680 6 : *cih = NULL;
681 6 : ret = FALSE;
682 :
683 : /* Check if we can use this algorithm */
684 12 : if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
685 6 : gcry_md_test_algo (hash_algo) != 0)
686 0 : goto done;
687 :
688 6 : asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBE-params");
689 6 : g_return_val_if_fail (asn, FALSE);
690 :
691 6 : if (!egg_asn1x_get_any_into (data, asn))
692 1 : goto done;
693 :
694 5 : salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", NULL));
695 5 : g_return_val_if_fail (salt != NULL, FALSE);
696 5 : if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
697 0 : g_return_val_if_reached (FALSE);
698 :
699 5 : n_key = gcry_cipher_get_algo_keylen (cipher_algo);
700 5 : g_return_val_if_fail (n_key > 0, FALSE);
701 5 : n_block = gcry_cipher_get_algo_blklen (cipher_algo);
702 :
703 10 : if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password,
704 5 : g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
705 : iterations, &key, n_block > 1 ? &iv : NULL))
706 0 : goto done;
707 :
708 5 : gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
709 5 : if (gcry != 0) {
710 0 : g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
711 0 : goto done;
712 : }
713 :
714 5 : if (iv)
715 5 : gcry_cipher_setiv (*cih, iv, n_block);
716 5 : gcry_cipher_setkey (*cih, key, n_key);
717 :
718 5 : ret = TRUE;
719 :
720 6 : done:
721 6 : g_free (iv);
722 6 : if (salt != NULL)
723 5 : g_bytes_unref (salt);
724 6 : egg_secure_free (key);
725 6 : egg_asn1x_destroy (asn);
726 :
727 6 : return ret;
728 : }
729 :
730 : #if NOT_SUPPORTED
731 : static gboolean
732 : setup_pkcs5_rc2_params (GNode *any,
733 : gcry_cipher_hd_t cih)
734 : {
735 : GNode *asn = NULL;
736 : gcry_error_t gcry;
737 : GBytes *iv = NULL;
738 : gulong version;
739 : gboolean ret = FALSE;
740 :
741 : g_assert (any != NULL);
742 :
743 : asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-rc2-CBC-params");
744 : if (asn == NULL)
745 : goto done;
746 :
747 : if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "rc2ParameterVersion", NULL), &version))
748 : goto done;
749 :
750 : iv = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "iv", NULL));
751 : if (!iv)
752 : goto done;
753 :
754 : gcry = gcry_cipher_setiv (cih, g_bytes_get_data (iv, NULL), g_bytes_get_size (iv));
755 : if (gcry != 0) {
756 : g_message ("couldn't set %lu byte iv on cipher", (gulong)g_bytes_get_size (iv));
757 : goto done;
758 : }
759 :
760 : ret = TRUE;
761 :
762 : done:
763 : if (iv != NULL)
764 : g_bytes_unref (iv);
765 : egg_asn1x_destroy (asn);
766 : return ret;
767 : }
768 : #endif
769 :
770 : static gboolean
771 15 : setup_pkcs5_des_params (GNode *any,
772 : gcry_cipher_hd_t cih)
773 : {
774 15 : GNode *asn = NULL;
775 : gcry_error_t gcry;
776 : GBytes *iv;
777 : gboolean ret;
778 :
779 15 : g_assert (any != NULL);
780 :
781 15 : asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params");
782 15 : if (!asn)
783 1 : asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-des-CBC-params");
784 15 : if (!asn)
785 1 : return FALSE;
786 :
787 14 : iv = egg_asn1x_get_string_as_bytes (asn);
788 14 : egg_asn1x_destroy (asn);
789 :
790 14 : if (!iv)
791 0 : return FALSE;
792 :
793 14 : gcry = gcry_cipher_setiv (cih, g_bytes_get_data (iv, NULL), g_bytes_get_size (iv));
794 14 : if (gcry != 0) {
795 0 : g_message ("couldn't set %lu byte iv on cipher", (gulong)g_bytes_get_size (iv));
796 0 : ret = FALSE;
797 : } else {
798 14 : ret = TRUE;
799 : }
800 :
801 14 : g_bytes_unref (iv);
802 14 : return ret;
803 : }
804 :
805 : static gboolean
806 13 : setup_pkcs5_pbkdf2_params (const gchar *password,
807 : gsize n_password,
808 : GNode *any,
809 : int cipher_algo,
810 : gcry_cipher_hd_t cih)
811 : {
812 13 : GNode *asn = NULL;
813 : gboolean ret;
814 : gcry_error_t gcry;
815 13 : guchar *key = NULL;
816 13 : GBytes *salt = NULL;
817 : gsize n_key;
818 : gulong iterations;
819 :
820 13 : g_assert (cipher_algo);
821 13 : g_assert (any != NULL);
822 :
823 13 : ret = FALSE;
824 :
825 13 : asn = egg_asn1x_get_any_as (any, pkix_asn1_tab, "pkcs-5-PBKDF2-params");
826 13 : if (!asn)
827 1 : goto done;
828 :
829 12 : if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
830 0 : g_return_val_if_reached (FALSE);
831 12 : salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", "specified", NULL));
832 12 : if (!salt)
833 1 : goto done;
834 :
835 22 : if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
836 11 : g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
837 : iterations, &key, NULL))
838 0 : goto done;
839 :
840 11 : n_key = gcry_cipher_get_algo_keylen (cipher_algo);
841 11 : g_return_val_if_fail (n_key > 0, FALSE);
842 :
843 11 : gcry = gcry_cipher_setkey (cih, key, n_key);
844 11 : if (gcry != 0) {
845 0 : g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
846 0 : goto done;
847 : }
848 :
849 11 : ret = TRUE;
850 :
851 13 : done:
852 13 : if (salt != NULL)
853 11 : g_bytes_unref (salt);
854 13 : egg_secure_free (key);
855 13 : egg_asn1x_destroy (asn);
856 13 : return ret;
857 : }
858 :
859 : static gboolean
860 17 : read_cipher_pkcs5_pbes2 (const gchar *password,
861 : gsize n_password,
862 : GNode *data,
863 : gcry_cipher_hd_t *cih)
864 : {
865 17 : GNode *asn = NULL;
866 : gboolean r, ret;
867 : GQuark key_deriv_algo, enc_oid;
868 17 : GNode *params = NULL;
869 : gcry_error_t gcry;
870 : int algo, mode;
871 :
872 17 : g_return_val_if_fail (cih != NULL, FALSE);
873 17 : g_return_val_if_fail (data != NULL, FALSE);
874 :
875 17 : init_quarks ();
876 :
877 17 : *cih = NULL;
878 17 : ret = FALSE;
879 :
880 17 : asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-5-PBES2-params");
881 17 : if (!asn)
882 1 : goto done;
883 :
884 16 : algo = mode = 0;
885 :
886 : /* Read in all the encryption type */
887 16 : enc_oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionScheme", "algorithm", NULL));
888 16 : if (!enc_oid)
889 0 : goto done;
890 16 : if (enc_oid == OID_DES_EDE3_CBC)
891 13 : algo = GCRY_CIPHER_3DES;
892 3 : else if (enc_oid == OID_DES_CBC)
893 2 : algo = GCRY_CIPHER_DES;
894 1 : else if (enc_oid == OID_DES_RC2_CBC)
895 : /* GCRY_CIPHER_RFC2268_128 isn't actually implemented in libgcrypt (yet?) */;
896 1 : else if (enc_oid == OID_DES_RC5_CBC)
897 : /* RC5 doesn't exist in libgcrypt */;
898 :
899 : /* Unsupported? */
900 16 : if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
901 1 : goto done;
902 :
903 : /* Instantiate our cipher */
904 15 : gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
905 15 : if (gcry != 0) {
906 0 : g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo)); /* UNREACHABLE: */
907 0 : goto done; /* UNREACHABLE: with normal libgcrypt behavior */
908 : }
909 :
910 : /* Read out the parameters. OPTIONAL, but will always find node */
911 15 : params = egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL);
912 15 : g_return_val_if_fail (params != NULL, FALSE);
913 :
914 15 : switch (algo) {
915 15 : case GCRY_CIPHER_3DES:
916 : case GCRY_CIPHER_DES:
917 15 : r = setup_pkcs5_des_params (params, *cih);
918 15 : break;
919 : #if 0
920 : case GCRY_CIPHER_RFC2268_128:
921 : r = setup_pkcs5_rc2_params (params, *cih);
922 : break;
923 : #endif
924 0 : default:
925 : /* Should have been caught on the oid check above */
926 0 : g_assert_not_reached ();
927 : r = FALSE;
928 : break;
929 : };
930 :
931 15 : if (r != TRUE)
932 1 : goto done;
933 :
934 : /* Read out the key creation paramaters */
935 14 : key_deriv_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "keyDerivationFunc", "algorithm", NULL));
936 14 : if (!key_deriv_algo)
937 0 : goto done;
938 14 : if (key_deriv_algo != OID_PBKDF2) {
939 1 : g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
940 1 : goto done;
941 : }
942 :
943 : /* parameters is OPTIONAL, but will always find node */
944 13 : params = egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL);
945 13 : g_return_val_if_fail (params != NULL, FALSE);
946 :
947 13 : ret = setup_pkcs5_pbkdf2_params (password, n_password, params, algo, *cih);
948 :
949 17 : done:
950 17 : if (ret != TRUE && *cih) {
951 4 : gcry_cipher_close (*cih);
952 4 : *cih = NULL;
953 : }
954 :
955 17 : egg_asn1x_destroy (asn);
956 17 : return ret;
957 : }
958 :
959 : static gboolean
960 9 : read_cipher_pkcs12_pbe (int cipher_algo,
961 : int cipher_mode,
962 : const gchar *password,
963 : gsize n_password,
964 : GNode *data,
965 : gcry_cipher_hd_t *cih)
966 : {
967 9 : GNode *asn = NULL;
968 : gcry_error_t gcry;
969 : gboolean ret;
970 9 : GBytes *salt = NULL;
971 : gsize n_block, n_key;
972 : gulong iterations;
973 9 : guchar *key = NULL;
974 9 : guchar *iv = NULL;
975 :
976 9 : g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
977 9 : g_return_val_if_fail (cih != NULL, FALSE);
978 9 : g_return_val_if_fail (data != NULL, FALSE);
979 :
980 9 : *cih = NULL;
981 9 : ret = FALSE;
982 :
983 : /* Check if we can use this algorithm */
984 9 : if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
985 0 : goto done;
986 :
987 9 : asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-12-PbeParams");
988 9 : if (!asn)
989 1 : goto done;
990 :
991 8 : salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "salt", NULL));
992 8 : g_return_val_if_fail (salt != NULL, FALSE);
993 8 : if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &iterations))
994 0 : g_return_val_if_reached (FALSE);
995 :
996 8 : n_block = gcry_cipher_get_algo_blklen (cipher_algo);
997 8 : n_key = gcry_cipher_get_algo_keylen (cipher_algo);
998 :
999 : /* Generate IV and key using salt read above */
1000 16 : if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, n_password,
1001 8 : g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
1002 : iterations, &key, n_block > 1 ? &iv : NULL))
1003 0 : goto done;
1004 :
1005 8 : gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
1006 8 : if (gcry != 0) {
1007 0 : g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
1008 0 : goto done;
1009 : }
1010 :
1011 8 : if (iv)
1012 7 : gcry_cipher_setiv (*cih, iv, n_block);
1013 8 : gcry_cipher_setkey (*cih, key, n_key);
1014 :
1015 8 : ret = TRUE;
1016 :
1017 9 : done:
1018 9 : if (ret != TRUE && *cih) {
1019 0 : gcry_cipher_close (*cih);
1020 0 : *cih = NULL;
1021 : }
1022 :
1023 9 : if (salt != NULL)
1024 8 : g_bytes_unref (salt);
1025 9 : g_free (iv);
1026 9 : egg_secure_free (key);
1027 9 : egg_asn1x_destroy (asn);
1028 9 : return ret;
1029 : }
1030 :
1031 : static gboolean
1032 2 : read_mac_pkcs12_pbe (int hash_algo,
1033 : const gchar *password,
1034 : gsize n_password,
1035 : GNode *data,
1036 : gcry_md_hd_t *mdh,
1037 : gsize *digest_len)
1038 : {
1039 2 : GNode *asn = NULL;
1040 : gcry_error_t gcry;
1041 : gboolean ret;
1042 : gsize n_key;
1043 2 : GBytes *salt = NULL;
1044 : gulong iterations;
1045 2 : guchar *key = NULL;
1046 :
1047 2 : g_return_val_if_fail (hash_algo != 0, FALSE);
1048 2 : g_return_val_if_fail (mdh != NULL, FALSE);
1049 2 : g_return_val_if_fail (data != NULL, FALSE);
1050 :
1051 2 : *mdh = NULL;
1052 2 : ret = FALSE;
1053 :
1054 : /* Check if we can use this algorithm */
1055 2 : if (gcry_md_algo_info (hash_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
1056 0 : goto done; /* UNREACHABLE: unless libgcrypt changes behavior */
1057 :
1058 2 : if (egg_asn1x_type (data) == EGG_ASN1X_ANY) {
1059 2 : asn = egg_asn1x_get_any_as (data, pkix_asn1_tab, "pkcs-12-MacData");
1060 2 : if (!asn)
1061 1 : goto done;
1062 1 : data = asn;
1063 : }
1064 :
1065 1 : salt = egg_asn1x_get_string_as_bytes (egg_asn1x_node (data, "macSalt", NULL));
1066 1 : if (!salt)
1067 0 : g_return_val_if_reached (FALSE);
1068 1 : if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (data, "iterations", NULL), &iterations))
1069 0 : g_return_val_if_reached (FALSE);
1070 :
1071 1 : n_key = gcry_md_get_algo_dlen (hash_algo);
1072 :
1073 : /* Generate IV and key using salt read above */
1074 2 : if (!egg_symkey_generate_pkcs12_mac (hash_algo, password, n_password,
1075 1 : g_bytes_get_data (salt, NULL), g_bytes_get_size (salt),
1076 : iterations, &key))
1077 0 : goto done;
1078 :
1079 1 : gcry = gcry_md_open (mdh, hash_algo, GCRY_MD_FLAG_HMAC);
1080 1 : if (gcry != 0) {
1081 0 : g_warning ("couldn't create mac digest: %s", gcry_strerror (gcry));
1082 0 : goto done;
1083 : }
1084 :
1085 1 : if (digest_len)
1086 1 : *digest_len = n_key;
1087 1 : gcry_md_setkey (*mdh, key, n_key);
1088 :
1089 1 : ret = TRUE;
1090 :
1091 2 : done:
1092 2 : if (ret != TRUE && *mdh) {
1093 0 : gcry_md_close (*mdh);
1094 0 : *mdh = NULL;
1095 : }
1096 :
1097 2 : if (salt != NULL)
1098 1 : g_bytes_unref (salt);
1099 2 : egg_secure_free (key);
1100 2 : egg_asn1x_destroy (asn);
1101 2 : return ret;
1102 : }
1103 :
1104 : gboolean
1105 32 : egg_symkey_read_cipher (GQuark oid_scheme,
1106 : const gchar *password,
1107 : gsize n_password,
1108 : GNode *data,
1109 : gcry_cipher_hd_t *cih)
1110 : {
1111 32 : gboolean ret = FALSE;
1112 :
1113 32 : g_return_val_if_fail (oid_scheme != 0, FALSE);
1114 32 : g_return_val_if_fail (cih != NULL, FALSE);
1115 32 : g_return_val_if_fail (data != NULL, FALSE);
1116 :
1117 32 : init_quarks ();
1118 :
1119 : /* PKCS#5 PBE */
1120 32 : if (oid_scheme == OID_PBE_MD2_DES_CBC)
1121 0 : ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1122 : GCRY_MD_MD2, password, n_password, data, cih);
1123 :
1124 32 : else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
1125 : /* RC2-64 has no implementation in libgcrypt */;
1126 :
1127 32 : else if (oid_scheme == OID_PBE_MD5_DES_CBC)
1128 3 : ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1129 : GCRY_MD_MD5, password, n_password, data, cih);
1130 29 : else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
1131 : /* RC2-64 has no implementation in libgcrypt */;
1132 :
1133 29 : else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
1134 3 : ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
1135 : GCRY_MD_SHA1, password, n_password, data, cih);
1136 26 : else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
1137 : /* RC2-64 has no implementation in libgcrypt */;
1138 :
1139 :
1140 : /* PKCS#5 PBES2 */
1141 26 : else if (oid_scheme == OID_PBES2)
1142 17 : ret = read_cipher_pkcs5_pbes2 (password, n_password, data, cih);
1143 :
1144 :
1145 : /* PKCS#12 PBE */
1146 9 : else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
1147 1 : ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
1148 : password, n_password, data, cih);
1149 8 : else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
1150 : /* RC4-40 has no implementation in libgcrypt */;
1151 :
1152 8 : else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
1153 7 : ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
1154 : password, n_password, data, cih);
1155 1 : else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1)
1156 : /* 2DES has no implementation in libgcrypt */;
1157 :
1158 1 : else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
1159 0 : ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
1160 : password, n_password, data, cih);
1161 :
1162 1 : else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
1163 1 : ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
1164 : password, n_password, data, cih);
1165 :
1166 32 : if (ret == FALSE)
1167 8 : g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
1168 :
1169 32 : return ret;
1170 : }
1171 :
1172 : gboolean
1173 2 : egg_symkey_read_mac (GQuark oid_scheme,
1174 : const gchar *password,
1175 : gsize n_password,
1176 : GNode *data,
1177 : gcry_md_hd_t *mdh,
1178 : gsize *digest_len)
1179 : {
1180 2 : gboolean ret = FALSE;
1181 :
1182 2 : g_return_val_if_fail (oid_scheme != 0, FALSE);
1183 2 : g_return_val_if_fail (mdh != NULL, FALSE);
1184 2 : g_return_val_if_fail (data != NULL, FALSE);
1185 :
1186 2 : init_quarks ();
1187 :
1188 : /* PKCS#12 MAC with SHA-1 */
1189 2 : if (oid_scheme == OID_SHA1)
1190 2 : ret = read_mac_pkcs12_pbe (GCRY_MD_SHA1, password, n_password,
1191 : data, mdh, digest_len);
1192 :
1193 2 : if (ret == FALSE)
1194 1 : g_message ("unsupported or invalid mac: %s", g_quark_to_string (oid_scheme));
1195 :
1196 2 : return ret;
1197 : }
|