Changeset 7921dc7 in mod_gnutls for src/gnutls_hooks.c
- Timestamp:
- Apr 22, 2018, 1:04:41 PM (3 years ago)
- Branches:
- asyncio, debian/master, master, proxy-ticket
- Children:
- 0470e44
- Parents:
- 2246a84
- git-author:
- Fiona Klute <fiona.klute@…> (04/18/18 04:38:36)
- git-committer:
- Fiona Klute <fiona.klute@…> (04/22/18 13:04:41)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_hooks.c
r2246a84 r7921dc7 55 55 /* use side==0 for server and side==1 for client */ 56 56 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, size_t export_cert_size); 57 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, size_t export_cert_size);58 57 static int mgs_status_hook(request_rec *r, int flags); 59 58 #ifdef ENABLE_MSVA … … 352 351 *privkey = ctxt->sc->privkey_x509; 353 352 return 0; 354 } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) {355 // OPENPGP CERTIFICATE356 *pcerts = ctxt->sc->cert_pgp;357 *pcert_length = 1;358 *privkey = ctxt->sc->privkey_pgp;359 return 0;360 353 } else { 361 354 // UNKNOWN CERTIFICATE … … 416 409 } 417 410 } 418 }419 420 return rv;421 }422 423 static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p,424 gnutls_openpgp_crt_t cert, char **cert_cn) {425 int rv = 0;426 size_t data_len;427 428 429 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);430 *cert_cn = NULL;431 432 data_len = 0;433 rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);434 435 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {436 *cert_cn = apr_palloc(p, data_len);437 rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn,438 &data_len);439 } else { /* No CN return subject alternative name */440 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,441 "No name found in PGP certificate for '%s:%d'.",442 s->server_hostname, s->port);443 411 } 444 412 … … 732 700 733 701 if ((sc->certs_x509_chain == NULL || sc->certs_x509_chain_num < 1) && 734 sc-> cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {702 sc->enabled == GNUTLS_ENABLED_TRUE) { 735 703 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 736 704 "GnuTLS: Host '%s:%d' is missing a Certificate File!", … … 739 707 } 740 708 if (sc->enabled == GNUTLS_ENABLED_TRUE && 741 ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) || 742 (sc->cert_crt_pgp != NULL && sc->privkey_pgp == NULL))) 709 (sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL)) 743 710 { 744 711 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, … … 748 715 } 749 716 750 /* If OpenPGP support is already disabled in the loaded GnuTLS751 * library startup will fail if the configuration tries to752 * load PGP credentials. Otherwise warn affected users about753 * deprecation. */754 if (sc->pgp_cert_file || sc->pgp_key_file || sc->pgp_ring_file)755 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,756 "Host '%s:%d' is configured to use OpenPGP auth. "757 "OpenPGP support has been deprecated in GnuTLS "758 "since version 3.5.9 and will be removed from "759 "mod_gnutls in a future release.",760 s->server_hostname, s->port);761 762 717 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 763 718 rv = -1; … … 765 720 rv = read_crt_cn(s, pconf, sc->certs_x509_crt_chain[0], &sc->cert_cn); 766 721 } 767 if (rv < 0 && sc->cert_pgp != NULL) {768 rv = read_pgpcrt_cn(s, pconf, sc->cert_crt_pgp[0], &sc->cert_cn);769 }770 722 771 723 if (rv < 0) { … … 1335 1287 1336 1288 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) { 1337 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, ctxt->sc->export_certificates_size); 1338 } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) { 1339 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_crt_pgp[0], 0, ctxt->sc->export_certificates_size); 1289 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, 1290 ctxt->sc->export_certificates_size); 1340 1291 } 1341 1292 … … 1532 1483 1533 1484 1534 /* @param side 0: server, 1: client1535 *1536 * @param export_cert_size (int) maximum size for environment variable1537 * to use for the PEM-encoded certificate (0 means do not export)1538 */1539 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, size_t export_cert_size) {1540 1541 unsigned char sbuf[64]; /* buffer to hold serials */1542 char buf[AP_IOBUFSIZE];1543 const char *tmp;1544 size_t len;1545 int ret;1546 1547 if (r == NULL)1548 return;1549 1550 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);1551 apr_table_t *env = r->subprocess_env;1552 1553 if (export_cert_size > 0) {1554 len = 0;1555 ret = gnutls_openpgp_crt_export(cert, GNUTLS_OPENPGP_FMT_BASE64, NULL, &len);1556 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {1557 if (len >= export_cert_size) {1558 apr_table_setn(env, MGS_SIDE("_CERT"),1559 "GNUTLS_CERTIFICATE_SIZE_LIMIT_EXCEEDED");1560 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,1561 "GnuTLS: Failed to export too-large OpenPGP certificate to environment");1562 } else {1563 char* cert_buf = apr_palloc(r->pool, len + 1);1564 if (cert_buf != NULL && gnutls_openpgp_crt_export(cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0) {1565 cert_buf[len] = 0;1566 apr_table_setn(env, MGS_SIDE("_CERT"), cert_buf);1567 } else {1568 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,1569 "GnuTLS: failed to export OpenPGP certificate");1570 }1571 }1572 } else {1573 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,1574 "GnuTLS: dazed and confused about OpenPGP certificate size");1575 }1576 }1577 1578 len = sizeof (buf);1579 gnutls_openpgp_crt_get_name(cert, 0, buf, &len);1580 apr_table_setn(env, MGS_SIDE("_NAME"), apr_pstrmemdup(r->pool, buf, len));1581 1582 len = sizeof (sbuf);1583 gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);1584 apr_table_setn(env, MGS_SIDE("_FINGERPRINT"),1585 apr_pescape_hex(r->pool, sbuf, len, 0));1586 1587 ret = gnutls_openpgp_crt_get_version(cert);1588 if (ret > 0)1589 apr_table_setn(env, MGS_SIDE("_M_VERSION"),1590 apr_psprintf(r->pool, "%u", ret));1591 1592 apr_table_setn(env, MGS_SIDE("_CERT_TYPE"), "OPENPGP");1593 1594 tmp =1595 mgs_time2sz(gnutls_openpgp_crt_get_expiration_time1596 (cert), buf, sizeof (buf));1597 apr_table_setn(env, MGS_SIDE("_V_END"), apr_pstrdup(r->pool, tmp));1598 1599 tmp =1600 mgs_time2sz(gnutls_openpgp_crt_get_creation_time1601 (cert), buf, sizeof (buf));1602 apr_table_setn(env, MGS_SIDE("_V_START"), apr_pstrdup(r->pool, tmp));1603 1604 ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL);1605 if (ret >= 0) {1606 apr_table_setn(env, MGS_SIDE("_A_KEY"), gnutls_pk_algorithm_get_name(ret));1607 }1608 1609 }1610 1485 1611 1486 /* TODO: Allow client sending a X.509 certificate chain */ … … 1619 1494 unsigned int ch_size = 0; 1620 1495 1496 // TODO: union no longer needed here after removing its "pgp" component. 1621 1497 union { 1622 1498 gnutls_x509_crt_t x509[MAX_CHAIN_SIZE]; 1623 gnutls_openpgp_crt_t pgp;1624 1499 } cert; 1625 1500 apr_time_t expiration_time, cur_time; … … 1672 1547 } 1673 1548 } 1674 } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {1675 if (cert_list_size > 1) {1676 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,1677 "GnuTLS: Failed to Verify Peer: "1678 "Chained Client Certificates are not supported.");1679 return HTTP_FORBIDDEN;1680 }1681 1682 gnutls_openpgp_crt_init(&cert.pgp);1683 rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0],1684 GNUTLS_OPENPGP_FMT_RAW);1685 1686 1549 } else 1687 1550 return HTTP_FORBIDDEN; … … 1759 1622 1760 1623 } else { 1761 apr_time_ansi_put(&expiration_time, 1762 gnutls_openpgp_crt_get_expiration_time 1763 (cert.pgp)); 1764 1765 switch(ctxt->sc->client_verify_method) { 1766 case mgs_cvm_cartel: 1767 rv = gnutls_openpgp_crt_verify_ring(cert.pgp, 1768 ctxt->sc->pgp_list, 0, 1769 &status); 1770 break; 1771 #ifdef ENABLE_MSVA 1772 case mgs_cvm_msva: 1773 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 1774 "GnuTLS: OpenPGP verification via MSVA is not yet implemented"); 1775 rv = GNUTLS_E_UNIMPLEMENTED_FEATURE; 1776 break; 1777 #endif 1778 default: 1779 /* If this block is reached, that indicates a 1780 * configuration error or bug in mod_gnutls (invalid value 1781 * of ctxt->sc->client_verify_method). */ 1782 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 1783 "GnuTLS: Failed to Verify OpenPGP Peer: method '%s' is not supported", 1784 mgs_readable_cvm(ctxt->sc->client_verify_method)); 1785 rv = GNUTLS_E_UNIMPLEMENTED_FEATURE; 1786 } 1624 /* Unknown certificate type */ 1625 rv = GNUTLS_E_UNIMPLEMENTED_FEATURE; 1787 1626 } 1788 1627 … … 1795 1634 if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND) 1796 1635 ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r, 1797 "GnuTLS: No certificate was found for verification. Did you set the GnuTLS X509CAFile or GnuTLSPGPKeyringFile directives?");1636 "GnuTLS: No certificate was found for verification. Did you set the GnuTLSClientCAFile directive?"); 1798 1637 ret = HTTP_FORBIDDEN; 1799 1638 goto exit; … … 1836 1675 } 1837 1676 1838 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) 1839 mgs_add_common_cert_vars(r, cert.x509[0], 1, ctxt->sc->export_certificates_size); 1840 else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) 1841 mgs_add_common_pgpcert_vars(r, cert.pgp, 1, ctxt->sc->export_certificates_size); 1677 mgs_add_common_cert_vars(r, cert.x509[0], 1, ctxt->sc->export_certificates_size); 1842 1678 1843 1679 { … … 1867 1703 for (unsigned int i = 0; i < ch_size; i++) 1868 1704 gnutls_x509_crt_deinit(cert.x509[i]); 1869 else if (gnutls_certificate_type_get(ctxt->session) == 1870 GNUTLS_CRT_OPENPGP) 1871 gnutls_openpgp_crt_deinit(cert.pgp); 1705 1872 1706 return ret; 1873 1707 } … … 1928 1762 * certificate, but doesn't tell us (in any other way) who they are 1929 1763 * trying to authenticate as. 1930 1931 * TODO: we might need another parallel for OpenPGP, but for that it's1932 * much simpler: we can just assume that the first User ID marked as1933 * "primary" (or the first User ID, period) is the identity the user1934 * is trying to present as.1935 1764 1936 1765 * one complaint might be "but the user wanted to be another identity,
Note: See TracChangeset
for help on using the changeset viewer.