Changeset 71e9a5c in mod_gnutls
- Timestamp:
- Aug 22, 2015, 3:53:31 PM (7 years ago)
- Branches:
- debian/master, debian/stretch-backports, jessie-backports
- Children:
- b837187
- Parents:
- 2db6923 (diff), 4addf74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 109 added
- 32 deleted
- 12 edited
- 71 moved
Legend:
- Unmodified
- Added
- Removed
-
CHANGELOG
r2db6923 r71e9a5c 1 1 **TODO: 2 - Fix support for proxy termination3 2 - Handle Unclean Shutdowns 4 3 - make session cache use generic apache caches 4 5 ** Version 0.7 (2015-07-12) 6 - Security fix for TLS client authentication (CVE-2015-2091) 7 - Bug fixes that enable support for reverse proxy operation 8 - Various test suite improvements. Tests are configured through autoconf, 9 so the test suite now works for builds without Monkeysphere support. 10 - Add support for TLS connections to back end servers when operating as a 11 reverse proxy (X.509 authentication only at the moment). 12 - PKCS #11 support for server keys and certificates 13 - Use strict compiler arguments by default (-Wall -Werror -Wextra) 14 - Allow limiting the size of certificates exported as SSL_SERVER_CERT 15 and SSL_CLIENT_CERT through the GnuTLSExportCertificates directive 5 16 6 17 ** Version 0.6 (2014-02-17) … … 88 99 - Added support for subject alternative names in certificates. 89 100 Only one per certificate is supported. 90 - New enviroment variables: SSL_CLIENT_M_VERSION, SSL_CLIENT_S_SAN%, 101 - New enviroment variables: SSL_CLIENT_M_VERSION, SSL_CLIENT_S_SAN%, 91 102 SSL_CLIENT_S_TYPE, SSL_SERVER_M_VERSION, SSL_SERVER_S_SAN%, SSL_SERVER_S_TYPE 92 103 - The compatibility mode can now be enabled explicitely with the -
Makefile.am
r2db6923 r71e9a5c 2 2 3 3 EXTRA_DIST = m4/outoforder.m4 m4/apache.m4 \ 4 m4/ libgnutls.m4 m4/apr_memcache.m4 \4 m4/apr_memcache.m4 \ 5 5 m4/apache_test.m4 \ 6 6 include/mod_gnutls.h.in \ 7 README README.ENV NEWS\8 NOTICE LICENSE autogen.sh7 README CHANGELOG \ 8 NOTICE LICENSE 9 9 10 SUBDIRS = src 10 SUBDIRS = src test doc 11 11 ACLOCAL_AMFLAGS = -I m4 12 TESTS = run_tests.sh -
README
r2db6923 r71e9a5c 1 mod_gnutls, Apache GnuTLS module 2 ================================ 1 3 2 mod_gnutls, Apache GnuTLS module. 3 ================================= 4 https://mod.gnutls.org/ 4 5 5 $LastChangedDate: $ 6 Mailing List: 6 7 7 Contents: 8 mod_gnutls development <mod_gnutls-devel@lists.gnutls.org> 8 9 9 I. ABOUT 10 II. AUTHORS 11 III. MAINTAINERS 12 IV. LICENSE 13 V. PREREQUISITES 14 VI. INSTALLATION 15 VII. BASIC CONFIGURATION 16 VIII. CREATE OPENPGP CREDENTIALS FOR THE SERVER 10 Lead Maintainer: 17 11 12 Thomas Klute <thomas2.klute@uni-dortmund.de> 18 13 14 Past maintainers and other contributors: 19 15 20 I. ABOUT 16 Daniel Kahn Gillmor <dkg@fifthhorseman.net> 17 Paul Querna <chip at force-elite.com> 18 Nikos Mavrogiannopoulos <nmav at gnutls.org> 19 Dash Shendy <neuromancer at dash.za.net> 21 20 22 This module started back in September of 2004 because I was tired of 23 trying to fix bugs in mod_ssl. mod_ssl is a giant beast of a module -- 24 no offense to it's authors is intended -- but I believe it has fallen 25 prey to massive feature bloat. 21 Prerequisites 22 ------------- 26 23 27 When I started hacking on httpd, mod_ssl remained a great mystery to me, 28 and when I actually looked at it, I ran away. The shear amount code is 29 huge, and it does not conform to the style guidelines. It was painful to 30 read, and even harder to debug. I wanted to understand how it worked, 31 and I had recently heard about GnuTLS, so long story short, I decided to 32 implement a mod_gnutls. 24 * GnuTLS >= 3.1.4 <http://www.gnutls.org/> (3.2.* or newer preferred) 25 * Apache HTTPD >= 2.2 <http://httpd.apache.org/> (2.4.* preferred) 26 * autotools & gcc 27 * APR Memcache >= 0.7.0 (Optional) 28 * libmsv >= 0.1 (Optional, enable with ./configure --enable-msva) 29 * pandoc (for documentation, optional) 30 * pdflatex (for PDF documentation, optional) 33 31 34 Lines of Code in mod_ssl: 15,324 35 Lines of Code in mod_gnutls: 3,594 32 Installation 33 ------------ 36 34 37 Because of writing mod_gnutls, I now understand how input and output 38 filters work, better than I ever thought possible. It was a little 39 painful at times, and some parts lift code and ideas directly from 40 mod_ssl. Kudos to the original authors of mod_ssl. 35 tar xzvf mod_gnutls-version.tar.gz 36 cd mod_gnutls-version/ 37 autoreconf -fiv 38 ./configure 39 make 40 make install 41 # Configure & restart apache 41 42 43 It is recommended to run "make check" before "make install". You may 44 need to pass TEST_HOST or TEST_IP to ./configure for the tests to work 45 correctly, please see test/README for details. 42 46 47 Configuration 48 ------------- 43 49 44 II. AUTHORS 45 46 Paul Querna <chip at force-elite.com> 47 Nikos Mavrogiannopoulos <nmav at gnutls.org> 48 Dash Shendy <neuromancer at dash.za.net> 49 50 III. MAINTAINERS 51 52 Dash Shendy <neuromancer at dash.za.net> 53 Execute `autoreconf -v -i -f` to Auto-generate files 54 55 IV. LICENSE 56 57 Apache License, Version 2.0 (see the LICENSE file for details) 58 59 V. PREREQUISITES 60 61 * GnuTLS >= 2.12.6 <http://www.gnu.org/software/gnutls/> 62 * Apache HTTPD >= 2.0.42 <http://httpd.apache.org/> 63 * >= 2.1.5-dev 64 * ARP Memcache >= 0.7.0 (Optinal) 65 66 67 VI. INSTALLATION 68 69 * tar xzvf mod_gnutls-version.tar.gz 70 * cd mod_gnutls-version/ 71 * ./configure --with-apxs=PATH --with-apr-memcache-prefix=PATH \ 72 --with-apr-memcache-libs=PATH --with-apr-memcache-includes=PATH 73 * make 74 * make install 75 * Configure & restart apache 76 77 VII. BASIC CONFIGURATION 78 79 LoadModule gnutls_module modules/mod_gnutls.so 80 81 # mod_gnutls can optionally use a memcached server to store it's SSL 82 # Sessions. This is useful in a cluster environment, where you want all 83 # of your servers to share a single SSL session cache. 84 #GnuTLSCache memcache "127.0.0.1 server2.example.com server3.example.com" 85 86 # The Default method is to use a DBM backed Cache. It isn't super fast, 87 # but it is portable and does not require another server to be running 88 # like memcached. 89 GnuTLSCache dbm conf/gnutls_cache 90 91 <VirtualHost 1.2.3.4:443> 92 93 # Enable mod_gnutls handlers for this virtual host 94 GnuTLSEnable On 95 96 # This is the private key for your server 97 GnuTLSX509KeyFile conf/server.key 98 99 # This is the server certificate 100 GnuTLSX509CertificateFile conf/server.cert 101 102 </VirtualHost> 103 104 # A more advanced configuration 105 GnuTLSCache dbm "/var/cache/www-tls-cache/cache" 106 GnuTLSCacheTimeout 600 107 NameVirtualHost 1.2.3.4:443 108 109 <VirtualHost 1.2.3.4:443> 110 111 Servername server.com:443 112 GnuTLSEnable on 113 GnuTLSPriority NORMAL 114 115 # Export exactly the same environment variables as mod_ssl to CGI 116 # scripts. 117 GNUTLSExportCertificates on 118 119 GnuTLSX509CertificateFile /etc/apache2/server-cert.pem 120 GnuTLSX509KeyFile /etc/apache2/server-key.pem 121 122 # To enable SRP you must have these files installed. Check the gnutls 123 # srptool. 124 GnuTLSSRPPasswdFile /etc/apache2/tpasswd 125 GnuTLSSRPPasswdConfFile /etc/apache2/tpasswd.conf 126 127 # In order to verify client certificates. Other options to 128 # GnuTLSClientVerify could be ignore or require. The 129 # GnuTLSClientCAFile contains the CAs to verify client certificates. 130 GnuTLSClientVerify request 131 GnuTLSX509CAFile ca.pem 132 133 </VirtualHost> 134 135 # A setup for OpenPGP and X.509 authentication 136 <VirtualHost 1.2.3.4:443> 137 138 Servername crystal.lan:443 139 GnuTLSEnable on 140 GnuTLSPriorities NORMAL:+COMP-NULL 141 142 # Setup the openpgp keys 143 GnuTLSPGPCertificateFile /etc/apache2/test.pub.asc 144 GnuTLSPGPKeyFile /etc/apache2/test.sec.asc 145 146 # - and the X.509 keys 147 GnuTLSCertificateFile /etc/apache2/server-cert.pem 148 GnuTLSKeyFile /etc/apache2/server-key.pem 149 150 GnuTLSClientVerify ignore 151 152 # To avoid using the default DH params 153 GnuTLSDHFile /etc/apache2/dh.pem 154 155 # These are only needed if GnuTLSClientVerify != ignore 156 GnuTLSClientCAFile ca.pem 157 GnuTLSPGPKeyringFile /etc/apache2/ring.asc 158 159 </VirtualHost> 160 161 162 163 IX. CREATE OPENPGP CREDENTIALS FOR THE SERVER 164 165 mod_gnutls currently cannot read encrypted OpenPGP credentials. That is, 166 when you generate a key with gpg and gpg prompts you for a passphrase, 167 just press enter. Then press enter again, to confirm an empty 168 passphrase. http://news.gmane.org/gmane.comp.apache.outoforder.modules 169 170 These instructions are from the GnuTLS manual: 171 http://www.gnu.org/software/gnutls/manual/html_node/Invoking-gnutls_002dserv.html#Invoking-gnutls_002dserv 172 173 $ gpg --gen-key 174 ...enter whatever details you want, use 'test.gnutls.org' as name... 175 176 Make a note of the OpenPGP key identifier of the newly generated key, 177 here it was 5D1D14D8. You will need to export the key for GnuTLS to be 178 able to use it. 179 180 $ gpg -a --export 5D1D14D8 > openpgp-server.txt 181 $ gpg -a --export-secret-keys 5D1D14D8 > openpgp-server-key.txt 50 Please see doc/mod_gnutls_manual.mdwn for more details. If pandoc is 51 available, HTML and PDF (requires pdflatex) documentation will be 52 built and installed as well. -
configure.ac
r2db6923 r71e9a5c 1 1 dnl 2 AC_INIT(mod_gnutls, 0. 6)2 AC_INIT(mod_gnutls, 0.7) 3 3 OOO_CONFIG_NICE(config.nice) 4 4 MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION … … 10 10 AM_MAINTAINER_MODE 11 11 AC_CANONICAL_TARGET 12 AM_INIT_AUTOMAKE (AC_PACKAGE_NAME, AC_PACKAGE_VERSION)12 AM_INIT_AUTOMAKE 13 13 AM_CONFIG_HEADER(include/mod_gnutls_config.h:config.in) 14 14 … … 22 22 AC_CONFIG_MACRO_DIR([m4]) 23 23 24 AP_VERSION=2. 0.4024 AP_VERSION=2.2.0 25 25 CHECK_APACHE(,$AP_VERSION, 26 26 :,:, … … 28 28 ) 29 29 30 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.12.6])30 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.1.4]) 31 31 32 32 LIBGNUTLS_VERSION=`pkg-config --modversion gnutls` … … 37 37 use_srp=$enableval, use_srp=yes) 38 38 39 # check if the available GnuTLS library supports SRP 40 AC_SEARCH_LIBS([gnutls_srp_server_get_username], [gnutls], [], [use_srp="no"]) 41 39 42 SRP_CFLAGS="" 40 43 if test "$use_srp" != "no"; then 41 SRP_CFLAGS="-DENABLE_SRP=1" 44 SRP_CFLAGS="-DENABLE_SRP=1" 45 fi 46 47 AC_ARG_ENABLE(strict, 48 AS_HELP_STRING([--disable-strict], 49 [Avoid strict compiler warnings and errors]), 50 use_strict=$enableval, use_strict=yes) 51 52 STRICT_CFLAGS="" 53 if test "$use_strict" != "no"; then 54 STRICT_CFLAGS="-Wall -Werror -Wextra" 42 55 fi 43 56 … … 49 62 [enable Monkeysphere client certificate verification]), 50 63 use_msva=$enableval, use_msva=no) 64 AM_CONDITIONAL([USE_MSVA], [test "$use_msva" != "no"]) 51 65 52 66 MSVA_CFLAGS="" 53 67 if test "$use_msva" != "no"; then 54 AC_CHECK_HEADERS([msv/msv.h], [], 68 AC_CHECK_HEADERS([msv/msv.h], [], 55 69 [AC_MSG_ERROR([*** No libmsv headers found!])]) 56 70 AC_SEARCH_LIBS([msv_query_agent], [msv], [], 57 71 [AC_MSG_ERROR([*** No libmsv found with msv_query_agent!])]) 58 72 MSVA_CFLAGS="-DENABLE_MSVA=1" 59 73 fi 60 74 … … 66 80 AC_SUBST(have_apr_memcache) 67 81 68 MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${SRP_CFLAGS} ${MSVA_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES}" 82 # Building documentation requires pandoc, which in turn needs pdflatex 83 # to build PDF output. 84 build_doc=no 85 AC_PATH_PROG([PANDOC], [pandoc], [no]) 86 if test "$PANDOC" != "no"; then 87 AC_PATH_PROG([PDFLATEX], [pdflatex], [no]) 88 if test "$PDFLATEX" != "no"; then 89 build_doc=yes 90 else 91 build_doc="html only" 92 fi 93 fi 94 AM_CONDITIONAL([USE_PANDOC], [test "$PANDOC" != "no"]) 95 AM_CONDITIONAL([USE_PDFLATEX], [test "$PANDOC" != "no" && \ 96 test "$PDFLATEX" != "no"]) 97 98 # Check for Apache binary 99 AC_PATH_PROGS([APACHE2], [apache2 httpd], [no]) 100 if test "${APACHE2}" = "no"; then 101 AC_MSG_WARN([Neither apache2 nor httpd found in \ 102 PATH. Test suite will fail.]) 103 fi 104 105 MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${SRP_CFLAGS} ${MSVA_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES} ${STRICT_CFLAGS}" 69 106 MODULE_LIBS="${APR_MEMCACHE_LIBS} ${LIBGNUTLS_LIBS}" 70 107 … … 72 109 AC_SUBST(MODULE_LIBS) 73 110 74 AC_CONFIG_FILES([Makefile src/Makefile include/mod_gnutls.h]) 111 # assign default values to TEST_HOST and TEST_IP if necessary 112 : ${TEST_HOST:="localhost"} 113 : ${TEST_IP:="[::1]"} 114 AC_ARG_VAR([TEST_HOST], [Host name to use for server instances started by \ 115 "make check", must resolve to TEST_IP. The default \ 116 is "localhost".]) 117 AC_ARG_VAR([TEST_IP], [IP address to use for server instances started by \ 118 "make check". The default is the IPv6 loopback address \ 119 [::1].]) 120 121 AC_CONFIG_FILES([Makefile src/Makefile test/Makefile test/tests/Makefile \ 122 doc/Makefile include/mod_gnutls.h]) 75 123 AC_OUTPUT 76 124 … … 81 129 echo " * Apache Modules directory: ${AP_LIBEXECDIR}" 82 130 echo " * GnuTLS Library version: ${LIBGNUTLS_VERSION}" 83 echo " * SRP Authentication: ${use_srp}" 84 echo " * MSVA Client Verification: ${use_msva}" 131 echo " * SRP Authentication: ${use_srp}" 132 echo " * MSVA Client Verification: ${use_msva}" 133 echo " * Build documentation: ${build_doc}" 85 134 echo "" 86 135 echo "---" -
doc/mod_gnutls_manual.mdwn
r2db6923 r71e9a5c 150 150 as the last certificate in the list. 151 151 152 Since version 0.7 this can be a PKCS #11 URL. 153 152 154 `GnuTLSKeyFile` 153 155 --------------- 154 156 155 Set to the PEM Encoded Server Certificate 156 157 GnuTLSCertificateFile FILEPATH 158 159 Default: *none*\ 160 Context: server config, virtual host 161 162 Takes an absolute or relative path to the Server Private Key. This 163 key cannot currently be password protected. 157 Set to the PEM Encoded Server Private Key 158 159 GnuTLSKeyFile FILEPATH 160 161 Default: *none*\ 162 Context: server config, virtual host 163 164 Takes an absolute or relative path to the Server Private Key. Set 165 `GnuTLSPIN` if the key file is encrypted. 166 167 Since version 0.7 this can be a PKCS #11 URL. 164 168 165 169 **Security Warning:**\ 166 170 This private key must be protected. It is read while Apache is still 167 171 running as root, and does not need to be readable by the nobody or 168 172 apache user. … … 368 372 achieve maximum compatibility (some broken mobile clients need this). 369 373 374 `GnuTLSP11Module` 375 ------------------ 376 377 Load an additional PKCS #11 module. 378 379 GnuTLSP11Module PATH_TO_LIBRARY 380 381 Default: *none*\ 382 Context: server config 383 384 Load this PKCS #11 provider module, in addition to the system 385 defaults. 386 387 `GnuTLSPIN` 388 ------------------ 389 390 Set the PIN to be used to access encrypted key files or PKCS #11 objects. 391 392 GnuTLSPIN XXXXXX 393 394 Default: *none*\ 395 Context: server config, virtual host 396 397 Takes a string to be used as a PIN for the protected objects in 398 a security module, or as a key to be used to decrypt PKCS #8, PKCS #12, 399 or openssl encrypted keys. 400 401 `GnuTLSSRKPIN` 402 ------------------ 403 404 Set the SRK PIN to be used to unlaccess the TPM. 405 406 GnuTLSSRKPIN XXXXXX 407 408 Default: *none*\ 409 Context: server config, virtual host 410 411 Takes a string to be used as a PIN for the protected objects in 412 the TPM module. 413 370 414 `GnuTLSExportCertificates` 371 415 -------------------------- … … 373 417 Export the PEM encoded certificates to CGIs 374 418 375 GnuTLSExportCertificates [o n|off]419 GnuTLSExportCertificates [off|on|SIZE] 376 420 377 421 Default: `off`\ 378 422 Context: server config, virtual host 379 423 380 This directive enables exporting the full certificates of the server and 381 the client to CGI scripts. The exported certificates will be PEM-encoded 382 (if X.509) or ASCII-armored (if OpenPGP). 424 This directive configures exporting the full certificates of the 425 server and the client to CGI scripts via the `SSL_SERVER_CERT` and 426 `SSL_CLIENT_CERT` environment variables. The exported certificates 427 will be PEM-encoded (if X.509) or ASCII-armored (if OpenPGP) up to the 428 size given. The type of the certificate will be exported in 429 `SSL_SERVER_CERT_TYPE` and `SSL_CLIENT_CERT_TYPE`. 430 431 SIZE should be an integer number of bytes, or may be written with a 432 trailing `K` to indicate kibibytes. `off` means the same thing as 433 `0`, in which case the certificates will not be exported to the 434 environment. `on` is an alias for `16K`. If a non-zero size is 435 specified for this directive, but a certificate is too large to fit in 436 the buffer, then the corresponding environment variable will contain 437 the fixed string `GNUTLS_CERTIFICATE_SIZE_LIMIT_EXCEEDED`. 438 383 439 With GnuTLSExportCertificates enabled, `mod_gnutls` exports the same 384 440 environment variables to the CGI process as `mod_ssl`. 441 442 443 `GnuTLSProxyEngine` 444 -------------- 445 446 Enable TLS proxy connections for this virtual host 447 448 GnuTLSProxyEngine [on|off] 449 450 Default: *off*\ 451 Context: virtual host 452 453 This directive enables support for TLS proxy connections for a virtual 454 host. 455 456 `GnuTLSProxyCAFile` 457 -------------------- 458 459 Set to the PEM encoded Certificate Authority Certificate 460 461 GnuTLSProxyCAFile FILEPATH 462 463 Default: *none*\ 464 Context: server config, virtual host 465 466 Takes an absolute or relative path to a PEM encoded certificate to use 467 as a Certificate Authority when verifying certificates provided by 468 proxy back end servers. This file may contain a list of trusted 469 authorities. If not set, verification of TLS back end servers will 470 always fail due to lack of a trusted CA. 471 472 `GnuTLSProxyCRLFile` 473 -------------------- 474 475 Set to the PEM encoded Certificate Revocation List 476 477 GnuTLSProxyCRLFile FILEPATH 478 479 Default: *none*\ 480 Context: server config, virtual host 481 482 Takes an absolute or relative path to a PEM encoded Certificate 483 Revocation List to use when verifying certificates provided by proxy 484 back end servers. The file may contain a list of CRLs. 485 486 `GnuTLSProxyCertificateFile` 487 ----------------------- 488 489 Set to the PEM encoded Client Certificate 490 491 GnuTLSProxyCertificateFile FILEPATH 492 493 Default: *none*\ 494 Context: server config, virtual host 495 496 Takes an absolute or relative path to a PEM encoded X.509 certificate 497 to use as this Server's End Entity (EE) client certificate for TLS 498 client authentication in proxy TLS connections. If you need to supply 499 certificates for intermediate Certificate Authorities (iCAs), they 500 should be listed in sequence in the file, from EE to the iCA closest 501 to the root CA. Optionally, you can also include the root CA's 502 certificate as the last certificate in the list. 503 504 If not set, TLS client authentication will be disabled for TLS proxy 505 connections. If set, `GnuTLSProxyKeyFile` must be set as well to 506 provide the matching private key. 507 508 `GnuTLSProxyKeyFile` 509 --------------- 510 511 Set to the PEM encoded Private Key 512 513 GnuTLSProxyKeyFile FILEPATH 514 515 Default: *none*\ 516 Context: server config, virtual host 517 518 Takes an absolute or relative path to the Private Key matching the 519 certificate configured using the `GnuTLSProxyCertificateFile` 520 directive. This key cannot currently be password protected. 521 522 **Security Warning:**\ 523 This private key must be protected. It is read while Apache is still 524 running as root, and does not need to be readable by the nobody or 525 apache user. 526 527 `GnuTLSProxyPriorities` 528 ------------------ 529 530 Set the allowed ciphers, key exchange algorithms, MACs and compression 531 methods for proxy connections 532 533 GnuTLSProxyPriorities NORMAL:+CIPHER_0:+CIPHER_1:...:+CIPHER_N 534 535 Default: *none*\ 536 Context: server config, virtual host 537 538 This option is used to set the allowed ciphers, key exchange 539 algorithms, MACs and compression methods for proxy connections. It 540 takes the same parameters as `GnuTLSPriorities`. Required if 541 `GnuTLSProxyEngine` is `On`. 385 542 386 543 * * * * * … … 671 828 The public key algorithm in server's certificate. 672 829 673 `SSL_SERVER1_CERT` 674 ------------------ 675 676 The PEM-encoded server certificate. 830 `SSL_SERVER_CERT` 831 ------------------ 832 833 The PEM-encoded (X.509) or ASCII-armored (OpenPGP) server certificate 834 (see the `GnuTLSExportCertificates` directive). 677 835 678 836 `SSL_SERVER_CERT_TYPE` … … 681 839 The certificate type can be `X.509` or `OPENPGP`. 682 840 841 `SSL_CLIENT_CERT` 842 ------------------ 843 844 The PEM-encoded (X.509) or ASCII-armored (OpenPGP) client certificate 845 (see the `GnuTLSExportCertificates` directive). 846 683 847 `SSL_CLIENT_CERT_TYPE` 684 848 ---------------------- -
include/mod_gnutls.h.in
r2db6923 r71e9a5c 1 1 /** 2 2 * Copyright 2004-2005 Paul Querna 3 * Copyright 2014 Nikos Mavrogiannopoulos 4 * Copyright 2015 Thomas Klute 3 5 * 4 6 * Licensed under the Apache License, Version 2.0 (the "License"); … … 34 36 #include <gnutls/extra.h> 35 37 #endif 38 #include <gnutls/abstract.h> 36 39 #include <gnutls/openpgp.h> 37 40 #include <gnutls/x509.h> … … 104 107 /* Server Configuration Record */ 105 108 typedef struct { 106 /* x509 Certificate Structure */ 107 gnutls_certificate_credentials_t certs; 108 /* SRP Certificate Structure*/ 109 gnutls_srp_server_credentials_t srp_creds; 110 /* Annonymous Certificate Structure */ 111 gnutls_anon_server_credentials_t anon_creds; 112 /* Current x509 Certificate CN [Common Name] */ 113 char* cert_cn; 114 /* Current x509 Certificate SAN [Subject Alternate Name]s*/ 115 char* cert_san[MAX_CERT_SAN]; 116 /* A x509 Certificate Chain */ 117 gnutls_x509_crt_t *certs_x509_chain; 118 /* Current x509 Certificate Private Key */ 119 gnutls_x509_privkey_t privkey_x509; 120 /* OpenPGP Certificate */ 121 gnutls_openpgp_crt_t cert_pgp; 122 /* OpenPGP Certificate Private Key */ 123 gnutls_openpgp_privkey_t privkey_pgp; 124 /* Number of Certificates in Chain */ 125 unsigned int certs_x509_chain_num; 109 /* --- Configuration values --- */ 126 110 /* Is the module enabled? */ 127 111 int enabled; 128 /* Export full certificates to CGI environment: */ 129 int export_certificates_enabled; 130 /* GnuTLS Priorities */ 131 gnutls_priority_t priorities; 132 /* GnuTLS DH Parameters */ 133 gnutls_dh_params_t dh_params; 112 /* Is mod_proxy enabled? */ 113 int proxy_enabled; 114 /* A Plain HTTP request */ 115 int non_ssl_request; 116 117 /* Additional PKCS #11 provider module to load, only valid in the 118 * base config, ignored in virtual hosts */ 119 char *p11_module; 120 121 /* PIN used for PKCS #11 operations */ 122 char *pin; 123 124 /* the SRK PIN used in TPM operations */ 125 char *srk_pin; 126 127 char *x509_cert_file; 128 char *x509_key_file; 129 char *x509_ca_file; 130 131 char *pgp_cert_file; 132 char *pgp_key_file; 133 char *pgp_ring_file; 134 135 char *dh_file; 136 137 char *priorities_str; 138 char *proxy_priorities_str; 139 140 const char* srp_tpasswd_file; 141 const char* srp_tpasswd_conf_file; 142 134 143 /* Cache timeout value */ 135 144 int cache_timeout; … … 137 146 mgs_cache_e cache_type; 138 147 const char* cache_config; 139 const char* srp_tpasswd_file; 140 const char* srp_tpasswd_conf_file; 148 149 /* GnuTLS uses Session Tickets */ 150 int tickets; 151 152 /* --- Things initialized at _child_init --- */ 153 154 /* x509 Certificate Structure */ 155 gnutls_certificate_credentials_t certs; 156 /* x509 credentials for proxy connections */ 157 gnutls_certificate_credentials_t proxy_x509_creds; 158 /* trust list for proxy_x509_creds */ 159 gnutls_x509_trust_list_t proxy_x509_tl; 160 const char* proxy_x509_key_file; 161 const char* proxy_x509_cert_file; 162 const char* proxy_x509_ca_file; 163 const char* proxy_x509_crl_file; 164 /* GnuTLS priorities for proxy connections */ 165 gnutls_priority_t proxy_priorities; 166 /* SRP Certificate Structure*/ 167 gnutls_srp_server_credentials_t srp_creds; 168 /* Anonymous Certificate Structure */ 169 gnutls_anon_server_credentials_t anon_creds; 170 /* Anonymous Client Certificate Structure, used for proxy 171 * connections */ 172 gnutls_anon_client_credentials_t anon_client_creds; 173 /* Current x509 Certificate CN [Common Name] */ 174 char* cert_cn; 175 /* Current x509 Certificate SAN [Subject Alternate Name]s*/ 176 char* cert_san[MAX_CERT_SAN]; 177 /* An x509 Certificate Chain */ 178 gnutls_pcert_st *certs_x509_chain; 179 gnutls_x509_crt_t *certs_x509_crt_chain; 180 /* Number of Certificates in Chain */ 181 unsigned int certs_x509_chain_num; 182 183 /* Current x509 Certificate Private Key */ 184 gnutls_privkey_t privkey_x509; 185 186 /* OpenPGP Certificate */ 187 gnutls_pcert_st *cert_pgp; 188 gnutls_openpgp_crt_t *cert_crt_pgp; 189 190 /* OpenPGP Certificate Private Key */ 191 gnutls_privkey_t privkey_pgp; 192 #if GNUTLS_VERSION_NUMBER < 0x030312 193 /* Internal structure for the OpenPGP private key, used in the 194 * workaround for a bug in gnutls_privkey_import_openpgp_raw that 195 * frees memory that is still needed. DO NOT USE for any other 196 * purpose. */ 197 gnutls_openpgp_privkey_t privkey_pgp_internal; 198 #endif 199 200 /* Export full certificates to CGI environment: */ 201 int export_certificates_size; 202 /* GnuTLS Priorities */ 203 gnutls_priority_t priorities; 204 /* GnuTLS DH Parameters */ 205 gnutls_dh_params_t dh_params; 141 206 /* A list of CA Certificates */ 142 207 gnutls_x509_crt_t *ca_list; … … 151 216 /* Last Cache timestamp */ 152 217 apr_time_t last_cache_check; 153 /* GnuTLS uses Session Tickets */154 int tickets;155 /* Is mod_proxy enabled? */156 int proxy_enabled;157 /* A Plain HTTP request */158 int non_ssl_request;159 218 } mgs_srvconf_rec; 160 219 … … 171 230 /* Connection record */ 172 231 conn_rec* c; 232 /* Is TLS enabled for this connection? */ 233 int enabled; 234 /* Is this a proxy connection? */ 235 int is_proxy; 173 236 /* GnuTLS Session handle */ 174 237 gnutls_session_t session; … … 302 365 303 366 /** 367 * Perform any reinitialization required in PKCS #11 368 */ 369 int mgs_pkcs11_reinit(server_rec * s); 370 371 /** 304 372 * Convert a SSL Session ID into a Null Terminated Hex Encoded String 305 373 * @param id raw SSL Session ID … … 321 389 322 390 /* Configuration Functions */ 391 392 /* Loads all files set in the configuration */ 393 int mgs_load_files(apr_pool_t * p, server_rec * s); 323 394 324 395 const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy, … … 355 426 const char *arg); 356 427 428 const char *mgs_set_p11_module(cmd_parms * parms, void *dummy, 429 const char *arg); 430 431 const char *mgs_set_pin(cmd_parms * parms, void *dummy, 432 const char *arg); 433 434 const char *mgs_set_srk_pin(cmd_parms * parms, void *dummy, 435 const char *arg); 436 357 437 const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, 358 438 const char *arg); … … 360 440 const char *mgs_set_enabled(cmd_parms * parms, void *dummy, 361 441 const char *arg); 362 const char *mgs_set_export_certificates_ enabled(cmd_parms * parms, void *dummy,442 const char *mgs_set_export_certificates_size(cmd_parms * parms, void *dummy, 363 443 const char *arg); 364 444 const char *mgs_set_priorities(cmd_parms * parms, void *dummy, … … 381 461 mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session); 382 462 463 const char *mgs_store_cred_path(cmd_parms * parms, 464 void *dummy __attribute__((unused)), 465 const char *arg); 466 383 467 /* mod_gnutls Hooks. */ 384 468 -
m4/apr_memcache.m4
r2db6923 r71e9a5c 45 45 apr_memcache_includedir=$includedir/apr_memcache-0 46 46 fi 47 47 48 CFLAGS="-I$apr_memcache_includedir $CFLAGS" 49 48 50 49 51 AC_CHECK_LIB( … … 58 60 ] 59 61 ) 62 63 64 dnl # if the apr_memcache was not found, try apr-util 65 if test -z "${APR_MEMCACHE_LIBS}"; then 66 if test -n "$apr_memcache_includes"; then 67 apr_memcache_includedir=$apr_memcache_includes 68 elif test -n "$apr_memcache_prefix"; then 69 apr_memcache_includedir=$apr_memcache_prefix/include/aprutil-1 70 else 71 apr_memcache_includedir=$includedir/aprutil-1 72 fi 73 AC_CHECK_LIB( 74 aprutil-1, 75 apr_memcache_create, 76 [ 77 APR_MEMCACHE_LIBS="`apu-1-config --link-ld`" 78 APR_MEMCACHE_CFLAGS="`apu-1-config --includes`" 79 ] 80 ) 81 fi 82 83 60 84 CFLAGS=$save_CFLAGS 61 85 LDFLAGS=$save_LDFLAGS -
src/Makefile.am
r2db6923 r71e9a5c 21 21 @echo "***********************************************" 22 22 @echo "" 23 @echo " Please read the documentation at " 24 @echo " http://modgnutls.sourceforge.net/?p=docs for " 25 @echo " details on configuration of this module " 23 @echo " Please read the manual in the doc/ directory for" 24 @echo " details on the configuration of this module" 26 25 @echo "" 27 26 @echo "***********************************************" 28 27 @echo "" 29 -
src/gnutls_cache.c
r2db6923 r71e9a5c 3 3 * Copyright 2008 Nikos Mavrogiannopoulos 4 4 * Copyright 2011 Dash Shendy 5 * Copyright 2015 Thomas Klute 5 6 * 6 7 * Licensed under the Apache License, Version 2.0 (the "License"); … … 45 46 #endif 46 47 48 #ifdef APLOG_USE_MODULE 49 APLOG_USE_MODULE(gnutls); 50 #endif 51 47 52 char *mgs_session_id2sz(unsigned char *id, int idlen, 48 53 char *str, int strsize) { … … 576 581 } 577 582 578 int mgs_cache_child_init(apr_pool_t * p, server_rec * s, 579 mgs_srvconf_rec * sc) { 583 #if HAVE_APR_MEMCACHE 584 int mgs_cache_child_init(apr_pool_t * p, 585 server_rec * s, 586 mgs_srvconf_rec * sc) 587 #else 588 int mgs_cache_child_init(apr_pool_t * p __attribute__((unused)), 589 server_rec * s __attribute__((unused)), 590 mgs_srvconf_rec * sc) 591 #endif 592 { 580 593 if (sc->cache_type == mgs_cache_dbm 581 594 || sc->cache_type == mgs_cache_gdbm) { -
src/gnutls_config.c
r2db6923 r71e9a5c 1 1 /** 2 2 * Copyright 2004-2005 Paul Querna 3 * Copyright 2008 Nikos Mavrogiannopoulos3 * Copyright 2008, 2014 Nikos Mavrogiannopoulos 4 4 * Copyright 2011 Dash Shendy 5 * Copyright 2015 Thomas Klute 5 6 * 6 7 * Licensed under the Apache License, Version 2.0 (the "License"); … … 19 20 20 21 #include "mod_gnutls.h" 22 #include "apr_lib.h" 23 #include <gnutls/abstract.h> 24 25 #define INIT_CA_SIZE 128 26 27 #ifdef APLOG_USE_MODULE 28 APLOG_USE_MODULE(gnutls); 29 #endif 30 31 static int pin_callback(void *user, int attempt __attribute__((unused)), 32 const char *token_url __attribute__((unused)), 33 const char *token_label, unsigned int flags, 34 char *pin, size_t pin_max) 35 { 36 mgs_srvconf_rec *sc = user; 37 38 if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY || 39 flags & GNUTLS_PIN_WRONG) { 40 return -1; 41 } 42 43 if (token_label && strcmp(token_label, "SRK") == 0) { 44 snprintf(pin, pin_max, "%s", sc->srk_pin); 45 } else { 46 snprintf(pin, pin_max, "%s", sc->pin); 47 } 48 return 0; 49 } 21 50 22 51 static int load_datum_from_file(apr_pool_t * pool, 23 const char *file, gnutls_datum_t * data) { 52 const char *file, gnutls_datum_t * data) 53 { 24 54 apr_file_t *fp; 25 55 apr_finfo_t finfo; … … 28 58 29 59 rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, 30 60 APR_OS_DEFAULT, pool); 31 61 if (rv != APR_SUCCESS) { 32 62 return rv; 33 63 } 34 64 … … 36 66 37 67 if (rv != APR_SUCCESS) { 38 68 return rv; 39 69 } 40 70 … … 43 73 44 74 if (rv != APR_SUCCESS) { 45 75 return rv; 46 76 } 47 77 apr_file_close(fp); … … 53 83 } 54 84 55 const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, 56 const char *arg) { 85 /* 2048-bit group parameters from SRP specification */ 86 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" 87 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" 88 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" 89 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n" 90 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n" 91 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n" 92 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n" 93 "-----END DH PARAMETERS-----\n"; 94 95 int mgs_load_files(apr_pool_t * p, server_rec * s) 96 { 97 apr_pool_t *spool; 98 const char *file; 99 gnutls_datum_t data; 57 100 int ret; 58 gnutls_datum_t data; 59 const char *file; 60 apr_pool_t *spool; 61 mgs_srvconf_rec *sc = 62 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 63 module_config, 64 &gnutls_module); 65 66 apr_pool_create(&spool, parms->pool); 67 68 file = ap_server_root_relative(spool, arg); 69 70 if (load_datum_from_file(spool, file, &data) != 0) { 71 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 72 "DH params '%s'", file); 73 } 101 mgs_srvconf_rec *sc = 102 (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 103 &gnutls_module); 104 105 apr_pool_create(&spool, p); 106 107 sc->cert_pgp = apr_pcalloc(p, sizeof(sc->cert_pgp[0])); 108 sc->cert_crt_pgp = apr_pcalloc(p, sizeof(sc->cert_crt_pgp[0])); 109 sc->certs_x509_chain = 110 apr_pcalloc(p, MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0])); 111 sc->certs_x509_crt_chain = 112 apr_pcalloc(p, 113 MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0])); 114 115 ret = gnutls_certificate_allocate_credentials(&sc->certs); 116 if (ret < 0) { 117 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 118 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 119 gnutls_strerror(ret)); 120 ret = -1; 121 goto cleanup; 122 } 123 124 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds); 125 if (ret < 0) { 126 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 127 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 128 gnutls_strerror(ret)); 129 ret = -1; 130 goto cleanup; 131 } 132 133 /* Load SRP parameters */ 134 #ifdef ENABLE_SRP 135 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds); 136 if (ret < 0) { 137 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 138 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 139 gnutls_strerror(ret)); 140 ret = -1; 141 goto cleanup; 142 } 143 144 if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) { 145 ret = gnutls_srp_set_server_credentials_file 146 (sc->srp_creds, sc->srp_tpasswd_file, 147 sc->srp_tpasswd_conf_file); 148 149 if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 150 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, 151 s, 152 "GnuTLS: Host '%s:%d' is missing a " 153 "SRP password or conf File!", 154 s->server_hostname, s->port); 155 ret = -1; 156 goto cleanup; 157 } 158 } 159 #endif 74 160 75 161 ret = gnutls_dh_params_init(&sc->dh_params); 76 162 if (ret < 0) { 77 return apr_psprintf(parms->pool, 78 "GnuTLS: Failed to initialize" 79 ": (%d) %s", ret, 80 gnutls_strerror(ret)); 81 } 82 83 ret = 84 gnutls_dh_params_import_pkcs3(sc->dh_params, &data, 85 GNUTLS_X509_FMT_PEM); 86 if (ret < 0) { 87 return apr_psprintf(parms->pool, 88 "GnuTLS: Failed to Import " 89 "DH params '%s': (%d) %s", file, ret, 90 gnutls_strerror(ret)); 91 } 92 163 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 164 "GnuTLS: Failed to initialize" 165 ": (%d) %s", ret, gnutls_strerror(ret)); 166 ret = -1; 167 goto cleanup; 168 } 169 170 /* Load DH parameters */ 171 if (sc->dh_file) { 172 if (load_datum_from_file(spool, sc->dh_file, &data) != 0) { 173 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 174 "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file); 175 ret = -1; 176 goto cleanup; 177 } 178 179 ret = 180 gnutls_dh_params_import_pkcs3(sc->dh_params, &data, 181 GNUTLS_X509_FMT_PEM); 182 if (ret < 0) { 183 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 184 "GnuTLS: Failed to Import " 185 "DH params '%s': (%d) %s", sc->dh_file, ret, 186 gnutls_strerror(ret)); 187 ret = -1; 188 goto cleanup; 189 } 190 } else { 191 gnutls_datum_t pdata = { 192 (void *) static_dh_params, 193 sizeof(static_dh_params) 194 }; 195 196 ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM); 197 if (ret < 0) { 198 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 199 "GnuTLS: Unable to generate or load DH Params: (%d) %s", 200 ret, gnutls_strerror(ret)); 201 ret = -1; 202 goto cleanup; 203 } 204 } 205 206 if (sc->x509_cert_file != NULL) { 207 unsigned int chain_num, i; 208 unsigned format = GNUTLS_X509_FMT_PEM; 209 210 /* Load X.509 certificate */ 211 if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) { 212 gnutls_pkcs11_obj_t obj; 213 214 file = sc->x509_cert_file; 215 216 ret = gnutls_pkcs11_obj_init(&obj); 217 if (ret < 0) { 218 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 219 "GnuTLS: Error Initializing PKCS #11 object"); 220 ret = -1; 221 goto cleanup; 222 } 223 224 gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc); 225 226 ret = gnutls_pkcs11_obj_import_url(obj, file, GNUTLS_PKCS11_OBJ_FLAG_LOGIN); 227 if (ret < 0) { 228 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 229 "GnuTLS: Error Importing PKCS #11 object: '%s': %s", 230 file, gnutls_strerror(ret)); 231 ret = -1; 232 goto cleanup; 233 } 234 235 format = GNUTLS_X509_FMT_DER; 236 ret = gnutls_pkcs11_obj_export2(obj, &data); 237 if (ret < 0) { 238 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 239 "GnuTLS: Error Exporting a PKCS #11 object: '%s': %s", 240 file, gnutls_strerror(ret)); 241 ret = -1; 242 goto cleanup; 243 } 244 245 gnutls_pkcs11_obj_deinit(obj); 246 } else { 247 file = ap_server_root_relative(spool, sc->x509_cert_file); 248 249 ret = gnutls_load_file(file, &data); 250 if (ret < 0) { 251 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 252 "GnuTLS: Error Reading Certificate '%s': %s", 253 file, gnutls_strerror(ret)); 254 ret = -1; 255 goto cleanup; 256 } 257 } 258 259 ret = 260 gnutls_x509_crt_list_import2(&sc->certs_x509_crt_chain, 261 &chain_num, &data, format, 262 GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); 263 gnutls_free(data.data); 264 sc->certs_x509_chain_num = chain_num; 265 266 if (ret < 0) { 267 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 268 "GnuTLS: Failed to Import Certificate Chain '%s': (%d) %s", 269 file, ret, gnutls_strerror(ret)); 270 ret = -1; 271 goto cleanup; 272 } 273 274 for (i = 0; i < chain_num; i++) { 275 ret = 276 gnutls_pcert_import_x509(&sc->certs_x509_chain[i], 277 sc->certs_x509_crt_chain[i], 0); 278 if (ret < 0) { 279 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 280 "GnuTLS: Failed to Import pCertificate '%s': (%d) %s", 281 file, ret, gnutls_strerror(ret)); 282 ret = -1; 283 goto cleanup; 284 } 285 } 286 sc->certs_x509_chain_num = chain_num; 287 } 288 289 if (sc->x509_key_file) { 290 ret = gnutls_privkey_init(&sc->privkey_x509); 291 if (ret < 0) { 292 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 293 "GnuTLS: Failed to initialize: (%d) %s", ret, 294 gnutls_strerror(ret)); 295 ret = -1; 296 goto cleanup; 297 } 298 299 if (gnutls_url_is_supported(sc->x509_key_file) != 0) { 300 file = sc->x509_key_file; 301 302 gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, 303 sc); 304 305 ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0); 306 307 if (ret < 0) { 308 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 309 "GnuTLS: Failed to Import Private Key URL '%s': (%d) %s", 310 file, ret, gnutls_strerror(ret)); 311 ret = -1; 312 goto cleanup; 313 } 314 } else { 315 file = ap_server_root_relative(spool, sc->x509_key_file); 316 317 if (load_datum_from_file(spool, file, &data) != 0) { 318 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 319 "GnuTLS: Error Reading Private Key '%s'", 320 file); 321 ret = -1; 322 goto cleanup; 323 } 324 325 ret = 326 gnutls_privkey_import_x509_raw(sc->privkey_x509, &data, 327 GNUTLS_X509_FMT_PEM, sc->pin, 328 0); 329 330 if (ret < 0) { 331 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 332 "GnuTLS: Failed to Import Private Key '%s': (%d) %s", 333 file, ret, gnutls_strerror(ret)); 334 ret = -1; 335 goto cleanup; 336 } 337 } 338 } 339 340 /* Load the X.509 CA file */ 341 if (sc->x509_ca_file) { 342 if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) { 343 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 344 "GnuTLS: Error Reading " "Client CA File '%s'", 345 sc->x509_ca_file); 346 ret = -1; 347 goto cleanup; 348 } 349 350 ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size, 351 &data, GNUTLS_X509_FMT_PEM, 0); 352 if (ret < 0) { 353 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 354 "GnuTLS: Failed to load " 355 "Client CA File '%s': (%d) %s", sc->x509_ca_file, 356 ret, gnutls_strerror(ret)); 357 ret = -1; 358 goto cleanup; 359 } 360 } 361 362 if (sc->pgp_cert_file) { 363 if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) { 364 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 365 "GnuTLS: Error Reading " "Certificate '%s'", 366 sc->pgp_cert_file); 367 ret = -1; 368 goto cleanup; 369 } 370 371 ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]); 372 if (ret < 0) { 373 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 374 "GnuTLS: Failed to Init " 375 "PGP Certificate: (%d) %s", ret, 376 gnutls_strerror(ret)); 377 ret = -1; 378 goto cleanup; 379 } 380 381 ret = 382 gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data, 383 GNUTLS_OPENPGP_FMT_BASE64); 384 if (ret < 0) { 385 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 386 "GnuTLS: Failed to Import " 387 "PGP Certificate: (%d) %s", ret, 388 gnutls_strerror(ret)); 389 ret = -1; 390 goto cleanup; 391 } 392 393 ret = 394 gnutls_pcert_import_openpgp(sc->cert_pgp, sc->cert_crt_pgp[0], 395 0); 396 if (ret < 0) { 397 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 398 "GnuTLS: Failed to Import " 399 "PGP pCertificate: (%d) %s", ret, 400 gnutls_strerror(ret)); 401 ret = -1; 402 goto cleanup; 403 } 404 } 405 406 /* Load the PGP key file */ 407 if (sc->pgp_key_file) { 408 if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) { 409 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 410 "GnuTLS: Error Reading " "Private Key '%s'", 411 sc->pgp_key_file); 412 ret = -1; 413 goto cleanup; 414 } 415 416 ret = gnutls_privkey_init(&sc->privkey_pgp); 417 if (ret < 0) { 418 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 419 "GnuTLS: Failed to initialize" 420 ": (%d) %s", ret, gnutls_strerror(ret)); 421 ret = -1; 422 goto cleanup; 423 } 424 425 #if GNUTLS_VERSION_NUMBER < 0x030312 426 /* GnuTLS versions before 3.3.12 contain a bug in 427 * gnutls_privkey_import_openpgp_raw which frees data that is 428 * accessed when the key is used, leading to segfault. Loading 429 * the key into a gnutls_openpgp_privkey_t and then assigning 430 * it to the gnutls_privkey_t works around the bug, hence this 431 * chain of gnutls_openpgp_privkey_init, 432 * gnutls_openpgp_privkey_import and 433 * gnutls_privkey_import_openpgp. */ 434 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal); 435 if (ret != 0) { 436 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 437 "GnuTLS: Failed to initialize " 438 "PGP Private Key '%s': (%d) %s", 439 sc->pgp_key_file, ret, gnutls_strerror(ret)); 440 ret = -1; 441 goto cleanup; 442 } 443 444 ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data, 445 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); 446 if (ret != 0) { 447 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 448 "GnuTLS: Failed to Import " 449 "PGP Private Key '%s': (%d) %s", 450 sc->pgp_key_file, ret, gnutls_strerror(ret)); 451 ret = -1; 452 goto cleanup; 453 } 454 455 ret = gnutls_privkey_import_openpgp(sc->privkey_pgp, 456 sc->privkey_pgp_internal, 0); 457 if (ret != 0) 458 { 459 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 460 "GnuTLS: Failed to assign PGP Private Key '%s' " 461 "to gnutls_privkey_t structure: (%d) %s", 462 sc->pgp_key_file, ret, gnutls_strerror(ret)); 463 ret = -1; 464 goto cleanup; 465 } 466 #else 467 ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data, 468 GNUTLS_OPENPGP_FMT_BASE64, 469 NULL, NULL); 470 if (ret != 0) 471 { 472 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 473 "GnuTLS: Failed to Import " 474 "PGP Private Key '%s': (%d) %s", 475 sc->pgp_key_file, ret, gnutls_strerror(ret)); 476 ret = -1; 477 goto cleanup; 478 } 479 #endif 480 } 481 482 /* Load the keyring file */ 483 if (sc->pgp_ring_file) { 484 if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) { 485 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 486 "GnuTLS: Error Reading " "Keyring File '%s'", 487 sc->pgp_ring_file); 488 ret = -1; 489 goto cleanup; 490 } 491 492 ret = gnutls_openpgp_keyring_init(&sc->pgp_list); 493 if (ret < 0) { 494 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 495 "GnuTLS: Failed to initialize" 496 "keyring: (%d) %s", ret, gnutls_strerror(ret)); 497 ret = -1; 498 goto cleanup; 499 } 500 501 ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data, 502 GNUTLS_OPENPGP_FMT_BASE64); 503 if (ret < 0) { 504 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 505 "GnuTLS: Failed to load " 506 "Keyring File '%s': (%d) %s", sc->pgp_ring_file, 507 ret, gnutls_strerror(ret)); 508 ret = -1; 509 goto cleanup; 510 } 511 } 512 513 if (sc->priorities_str) { 514 const char *err; 515 ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err); 516 517 if (ret < 0) { 518 if (ret == GNUTLS_E_INVALID_REQUEST) { 519 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 520 "GnuTLS: Syntax error parsing priorities string at: %s", 521 err); 522 } else { 523 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 524 "GnuTLS: error parsing priorities string"); 525 526 } 527 ret = -1; 528 goto cleanup; 529 } 530 } 531 532 ret = 0; 533 cleanup: 93 534 apr_pool_destroy(spool); 94 535 95 return NULL;96 } 97 98 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, const char *arg) { 99 536 return ret; 537 } 538 539 int mgs_pkcs11_reinit(server_rec * base_server) 540 { 100 541 int ret; 101 gnutls_datum_t data; 102 const char *file; 103 apr_pool_t *spool; 104 105 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 106 apr_pool_create(&spool, parms->pool); 107 108 file = ap_server_root_relative(spool, arg); 109 110 if (load_datum_from_file(spool, file, &data) != 0) { 111 apr_pool_destroy(spool); 112 return apr_psprintf(parms->pool, "GnuTLS: Error Reading Certificate '%s'", file); 113 } 114 115 sc->certs_x509_chain_num = MAX_CHAIN_SIZE; 116 ret = gnutls_x509_crt_list_import(sc->certs_x509_chain, &sc->certs_x509_chain_num, &data, GNUTLS_X509_FMT_PEM, 0); 117 if (ret < 0) { 118 apr_pool_destroy(spool); 119 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret)); 120 } 121 122 apr_pool_destroy(spool); 123 return NULL; 124 125 } 126 127 const char *mgs_set_key_file(cmd_parms * parms, void *dummy, const char *arg) { 128 129 int ret; 130 gnutls_datum_t data; 131 const char *file; 132 apr_pool_t *spool; 133 const char *out; 134 135 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 136 137 apr_pool_create(&spool, parms->pool); 138 139 file = ap_server_root_relative(spool, arg); 140 141 if (load_datum_from_file(spool, file, &data) != 0) { 142 out = apr_psprintf(parms->pool, "GnuTLS: Error Reading Private Key '%s'", file); 143 apr_pool_destroy(spool); 144 return out; 145 } 146 147 ret = gnutls_x509_privkey_init(&sc->privkey_x509); 148 149 if (ret < 0) { 150 apr_pool_destroy(spool); 151 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize: (%d) %s", ret, gnutls_strerror(ret)); 152 } 153 154 ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM); 155 156 if (ret < 0) { 157 ret = gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN); 158 } 159 160 if (ret < 0) { 161 out = apr_psprintf(parms->pool, "GnuTLS: Failed to Import Private Key '%s': (%d) %s", file, ret, gnutls_strerror(ret)); 162 apr_pool_destroy(spool); 163 return out; 164 } 165 166 apr_pool_destroy(spool); 167 168 return NULL; 169 } 170 171 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy, 542 server_rec *s; 543 mgs_srvconf_rec *sc; 544 545 gnutls_pkcs11_reinit(); 546 547 for (s = base_server; s; s = s->next) { 548 sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 549 550 /* gnutls caches the session in a private key, so we need to open 551 * a new one */ 552 if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) { 553 gnutls_privkey_deinit(sc->privkey_x509); 554 555 ret = gnutls_privkey_init(&sc->privkey_x509); 556 if (ret < 0) { 557 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 558 "GnuTLS: Failed to initialize: (%d) %s", ret, 559 gnutls_strerror(ret)); 560 goto fail; 561 } 562 563 gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc); 564 565 ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0); 566 if (ret < 0) { 567 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 568 "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s", 569 sc->x509_key_file, ret, gnutls_strerror(ret)); 570 goto fail; 571 } 572 } 573 } 574 575 return 0; 576 577 fail: 578 gnutls_privkey_deinit(sc->privkey_x509); 579 return -1; 580 } 581 582 const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)), 172 583 const char *arg) { 173 int ret; 174 gnutls_datum_t data; 175 const char *file; 176 apr_pool_t *spool; 177 mgs_srvconf_rec *sc = 178 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 179 module_config, 180 &gnutls_module); 181 apr_pool_create(&spool, parms->pool); 182 183 file = ap_server_root_relative(spool, arg); 184 185 if (load_datum_from_file(spool, file, &data) != 0) { 186 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 187 "Certificate '%s'", file); 188 } 189 190 ret = gnutls_openpgp_crt_init(&sc->cert_pgp); 191 if (ret < 0) { 192 return apr_psprintf(parms->pool, "GnuTLS: Failed to Init " 193 "PGP Certificate: (%d) %s", ret, 194 gnutls_strerror(ret)); 195 } 196 197 ret = 198 gnutls_openpgp_crt_import(sc->cert_pgp, &data, 199 GNUTLS_OPENPGP_FMT_BASE64); 200 if (ret < 0) { 201 return apr_psprintf(parms->pool, 202 "GnuTLS: Failed to Import " 203 "PGP Certificate '%s': (%d) %s", file, 204 ret, gnutls_strerror(ret)); 205 } 206 207 apr_pool_destroy(spool); 208 return NULL; 209 } 210 211 const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy, 584 mgs_srvconf_rec *sc = 585 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 586 module_config, 587 &gnutls_module); 588 589 sc->dh_file = ap_server_root_relative(parms->pool, arg); 590 591 return NULL; 592 } 593 594 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 595 596 mgs_srvconf_rec *sc = 597 (mgs_srvconf_rec *) ap_get_module_config(parms-> 598 server->module_config, 599 &gnutls_module); 600 601 sc->x509_cert_file = apr_pstrdup(parms->pool, arg); 602 603 return NULL; 604 605 } 606 607 const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 608 609 mgs_srvconf_rec *sc = 610 (mgs_srvconf_rec *) ap_get_module_config(parms-> 611 server->module_config, 612 &gnutls_module); 613 614 sc->x509_key_file = apr_pstrdup(parms->pool, arg); 615 616 return NULL; 617 } 618 619 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)), 620 const char *arg) 621 { 622 mgs_srvconf_rec *sc = 623 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 624 module_config, 625 &gnutls_module); 626 627 sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg); 628 629 return NULL; 630 } 631 632 const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)), 212 633 const char *arg) { 213 int ret; 214 gnutls_datum_t data; 215 const char *file; 216 apr_pool_t *spool; 217 mgs_srvconf_rec *sc = 218 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 219 module_config, 220 &gnutls_module); 221 apr_pool_create(&spool, parms->pool); 222 223 file = ap_server_root_relative(spool, arg); 224 225 if (load_datum_from_file(spool, file, &data) != 0) { 226 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 227 "Private Key '%s'", file); 228 } 229 230 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp); 231 if (ret < 0) { 232 return apr_psprintf(parms->pool, 233 "GnuTLS: Failed to initialize" 234 ": (%d) %s", ret, 235 gnutls_strerror(ret)); 236 } 237 238 ret = 239 gnutls_openpgp_privkey_import(sc->privkey_pgp, &data, 240 GNUTLS_OPENPGP_FMT_BASE64, NULL, 241 0); 242 if (ret != 0) { 243 return apr_psprintf(parms->pool, 244 "GnuTLS: Failed to Import " 245 "PGP Private Key '%s': (%d) %s", file, 246 ret, gnutls_strerror(ret)); 247 } 248 apr_pool_destroy(spool); 249 return NULL; 250 } 251 252 const char *mgs_set_tickets(cmd_parms * parms, void *dummy, 634 mgs_srvconf_rec *sc = 635 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 636 module_config, 637 &gnutls_module); 638 639 sc->pgp_key_file = ap_server_root_relative(parms->pool, arg); 640 641 return NULL; 642 } 643 644 const char *mgs_set_tickets(cmd_parms * parms, void *dummy __attribute__((unused)), 253 645 const char *arg) { 254 646 mgs_srvconf_rec *sc = 255 256 257 647 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 648 module_config, 649 &gnutls_module); 258 650 259 651 sc->tickets = 0; 260 652 if (strcasecmp("on", arg) == 0) { 261 653 sc->tickets = 1; 262 654 } 263 655 … … 268 660 #ifdef ENABLE_SRP 269 661 270 const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy ,662 const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy __attribute__((unused)), 271 663 const char *arg) { 272 664 mgs_srvconf_rec *sc = 273 274 275 665 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 666 module_config, 667 &gnutls_module); 276 668 277 669 sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg); … … 280 672 } 281 673 282 const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy ,674 const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy __attribute__((unused)), 283 675 const char *arg) { 284 676 mgs_srvconf_rec *sc = 285 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 286 module_config, 287 &gnutls_module); 288 289 sc->srp_tpasswd_conf_file = 290 ap_server_root_relative(parms->pool, arg); 677 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 678 module_config, 679 &gnutls_module); 680 681 sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg); 291 682 292 683 return NULL; … … 295 686 #endif 296 687 297 const char *mgs_set_cache(cmd_parms * parms, void *dummy ,688 const char *mgs_set_cache(cmd_parms * parms, void *dummy __attribute__((unused)), 298 689 const char *type, const char *arg) { 299 690 const char *err; 300 691 mgs_srvconf_rec *sc = 301 302 692 ap_get_module_config(parms->server->module_config, 693 &gnutls_module); 303 694 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { 304 695 return err; 305 696 } 306 697 307 698 if (strcasecmp("none", type) == 0) { 308 309 310 699 sc->cache_type = mgs_cache_none; 700 sc->cache_config = NULL; 701 return NULL; 311 702 } else if (strcasecmp("dbm", type) == 0) { 312 703 sc->cache_type = mgs_cache_dbm; 313 704 } else if (strcasecmp("gdbm", type) == 0) { 314 705 sc->cache_type = mgs_cache_gdbm; 315 706 } 316 707 #if HAVE_APR_MEMCACHE 317 708 else if (strcasecmp("memcache", type) == 0) { 318 709 sc->cache_type = mgs_cache_memcache; 319 710 } 320 711 #endif 321 712 else { 322 713 return "Invalid Type for GnuTLSCache!"; 323 714 } 324 715 325 716 if (arg == NULL) 326 717 return "Invalid argument 2 for GnuTLSCache!"; 327 718 328 719 if (sc->cache_type == mgs_cache_dbm 329 || sc->cache_type == mgs_cache_gdbm) { 330 sc->cache_config = 331 ap_server_root_relative(parms->pool, arg); 720 || sc->cache_type == mgs_cache_gdbm) { 721 sc->cache_config = ap_server_root_relative(parms->pool, arg); 332 722 } else { 333 334 } 335 336 return NULL; 337 } 338 339 const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy ,723 sc->cache_config = apr_pstrdup(parms->pool, arg); 724 } 725 726 return NULL; 727 } 728 729 const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy __attribute__((unused)), 340 730 const char *arg) { 341 731 int argint; 342 732 const char *err; 343 733 mgs_srvconf_rec *sc = 344 345 346 734 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 735 module_config, 736 &gnutls_module); 347 737 348 738 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { 349 739 return err; 350 740 } 351 741 … … 353 743 354 744 if (argint < 0) { 355 745 return "GnuTLSCacheTimeout: Invalid argument"; 356 746 } else if (argint == 0) { 357 747 sc->cache_timeout = 0; 358 748 } else { 359 360 } 361 362 return NULL; 363 } 364 365 const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy ,749 sc->cache_timeout = apr_time_from_sec(argint); 750 } 751 752 return NULL; 753 } 754 755 const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy __attribute__((unused)), 366 756 const char *arg) { 367 757 mgs_srvconf_rec *sc = (mgs_srvconf_rec *)ap_get_module_config(parms->server->module_config, &gnutls_module); 368 758 369 759 if (strcasecmp("cartel", arg) == 0) { 370 760 sc->client_verify_method = mgs_cvm_cartel; 371 761 } else if (strcasecmp("msva", arg) == 0) { 372 762 #ifdef ENABLE_MSVA 373 763 sc->client_verify_method = mgs_cvm_msva; 374 764 #else 375 765 return "GnuTLSClientVerifyMethod: msva is not supported"; 376 766 #endif 377 767 } else { 378 return "GnuTLSClientVerifyMethod: Invalid argument"; 379 } 380 381 return NULL; 382 } 383 384 const char *mgs_set_client_verify(cmd_parms * parms, void *dummy, 385 const char *arg) { 768 return "GnuTLSClientVerifyMethod: Invalid argument"; 769 } 770 771 return NULL; 772 } 773 774 const char *mgs_set_client_verify(cmd_parms * parms, 775 void *dirconf, 776 const char *arg) { 386 777 int mode; 387 778 388 779 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { 389 780 mode = GNUTLS_CERT_IGNORE; 390 781 } else if (strcasecmp("optional", arg) == 0 391 392 782 || strcasecmp("request", arg) == 0) { 783 mode = GNUTLS_CERT_REQUEST; 393 784 } else if (strcasecmp("require", arg) == 0) { 394 785 mode = GNUTLS_CERT_REQUIRE; 395 786 } else { 396 787 return "GnuTLSClientVerify: Invalid argument"; 397 788 } 398 789 399 790 /* This was set from a directory context */ 400 791 if (parms->path) { 401 mgs_dirconf_rec *dc = (mgs_dirconf_rec *) d ummy;792 mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dirconf; 402 793 dc->client_verify_mode = mode; 403 794 } else { 404 mgs_srvconf_rec *sc = 405 (mgs_srvconf_rec *) 406 ap_get_module_config(parms->server->module_config, 407 &gnutls_module); 408 sc->client_verify_mode = mode; 409 } 410 411 return NULL; 412 } 413 414 #define INIT_CA_SIZE 128 415 416 const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, 795 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 796 ap_get_module_config(parms->server->module_config, 797 &gnutls_module); 798 sc->client_verify_mode = mode; 799 } 800 801 return NULL; 802 } 803 804 const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy __attribute__((unused)), 417 805 const char *arg) { 418 int rv; 419 const char *file; 420 apr_pool_t *spool; 421 gnutls_datum_t data; 422 423 mgs_srvconf_rec *sc = 424 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 425 module_config, 426 &gnutls_module); 427 apr_pool_create(&spool, parms->pool); 428 429 file = ap_server_root_relative(spool, arg); 430 431 if (load_datum_from_file(spool, file, &data) != 0) { 432 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 433 "Client CA File '%s'", file); 434 } 435 436 sc->ca_list_size = INIT_CA_SIZE; 437 sc->ca_list = malloc(sc->ca_list_size * sizeof (*sc->ca_list)); 438 if (sc->ca_list == NULL) { 439 return apr_psprintf(parms->pool, 440 "mod_gnutls: Memory allocation error"); 441 } 442 443 rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, 444 &data, GNUTLS_X509_FMT_PEM, 445 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); 446 if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) { 447 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 448 "Client CA File '%s': (%d) %s", file, 449 rv, gnutls_strerror(rv)); 450 } 451 452 if (INIT_CA_SIZE < sc->ca_list_size) { 453 sc->ca_list = 454 realloc(sc->ca_list, 455 sc->ca_list_size * sizeof (*sc->ca_list)); 456 if (sc->ca_list == NULL) { 457 return apr_psprintf(parms->pool, 458 "mod_gnutls: Memory allocation error"); 459 } 460 461 /* re-read */ 462 rv = gnutls_x509_crt_list_import(sc->ca_list, 463 &sc->ca_list_size, &data, 464 GNUTLS_X509_FMT_PEM, 0); 465 466 if (rv < 0) { 467 return apr_psprintf(parms->pool, 468 "GnuTLS: Failed to load " 469 "Client CA File '%s': (%d) %s", 470 file, rv, gnutls_strerror(rv)); 471 } 472 } 473 474 apr_pool_destroy(spool); 475 return NULL; 476 } 477 478 const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, 806 mgs_srvconf_rec *sc = 807 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 808 module_config, 809 &gnutls_module); 810 811 sc->x509_ca_file = ap_server_root_relative(parms->pool, arg); 812 813 return NULL; 814 } 815 816 const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy __attribute__((unused)), 479 817 const char *arg) { 480 int rv; 481 const char *file; 482 apr_pool_t *spool; 483 gnutls_datum_t data; 484 485 mgs_srvconf_rec *sc = 486 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 487 module_config, 488 &gnutls_module); 489 apr_pool_create(&spool, parms->pool); 490 491 file = ap_server_root_relative(spool, arg); 492 493 if (load_datum_from_file(spool, file, &data) != 0) { 494 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 495 "Keyring File '%s'", file); 496 } 497 498 rv = gnutls_openpgp_keyring_init(&sc->pgp_list); 499 if (rv < 0) { 500 return apr_psprintf(parms->pool, 501 "GnuTLS: Failed to initialize" 502 "keyring: (%d) %s", rv, 503 gnutls_strerror(rv)); 504 } 505 506 rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, 507 GNUTLS_OPENPGP_FMT_BASE64); 508 if (rv < 0) { 509 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 510 "Keyring File '%s': (%d) %s", file, rv, 511 gnutls_strerror(rv)); 512 } 513 514 apr_pool_destroy(spool); 515 return NULL; 516 } 517 518 const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy, 818 mgs_srvconf_rec *sc = 819 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 820 module_config, 821 &gnutls_module); 822 823 sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg); 824 825 return NULL; 826 } 827 828 const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy __attribute__((unused)), 519 829 const char *arg) { 520 830 521 mgs_srvconf_rec *sc = (mgs_srvconf_rec *)522 831 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 832 ap_get_module_config(parms->server->module_config, &gnutls_module); 523 833 524 834 if (!strcasecmp(arg, "On")) { 525 835 sc->proxy_enabled = GNUTLS_ENABLED_TRUE; 526 836 } else if (!strcasecmp(arg, "Off")) { 527 837 sc->proxy_enabled = GNUTLS_ENABLED_FALSE; 528 838 } else { 529 return "SSLProxyEngine must be set to 'On' or 'Off'";530 } 531 532 return NULL; 533 } 534 535 const char *mgs_set_enabled(cmd_parms * parms, void *dummy ,839 return "GnuTLSProxyEngine must be set to 'On' or 'Off'"; 840 } 841 842 return NULL; 843 } 844 845 const char *mgs_set_enabled(cmd_parms * parms, void *dummy __attribute__((unused)), 536 846 const char *arg) { 537 847 mgs_srvconf_rec *sc = 538 539 540 848 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 849 module_config, 850 &gnutls_module); 541 851 if (!strcasecmp(arg, "On")) { 542 852 sc->enabled = GNUTLS_ENABLED_TRUE; 543 853 } else if (!strcasecmp(arg, "Off")) { 544 854 sc->enabled = GNUTLS_ENABLED_FALSE; 545 855 } else { 546 547 } 548 549 return NULL; 550 } 551 552 const char *mgs_set_export_certificates_ enabled(cmd_parms * parms, void *dummy, const char *arg) {856 return "GnuTLSEnable must be set to 'On' or 'Off'"; 857 } 858 859 return NULL; 860 } 861 862 const char *mgs_set_export_certificates_size(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 553 863 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 554 864 if (!strcasecmp(arg, "On")) { 555 sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;865 sc->export_certificates_size = 16 * 1024; 556 866 } else if (!strcasecmp(arg, "Off")) { 557 sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;867 sc->export_certificates_size = 0; 558 868 } else { 559 return 560 "GnuTLSExportCertificates must be set to 'On' or 'Off'"; 561 } 562 563 return NULL; 564 } 565 566 const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg) { 567 568 int ret; 569 const char *err; 570 869 char *endptr; 870 sc->export_certificates_size = strtol(arg, &endptr, 10); 871 while (apr_isspace(*endptr)) 872 endptr++; 873 if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') { 874 ; 875 } else if (*endptr == 'k' || *endptr == 'K') { 876 sc->export_certificates_size *= 1024; 877 } else { 878 return 879 "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'"; 880 } 881 } 882 883 return NULL; 884 } 885 886 887 888 /* 889 * Store GnuTLS priority strings. Used for GnuTLSPriorities and 890 * GnuTLSProxyPriorities. 891 */ 892 const char *mgs_set_priorities(cmd_parms * parms, 893 void *dummy __attribute__((unused)), 894 const char *arg) 895 { 571 896 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 572 ap_get_module_config(parms->server->module_config, &gnutls_module); 573 574 ret = gnutls_priority_init(&sc->priorities, arg, &err); 575 576 if (ret < 0) { 577 if (ret == GNUTLS_E_INVALID_REQUEST) { 578 return apr_psprintf(parms->pool, 579 "GnuTLS: Syntax error parsing priorities string at: %s", err); 580 } 581 return "Error setting priorities"; 582 } 583 584 return NULL; 585 } 586 587 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, char** err) { 588 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof (*sc)); 589 int ret; 897 ap_get_module_config(parms->server->module_config, &gnutls_module); 898 899 if (!strcasecmp(parms->directive->directive, "GnuTLSPriorities")) 900 sc->priorities_str = apr_pstrdup(parms->pool, arg); 901 else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyPriorities")) 902 sc->proxy_priorities_str = apr_pstrdup(parms->pool, arg); 903 else 904 /* Can't happen unless there's a serious bug in mod_gnutls or Apache */ 905 return apr_psprintf(parms->pool, 906 "mod_gnutls: %s called for invalid option '%s'", 907 __func__, parms->directive->directive); 908 909 return NULL; 910 } 911 912 913 914 const char *mgs_set_pin(cmd_parms * parms, void *dummy __attribute__((unused)), 915 const char *arg) 916 { 917 918 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 919 ap_get_module_config(parms->server->module_config, &gnutls_module); 920 921 sc->pin = apr_pstrdup(parms->pool, arg); 922 923 return NULL; 924 } 925 926 const char *mgs_set_srk_pin(cmd_parms * parms, 927 void *dummy __attribute__((unused)), 928 const char *arg) 929 { 930 931 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 932 ap_get_module_config(parms->server->module_config, &gnutls_module); 933 934 sc->srk_pin = apr_pstrdup(parms->pool, arg); 935 936 return NULL; 937 } 938 939 940 941 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, 942 char **err __attribute__((unused))) 943 { 944 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); 590 945 591 946 sc->enabled = GNUTLS_ENABLED_UNSET; 592 947 593 ret = gnutls_certificate_allocate_credentials(&sc->certs);594 if (ret < 0) {595 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"596 ": (%d) %s", ret,597 gnutls_strerror(ret));598 return NULL;599 }600 601 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);602 if (ret < 0) {603 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"604 ": (%d) %s", ret,605 gnutls_strerror(ret));606 return NULL;607 }608 #ifdef ENABLE_SRP609 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);610 if (ret < 0) {611 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"612 ": (%d) %s", ret,613 gnutls_strerror(ret));614 return NULL;615 }616 617 sc->srp_tpasswd_conf_file = NULL;618 sc->srp_tpasswd_file = NULL;619 #endif620 621 948 sc->privkey_x509 = NULL; 622 /* Initialize all Certificate Chains */ 623 /* FIXME: how do we indicate that this is unset for a merge? (that 624 * is, how can a subordinate server override the chain by setting 625 * an empty one? what would that even look like in the 626 * configuration?) */ 627 sc->certs_x509_chain = malloc(MAX_CHAIN_SIZE * sizeof (*sc->certs_x509_chain)); 949 sc->privkey_pgp = NULL; 628 950 sc->certs_x509_chain_num = 0; 629 sc->cache_timeout = -1; /* -1 means "unset" */ 951 sc->p11_module = NULL; 952 sc->pin = NULL; 953 sc->priorities_str = NULL; 954 sc->cache_timeout = -1; /* -1 means "unset" */ 630 955 sc->cache_type = mgs_cache_unset; 631 956 sc->cache_config = NULL; … … 634 959 sc->dh_params = NULL; 635 960 sc->proxy_enabled = GNUTLS_ENABLED_UNSET; 636 sc->export_certificates_ enabled = GNUTLS_ENABLED_UNSET;961 sc->export_certificates_size = -1; 637 962 sc->client_verify_method = mgs_cvm_unset; 963 964 sc->proxy_x509_key_file = NULL; 965 sc->proxy_x509_cert_file = NULL; 966 sc->proxy_x509_ca_file = NULL; 967 sc->proxy_x509_crl_file = NULL; 968 sc->proxy_priorities_str = NULL; 969 sc->proxy_priorities = NULL; 638 970 639 971 /* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */ … … 643 975 } 644 976 645 void *mgs_config_server_create(apr_pool_t * p, server_rec * s) { 977 void *mgs_config_server_create(apr_pool_t * p, 978 server_rec * s __attribute__((unused))) { 646 979 char *err = NULL; 647 980 mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err); 648 if (sc) return sc; else return err; 981 if (sc) 982 return sc; 983 else 984 return err; 649 985 } 650 986 … … 652 988 #define gnutls_srvconf_assign(t) sc->t = add->t 653 989 654 void *mgs_config_server_merge(apr_pool_t *p, void *BASE, void *ADD) { 990 void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD) 991 { 655 992 int i; 656 993 char *err = NULL; 657 mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;658 mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;994 mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE; 995 mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD; 659 996 mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err); 660 if (NULL == sc) return err; 997 if (NULL == sc) 998 return err; 661 999 662 1000 gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET); 663 1001 gnutls_srvconf_merge(tickets, GNUTLS_ENABLED_UNSET); 664 1002 gnutls_srvconf_merge(proxy_enabled, GNUTLS_ENABLED_UNSET); 665 gnutls_srvconf_merge(export_certificates_ enabled, GNUTLS_ENABLED_UNSET);1003 gnutls_srvconf_merge(export_certificates_size, -1); 666 1004 gnutls_srvconf_merge(client_verify_method, mgs_cvm_unset); 667 1005 gnutls_srvconf_merge(client_verify_mode, -1); 668 1006 gnutls_srvconf_merge(srp_tpasswd_file, NULL); 669 1007 gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL); 670 gnutls_srvconf_merge(privkey_x509, NULL); 671 gnutls_srvconf_merge(priorities, NULL); 672 gnutls_srvconf_merge(dh_params, NULL); 1008 gnutls_srvconf_merge(x509_cert_file, NULL); 1009 1010 gnutls_srvconf_merge(x509_key_file, NULL); 1011 gnutls_srvconf_merge(x509_ca_file, NULL); 1012 gnutls_srvconf_merge(p11_module, NULL); 1013 gnutls_srvconf_merge(pin, NULL); 1014 gnutls_srvconf_merge(pgp_cert_file, NULL); 1015 gnutls_srvconf_merge(pgp_key_file, NULL); 1016 gnutls_srvconf_merge(pgp_ring_file, NULL); 1017 gnutls_srvconf_merge(dh_file, NULL); 1018 gnutls_srvconf_merge(priorities_str, NULL); 1019 1020 gnutls_srvconf_merge(proxy_x509_key_file, NULL); 1021 gnutls_srvconf_merge(proxy_x509_cert_file, NULL); 1022 gnutls_srvconf_merge(proxy_x509_ca_file, NULL); 1023 gnutls_srvconf_merge(proxy_x509_crl_file, NULL); 1024 gnutls_srvconf_merge(proxy_priorities_str, NULL); 1025 gnutls_srvconf_merge(proxy_priorities, NULL); 673 1026 674 1027 /* FIXME: the following items are pre-allocated, and should be 675 1028 * properly disposed of before assigning in order to avoid leaks; 676 1029 * so at the moment, we can't actually have them in the config. 677 * what happens during de-allocation? 678 679 * This is probably leaky. 680 */ 1030 * what happens during de-allocation? */ 1031 /* TODO: mgs_load_files takes care of most of these now, verify 1032 * and clean up the following lines */ 1033 gnutls_srvconf_assign(ca_list); 1034 gnutls_srvconf_assign(ca_list_size); 1035 gnutls_srvconf_assign(cert_pgp); 1036 gnutls_srvconf_assign(cert_crt_pgp); 1037 gnutls_srvconf_assign(pgp_list); 681 1038 gnutls_srvconf_assign(certs); 682 1039 gnutls_srvconf_assign(anon_creds); 683 1040 gnutls_srvconf_assign(srp_creds); 684 1041 gnutls_srvconf_assign(certs_x509_chain); 1042 gnutls_srvconf_assign(certs_x509_crt_chain); 685 1043 gnutls_srvconf_assign(certs_x509_chain_num); 686 1044 … … 689 1047 gnutls_srvconf_assign(cert_cn); 690 1048 for (i = 0; i < MAX_CERT_SAN; i++) 691 gnutls_srvconf_assign(cert_san[i]); 692 gnutls_srvconf_assign(ca_list); 693 gnutls_srvconf_assign(ca_list_size); 694 gnutls_srvconf_assign(cert_pgp); 695 gnutls_srvconf_assign(pgp_list); 696 gnutls_srvconf_assign(privkey_pgp); 1049 gnutls_srvconf_assign(cert_san[i]); 697 1050 698 1051 return sc; … … 702 1055 #undef gnutls_srvconf_assign 703 1056 704 void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) { 1057 void *mgs_config_dir_merge(apr_pool_t * p, 1058 void *basev __attribute__((unused)), 1059 void *addv __attribute__((unused))) { 705 1060 mgs_dirconf_rec *new; 706 1061 /* mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */ 707 1062 mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv; 708 1063 709 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof 1064 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec)); 710 1065 new->client_verify_mode = add->client_verify_mode; 711 1066 return new; 712 1067 } 713 1068 714 void *mgs_config_dir_create(apr_pool_t * p, char *dir) { 1069 void *mgs_config_dir_create(apr_pool_t * p, 1070 char *dir __attribute__((unused))) { 715 1071 mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc)); 716 1072 dc->client_verify_mode = -1; … … 718 1074 } 719 1075 1076 1077 1078 /* 1079 * Store paths to proxy credentials 1080 * 1081 * This function copies the paths provided in the configuration file 1082 * into the server configuration. The post configuration hook takes 1083 * care of actually loading the credentials, which means than invalid 1084 * paths or the like will be detected there. 1085 */ 1086 const char *mgs_store_cred_path(cmd_parms * parms, 1087 void *dummy __attribute__((unused)), 1088 const char *arg) 1089 { 1090 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 1091 ap_get_module_config(parms->server->module_config, &gnutls_module); 1092 1093 /* parms->directive->directive contains the directive string */ 1094 if (!strcasecmp(parms->directive->directive, "GnuTLSProxyKeyFile")) 1095 sc->proxy_x509_key_file = apr_pstrdup(parms->pool, arg); 1096 else if (!strcasecmp(parms->directive->directive, 1097 "GnuTLSProxyCertificateFile")) 1098 sc->proxy_x509_cert_file = apr_pstrdup(parms->pool, arg); 1099 else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCAFile")) 1100 sc->proxy_x509_ca_file = apr_pstrdup(parms->pool, arg); 1101 else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCRLFile")) 1102 sc->proxy_x509_crl_file = apr_pstrdup(parms->pool, arg); 1103 return NULL; 1104 } 1105 1106 1107 1108 /* 1109 * Record additional PKCS #11 module to load. Note that the value is 1110 * only used in the base config, settings in virtual hosts are 1111 * ignored. 1112 */ 1113 const char *mgs_set_p11_module(cmd_parms * parms, 1114 void *dummy __attribute__((unused)), 1115 const char *arg) 1116 { 1117 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 1118 ap_get_module_config(parms->server->module_config, &gnutls_module); 1119 sc->p11_module = apr_pstrdup(parms->pool, arg); 1120 return NULL; 1121 } -
src/gnutls_hooks.c
r2db6923 r71e9a5c 1 1 /** 2 2 * Copyright 2004-2005 Paul Querna 3 * Copyright 2008 Nikos Mavrogiannopoulos3 * Copyright 2008, 2014 Nikos Mavrogiannopoulos 4 4 * Copyright 2011 Dash Shendy 5 * Copyright 2013-2014 Daniel Kahn Gillmor 6 * Copyright 2015 Thomas Klute 5 7 * 6 8 * Licensed under the Apache License, Version 2.0 (the "License"); … … 27 29 #endif 28 30 31 #ifdef APLOG_USE_MODULE 32 APLOG_USE_MODULE(gnutls); 33 #endif 34 29 35 #if !USING_2_1_RECENT 30 36 extern server_rec *ap_server_conf; … … 35 41 #endif 36 42 43 #define IS_PROXY_STR(c) \ 44 ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "") 45 37 46 static gnutls_datum_t session_ticket_key = {NULL, 0}; 38 47 39 48 static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); 40 49 /* use side==0 for server and side==1 for client */ 41 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, int export_full_cert); 42 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, int export_full_cert); 50 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, size_t export_cert_size); 51 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, size_t export_cert_size); 52 static int mgs_status_hook(request_rec *r, int flags); 53 #ifdef ENABLE_MSVA 43 54 static const char* mgs_x509_construct_uid(request_rec * pool, gnutls_x509_crt_t cert); 44 static int mgs_status_hook(request_rec *r, int flags); 55 #endif 56 static int load_proxy_x509_credentials(server_rec *s); 45 57 46 58 /* Pool Cleanup Function */ 47 apr_status_t mgs_cleanup_pre_config(void *data ) {59 apr_status_t mgs_cleanup_pre_config(void *data __attribute__((unused))) { 48 60 /* Free all session data */ 49 61 gnutls_free(session_ticket_key.data); … … 78 90 79 91 /* Pre-Configuration HOOK: Runs First */ 80 int mgs_hook_pre_config(apr_pool_t * pconf, apr_pool_t * plog, apr_pool_t * ptemp ) {92 int mgs_hook_pre_config(apr_pool_t * pconf, apr_pool_t * plog, apr_pool_t * ptemp __attribute__((unused))) { 81 93 82 94 /* Maintainer Logging */ … … 140 152 gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode); 141 153 154 /* Set x509 credentials */ 155 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs); 142 156 /* Set Anon credentials */ 143 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);144 /* Set x509 credentials */145 157 gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds); 146 158 … … 164 176 165 177 static int cert_retrieve_fn(gnutls_session_t session, 166 const gnutls_datum_t * req_ca_rdn, int nreqs, 167 const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length, 168 gnutls_retr2_st *ret) { 169 170 171 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 172 173 mgs_handle_t *ctxt; 178 const gnutls_datum_t * req_ca_rdn __attribute__((unused)), 179 int nreqs __attribute__((unused)), 180 const gnutls_pk_algorithm_t * pk_algos __attribute__((unused)), 181 int pk_algos_length __attribute__((unused)), 182 gnutls_pcert_st **pcerts, 183 unsigned int *pcert_length, 184 gnutls_privkey_t *privkey) 185 { 186 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 187 188 mgs_handle_t *ctxt; 174 189 175 190 if (session == NULL) { 176 191 // ERROR INVALID SESSION 177 ret->ncerts = 0;178 ret->deinit_all = 1;179 192 return -1; 180 } 193 } 194 181 195 ctxt = gnutls_transport_get_ptr(session); 182 196 183 197 if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { 184 198 // X509 CERTIFICATE 185 ret->cert_type = GNUTLS_CRT_X509; 186 ret->key_type = GNUTLS_PRIVKEY_X509; 187 ret->ncerts = ctxt->sc->certs_x509_chain_num; 188 ret->deinit_all = 0; 189 ret->cert.x509 = ctxt->sc->certs_x509_chain; 190 ret->key.x509 = ctxt->sc->privkey_x509; 199 *pcerts = ctxt->sc->certs_x509_chain; 200 *pcert_length = ctxt->sc->certs_x509_chain_num; 201 *privkey = ctxt->sc->privkey_x509; 191 202 return 0; 192 203 } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) { 193 204 // OPENPGP CERTIFICATE 194 ret->cert_type = GNUTLS_CRT_OPENPGP; 195 ret->key_type = GNUTLS_PRIVKEY_OPENPGP; 196 ret->ncerts = 1; 197 ret->deinit_all = 0; 198 ret->cert.pgp = ctxt->sc->cert_pgp; 199 ret->key.pgp = ctxt->sc->privkey_pgp; 205 *pcerts = ctxt->sc->cert_pgp; 206 *pcert_length = 1; 207 *privkey = ctxt->sc->privkey_pgp; 200 208 return 0; 201 209 } else { 202 210 // UNKNOWN CERTIFICATE 203 ret->ncerts = 0;204 ret->deinit_all = 1;205 211 return -1; 206 212 } 207 213 } 208 209 /* 2048-bit group parameters from SRP specification */210 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"211 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"212 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"213 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"214 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"215 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"216 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"217 "-----END DH PARAMETERS-----\n";218 214 219 215 /* Read the common name or the alternative name of the certificate. … … 298 294 } 299 295 300 int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog , apr_pool_t * ptemp, server_rec * base_server) {296 int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog __attribute__((unused)), apr_pool_t * ptemp __attribute__((unused)), server_rec * base_server) { 301 297 302 298 int rv; … … 315 311 } 316 312 317 318 313 s = base_server; 319 314 sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 320 315 321 gnutls_dh_params_init(&dh_params);322 323 if (sc_base->dh_params == NULL) {324 gnutls_datum_t pdata = {325 (void *) static_dh_params,326 sizeof(static_dh_params)327 };328 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM);329 /* Generate DH Params330 int dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,331 GNUTLS_SEC_PARAM_NORMAL);332 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,333 "GnuTLS: Generating DH Params of %i bits. "334 "To avoid this use GnuTLSDHFile to specify DH Params for this host",335 dh_bits);336 #if MOD_GNUTLS_DEBUG337 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,338 "GnuTLS: Generated DH Params of %i bits",dh_bits);339 #endif340 rv = gnutls_dh_params_generate2 (dh_params,dh_bits);341 */342 if (rv < 0) {343 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,344 "GnuTLS: Unable to generate or load DH Params: (%d) %s",345 rv, gnutls_strerror(rv));346 exit(rv);347 }348 } else {349 dh_params = sc_base->dh_params;350 }351 316 352 317 rv = mgs_cache_post_config(p, s, sc_base); … … 358 323 } 359 324 325 /* Load additional PKCS #11 module, if requested */ 326 if (sc_base->p11_module != NULL) 327 { 328 rv = gnutls_pkcs11_add_provider(sc_base->p11_module, NULL); 329 if (rv != GNUTLS_E_SUCCESS) 330 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 331 "GnuTLS: Loading PKCS #11 provider module %s " 332 "failed: %s (%d).", 333 sc_base->p11_module, gnutls_strerror(rv), rv); 334 } 335 360 336 for (s = base_server; s; s = s->next) { 361 337 sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); … … 364 340 sc->cache_timeout = sc_base->cache_timeout; 365 341 342 rv = mgs_load_files(p, s); 343 if (rv != 0) { 344 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 345 "GnuTLS: Loading required files failed." 346 " Shutting Down."); 347 exit(-1); 348 } 349 366 350 /* defaults for unset values: */ 367 351 if (sc->enabled == GNUTLS_ENABLED_UNSET) … … 369 353 if (sc->tickets == GNUTLS_ENABLED_UNSET) 370 354 sc->tickets = GNUTLS_ENABLED_TRUE; 371 if (sc->export_certificates_ enabled == GNUTLS_ENABLED_UNSET)372 sc->export_certificates_ enabled = GNUTLS_ENABLED_FALSE;355 if (sc->export_certificates_size < 0) 356 sc->export_certificates_size = 0; 373 357 if (sc->client_verify_mode == -1) 374 358 sc->client_verify_mode = GNUTLS_CERT_IGNORE; 375 359 if (sc->client_verify_method == mgs_cvm_unset) 376 360 sc->client_verify_method = mgs_cvm_cartel; 377 378 361 379 362 /* Check if the priorities have been set */ … … 394 377 } 395 378 396 gnutls_certificate_set_retrieve_function(sc->certs, cert_retrieve_fn); 397 398 #ifdef ENABLE_SRP 399 if (sc->srp_tpasswd_conf_file != NULL 400 && sc->srp_tpasswd_file != NULL) { 401 rv = gnutls_srp_set_server_credentials_file 402 (sc->srp_creds, sc->srp_tpasswd_file, 403 sc->srp_tpasswd_conf_file); 404 405 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 406 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, 407 s, 408 "[GnuTLS] - Host '%s:%d' is missing a " 409 "SRP password or conf File!", 410 s->server_hostname, s->port); 411 exit(-1); 412 } 413 } 379 /* The call after this comment is a workaround for bug in 380 * gnutls_certificate_set_retrieve_function2 that ignores 381 * supported certificate types. Should be fixed in GnuTLS 382 * 3.3.12. 383 * 384 * Details: 385 * https://lists.gnupg.org/pipermail/gnutls-devel/2015-January/007377.html 386 * Workaround from: 387 * https://github.com/vanrein/tlspool/commit/4938102d3d1b086491d147e6c8e4e2a02825fc12 */ 388 #if GNUTLS_VERSION_NUMBER < 0x030312 389 gnutls_certificate_set_retrieve_function(sc->certs, (void *) exit); 414 390 #endif 391 392 gnutls_certificate_set_retrieve_function2(sc->certs, cert_retrieve_fn); 415 393 416 394 if ((sc->certs_x509_chain == NULL || sc->certs_x509_chain_num < 1) && 417 395 sc->cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 418 396 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 419 " [GnuTLS] -Host '%s:%d' is missing a Certificate File!",397 "GnuTLS: Host '%s:%d' is missing a Certificate File!", 420 398 s->server_hostname, s->port); 421 399 exit(-1); 422 400 } 423 424 401 if (sc->enabled == GNUTLS_ENABLED_TRUE && 425 ((sc->certs_x509_chain != NULL && sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||426 (sc->cert_ pgp!= NULL && sc->privkey_pgp == NULL))) {402 ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) || 403 (sc->cert_crt_pgp[0] != NULL && sc->privkey_pgp == NULL))) { 427 404 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 428 " [GnuTLS] -Host '%s:%d' is missing a Private Key File!",405 "GnuTLS: Host '%s:%d' is missing a Private Key File!", 429 406 s->server_hostname, s->port); 430 407 exit(-1); … … 434 411 rv = -1; 435 412 if (sc->certs_x509_chain_num > 0) { 436 rv = read_crt_cn(s, p, sc->certs_x509_c hain[0], &sc->cert_cn);413 rv = read_crt_cn(s, p, sc->certs_x509_crt_chain[0], &sc->cert_cn); 437 414 } 438 415 if (rv < 0 && sc->cert_pgp != NULL) { 439 rv = read_pgpcrt_cn(s, p, sc->cert_ pgp, &sc->cert_cn);416 rv = read_pgpcrt_cn(s, p, sc->cert_crt_pgp[0], &sc->cert_cn); 440 417 } 441 418 442 419 if (rv < 0) { 443 420 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 444 " [GnuTLS] -Cannot find a certificate for host '%s:%d'!",421 "GnuTLS: Cannot find a certificate for host '%s:%d'!", 445 422 s->server_hostname, s->port); 446 423 sc->cert_cn = NULL; 447 424 continue; 448 425 } 426 } 427 428 if (sc->enabled == GNUTLS_ENABLED_TRUE 429 && sc->proxy_enabled == GNUTLS_ENABLED_TRUE 430 && load_proxy_x509_credentials(s) != APR_SUCCESS) 431 { 432 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 433 "%s: loading proxy credentials for host " 434 "'%s:%d' failed, exiting!", 435 __func__, s->server_hostname, s->port); 436 exit(-1); 449 437 } 450 438 } … … 467 455 } 468 456 469 void mgs_hook_child_init(apr_pool_t * p, server_rec * 457 void mgs_hook_child_init(apr_pool_t * p, server_rec *s) { 470 458 apr_status_t rv = APR_SUCCESS; 471 mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,472 459 mgs_srvconf_rec *sc = 460 (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 473 461 474 462 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 463 /* if we use PKCS #11 reinitialize it */ 464 465 if (mgs_pkcs11_reinit(s) < 0) { 466 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 467 "GnuTLS: Failed to reinitialize PKCS #11"); 468 exit(-1); 469 } 470 475 471 if (sc->cache_type != mgs_cache_none) { 476 472 rv = mgs_cache_child_init(p, s, sc); 477 473 if (rv != APR_SUCCESS) { 478 474 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, 479 " [GnuTLS] -Failed to run Cache Init");475 "GnuTLS: Failed to run Cache Init"); 480 476 } 481 477 } … … 584 580 } 585 581 586 static int vhost_cb(void *baton, conn_rec * conn , server_rec * s) {582 static int vhost_cb(void *baton, conn_rec * conn __attribute__((unused)), server_rec * s) { 587 583 mgs_srvconf_rec *tsc; 588 584 vhost_cb_rec *x = baton; … … 598 594 599 595 if (tsc->certs_x509_chain_num > 0) { 600 /* why are we doing this check? */ 601 ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_chain[0], s->server_hostname); 596 /* this check is there to warn administrator of any missing hostname 597 * in the certificate. */ 598 ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_crt_chain[0], s->server_hostname); 602 599 if (0 == ret) 603 ap_log_error(APLOG_MARK, APLOG_ INFO, 0, s,604 "GnuTLS: Error checking certificate forhostname "600 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 601 "GnuTLS: the certificate doesn't match requested hostname " 605 602 "'%s'", s->server_hostname); 606 603 } else { … … 613 610 #endif 614 611 615 mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) { 612 mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) 613 { 616 614 int rv; 617 615 unsigned int sni_type; … … 664 662 665 663 tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 666 &gnutls_module);664 &gnutls_module); 667 665 668 666 if (tsc->enabled != GNUTLS_ENABLED_TRUE) { continue; } 669 667 670 if(check_server_aliases(x, s, tsc)) { 671 return tsc; 672 } 668 if(check_server_aliases(x, s, tsc)) { 669 return tsc; 670 } 671 } 673 672 #endif 674 673 return NULL; 675 674 } 676 675 677 static void create_gnutls_handle(conn_rec * c) { 678 mgs_handle_t *ctxt; 679 /* Get mod_gnutls Configuration Record */ 680 mgs_srvconf_rec *sc =(mgs_srvconf_rec *) 681 ap_get_module_config(c->base_server->module_config,&gnutls_module); 676 /* 677 * This function is intended as a cleanup handler for connections 678 * using GnuTLS. 679 * 680 * @param data must point to the mgs_handle_t associated with the 681 * connection 682 */ 683 static apr_status_t cleanup_gnutls_session(void *data) 684 { 685 /* nothing to do */ 686 if (data == NULL) 687 return APR_SUCCESS; 688 689 /* check if session needs closing */ 690 mgs_handle_t *ctxt = (mgs_handle_t *) data; 691 if (ctxt->session != NULL) 692 { 693 int ret; 694 /* Try A Clean Shutdown */ 695 do 696 ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); 697 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); 698 if (ret != GNUTLS_E_SUCCESS) 699 ap_log_cerror(APLOG_MARK, APLOG_INFO, ret, ctxt->c, 700 "%s: error while closing TLS %sconnection: %s (%d)", 701 __func__, IS_PROXY_STR(ctxt), 702 gnutls_strerror(ret), ret); 703 else 704 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c, 705 "%s: TLS %sconnection closed.", 706 __func__, IS_PROXY_STR(ctxt)); 707 /* De-Initialize Session */ 708 gnutls_deinit(ctxt->session); 709 ctxt->session = NULL; 710 } 711 return APR_SUCCESS; 712 } 713 714 static void create_gnutls_handle(conn_rec * c) 715 { 716 /* Get mod_gnutls server configuration */ 717 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 718 ap_get_module_config(c->base_server->module_config, &gnutls_module); 682 719 683 720 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 684 ctxt = apr_pcalloc(c->pool, sizeof (*ctxt)); 721 722 /* Get connection specific configuration */ 723 mgs_handle_t *ctxt = (mgs_handle_t *) ap_get_module_config(c->conn_config, &gnutls_module); 724 if (ctxt == NULL) 725 { 726 ctxt = apr_pcalloc(c->pool, sizeof (*ctxt)); 727 ap_set_module_config(c->conn_config, &gnutls_module, ctxt); 728 ctxt->is_proxy = GNUTLS_ENABLED_FALSE; 729 } 730 ctxt->enabled = GNUTLS_ENABLED_TRUE; 685 731 ctxt->c = c; 686 732 ctxt->sc = sc; … … 693 739 ctxt->output_blen = 0; 694 740 ctxt->output_length = 0; 741 695 742 /* Initialize GnuTLS Library */ 696 gnutls_init(&ctxt->session, GNUTLS_SERVER); 697 /* Initialize Session Tickets */ 698 if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) { 699 gnutls_session_ticket_enable_server(ctxt->session,&session_ticket_key); 743 int err = 0; 744 if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE) 745 { 746 /* this is an outgoing proxy connection, client mode */ 747 err = gnutls_init(&ctxt->session, GNUTLS_CLIENT); 748 if (err != GNUTLS_E_SUCCESS) 749 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, 750 "gnutls_init for proxy connection failed: %s (%d)", 751 gnutls_strerror(err), err); 752 err = gnutls_session_ticket_enable_client(ctxt->session); 753 if (err != GNUTLS_E_SUCCESS) 754 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, 755 "gnutls_session_ticket_enable_client failed: %s (%d)", 756 gnutls_strerror(err), err); 757 /* Try to close and deinit the session when the connection 758 * pool is cleared. Note that mod_proxy might not close 759 * connections immediately, if you need that, look at the 760 * "proxy-nokeepalive" environment variable for 761 * mod_proxy_http. */ 762 apr_pool_pre_cleanup_register(c->pool, ctxt, cleanup_gnutls_session); 763 } 764 else 765 { 766 /* incoming connection, server mode */ 767 err = gnutls_init(&ctxt->session, GNUTLS_SERVER); 768 if (err != GNUTLS_E_SUCCESS) 769 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, 770 "gnutls_init for server side failed: %s (%d)", 771 gnutls_strerror(err), err); 772 /* Initialize Session Tickets */ 773 if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) 774 { 775 err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key); 776 if (err != GNUTLS_E_SUCCESS) 777 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, 778 "gnutls_session_ticket_enable_server failed: %s (%d)", 779 gnutls_strerror(err), err); 780 } 700 781 } 701 782 702 783 /* Set Default Priority */ 703 gnutls_priority_set_direct (ctxt->session, "NORMAL", NULL); 784 err = gnutls_priority_set_direct(ctxt->session, "NORMAL", NULL); 785 if (err != GNUTLS_E_SUCCESS) 786 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, "gnutls_priority_set_direct failed!"); 704 787 /* Set Handshake function */ 705 788 gnutls_handshake_set_post_client_hello_function(ctxt->session, 706 789 mgs_select_virtual_server_cb); 790 791 /* Set GnuTLS user pointer, so we can access the module session 792 * context in GnuTLS callbacks */ 793 gnutls_session_set_ptr(ctxt->session, ctxt); 794 795 /* If mod_gnutls is the TLS server, mgs_select_virtual_server_cb 796 * will load appropriate credentials during handshake. However, 797 * when handling a proxy backend connection, mod_gnutls acts as 798 * TLS client and credentials must be loaded here. */ 799 if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE) 800 { 801 /* Set anonymous client credentials for proxy connections */ 802 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, 803 ctxt->sc->anon_client_creds); 804 /* Set x509 credentials */ 805 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, 806 ctxt->sc->proxy_x509_creds); 807 /* Load priorities from the server configuration */ 808 err = gnutls_priority_set(ctxt->session, ctxt->sc->proxy_priorities); 809 if (err != GNUTLS_E_SUCCESS) 810 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, 811 "%s: setting priorities for proxy connection " 812 "failed: %s (%d)", 813 __func__, gnutls_strerror(err), err); 814 } 815 707 816 /* Initialize Session Cache */ 708 817 mgs_cache_session_init(ctxt); 709 818 710 /* Set this config for this connection */711 ap_set_module_config(c->conn_config, &gnutls_module, ctxt);712 819 /* Set pull, push & ptr functions */ 713 820 gnutls_transport_set_pull_function(ctxt->session, … … 723 830 } 724 831 725 int mgs_hook_pre_connection(conn_rec * c, void *csd) { 726 mgs_srvconf_rec *sc; 727 832 int mgs_hook_pre_connection(conn_rec * c, void *csd __attribute__((unused))) 833 { 728 834 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 729 835 730 sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server->module_config, 731 &gnutls_module); 732 733 if (sc && (!sc->enabled || sc->proxy_enabled == GNUTLS_ENABLED_TRUE)) { 836 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 837 ap_get_module_config(c->base_server->module_config, &gnutls_module); 838 mgs_handle_t *ctxt = (mgs_handle_t *) 839 ap_get_module_config(c->conn_config, &gnutls_module); 840 841 if ((sc && (!sc->enabled)) || (ctxt && ctxt->enabled == GNUTLS_ENABLED_FALSE)) 842 { 843 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s declined connection", 844 __func__); 734 845 return DECLINED; 735 846 } … … 753 864 apr_table_t *env = r->subprocess_env; 754 865 755 ctxt = 756 ap_get_module_config(r->connection->conn_config, 757 &gnutls_module); 758 759 if (!ctxt || ctxt->session == NULL) { 866 ctxt = ap_get_module_config(r->connection->conn_config, 867 &gnutls_module); 868 869 if (!ctxt || ctxt->enabled != GNUTLS_ENABLED_TRUE || ctxt->session == NULL) 870 { 871 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "request declined in %s", __func__); 760 872 return DECLINED; 761 873 } … … 814 926 815 927 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) { 816 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_chain[0], 0, ctxt->sc->export_certificates_enabled);817 818 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_ pgp, 0, ctxt->sc->export_certificates_enabled);819 928 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, ctxt->sc->export_certificates_size); 929 } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) { 930 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_crt_pgp[0], 0, ctxt->sc->export_certificates_size); 931 } 820 932 821 933 return rv; … … 872 984 } 873 985 rv = mgs_cert_verify(r, ctxt); 874 if (rv != DECLINED && 875 (rv != HTTP_FORBIDDEN || 876 dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) { 986 if (rv != DECLINED 987 && (rv != HTTP_FORBIDDEN 988 || dc->client_verify_mode == GNUTLS_CERT_REQUIRE 989 || (dc->client_verify_mode == -1 990 && ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUIRE))) 991 { 877 992 return rv; 878 993 } … … 890 1005 /* @param side is either 0 for SERVER or 1 for CLIENT 891 1006 * 892 * @param export_ full_cert (boolean) export the PEM-encoded893 * certificate in full as an environment variable.1007 * @param export_cert_size (int) maximum size for environment variable 1008 * to use for the PEM-encoded certificate (0 means do not export) 894 1009 */ 895 #define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT")896 897 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, int export_full_cert) {1010 #define MGS_SIDE(suffix) ((side==0) ? "SSL_SERVER" suffix : "SSL_CLIENT" suffix) 1011 1012 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, size_t export_cert_size) { 898 1013 unsigned char sbuf[64]; /* buffer to hold serials */ 899 1014 char buf[AP_IOBUFSIZE]; … … 909 1024 910 1025 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 911 if (export_full_cert != 0) { 912 char cert_buf[10 * 1024]; 913 len = sizeof (cert_buf); 914 915 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) 916 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 917 apr_pstrmemdup(r->pool, cert_buf, len)); 918 else 919 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 920 "GnuTLS: Failed to export X.509 certificate to environment"); 1026 if (export_cert_size > 0) { 1027 len = 0; 1028 ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, NULL, &len); 1029 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { 1030 if (len >= export_cert_size) { 1031 apr_table_setn(env, MGS_SIDE("_CERT"), "GNUTLS_CERTIFICATE_SIZE_LIMIT_EXCEEDED"); 1032 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 1033 "GnuTLS: Failed to export too-large X.509 certificate to environment"); 1034 } else { 1035 char* cert_buf = apr_palloc(r->pool, len + 1); 1036 if (cert_buf != NULL && gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) { 1037 cert_buf[len] = 0; 1038 apr_table_setn(env, MGS_SIDE("_CERT"), cert_buf); 1039 } else { 1040 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 1041 "GnuTLS: failed to export X.509 certificate"); 1042 } 1043 } 1044 } else { 1045 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 1046 "GnuTLS: dazed and confused about X.509 certificate size"); 1047 } 921 1048 } 922 1049 923 1050 len = sizeof (buf); 924 1051 gnutls_x509_crt_get_dn(cert, buf, &len); 925 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL), 926 apr_pstrmemdup(r->pool, buf, len)); 1052 apr_table_setn(env, MGS_SIDE("_S_DN"), apr_pstrmemdup(r->pool, buf, len)); 927 1053 928 1054 len = sizeof (buf); 929 1055 gnutls_x509_crt_get_issuer_dn(cert, buf, &len); 930 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL), 931 apr_pstrmemdup(r->pool, buf, len)); 1056 apr_table_setn(env, MGS_SIDE("_I_DN"), apr_pstrmemdup(r->pool, buf, len)); 932 1057 933 1058 len = sizeof (sbuf); 934 1059 gnutls_x509_crt_get_serial(cert, sbuf, &len); 935 1060 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof (buf)); 936 apr_table_setn(env, 937 apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), 938 apr_pstrdup(r->pool, tmp)); 1061 apr_table_setn(env, MGS_SIDE("_M_SERIAL"), apr_pstrdup(r->pool, tmp)); 939 1062 940 1063 ret = gnutls_x509_crt_get_version(cert); 941 1064 if (ret > 0) 942 apr_table_setn(env, 943 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", 944 NULL), apr_psprintf(r->pool, 945 "%u", ret)); 946 947 apr_table_setn(env, 948 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), 949 "X.509"); 1065 apr_table_setn(env, MGS_SIDE("_M_VERSION"), 1066 apr_psprintf(r->pool, "%u", ret)); 1067 1068 apr_table_setn(env, MGS_SIDE("_CERT_TYPE"), "X.509"); 950 1069 951 1070 tmp = 952 1071 mgs_time2sz(gnutls_x509_crt_get_expiration_time 953 1072 (cert), buf, sizeof (buf)); 954 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL), 955 apr_pstrdup(r->pool, tmp)); 1073 apr_table_setn(env, MGS_SIDE("_V_END"), apr_pstrdup(r->pool, tmp)); 956 1074 957 1075 tmp = 958 1076 mgs_time2sz(gnutls_x509_crt_get_activation_time 959 1077 (cert), buf, sizeof (buf)); 960 apr_table_setn(env, 961 apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), 962 apr_pstrdup(r->pool, tmp)); 1078 apr_table_setn(env, MGS_SIDE("_V_START"), apr_pstrdup(r->pool, tmp)); 963 1079 964 1080 ret = gnutls_x509_crt_get_signature_algorithm(cert); 965 1081 if (ret >= 0) { 966 apr_table_setn(env, 967 apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", 968 NULL), 1082 apr_table_setn(env, MGS_SIDE("_A_SIG"), 969 1083 gnutls_sign_algorithm_get_name(ret)); 970 1084 } … … 972 1086 ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL); 973 1087 if (ret >= 0) { 974 apr_table_setn(env, 975 apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", 976 NULL), 1088 apr_table_setn(env, MGS_SIDE("_A_KEY"), 977 1089 gnutls_pk_algorithm_get_name(ret)); 978 1090 } … … 980 1092 /* export all the alternative names (DNS, RFC822 and URI) */ 981 1093 for (i = 0; !(ret < 0); i++) { 1094 const char *san, *sanlabel; 982 1095 len = 0; 983 1096 ret = gnutls_x509_crt_get_subject_alt_name(cert, i, … … 995 1108 tmp2[len] = 0; 996 1109 1110 sanlabel = apr_psprintf(r->pool, "%s%u", MGS_SIDE("_S_AN"), i); 997 1111 if (ret == GNUTLS_SAN_DNSNAME) { 998 apr_table_setn(env, 999 apr_psprintf(r->pool, 1000 "%s_S_AN%u", 1001 MGS_SIDE, i), 1002 apr_psprintf(r->pool, 1003 "DNSNAME:%s", 1004 tmp2)); 1112 san = apr_psprintf(r->pool, "DNSNAME:%s", tmp2); 1005 1113 } else if (ret == GNUTLS_SAN_RFC822NAME) { 1006 apr_table_setn(env, 1007 apr_psprintf(r->pool, 1008 "%s_S_AN%u", 1009 MGS_SIDE, i), 1010 apr_psprintf(r->pool, 1011 "RFC822NAME:%s", 1012 tmp2)); 1114 san = apr_psprintf(r->pool, "RFC822NAME:%s", tmp2); 1013 1115 } else if (ret == GNUTLS_SAN_URI) { 1014 apr_table_setn(env, 1015 apr_psprintf(r->pool, 1016 "%s_S_AN%u", 1017 MGS_SIDE, i), 1018 apr_psprintf(r->pool, 1019 "URI:%s", 1020 tmp2)); 1116 san = apr_psprintf(r->pool, "URI:%s", tmp2); 1021 1117 } else { 1022 apr_table_setn(env, 1023 apr_psprintf(r->pool, 1024 "%s_S_AN%u", 1025 MGS_SIDE, i), 1026 "UNSUPPORTED"); 1118 san = "UNSUPPORTED"; 1027 1119 } 1120 apr_table_setn(env, sanlabel, san); 1028 1121 } 1029 1122 } … … 1033 1126 /* @param side 0: server, 1: client 1034 1127 * 1035 * @param export_ full_cert (boolean) export the PEM-encoded1036 * certificate in full as an environment variable.1128 * @param export_cert_size (int) maximum size for environment variable 1129 * to use for the PEM-encoded certificate (0 means do not export) 1037 1130 */ 1038 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, int export_full_cert) {1131 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, size_t export_cert_size) { 1039 1132 1040 1133 unsigned char sbuf[64]; /* buffer to hold serials */ … … 1050 1143 apr_table_t *env = r->subprocess_env; 1051 1144 1052 if (export_full_cert != 0) { 1053 char cert_buf[10 * 1024]; 1054 len = sizeof (cert_buf); 1055 1056 if (gnutls_openpgp_crt_export(cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0) 1057 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 1058 apr_pstrmemdup(r->pool, cert_buf, len)); 1059 else 1060 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 1061 "GnuTLS: Failed to export OpenPGP certificate to environment"); 1145 if (export_cert_size > 0) { 1146 len = 0; 1147 ret = gnutls_openpgp_crt_export(cert, GNUTLS_OPENPGP_FMT_BASE64, NULL, &len); 1148 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { 1149 if (len >= export_cert_size) { 1150 apr_table_setn(env, MGS_SIDE("_CERT"), 1151 "GNUTLS_CERTIFICATE_SIZE_LIMIT_EXCEEDED"); 1152 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 1153 "GnuTLS: Failed to export too-large OpenPGP certificate to environment"); 1154 } else { 1155 char* cert_buf = apr_palloc(r->pool, len + 1); 1156 if (cert_buf != NULL && gnutls_openpgp_crt_export(cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0) { 1157 cert_buf[len] = 0; 1158 apr_table_setn(env, MGS_SIDE("_CERT"), cert_buf); 1159 } else { 1160 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 1161 "GnuTLS: failed to export OpenPGP certificate"); 1162 } 1163 } 1164 } else { 1165 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, 1166 "GnuTLS: dazed and confused about OpenPGP certificate size"); 1167 } 1062 1168 } 1063 1169 1064 1170 len = sizeof (buf); 1065 1171 gnutls_openpgp_crt_get_name(cert, 0, buf, &len); 1066 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL), 1067 apr_pstrmemdup(r->pool, buf, len)); 1172 apr_table_setn(env, MGS_SIDE("_NAME"), apr_pstrmemdup(r->pool, buf, len)); 1068 1173 1069 1174 len = sizeof (sbuf); 1070 1175 gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len); 1071 1176 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof (buf)); 1072 apr_table_setn(env, 1073 apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT", 1074 NULL), apr_pstrdup(r->pool, tmp)); 1177 apr_table_setn(env, MGS_SIDE("_FINGERPRINT"), apr_pstrdup(r->pool, tmp)); 1075 1178 1076 1179 ret = gnutls_openpgp_crt_get_version(cert); 1077 1180 if (ret > 0) 1078 apr_table_setn(env, 1079 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", 1080 NULL), apr_psprintf(r->pool, 1081 "%u", ret)); 1082 1083 apr_table_setn(env, 1084 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), 1085 "OPENPGP"); 1181 apr_table_setn(env, MGS_SIDE("_M_VERSION"), 1182 apr_psprintf(r->pool, "%u", ret)); 1183 1184 apr_table_setn(env, MGS_SIDE("_CERT_TYPE"), "OPENPGP"); 1086 1185 1087 1186 tmp = 1088 1187 mgs_time2sz(gnutls_openpgp_crt_get_expiration_time 1089 1188 (cert), buf, sizeof (buf)); 1090 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL), 1091 apr_pstrdup(r->pool, tmp)); 1189 apr_table_setn(env, MGS_SIDE("_V_END"), apr_pstrdup(r->pool, tmp)); 1092 1190 1093 1191 tmp = 1094 1192 mgs_time2sz(gnutls_openpgp_crt_get_creation_time 1095 1193 (cert), buf, sizeof (buf)); 1096 apr_table_setn(env, 1097 apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), 1098 apr_pstrdup(r->pool, tmp)); 1194 apr_table_setn(env, MGS_SIDE("_V_START"), apr_pstrdup(r->pool, tmp)); 1099 1195 1100 1196 ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL); 1101 1197 if (ret >= 0) { 1102 apr_table_setn(env, 1103 apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", 1104 NULL), 1105 gnutls_pk_algorithm_get_name(ret)); 1198 apr_table_setn(env, MGS_SIDE("_A_KEY"), gnutls_pk_algorithm_get_name(ret)); 1106 1199 } 1107 1200 … … 1324 1417 1325 1418 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) 1326 mgs_add_common_cert_vars(r, cert.x509[0], 1, ctxt->sc->export_certificates_ enabled);1419 mgs_add_common_cert_vars(r, cert.x509[0], 1, ctxt->sc->export_certificates_size); 1327 1420 else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) 1328 mgs_add_common_pgpcert_vars(r, cert.pgp, 1, ctxt->sc->export_certificates_ enabled);1421 mgs_add_common_pgpcert_vars(r, cert.pgp, 1, ctxt->sc->export_certificates_size); 1329 1422 1330 1423 { … … 1352 1445 exit: 1353 1446 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) { 1354 int i;1447 unsigned int i; 1355 1448 for (i = 0; i < ch_size; i++) { 1356 1449 gnutls_x509_crt_deinit(cert.x509[i]); … … 1364 1457 } 1365 1458 1459 #ifdef ENABLE_MSVA 1460 /* this section of code is used only when trying to talk to the MSVA */ 1366 1461 static const char* mgs_x509_leaf_oid_from_dn(apr_pool_t *pool, const char* oid, gnutls_x509_crt_t cert) { 1367 1462 int rv=GNUTLS_E_SUCCESS, i; … … 1400 1495 data = apr_palloc(pool, sz); 1401 1496 rv = gnutls_x509_crt_get_subject_alt_name2(cert, i, data, &sz, &thistype, NULL); 1402 if (rv == target)1497 if (rv >=0 && (thistype == target)) 1403 1498 return data; 1404 1499 } … … 1407 1502 return NULL; 1408 1503 } 1504 1409 1505 1410 1506 /* Create a string representing a candidate User ID from an X.509 … … 1522 1618 return ret; 1523 1619 } 1524 1525 static int mgs_status_hook(request_rec *r, int flags) 1620 #endif /* ENABLE_MSVA */ 1621 1622 static int mgs_status_hook(request_rec *r, int flags __attribute__((unused))) 1526 1623 { 1527 1624 mgs_srvconf_rec *sc; … … 1564 1661 } 1565 1662 1663 1664 1665 /* 1666 * Callback to check the server certificate for proxy HTTPS 1667 * connections, to be used with 1668 * gnutls_certificate_set_verify_function. 1669 1670 * Returns: 0 if certificate check was successful (certificate 1671 * trusted), non-zero otherwise (error during check or untrusted 1672 * certificate). 1673 */ 1674 static int gtls_check_server_cert(gnutls_session_t session) 1675 { 1676 mgs_handle_t *ctxt = (mgs_handle_t *) gnutls_session_get_ptr(session); 1677 unsigned int status; 1678 1679 /* Get peer hostname from a note left by mod_proxy */ 1680 const char *peer_hostname = 1681 apr_table_get(ctxt->c->notes, "proxy-request-hostname"); 1682 if (peer_hostname == NULL) 1683 ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, ctxt->c, 1684 "%s: proxy-request-hostname is NULL, cannot check " 1685 "peer's hostname", __func__); 1686 1687 /* Verify certificate, including hostname match. Should 1688 * peer_hostname be NULL for some reason, the name is not 1689 * checked. */ 1690 int err = gnutls_certificate_verify_peers3(session, peer_hostname, 1691 &status); 1692 if (err != GNUTLS_E_SUCCESS) 1693 { 1694 ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c, 1695 "%s: server certificate check failed: %s (%d)", 1696 __func__, gnutls_strerror(err), err); 1697 return err; 1698 } 1699 1700 gnutls_datum_t * out = gnutls_malloc(sizeof(gnutls_datum_t)); 1701 /* GNUTLS_CRT_X509: ATM, only X509 is supported for proxy certs 1702 * 0: according to function API, the last argument should be 0 */ 1703 err = gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509, 1704 out, 0); 1705 if (err != GNUTLS_E_SUCCESS) 1706 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 1707 "%s: server verify print failed: %s (%d)", 1708 __func__, gnutls_strerror(err), err); 1709 else 1710 { 1711 /* If the certificate is trusted, logging the result is just 1712 * nice for debugging. But if the back end server provided an 1713 * untrusted certificate, warn! */ 1714 int level = (status == 0 ? APLOG_DEBUG : APLOG_WARNING); 1715 ap_log_cerror(APLOG_MARK, level, 0, ctxt->c, 1716 "%s: server certificate verify result: %s", 1717 __func__, out->data); 1718 } 1719 1720 gnutls_free(out); 1721 return status; 1722 } 1723 1724 1725 1726 static apr_status_t load_proxy_x509_credentials(server_rec *s) 1727 { 1728 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 1729 ap_get_module_config(s->module_config, &gnutls_module); 1730 1731 if (sc == NULL) 1732 return APR_EGENERAL; 1733 1734 apr_status_t ret = APR_SUCCESS; 1735 int err = GNUTLS_E_SUCCESS; 1736 1737 /* Function pool, gets destroyed before exit. */ 1738 apr_pool_t *pool; 1739 ret = apr_pool_create(&pool, s->process->pool); 1740 if (ret != APR_SUCCESS) 1741 { 1742 ap_log_error(APLOG_MARK, APLOG_ERR, ret, s, 1743 "%s: failed to allocate function memory pool.", __func__); 1744 return ret; 1745 } 1746 1747 /* allocate credentials structures */ 1748 err = gnutls_certificate_allocate_credentials(&sc->proxy_x509_creds); 1749 if (err != GNUTLS_E_SUCCESS) 1750 { 1751 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1752 "%s: Failed to initialize proxy credentials: (%d) %s", 1753 __func__, err, gnutls_strerror(err)); 1754 return APR_EGENERAL; 1755 } 1756 err = gnutls_anon_allocate_client_credentials(&sc->anon_client_creds); 1757 if (err != GNUTLS_E_SUCCESS) 1758 { 1759 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1760 "%s: Failed to initialize anon credentials for proxy: " 1761 "(%d) %s", __func__, err, gnutls_strerror(err)); 1762 return APR_EGENERAL; 1763 } 1764 1765 /* Check if the proxy priorities have been set, fail immediately 1766 * if not */ 1767 if (sc->proxy_priorities_str == NULL) 1768 { 1769 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 1770 "Host '%s:%d' is missing the GnuTLSProxyPriorities " 1771 "directive!", 1772 s->server_hostname, s->port); 1773 return APR_EGENERAL; 1774 } 1775 /* parse proxy priorities */ 1776 const char *err_pos = NULL; 1777 err = gnutls_priority_init(&sc->proxy_priorities, 1778 sc->proxy_priorities_str, &err_pos); 1779 if (err != GNUTLS_E_SUCCESS) 1780 { 1781 if (ret == GNUTLS_E_INVALID_REQUEST) 1782 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1783 "%s: Syntax error parsing proxy priorities " 1784 "string at: %s", 1785 __func__, err_pos); 1786 else 1787 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1788 "Error setting proxy priorities: %s (%d)", 1789 gnutls_strerror(err), err); 1790 ret = APR_EGENERAL; 1791 } 1792 1793 /* load certificate and key for client auth, if configured */ 1794 if (sc->proxy_x509_key_file && sc->proxy_x509_cert_file) 1795 { 1796 char* cert_file = ap_server_root_relative(pool, 1797 sc->proxy_x509_cert_file); 1798 char* key_file = ap_server_root_relative(pool, 1799 sc->proxy_x509_key_file); 1800 err = gnutls_certificate_set_x509_key_file(sc->proxy_x509_creds, 1801 cert_file, 1802 key_file, 1803 GNUTLS_X509_FMT_PEM); 1804 if (err != GNUTLS_E_SUCCESS) 1805 { 1806 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1807 "%s: loading proxy client credentials failed: %s (%d)", 1808 __func__, gnutls_strerror(err), err); 1809 ret = APR_EGENERAL; 1810 } 1811 } 1812 else if (!sc->proxy_x509_key_file && sc->proxy_x509_cert_file) 1813 { 1814 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, 1815 "%s: proxy key file not set!", __func__); 1816 ret = APR_EGENERAL; 1817 } 1818 else if (!sc->proxy_x509_cert_file && sc->proxy_x509_key_file) 1819 { 1820 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, 1821 "%s: proxy certificate file not set!", __func__); 1822 ret = APR_EGENERAL; 1823 } 1824 else 1825 /* if both key and cert are NULL, client auth is not used */ 1826 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 1827 "%s: no client credentials for proxy", __func__); 1828 1829 /* must be set if the server certificate is to be checked */ 1830 if (sc->proxy_x509_ca_file) 1831 { 1832 /* initialize the trust list */ 1833 err = gnutls_x509_trust_list_init(&sc->proxy_x509_tl, 0); 1834 if (err != GNUTLS_E_SUCCESS) 1835 { 1836 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1837 "%s: gnutls_x509_trust_list_init failed: %s (%d)", 1838 __func__, gnutls_strerror(err), err); 1839 ret = APR_EGENERAL; 1840 } 1841 1842 char* ca_file = ap_server_root_relative(pool, 1843 sc->proxy_x509_ca_file); 1844 /* if no CRL is used, sc->proxy_x509_crl_file is NULL */ 1845 char* crl_file = NULL; 1846 if (sc->proxy_x509_crl_file) 1847 crl_file = ap_server_root_relative(pool, 1848 sc->proxy_x509_crl_file); 1849 1850 /* returns number of loaded elements */ 1851 err = gnutls_x509_trust_list_add_trust_file(sc->proxy_x509_tl, 1852 ca_file, 1853 crl_file, 1854 GNUTLS_X509_FMT_PEM, 1855 0 /* tl_flags */, 1856 0 /* tl_vflags */); 1857 if (err > 0) 1858 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 1859 "%s: proxy CA trust list: %d structures loaded", 1860 __func__, err); 1861 else if (err == 0) 1862 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, 1863 "%s: proxy CA trust list is empty (%d)", 1864 __func__, err); 1865 else /* err < 0 */ 1866 { 1867 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1868 "%s: error loading proxy CA trust list: %s (%d)", 1869 __func__, gnutls_strerror(err), err); 1870 ret = APR_EGENERAL; 1871 } 1872 1873 /* attach trust list to credentials */ 1874 gnutls_certificate_set_trust_list(sc->proxy_x509_creds, 1875 sc->proxy_x509_tl, 0); 1876 } 1877 else 1878 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, 1879 "%s: no CA trust list for proxy connections, " 1880 "TLS connections will fail!", __func__); 1881 1882 gnutls_certificate_set_verify_function(sc->proxy_x509_creds, 1883 gtls_check_server_cert); 1884 apr_pool_destroy(pool); 1885 return ret; 1886 } -
src/gnutls_io.c
r2db6923 r71e9a5c 3 3 * Copyright 2008 Nikos Mavrogiannopoulos 4 4 * Copyright 2011 Dash Shendy 5 * Copyright 2015 Thomas Klute 5 6 * 6 7 * Licensed under the Apache License, Version 2.0 (the "License"); … … 20 21 #include "mod_gnutls.h" 21 22 23 #ifdef APLOG_USE_MODULE 24 APLOG_USE_MODULE(gnutls); 25 #endif 26 22 27 /** 23 28 * Describe how the GnuTLS Filter system works here … … 34 39 alloc) 35 40 41 #define IS_PROXY_STR(c) \ 42 ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "") 43 36 44 static apr_status_t gnutls_io_filter_error(ap_filter_t * f, 37 45 apr_bucket_brigade * bb, … … 41 49 42 50 switch (status) { 43 case HTTP_BAD_REQUEST: 44 /* log the situation */ 45 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 46 f->c->base_server, 47 "GnuTLS handshake failed: HTTP spoken on HTTPS port; " 48 "trying to send HTML error page"); 49 50 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config( 51 f->c->base_server->module_config, 52 &gnutls_module 53 ); 54 ctxt->status = -1; 55 sc->non_ssl_request = 1; 56 57 /* fake the request line */ 58 bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); 59 break; 60 61 default: 62 return status; 51 case HTTP_BAD_REQUEST: 52 /* log the situation */ 53 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 54 f->c->base_server, 55 "GnuTLS handshake failed: HTTP spoken on HTTPS port; " 56 "trying to send HTML error page"); 57 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 58 ap_get_module_config(f->c->base_server->module_config, 59 &gnutls_module); 60 ctxt->status = -1; 61 sc->non_ssl_request = 1; 62 63 /* fake the request line */ 64 bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); 65 break; 66 67 default: 68 return status; 63 69 } 64 70 … … 182 188 183 189 static apr_status_t gnutls_io_input_read(mgs_handle_t * ctxt, 184 char *buf, apr_size_t * len) { 190 char *buf, apr_size_t * len) 191 { 185 192 apr_size_t wanted = *len; 186 193 apr_size_t bytes = 0; … … 221 228 222 229 if (ctxt->session == NULL) { 230 ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c, 231 "%s: GnuTLS session is NULL!", __func__); 223 232 return APR_EGENERAL; 224 233 } … … 226 235 while (1) { 227 236 228 rc = gnutls_record_recv(ctxt->session, buf + bytes, 229 wanted - bytes); 237 do 238 rc = gnutls_record_recv(ctxt->session, buf + bytes, 239 wanted - bytes); 240 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN); 230 241 231 242 if (rc > 0) { … … 266 277 if (rc == GNUTLS_E_REHANDSHAKE) { 267 278 /* A client has asked for a new Hankshake. Currently, we don't do it */ 268 ap_log_ error(APLOG_MARK, APLOG_INFO,279 ap_log_cerror(APLOG_MARK, APLOG_INFO, 269 280 ctxt->input_rc, 270 ctxt->c ->base_server,281 ctxt->c, 271 282 "GnuTLS: Error reading data. Client Requested a New Handshake." 272 283 " (%d) '%s'", rc, … … 274 285 } else if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { 275 286 rc = gnutls_alert_get(ctxt->session); 276 ap_log_ error(APLOG_MARK, APLOG_INFO,287 ap_log_cerror(APLOG_MARK, APLOG_INFO, 277 288 ctxt->input_rc, 278 ctxt->c ->base_server,289 ctxt->c, 279 290 "GnuTLS: Warning Alert From Client: " 280 291 " (%d) '%s'", rc, … … 282 293 } else if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { 283 294 rc = gnutls_alert_get(ctxt->session); 284 ap_log_ error(APLOG_MARK, APLOG_INFO,295 ap_log_cerror(APLOG_MARK, APLOG_INFO, 285 296 ctxt->input_rc, 286 ctxt->c ->base_server,297 ctxt->c, 287 298 "GnuTLS: Fatal Alert From Client: " 288 299 "(%d) '%s'", rc, … … 293 304 /* Some Other Error. Report it. Die. */ 294 305 if (gnutls_error_is_fatal(rc)) { 295 ap_log_ error(APLOG_MARK,306 ap_log_cerror(APLOG_MARK, 296 307 APLOG_INFO, 297 308 ctxt->input_rc, 298 ctxt->c ->base_server,309 ctxt->c, 299 310 "GnuTLS: Error reading data. (%d) '%s'", 300 311 rc, … … 307 318 308 319 if (ctxt->input_rc == APR_SUCCESS) { 320 ap_log_cerror(APLOG_MARK, APLOG_INFO, ctxt->input_rc, ctxt->c, 321 "%s: GnuTLS error: %s (%d)", 322 __func__, gnutls_strerror(rc), rc); 309 323 ctxt->input_rc = APR_EGENERAL; 310 324 } … … 401 415 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 402 416 ctxt->c->base_server, 403 "GnuTLS: Han shake Alert (%d) '%s'.",417 "GnuTLS: Handshake Alert (%d) '%s'.", 404 418 errcode, 405 419 gnutls_alert_get_name(errcode)); … … 445 459 } 446 460 } 447 return 0;461 return GNUTLS_E_SUCCESS; 448 462 } 449 463 } … … 475 489 apr_bucket_brigade * bb, 476 490 ap_input_mode_t mode, 477 apr_read_type_e block, apr_off_t readbytes) { 491 apr_read_type_e block, apr_off_t readbytes) 492 { 478 493 apr_status_t status = APR_SUCCESS; 479 494 mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx; … … 484 499 apr_bucket_eos_create(f->c->bucket_alloc); 485 500 APR_BRIGADE_INSERT_TAIL(bb, bucket); 501 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 502 "%s: %sconnection aborted", 503 __func__, IS_PROXY_STR(ctxt)); 486 504 return APR_ECONNABORTED; 487 505 } 488 506 489 507 if (ctxt->status == 0) { 490 gnutls_do_handshake(ctxt); 508 int ret = gnutls_do_handshake(ctxt); 509 if (ret == GNUTLS_E_SUCCESS) 510 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 511 "%s: TLS %sconnection opened.", 512 __func__, IS_PROXY_STR(ctxt)); 491 513 } 492 514 493 515 if (ctxt->status < 0) { 516 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 517 "%s %s: ap_get_brigade", __func__, IS_PROXY_STR(ctxt)); 494 518 return ap_get_brigade(f->next, bb, mode, block, readbytes); 495 519 } … … 506 530 if (ctxt->input_mode == AP_MODE_READBYTES || 507 531 ctxt->input_mode == AP_MODE_SPECULATIVE) { 532 if (readbytes < 0) { 533 /* you're asking us to speculatively read a negative number of bytes! */ 534 return APR_ENOTIMPL; 535 } 508 536 /* Err. This is bad. readbytes *can* be a 64bit int! len.. is NOT */ 509 if ( readbytes < len) {537 if ((apr_size_t) readbytes < len) { 510 538 len = (apr_size_t) readbytes; 511 539 } … … 569 597 570 598 apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) { 571 apr_size_t ret;599 int ret; 572 600 mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx; 573 601 apr_status_t status = APR_SUCCESS; … … 580 608 581 609 if (ctxt->status == 0) { 582 gnutls_do_handshake(ctxt); 610 ret = gnutls_do_handshake(ctxt); 611 if (ret == GNUTLS_E_SUCCESS) 612 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 613 "%s: TLS %sconnection opened.", 614 __func__, IS_PROXY_STR(ctxt)); 583 615 } 584 616 … … 607 639 ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR); 608 640 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); 641 if (ret != GNUTLS_E_SUCCESS) 642 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 643 "%s: Error while closing TLS %sconnection: " 644 "'%s' (%d)", 645 __func__, IS_PROXY_STR(ctxt), 646 gnutls_strerror(ret), (int) ret); 647 else 648 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c, 649 "%s: TLS %sconnection closed.", 650 __func__, IS_PROXY_STR(ctxt)); 609 651 /* De-Initialize Session */ 610 652 gnutls_deinit(ctxt->session); … … 668 710 return ctxt->output_rc; 669 711 } 670 } else if (ret != len) { 712 } else if ((apr_size_t)(ret) != len) { 713 /* we know the above cast is OK because len > 0 and ret >= 0 */ 671 714 /* Not able to send the entire bucket, 672 715 split it and send it again. */ -
src/mod_gnutls.c
r2db6923 r71e9a5c 1 1 /** 2 2 * Copyright 2004-2005 Paul Querna 3 * Copyright 2008 Nikos Mavrogiannopoulos3 * Copyright 2008, 2014 Nikos Mavrogiannopoulos 4 4 * Copyright 2011 Dash Shendy 5 * Copyright 2015 Thomas Klute 5 6 * 6 7 * Licensed under the Apache License, Version 2.0 (the "License"); … … 20 21 #include "mod_gnutls.h" 21 22 22 static void gnutls_hooks(apr_pool_t * p) { 23 23 #ifdef APLOG_USE_MODULE 24 APLOG_USE_MODULE(gnutls); 25 #endif 26 27 static void gnutls_hooks(apr_pool_t * p __attribute__((unused))) 28 { 24 29 /* Try Run Post-Config Hook After mod_proxy */ 25 30 static const char * const aszPre[] = { "mod_proxy.c", NULL }; 26 ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,APR_HOOK_REALLY_LAST); 31 ap_hook_post_config(mgs_hook_post_config, aszPre, NULL, 32 APR_HOOK_REALLY_LAST); 27 33 /* HTTP Scheme Hook */ 28 34 #if USING_2_1_RECENT … … 32 38 #endif 33 39 /* Default Port Hook */ 34 ap_hook_default_port(mgs_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE);40 ap_hook_default_port(mgs_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE); 35 41 /* Pre-Connect Hook */ 36 ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); 42 ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL, 43 APR_HOOK_MIDDLE); 37 44 /* Pre-Config Hook */ 38 45 ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL, 39 APR_HOOK_MIDDLE);46 APR_HOOK_MIDDLE); 40 47 /* Child-Init Hook */ 41 48 ap_hook_child_init(mgs_hook_child_init, NULL, NULL, 42 APR_HOOK_MIDDLE);49 APR_HOOK_MIDDLE); 43 50 /* Authentication Hook */ 44 51 ap_hook_access_checker(mgs_hook_authz, NULL, NULL, 45 APR_HOOK_REALLY_FIRST);52 APR_HOOK_REALLY_FIRST); 46 53 /* Fixups Hook */ 47 54 ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST); … … 53 60 54 61 /* Input Filter */ 55 ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, 56 mgs_filter_input, NULL,AP_FTYPE_CONNECTION + 5);62 ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, mgs_filter_input, 63 NULL, AP_FTYPE_CONNECTION + 5); 57 64 /* Output Filter */ 58 ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, 59 mgs_filter_output, NULL,AP_FTYPE_CONNECTION + 5);65 ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, mgs_filter_output, 66 NULL, AP_FTYPE_CONNECTION + 5); 60 67 61 68 /* mod_proxy calls these functions */ … … 64 71 } 65 72 66 int ssl_is_https(conn_rec *c) { 73 int ssl_is_https(conn_rec *c) 74 { 67 75 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 68 76 ap_get_module_config(c->base_server->module_config, &gnutls_module); 69 77 if(sc->enabled == 0 || sc->non_ssl_request == 1) { 70 78 /* SSL/TLS Disabled or Plain HTTP Connection Detected */ … … 75 83 } 76 84 77 int ssl_engine_disable(conn_rec *c) { 85 int ssl_engine_disable(conn_rec *c) 86 { 78 87 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 79 88 ap_get_module_config(c->base_server->module_config, &gnutls_module); 80 89 if(sc->enabled == GNUTLS_ENABLED_FALSE) { 81 90 return 1; 82 91 } 83 ap_remove_input_filter(c->input_filters); 84 ap_remove_input_filter(c->output_filters); 85 mgs_cleanup_pre_config(c->pool); 86 sc->enabled = 0; 92 93 /* disable TLS for this connection */ 94 mgs_handle_t *ctxt = (mgs_handle_t *) 95 ap_get_module_config(c->conn_config, &gnutls_module); 96 if (ctxt == NULL) 97 { 98 ctxt = apr_pcalloc(c->pool, sizeof (*ctxt)); 99 ap_set_module_config(c->conn_config, &gnutls_module, ctxt); 100 } 101 ctxt->enabled = GNUTLS_ENABLED_FALSE; 102 ctxt->is_proxy = GNUTLS_ENABLED_TRUE; 103 104 if (c->input_filters) 105 ap_remove_input_filter(c->input_filters); 106 if (c->output_filters) 107 ap_remove_output_filter(c->output_filters); 108 87 109 return 1; 88 110 } 89 111 90 int ssl_proxy_enable(conn_rec *c) { 112 int ssl_proxy_enable(conn_rec *c) 113 { 114 /* check if TLS proxy support is enabled */ 91 115 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 92 ap_get_module_config(c->base_server->module_config, &gnutls_module); 93 sc->proxy_enabled = 1; 94 sc->enabled = 0; 116 ap_get_module_config(c->base_server->module_config, &gnutls_module); 117 if (sc->proxy_enabled != GNUTLS_ENABLED_TRUE) 118 { 119 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, 120 "%s: mod_proxy requested TLS proxy, but not enabled " 121 "for %s", __func__, sc->cert_cn); 122 return 0; 123 } 124 125 /* enable TLS for this connection */ 126 mgs_handle_t *ctxt = (mgs_handle_t *) 127 ap_get_module_config(c->conn_config, &gnutls_module); 128 if (ctxt == NULL) 129 { 130 ctxt = apr_pcalloc(c->pool, sizeof (*ctxt)); 131 ap_set_module_config(c->conn_config, &gnutls_module, ctxt); 132 } 133 ctxt->enabled = GNUTLS_ENABLED_TRUE; 134 ctxt->is_proxy = GNUTLS_ENABLED_TRUE; 95 135 return 1; 96 136 } 97 137 98 138 static const command_rec mgs_config_cmds[] = { 99 AP_INIT_TAKE1(" SSLProxyEngine", mgs_set_proxy_engine,139 AP_INIT_TAKE1("GnuTLSProxyEngine", mgs_set_proxy_engine, 100 140 NULL, 101 141 RSRC_CONF | OR_AUTHCFG, 102 142 "Enable SSL Proxy Engine"), 143 AP_INIT_TAKE1("GnuTLSP11Module", mgs_set_p11_module, 144 NULL, 145 RSRC_CONF, 146 "Load this additional PKCS #11 provider library"), 147 AP_INIT_RAW_ARGS("GnuTLSPIN", mgs_set_pin, 148 NULL, 149 RSRC_CONF, 150 "The PIN to use in case of encrypted keys or PKCS #11 tokens."), 151 AP_INIT_RAW_ARGS("GnuTLSSRKPIN", mgs_set_srk_pin, 152 NULL, 153 RSRC_CONF, 154 "The SRK PIN to use in case of TPM keys."), 103 155 AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify, 104 156 NULL, … … 181 233 "Whether this server has GnuTLS Enabled. Default: Off"), 182 234 AP_INIT_TAKE1("GnuTLSExportCertificates", 183 mgs_set_export_certificates_enabled, 184 NULL, 185 RSRC_CONF, 186 "Whether to export PEM encoded certificates to CGIs. Default: Off"), 235 mgs_set_export_certificates_size, 236 NULL, 237 RSRC_CONF, 238 "Max size to export PEM encoded certificates to CGIs (or off to disable). Default: off"), 239 AP_INIT_TAKE1("GnuTLSProxyKeyFile", mgs_store_cred_path, 240 NULL, 241 RSRC_CONF, 242 "X509 client private file for proxy connections"), 243 AP_INIT_TAKE1("GnuTLSProxyCertificateFile", mgs_store_cred_path, 244 NULL, 245 RSRC_CONF, 246 "X509 client certificate file for proxy connections"), 247 AP_INIT_TAKE1("GnuTLSProxyCAFile", mgs_store_cred_path, 248 NULL, 249 RSRC_CONF, 250 "X509 trusted CA file for proxy connections"), 251 AP_INIT_TAKE1("GnuTLSProxyCRLFile", mgs_store_cred_path, 252 NULL, 253 RSRC_CONF, 254 "X509 CRL file for proxy connections"), 255 AP_INIT_RAW_ARGS("GnuTLSProxyPriorities", mgs_set_priorities, 256 NULL, 257 RSRC_CONF, 258 "The priorities to enable for proxy connections (ciphers, key exchange, " 259 "MACs, compression)."), 187 260 { NULL }, 188 261 }; -
test/README
r2db6923 r71e9a5c 2 2 ================================== 3 3 4 Initial Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net> 4 Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net> 5 Thomas Klute <thomas2.klute@uni-dortmund.de> 5 6 6 7 There are a lot of ways that a TLS-capable web server can go wrong. I … … 11 12 ================= 12 13 13 from the top level of the source, just run: 14 from the top level of the source, or from test/ (where this README is), 15 just run: 14 16 15 17 make check 16 18 17 from t/ (where this README is), just run: 19 from test/ you can also run specific tests by passing their script 20 names to make in the TESTS variable: 18 21 19 make 20 21 also from t/ you can also run specific tests (identified by number) 22 with: 23 24 make t-3 22 TESTS="test-03_cachetimeout_in_vhost.bash" make -e check 25 23 26 24 This should be handy when you're just trying to experiment with a new 27 25 test and don't want to wait for the full test suite to run. 28 26 27 The default configuration assumes that an IPv6 loopback device is 28 available (TEST_IP=[::1]) and that TEST_HOST="localhost" resolves to 29 the IPv6 loopback address [::1]. If this does not apply to your 30 system, you can pass different values to ./configure, e.g. to use IPv4 31 instead: 32 33 TEST_HOST="localhost" TEST_IP="127.0.0.1" ./configure 29 34 30 35 Adding a Test … … 33 38 Please add more tests! 34 39 35 The simplest way to add a test is (from t /):40 The simplest way to add a test is (from test/): 36 41 37 42 ./newtest 38 43 39 This will prompt you for a simple name for the test and then copy a starting 40 set of files from tests/00_basic. 44 This will prompt you for a simple name for the test and then copy a 45 starting set of files from tests/00_basic, and create a script which 46 you can add to TESTS in Makefile.am when your test is ready for 47 inclusion in the test suite. 41 48 42 49 … … 44 51 ============== 45 52 46 Each test consists of a directory in t /tests/, which will cause the53 Each test consists of a directory in test/tests/, which will cause the 47 54 test suite to spin up an isolated apache instance and try to connect 48 55 to it with gnutls-cli and make a simple HTTP 1.1 request. … … 82 89 check" to adjust them): 83 90 84 * they need a functioning loopback device and expect (by default) to 85 have IPv6 functionality. [TEST_IP] 91 * they need a functioning loopback device. 86 92 87 * they expect (by default) the IPv6 loopbackto have port 993293 * they expect (by default) the TEST_IP to have port 9932 88 94 open. [TEST_PORT] 89 95 … … 92 98 reasons. [TEST_QUERY_DELAY (seconds for the http request to be sent 93 99 and responded to)] and [TEST_GAP (seconds to wait between tests)] 94 95 * they assume that the name "localhost" is associated with the IPv696 loopback address [TEST_HOST] -
test/TestMakefile
r2db6923 r71e9a5c 6 6 # simple configuration choices. 7 7 8 export srcdir ?= . 9 # If the Apache binary is not set, try to find apache2 in default PATH 10 # (should only happen when the test script is run manually) 11 export APACHE2 ?= apache2 12 8 13 export TEST_HOST ?= localhost 9 14 export TEST_IP ?= ::1 … … 12 17 export MSVA_PORT ?= 9933 13 18 14 export TEST_GAP ?= 1.5 15 export TEST_QUERY_DELAY ?= 2 19 export TEST_GAP ?= 0.4 20 export TEST_MSVA_MAX_WAIT ?= 10 21 export TEST_QUERY_DELAY ?= 30 22 export TEST_LOCK_WAIT ?= 30 23 24 TEST_LOCK := ./test.lock 16 25 17 26 all: setup.done 18 ./runtests27 TEST_LOCK=$(TEST_LOCK) $(srcdir)/runtests 19 28 20 29 t-%: setup.done 21 ./runtests $@30 TEST_LOCK=$(TEST_LOCK) $(srcdir)/runtests $@ 22 31 23 32 … … 30 39 all_tokens := $(foreach id,$(identities),$(foreach token,$(tokens),$(id)/$(token))) 31 40 32 %.template: %.template.in41 %.template: $(srcdir)/%.template.in 33 42 sed s/__HOSTNAME__/$(TEST_HOST)/ < $< > $@ 34 43 35 server.uid: server.uid.in44 %.uid: $(srcdir)/%.uid.in 36 45 sed s/__HOSTNAME__/$(TEST_HOST)/ < $< > $@ 37 46 … … 55 64 GNUPGHOME=$(dir $@) gpg --armor --export "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)" > $@ 56 65 66 # Import and signing modify the shared keyring, which leads to race 67 # conditions with parallel make. Locking avoids this problem. 57 68 %/cert.pgp: %/minimal.pgp authority/gpg.conf 58 GNUPGHOME=authority gpg --import $<59 GNUPGHOME=authority gpg --batch --sign-key --no-tty --yes "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)"69 GNUPGHOME=authority flock authority/lock gpg --import $< 70 GNUPGHOME=authority flock authority/lock gpg --batch --sign-key --no-tty --yes "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)" 60 71 GNUPGHOME=authority gpg --armor --export "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)" > $@ 61 72 62 73 # special cases for the authorities' root certs: 63 74 authority/x509.pem: authority.template authority/secret.key 64 certtool --generate-self-signed --load-privkey =authority/secret.key --template=authority.template > $@65 rogueca/x509.pem: rogueca.template rogueca/secret.key66 certtool --generate-self-signed --load-privkey =rogueca/secret.key --template=rogueca.template > $@75 certtool --generate-self-signed --load-privkey authority/secret.key --template authority.template > $@ 76 rogueca/x509.pem: $(srcdir)/rogueca.template rogueca/secret.key 77 certtool --generate-self-signed --load-privkey rogueca/secret.key --template $(srcdir)/rogueca.template > $@ 67 78 68 79 %/cert-request: %.template %/secret.key 69 certtool --generate-request --load-privkey =$(dir $@)secret.key --template=$< > $@80 certtool --generate-request --load-privkey $(dir $@)secret.key --template $< > $@ 70 81 71 82 %/x509.pem: %.template %/cert-request authority/secret.key authority/x509.pem 72 certtool --generate-certificate --load-ca-certificate=authority/x509.pem --load-ca-privkey=authority/secret.key --load-request=$(dir $@)cert-request --template=$< > $@ 83 certtool --generate-certificate --load-ca-certificate authority/x509.pem --load-ca-privkey authority/secret.key --load-request $(dir $@)cert-request --template $< > $@ 84 85 %/softhsm.db: %/x509.pem %/secret.key 86 SOFTHSM_CONF="$(srcdir)/$(*)-softhsm.conf" $(srcdir)/softhsm.bash init $(dir $@)secret.key $(dir $@)x509.pem 87 88 # Generate CRL revoking a certain certificate. Currently used to 89 # revoke the server certificate and check if setting the CRL as 90 # GnuTLSProxyCRLFile causes the connection to the back end server to 91 # fail. 92 %/crl.pem: %/x509.pem ${srcdir}/%-crl.template 93 certtool --generate-crl \ 94 --load-ca-privkey authority/secret.key \ 95 --load-ca-certificate authority/x509.pem \ 96 --load-certificate $< \ 97 --template "${srcdir}/$(*)-crl.template" \ 98 > $@ 73 99 74 100 msva.gnupghome/trustdb.gpg: authority/minimal.pgp client/cert.pgp … … 80 106 81 107 82 setup.done: $(all_tokens) msva.gnupghome/trustdb.gpg 108 setup.done: $(all_tokens) msva.gnupghome/trustdb.gpg client.uid 83 109 mkdir -p logs cache outputs 84 110 touch setup.done … … 86 112 87 113 clean: 88 rm -rf server client authority logs cache outputs setup.done server.template msva.gnupghome 114 rm -rf server client authority logs cache outputs setup.done \ 115 server.template imposter.template msva.gnupghome \ 116 */*.pgp */*.gpg */*.gpg~ */*.pem */*.key authority.template \ 117 client.template client.uid server.uid *.lock tests/*/*.pem 118 rmdir imposter rogueca || true 89 119 90 120 .PHONY: all clean -
test/authority.template.in
r2db6923 r71e9a5c 3 3 ca 4 4 cert_signing_key 5 crl_signing_key -
test/client.template.in
r2db6923 r71e9a5c 1 serial= 21 serial=3 2 2 cn="Test User" 3 3 email=test0@modgnutls.test -
test/rogueca.template
r2db6923 r71e9a5c 3 3 ca 4 4 cert_signing_key 5 crl_signing_key -
test/tests/00_basic/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/01_serverwide_priorities/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/02_cache_in_vhost/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 <VirtualHost ${TEST_IP}:${TEST_PORT}> -
test/tests/03_cachetimeout_in_vhost/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 <VirtualHost ${TEST_IP}:${TEST_PORT}> -
test/tests/04_basic_nosni/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/04_basic_nosni/gnutls-cli.args
r2db6923 r71e9a5c 1 --x509cafile= ../../authority/x509.pem1 --x509cafile=authority/x509.pem 2 2 --priority=NORMAL 3 3 --disable-extensions -
test/tests/05_mismatched-priorities/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/05_mismatched-priorities/gnutls-cli.args
r2db6923 r71e9a5c 1 --x509cafile= ../../authority/x509.pem1 --x509cafile=authority/x509.pem 2 2 --priority=NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0 -
test/tests/06_verify_sni_a/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/07_verify_sni_b/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/08_verify_no_sni_fallback_to_first_vhost/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/08_verify_no_sni_fallback_to_first_vhost/gnutls-cli.args
r2db6923 r71e9a5c 1 1 --disable-extensions 2 --x509cafile= ../../authority/x509.pem2 --x509cafile=authority/x509.pem 3 3 --priority=NORMAL -
test/tests/09_verify_no_sni_fails_with_wrong_order/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/09_verify_no_sni_fails_with_wrong_order/gnutls-cli.args
r2db6923 r71e9a5c 1 1 --disable-extensions 2 --x509cafile= ../../authority/x509.pem2 --x509cafile=authority/x509.pem 3 3 --priority=NORMAL -
test/tests/10_basic_client_verification/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/11_basic_client_verification_fail/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/12_cgi_variables/apache.conf
r2db6923 r71e9a5c 1 Include ${PWD}/../../base_apache.conf 2 3 LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so 4 5 AddHandler cgi-script .cgi 1 Include ${srcdir}/base_apache.conf 2 Include ${srcdir}/cgi_module.conf 6 3 7 4 GnuTLSCache dbm cache/gnutls_cache 8 5 9 <Directory ${ PWD}/../../data>6 <Directory ${srcdir}/data> 10 7 Options +ExecCGI 11 8 </Directory> -
test/tests/12_cgi_variables/output
r2db6923 r71e9a5c 9 9 10 10 DH prime bits: 2048 11 12 013 14 11 - Peer has closed the GnuTLS connection -
test/tests/13_cgi_variables_no_client_cert/apache.conf
r2db6923 r71e9a5c 1 Include ${PWD}/../../base_apache.conf 2 3 LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so 4 5 AddHandler cgi-script .cgi 1 Include ${srcdir}/base_apache.conf 2 Include ${srcdir}/cgi_module.conf 6 3 7 4 GnuTLSCache dbm cache/gnutls_cache 8 5 9 <Directory ${ PWD}/../../data>6 <Directory ${srcdir}/data> 10 7 Options +ExecCGI 11 8 </Directory> -
test/tests/13_cgi_variables_no_client_cert/output
r2db6923 r71e9a5c 1 1 Connection: close 2 Transfer-Encoding: chunked3 2 Content-Type: text/plain 4 3 5 646 4 ----Certificate:---- 7 5 … … 14 12 15 13 DH prime bits: 16 17 018 19 14 - Peer has closed the GnuTLS connection -
test/tests/14_basic_openpgp/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/14_basic_openpgp/gnutls-cli.args
r2db6923 r71e9a5c 1 --pgpkeyring= ../../authority/cert.pgp1 --pgpkeyring=authority/cert.pgp 2 2 --priority=NORMAL:-CTYPE-X509:+CTYPE-OPENPGP:+CTYPE-X509 -
test/tests/15_basic_msva/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 3 GnuTLSCache dbm cache/gnutls_cache -
test/tests/16_view-status/apache.conf
r2db6923 r71e9a5c 1 Include ${ PWD}/../../base_apache.conf1 Include ${srcdir}/base_apache.conf 2 2 3 LoadModule status_module /usr/lib/apache2/modules/mod_status.so3 LoadModule status_module ${AP_LIBEXECDIR}/mod_status.so 4 4 <Location /status> 5 5 SetHandler server-status -
test/tests/16_view-status/gnutls-cli.args
r2db6923 r71e9a5c 1 --x509cafile= ../../authority/x509.pem1 --x509cafile=authority/x509.pem 2 2 --priority=NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+RSA:+COMP-NULL
Note: See TracChangeset
for help on using the changeset viewer.