aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/gnutls_x509.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls/gnutls_x509.c')
-rw-r--r--src/daemon/https/tls/gnutls_x509.c449
1 files changed, 18 insertions, 431 deletions
diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c
index 067d78da..35322db4 100644
--- a/src/daemon/https/tls/gnutls_x509.c
+++ b/src/daemon/https/tls/gnutls_x509.c
@@ -249,8 +249,8 @@ _gnutls_check_key_cert_match (mhd_gtls_cert_credentials_t res)
249} 249}
250 250
251/* Reads a DER encoded certificate list from memory and stores it to 251/* Reads a DER encoded certificate list from memory and stores it to
252 * a gnutls_cert structure. This is only called if PKCS7 read fails. 252 * a gnutls_cert structure.
253 * returns the number of certificates parsed (1) 253 * Returns the number of certificates parsed.
254 */ 254 */
255static int 255static int
256parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts, 256parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts,
@@ -284,8 +284,8 @@ parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts,
284} 284}
285 285
286/* Reads a DER encoded certificate list from memory and stores it to 286/* Reads a DER encoded certificate list from memory and stores it to
287 * a gnutls_cert structure. This is only called if PKCS7 read fails. 287 * a gnutls_cert structure.
288 * returns the number of certificates parsed (1) 288 * Returns the number of certificates parsed.
289 */ 289 */
290static int 290static int
291parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts, 291parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
@@ -319,134 +319,6 @@ parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
319 return ret; 319 return ret;
320} 320}
321 321
322#define CERT_PEM 1
323
324
325/* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
326 * a gnutls_cert structure.
327 * returns the number of certificate parsed
328 */
329static int
330parse_pkcs7_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts, const
331 void *input_cert, int input_cert_size, int flags)
332{
333#ifdef ENABLE_PKI
334 int i, j, count;
335 gnutls_datum_t tmp, tmp2;
336 int ret;
337 opaque *pcert = NULL;
338 size_t pcert_size;
339 gnutls_pkcs7_t pkcs7;
340
341 ret = gnutls_pkcs7_init (&pkcs7);
342 if (ret < 0)
343 {
344 gnutls_assert ();
345 return ret;
346 }
347 tmp.data = (opaque * ) input_cert;
348 tmp.size = input_cert_size;
349 if (flags & CERT_PEM)
350 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_PEM);
351 else
352 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_DER);
353 if (ret < 0)
354 {
355 /* if we failed to read the structure,
356 * then just try to decode a plain DER
357 * certificate.
358 */
359 gnutls_assert ();
360 gnutls_pkcs7_deinit (pkcs7);
361#endif
362 return parse_der_cert_mem (cert_list, ncerts,
363 input_cert, input_cert_size);
364#ifdef ENABLE_PKI
365 }
366
367 i = *ncerts + 1;
368
369 /* tmp now contains the decoded certificate list */
370 tmp.data = (opaque *) input_cert;
371 tmp.size = input_cert_size;
372
373 ret = gnutls_pkcs7_get_crt_count (pkcs7);
374
375 if (ret < 0)
376 {
377 gnutls_assert ();
378 gnutls_pkcs7_deinit (pkcs7);
379 return ret;
380 }
381 count = ret;
382
383 j = count - 1;
384 do
385 {
386 pcert_size = 0;
387 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, NULL, &pcert_size);
388 if (ret != GNUTLS_E_MEMORY_ERROR)
389 {
390 count--;
391 continue;
392 }
393
394 pcert = gnutls_malloc (pcert_size);
395 if (ret == GNUTLS_E_MEMORY_ERROR)
396 {
397 gnutls_assert ();
398 count--;
399 continue;
400 }
401
402 /* read the certificate
403 */
404 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, pcert, &pcert_size);
405
406 j--;
407
408 if (ret >= 0)
409 {
410 *cert_list =
411 (gnutls_cert *) mhd_gtls_realloc_fast (*cert_list,
412 i * sizeof (gnutls_cert));
413
414 if (*cert_list == NULL)
415 {
416 gnutls_assert ();
417 gnutls_free (pcert);
418 return GNUTLS_E_MEMORY_ERROR;
419 }
420
421 tmp2.data = pcert;
422 tmp2.size = pcert_size;
423
424 ret =
425 mhd_gtls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp2, 0);
426
427 if (ret < 0)
428 {
429 gnutls_assert ();
430 gnutls_pkcs7_deinit (pkcs7);
431 gnutls_free (pcert);
432 return ret;
433 }
434
435 i++;
436 }
437
438 gnutls_free (pcert);
439
440 }
441 while (ret >= 0 && j >= 0);
442
443 *ncerts = i - 1;
444
445 gnutls_pkcs7_deinit (pkcs7);
446 return count;
447#endif
448}
449
450/* Reads a base64 encoded certificate list from memory and stores it to 322/* Reads a base64 encoded certificate list from memory and stores it to
451 * a gnutls_cert structure. Returns the number of certificate parsed. 323 * a gnutls_cert structure. Returns the number of certificate parsed.
452 */ 324 */
@@ -460,18 +332,6 @@ parse_pem_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
460 gnutls_datum_t tmp; 332 gnutls_datum_t tmp;
461 int ret, count; 333 int ret, count;
462 334
463#ifdef ENABLE_PKI
464 if ((ptr = memmem (input_cert, input_cert_size,
465 PEM_PKCS7_SEP, sizeof (PEM_PKCS7_SEP) - 1)) != NULL)
466 {
467 size = strlen (ptr);
468
469 ret = parse_pkcs7_cert_mem (cert_list, ncerts, ptr, size, CERT_PEM);
470
471 return ret;
472 }
473#endif
474
475 /* move to the certificate 335 /* move to the certificate
476 */ 336 */
477 ptr = memmem (input_cert, input_cert_size, 337 ptr = memmem (input_cert, input_cert_size,
@@ -493,7 +353,7 @@ parse_pem_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
493 do 353 do
494 { 354 {
495 355
496 siz2 = _gnutls_fbase64_decode (NULL, ptr, size, &ptr2); 356 siz2 = _gnutls_fbase64_decode (NULL, (const unsigned char*) ptr, size, &ptr2);
497 357
498 if (siz2 < 0) 358 if (siz2 < 0)
499 { 359 {
@@ -590,9 +450,9 @@ read_cert_mem (mhd_gtls_cert_credentials_t res, const void *cert,
590 res->cert_list_length[res->ncerts] = 0; 450 res->cert_list_length[res->ncerts] = 0;
591 451
592 if (type == GNUTLS_X509_FMT_DER) 452 if (type == GNUTLS_X509_FMT_DER)
593 ret = parse_pkcs7_cert_mem (&res->cert_list[res->ncerts], 453 ret = parse_der_cert_mem (&res->cert_list[res->ncerts],
594 &res->cert_list_length[res->ncerts], 454 &res->cert_list_length[res->ncerts],
595 cert, cert_size, 0); 455 cert, cert_size);
596 else 456 else
597 ret = 457 ret =
598 parse_pem_cert_mem (&res->cert_list[res->ncerts], 458 parse_pem_cert_mem (&res->cert_list[res->ncerts],
@@ -672,11 +532,13 @@ _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
672 532
673 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type); 533 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
674 534
535#ifdef ENABLE_PKI
675 /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */ 536 /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */
676 if (ret < 0) 537 if (ret < 0)
677 ret = 538 ret =
678 gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL, 539 gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL,
679 GNUTLS_PKCS_PLAIN); 540 GNUTLS_PKCS_PLAIN);
541#endif
680 542
681 if (ret < 0) 543 if (ret < 0)
682 { 544 {
@@ -1088,7 +950,7 @@ parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1088 ptr3 = memmem (ptr, size, 950 ptr3 = memmem (ptr, size,
1089 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1); 951 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1090 952
1091 ptr = ptr3; 953 ptr = (const opaque *) ptr3;
1092 size = input_cert_size - (ptr - input_cert); 954 size = input_cert_size - (ptr - input_cert);
1093 } 955 }
1094 else 956 else
@@ -1106,8 +968,8 @@ parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1106} 968}
1107 969
1108/* Reads a DER encoded certificate list from memory and stores it to 970/* Reads a DER encoded certificate list from memory and stores it to
1109 * a gnutls_cert structure. This is only called if PKCS7 read fails. 971 * a gnutls_cert structure.
1110 * returns the number of certificates parsed (1) 972 * returns the number of certificates parsed.
1111 */ 973 */
1112static int 974static int
1113parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts, 975parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
@@ -1218,7 +1080,7 @@ MHD_gnutls_certificate_set_x509_trust_file (mhd_gtls_cert_credentials_t
1218{ 1080{
1219 int ret, ret2; 1081 int ret, ret2;
1220 size_t size; 1082 size_t size;
1221 char *data = read_binary_file (cafile, &size); 1083 unsigned char *data = (unsigned char*) read_binary_file (cafile, &size);
1222 1084
1223 if (data == NULL) 1085 if (data == NULL)
1224 { 1086 {
@@ -1292,8 +1154,8 @@ parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1292 gnutls_assert (); 1154 gnutls_assert ();
1293 return ret; 1155 return ret;
1294 } 1156 }
1295 1157
1296 tmp.data = (char *) ptr; 1158 tmp.data = (unsigned char *) ptr;
1297 tmp.size = size; 1159 tmp.size = size;
1298 1160
1299 ret = 1161 ret =
@@ -1329,8 +1191,8 @@ parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1329} 1191}
1330 1192
1331/* Reads a DER encoded certificate list from memory and stores it to 1193/* Reads a DER encoded certificate list from memory and stores it to
1332 * a gnutls_cert structure. This is only called if PKCS7 read fails. 1194 * a gnutls_cert structure.
1333 * returns the number of certificates parsed (1) 1195 * returns the number of certificates parsed.
1334 */ 1196 */
1335static int 1197static int
1336parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls, 1198parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
@@ -1461,7 +1323,7 @@ MHD_gnutls_certificate_set_x509_crl_file (mhd_gtls_cert_credentials_t
1461{ 1323{
1462 int ret; 1324 int ret;
1463 size_t size; 1325 size_t size;
1464 char *data = read_binary_file (crlfile, &size); 1326 unsigned char *data = (unsigned char*) read_binary_file (crlfile, &size);
1465 1327
1466 if (data == NULL) 1328 if (data == NULL)
1467 { 1329 {
@@ -1489,281 +1351,6 @@ MHD_gnutls_certificate_set_x509_crl_file (mhd_gtls_cert_credentials_t
1489 1351
1490#include <pkcs12.h> 1352#include <pkcs12.h>
1491 1353
1492static int
1493parse_pkcs12 (mhd_gtls_cert_credentials_t res,
1494 gnutls_pkcs12_t p12,
1495 const char *password,
1496 gnutls_x509_privkey_t * key,
1497 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1498{
1499 gnutls_pkcs12_bag_t bag = NULL;
1500 int index = 0;
1501 int ret;
1502
1503 for (;;)
1504 {
1505 int elements_in_bag;
1506 int i;
1507
1508 ret = gnutls_pkcs12_bag_init (&bag);
1509 if (ret < 0)
1510 {
1511 bag = NULL;
1512 gnutls_assert ();
1513 goto done;
1514 }
1515
1516 ret = gnutls_pkcs12_get_bag (p12, index, bag);
1517 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1518 break;
1519 if (ret < 0)
1520 {
1521 gnutls_assert ();
1522 goto done;
1523 }
1524
1525 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1526 if (ret < 0)
1527 {
1528 gnutls_assert ();
1529 goto done;
1530 }
1531
1532 if (ret == GNUTLS_BAG_ENCRYPTED)
1533 {
1534 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1535 if (ret < 0)
1536 {
1537 gnutls_assert ();
1538 goto done;
1539 }
1540 }
1541
1542 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1543 if (elements_in_bag < 0)
1544 {
1545 gnutls_assert ();
1546 goto done;
1547 }
1548
1549 for (i = 0; i < elements_in_bag; i++)
1550 {
1551 int type;
1552 gnutls_datum_t data;
1553
1554 type = gnutls_pkcs12_bag_get_type (bag, i);
1555 if (type < 0)
1556 {
1557 gnutls_assert ();
1558 goto done;
1559 }
1560
1561 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1562 if (ret < 0)
1563 {
1564 gnutls_assert ();
1565 goto done;
1566 }
1567
1568 switch (type)
1569 {
1570 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1571 case GNUTLS_BAG_PKCS8_KEY:
1572 ret = gnutls_x509_privkey_init (key);
1573 if (ret < 0)
1574 {
1575 gnutls_assert ();
1576 goto done;
1577 }
1578
1579 ret = gnutls_x509_privkey_import_pkcs8
1580 (*key, &data, GNUTLS_X509_FMT_DER, password,
1581 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1582 if (ret < 0)
1583 {
1584 gnutls_assert ();
1585 goto done;
1586 }
1587 break;
1588
1589 case GNUTLS_BAG_CERTIFICATE:
1590 ret = gnutls_x509_crt_init (cert);
1591 if (ret < 0)
1592 {
1593 gnutls_assert ();
1594 goto done;
1595 }
1596
1597 ret =
1598 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
1599 if (ret < 0)
1600 {
1601 gnutls_assert ();
1602 goto done;
1603 }
1604 break;
1605
1606 case GNUTLS_BAG_CRL:
1607 ret = gnutls_x509_crl_init (crl);
1608 if (ret < 0)
1609 {
1610 gnutls_assert ();
1611 goto done;
1612 }
1613
1614 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
1615 if (ret < 0)
1616 {
1617 gnutls_assert ();
1618 goto done;
1619 }
1620 break;
1621
1622 case GNUTLS_BAG_ENCRYPTED:
1623 /* XXX Bother to recurse one level down? Unlikely to
1624 use the same password anyway. */
1625 case GNUTLS_BAG_EMPTY:
1626 default:
1627 break;
1628 }
1629 }
1630
1631 index++;
1632 gnutls_pkcs12_bag_deinit (bag);
1633 }
1634
1635 ret = 0;
1636
1637done:
1638 if (bag)
1639 gnutls_pkcs12_bag_deinit (bag);
1640
1641 return ret;
1642}
1643
1644/**
1645 * gnutls_certificate_set_x509_simple_pkcs12_file:
1646 * @res: is an #mhd_gtls_cert_credentials_t structure.
1647 * @pkcs12file: filename of file containing PKCS#12 blob.
1648 * @type: is PEM or DER of the @pkcs12file.
1649 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1650 *
1651 * This function sets a certificate/private key pair and/or a CRL in
1652 * the mhd_gtls_cert_credentials_t structure. This function may
1653 * be called more than once (in case multiple keys/certificates exist
1654 * for the server).
1655 *
1656 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
1657 * supported. Encrypted PKCS#8 private keys are supported. However,
1658 * only password based security, and the same password for all
1659 * operations, are supported.
1660 *
1661 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
1662 * the OpenSSL way.
1663 *
1664 * PKCS#12 file may contain many keys and/or certificates, and there
1665 * is no way to identify which key/certificate pair you want. You
1666 * should make sure the PKCS#12 file only contain one key/certificate
1667 * pair and/or one CRL.
1668 *
1669 * It is believed that the limitations of this function is acceptable
1670 * for most usage, and that any more flexibility would introduce
1671 * complexity that would make it harder to use this functionality at
1672 * all.
1673 *
1674 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1675 **/
1676//int
1677// gnutls_certificate_set_x509_simple_pkcs12_file
1678// (mhd_gtls_cert_credentials_t res, const char *pkcs12file,
1679// gnutls_x509_crt_fmt_t type, const char *password)
1680//{
1681// gnutls_pkcs12_t p12;
1682// gnutls_datum_t p12blob;
1683// gnutls_x509_privkey_t key = NULL;
1684// gnutls_x509_crt_t cert = NULL;
1685// gnutls_x509_crl_t crl = NULL;
1686// int ret;
1687// size_t size;
1688//
1689// ret = gnutls_pkcs12_init (&p12);
1690// if (ret < 0)
1691// {
1692// gnutls_assert ();
1693// return ret;
1694// }
1695//
1696// p12blob.data = read_binary_file (pkcs12file, &size);
1697// p12blob.size = (unsigned int) size;
1698// if (p12blob.data == NULL)
1699// {
1700// gnutls_assert ();
1701// gnutls_pkcs12_deinit (p12);
1702// return GNUTLS_E_FILE_ERROR;
1703// }
1704//
1705// ret = gnutls_pkcs12_import (p12, &p12blob, type, 0);
1706// free (p12blob.data);
1707// if (ret < 0)
1708// {
1709// gnutls_assert ();
1710// gnutls_pkcs12_deinit (p12);
1711// return ret;
1712// }
1713//
1714// if (password)
1715// {
1716// ret = gnutls_pkcs12_verify_mac (p12, password);
1717// if (ret < 0)
1718// {
1719// gnutls_assert ();
1720// gnutls_pkcs12_deinit (p12);
1721// return ret;
1722// }
1723// }
1724//
1725// ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
1726// gnutls_pkcs12_deinit (p12);
1727// if (ret < 0)
1728// {
1729// gnutls_assert ();
1730// return ret;
1731// }
1732//
1733// if (key && cert)
1734// {
1735// ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
1736// if (ret < 0)
1737// {
1738// gnutls_assert ();
1739// goto done;
1740// }
1741// }
1742//
1743// if (crl)
1744// {
1745// ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
1746// if (ret < 0)
1747// {
1748// gnutls_assert ();
1749// goto done;
1750// }
1751// }
1752//
1753// ret = 0;
1754//
1755//done:
1756// if (cert)
1757// gnutls_x509_crt_deinit (cert);
1758// if (key)
1759// gnutls_x509_privkey_deinit (key);
1760// if (crl)
1761// gnutls_x509_crl_deinit (crl);
1762//
1763// return ret;
1764//}
1765
1766
1767/** 1354/**
1768 * MHD_gnutls_certificate_free_crls - Used to free all the CRLs from a mhd_gtls_cert_credentials_t structure 1355 * MHD_gnutls_certificate_free_crls - Used to free all the CRLs from a mhd_gtls_cert_credentials_t structure
1769 * @sc: is an #mhd_gtls_cert_credentials_t structure. 1356 * @sc: is an #mhd_gtls_cert_credentials_t structure.