Changeset d8afa3e in mod_gnutls


Ignore:
Timestamp:
Dec 17, 2016, 6:56:34 PM (3 years ago)
Author:
Daniel Kahn Gillmor <dkg@…>
Branches:
debian/master, debian/stretch-backports, upstream
Children:
c598e21, d2b32f1
Parents:
ce12806 (diff), 677754f (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.
Message:

New upstream version 0.8.0

Files:
19 added
18 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    rce12806 rd8afa3e  
    1 **TODO:
    2 - Handle Unclean Shutdowns
    3 - make session cache use generic apache caches
     1** Version 0.8.0 (2016-12-11)
     2- New: Support for OCSP stapling
     3- Bugfix: Access to DBM cache is locked using global mutex
     4  "gnutls-cache"
     5- Bugfix: GnuTLSSessionTickets is now disabled by default as described
     6  in the handbook
     7- Fixed memory leak while checking proxy backend certificate
     8- Fixed memory leaks in post_config
     9- Safely delete session ticket key (requires GnuTLS >= 3.4)
     10- Improved error handling in post_config hook
     11- Various handbook updates
     12- Internal API documentation can be generated using Doxygen
     13- Unused code has been removed (conditionals for GnuTLS 2.x and Apache
     14  versions before 2.2, internal Lua bytecode structure last used in
     15  2011).
     16- Test suite: Fixed locking for access to the PGP keyring of the test
     17  certificate authority
     18- mod_gnutls can be built using Clang (unsupported)
    419
    520** Version 0.7.5 (2016-05-28)
  • Makefile.am

    rce12806 rd8afa3e  
    1010AM_DISTCHECK_CONFIGURE_FLAGS = "--enable-vpath-install"
    1111DISTCLEANFILES = config.nice
     12MOSTLYCLEANFILES = $(DX_CLEANFILES)
    1213
    1314SUBDIRS = src test doc
    1415ACLOCAL_AMFLAGS = -I m4
     16
     17@DX_RULES@
  • README

    rce12806 rd8afa3e  
    2222-------------
    2323
    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, GNU make, & gcc
     24 * GnuTLS          >= 3.3 <https://www.gnutls.org/> (3.4 or newer recommended)
     25 * Apache HTTPD    >= 2.4 <https://httpd.apache.org/>
     26 * autotools, GNU make, & GCC
    2727 * libmsv          >= 0.1 (Optional, enable with ./configure --enable-msva)
    2828 * pandoc   (for documentation, optional)
     
    3232------------
    3333
    34  tar xzvf mod_gnutls-version.tar.gz
     34 tar xzvf mod_gnutls-version.tar.bz2
    3535 cd mod_gnutls-version/
    3636 autoreconf -fiv
     
    4444correctly, please see test/README for details.
    4545
     46If Doxygen is available, you can build internal API documentation
     47using "make doxygen-doc". The documentation will be placed in
     48doc/api/.
     49
    4650Configuration
    4751-------------
  • configure.ac

    rce12806 rd8afa3e  
    11dnl
    2 AC_INIT(mod_gnutls, 0.7.5)
     2AC_INIT(mod_gnutls, 0.8.0)
    33OOO_CONFIG_NICE(config.nice)
    44MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION
     
    2626AC_CONFIG_MACRO_DIR([m4])
    2727
    28 AP_VERSION=2.2.0
     28AP_VERSION=2.4.0
    2929CHECK_APACHE(,$AP_VERSION,
    3030    :,:,
     
    3232)
    3333
    34 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.1.4])
     34PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.3.0])
    3535
    3636LIBGNUTLS_VERSION=`pkg-config --modversion gnutls`
     
    9191AM_CONDITIONAL([DISABLE_FLOCK],
    9292               [test "$enable_flock" = "no" || test "$flock_works" = "no"])
     93
     94# openssl is needed as the responder for OCSP tests
     95AC_PATH_PROG([OPENSSL], [openssl], [no])
     96# OCSP checks with gnutls-cli from GnuTLS versions before 3.3.23,
     97# 3.4.12, or 3.5.1 (on the respective 3.x branch) fail if intermediate
     98# CAs cannot be status checked, even if there are no intermediate CAs
     99# like in the mod_gnutls test suite where end entity certificates are
     100# directly issued by a root CA.
     101AC_MSG_CHECKING([for gnutls-cli version supporting OCSP for EE under root CA])
     102AC_PREPROC_IFELSE(
     103        [AC_LANG_SOURCE([[#include "gnutls/gnutls.h"
     104                        #if GNUTLS_VERSION_NUMBER < 0x030317
     105                        #error
     106                        #elif GNUTLS_VERSION_NUMBER >= 0x030400 && GNUTLS_VERSION_NUMBER < 0x03040c
     107                        #error
     108                        #elif GNUTLS_VERSION_NUMBER == 0x030500
     109                        #error
     110                        #endif
     111                        ]])],
     112        [gnutls_ocsp_ok="yes"],
     113        [gnutls_ocsp_ok="no"],
     114)
     115AC_MSG_RESULT([$gnutls_ocsp_ok])
     116AM_CONDITIONAL([ENABLE_OCSP_TEST], [test "${OPENSSL}" != "no" && test "${gnutls_ocsp_ok}" = "yes"])
    93117
    94118dnl Enable test namespaces? Default is "yes".
     
    216240
    217241dnl Build list of "Listen" statements for Apache
    218 LISTEN_LIST="# Listen addresses for the test servers"
     242LISTEN_LIST="@%:@ Listen addresses for the test servers"
    219243for i in ${TEST_IP}; do
    220244        LISTEN_LIST="${LISTEN_LIST}
    221245Listen ${i}:\${TEST_PORT}"
    222246done
    223 dnl HTTP ports, only active if TEST_HTTP_PORT is defined
     247# Available extra ports, tests can "Define" variables of the listed
     248# names in their apache.conf to enable them.
     249for j in TEST_HTTP_PORT OCSP_PORT; do
    224250LISTEN_LIST="${LISTEN_LIST}
    225 <IfDefine TEST_HTTP_PORT>"
     251<IfDefine ${j}>"
    226252for i in ${TEST_IP}; do
    227253        LISTEN_LIST="${LISTEN_LIST}
    228         Listen ${i}:\${TEST_HTTP_PORT}"
     254        Listen ${i}:\${${j}}"
    229255done
    230256LISTEN_LIST="${LISTEN_LIST}
    231257</IfDefine>"
     258done
    232259AC_SUBST(LISTEN_LIST)
    233260AM_SUBST_NOTMAKE(LISTEN_LIST)
    234261
     262DX_DOXYGEN_FEATURE(ON)
     263DX_DOT_FEATURE(ON)
     264DX_HTML_FEATURE(ON)
     265DX_MAN_FEATURE(OFF)
     266DX_RTF_FEATURE(OFF)
     267DX_XML_FEATURE(OFF)
     268DX_PDF_FEATURE(ON)
     269DX_PS_FEATURE(OFF)
     270DX_INIT_DOXYGEN([mod_gnutls], [doc/doxygen.conf], [doc/api])
     271
    235272AC_CONFIG_FILES([Makefile src/Makefile test/Makefile test/tests/Makefile \
    236                         doc/Makefile include/mod_gnutls.h \
     273                        doc/Makefile doc/doxygen.conf include/mod_gnutls.h \
    237274                        test/proxy_backend.conf \
    238275                        test/apache-conf/listen.conf \
  • doc/mod_gnutls_manual.mdwn

    rce12806 rd8afa3e  
    5353========================
    5454
    55 `GnuTLSEnable`
    56 --------------
     55General Options
     56---------------
     57
     58### GnuTLSEnable
    5759
    5860Enable GnuTLS for this virtual host
     
    6567This directive enables SSL/TLS Encryption for a Virtual Host.
    6668
    67 `GnuTLSCache`
    68 -------------
    69 
    70 Configure SSL Session Cache
     69### GnuTLSCache
     70
     71Configure TLS Session Cache
    7172
    7273    GnuTLSCache [dbm|gdbm|memcache|none] [PATH|SERVERLIST|-]
     
    7576Context: server config
    7677
    77 This directive configures the SSL Session Cache for `mod_gnutls`.
    78 This could be shared between machines of different architectures.
     78This directive configures the TLS Session Cache for `mod_gnutls`.
     79This could be shared between machines of different architectures. If a
     80DBM cache is used, access is serialized using the `gnutls-cache`
     81mutex. Which DBM types are available is part of the APR (Apache
     82Portable Runtime) compile time configuration.
    7983
    8084`dbm` (Requires Berkeley DBM)
    81 :   Uses the default Berkeley DB backend of APR DBM to cache SSL
    82     Sessions results.  The argument is a relative or absolute path to
    83     be used as the DBM Cache file. This is compatible with most
    84     operating systems, but needs the Apache Runtime to be compiled
    85     with Berkeley DBM support.
    86 
    87 `gdbm`
    88 :   Uses the GDBM backend of APR DBM to cache SSL Sessions results.
    89 
    90     The argument is a relative or absolute path to be used as the DBM Cache
    91     file.  This is the recommended option.
     85:   Uses the Berkeley DB backend of APR DBM to cache TLS Session
     86        data.
     87
     88        The argument is a relative or absolute path to be used as
     89    the DBM Cache file. This is compatible with most operating
     90    systems.
     91
     92`gdbm` (Requires GDBM)
     93:   Uses the GDBM backend of APR DBM to cache TLS Session data.
     94
     95    The argument is a relative or absolute path to be used as the DBM
     96    Cache file.
    9297
    9398`memcache`
    94 :   Uses a memcached server to cache the SSL Session.
     99:   Uses memcached server(s) to cache TLS Session data.
    95100
    96101    The argument is a space separated list of servers. If no port
     
    99104
    100105`none`
    101 :   Turns off all caching of SSL Sessions.
     106:   Turns off all caching of TLS Sessions.
    102107
    103108    This can significantly reduce the performance of `mod_gnutls` since
     
    106111    requires no configuration.
    107112
    108 `GnuTLSCacheTimeout`
    109 --------------------
    110 
    111 Timeout for SSL Session Cache expiration
     113### GnuTLSCacheTimeout
     114
     115Timeout for TLS Session Cache expiration
    112116
    113117    GnuTLSCacheTimeout SECONDS
     
    116120Context: server config
    117121
    118 Sets the timeout for SSL Session Cache entries expiration.  This
    119 directive is valid even if Session Tickets are used, and indicates the
    120 expiration time of the ticket in seconds.
    121 
    122 `GnuTLSSessionTickets`
    123 ----------------------
     122Sets the timeout for TLS Session Cache entries expiration. This value
     123is also used for OCSP responses if they do not contain a `nextUpdate`
     124time.
     125
     126### GnuTLSSessionTickets
    124127
    125128Enable Session Tickets for the server
     
    130133Context: server config, virtual host
    131134
    132 To avoid storing data for TLS session resumption it is allowed to
    133 provide client with a ticket, to use on return.  Use for servers with
    134 limited storage, and don't combine with GnuTLSCache. For a pool of
    135 servers this option is not recommended since the tickets are unique
    136 for the issuing server only.
    137 
    138 
    139 `GnuTLSCertificateFile`
    140 -----------------------
    141 
    142 Set to the PEM Encoded Server Certificate
    143 
    144     GnuTLSCertificateFile FILEPATH
    145 
    146 Default: *none*\
    147 Context: server config, virtual host
    148 
    149 Takes an absolute or relative path to a PEM-encoded X.509 certificate to
    150 use as this Server's End Entity (EE) certificate. If you need to supply
    151 certificates for intermediate Certificate Authorities (iCAs), they
    152 should be listed in sequence in the file, from EE to the iCA closest to
    153 the root CA. Optionally, you can also include the root CA's certificate
    154 as the last certificate in the list.
    155 
    156 Since version 0.7 this can be a PKCS #11 URL.
    157 
    158 `GnuTLSKeyFile`
    159 ---------------
    160 
    161 Set to the PEM Encoded Server Private Key
    162 
    163     GnuTLSKeyFile FILEPATH
    164 
    165 Default: *none*\
    166 Context: server config, virtual host
    167 
    168 Takes an absolute or relative path to the Server Private Key. Set
    169 `GnuTLSPIN` if the key file is encrypted.
    170 
    171 Since version 0.7 this can be a PKCS #11 URL.
    172 
    173 **Security Warning:**\
    174 This private key must be protected. It is read while Apache is still
    175 running as root, and does not need to be readable by the nobody or
    176 apache user.
    177 
    178 `GnuTLSPGPCertificateFile`
    179 --------------------------
    180 
    181 Set to a base64 Encoded Server OpenPGP Certificate
    182 
    183     GnuTLSPGPCertificateFile FILEPATH
    184 
    185 Default: *none*\
    186 Context: server config, virtual host
    187 
    188 Takes an absolute or relative path to a base64 Encoded OpenPGP
    189 Certificate to use as this Server's Certificate.
    190 
    191 `GnuTLSPGPKeyFile`
    192 ------------------
    193 
    194 Set to the Server OpenPGP Secret Key
    195 
    196     GnuTLSPGPKeyFile FILEPATH
    197 
    198 Default: *none*\
    199 Context: server config, virtual host
    200 
    201 Takes an absolute or relative path to the Server Private Key. This key
    202 cannot currently be password protected.
    203 
    204 **Security Warning:**\
    205  This private key must be protected. It is read while Apache is still
    206 running as root, and does not need to be readable by the nobody or
    207 apache user.
    208 
    209 `GnuTLSClientVerify`
    210 --------------------
    211 
    212 Enable Client Certificate Verification\
     135To avoid storing data for TLS session resumption the server can
     136provide clients with tickets, to use on return. Tickets are an
     137alternative to using a session cache, mostly used for busy servers
     138with limited storage. For a pool of servers this option is not
     139recommended since the tickets are bound to the issuing server only.
     140
     141If this option is set in the global configuration, virtual hosts
     142without a `GnuTLSSessionTickets` setting will use the global setting.
     143
     144*Warning:* Currently the master key that protects the tickets is
     145generated only on server start, and there is no mechanism to roll over
     146the key. If session tickets are enabled it is highly recommened to
     147restart the server regularly to protect past sessions in case an
     148attacker gains access to server memory.
     149
     150### GnuTLSClientVerify
     151
     152Enable Client Certificate Verification
    213153
    214154    GnuTLSClientVerify [ignore|request|require]
     
    217157Context: server config, virtual host, directory, .htaccess
    218158
    219 This directive controls the use of SSL Client Certificate
     159This directive controls the use of TLS Client Certificate
    220160Authentication. If used in the .htaccess context, it can force TLS
    221161re-negotiation.
    222162
    223163`ignore`
    224 :   `mod_gnutls` will ignore the contents of any SSL Client Certificates
     164:   `mod_gnutls` will ignore the contents of any TLS Client Certificates
    225165    sent. It will not request that the client sends a certificate.
    226166
     
    236176    environment variable will only be set to `SUCCESS`.
    237177
    238 `GnuTLSClientCAFile`
    239 --------------------
    240 
    241 Set to the PEM Encoded Certificate Authority Certificate
    242 
    243     GnuTLSClientCAFile FILEPATH
    244 
    245 Default: *none*
    246 Context: server config, virtual host
    247 
    248 Takes an absolute or relative path to a PEM Encoded Certificate to use
    249 as a Certificate Authority with Client Certificate Authentication.
    250 This file may contain a list of trusted authorities.
    251 
    252 `GnuTLSPGPKeyringFile`
    253 ----------------------
    254 
    255 Set to a base64 Encoded key ring
    256 
    257     GnuTLSPGPKeyringFile FILEPATH
    258 
    259 Default: *none*\
    260 Context: server config, virtual host
    261 
    262 Takes an absolute or relative path to a base64 Encoded Certificate
    263 list (key ring) to use as a means of verification of Client
    264 Certificates.  This file should contain a list of trusted signers.
    265 
    266 `GnuTLSDHFile`
    267 --------------
     178### GnuTLSDHFile
    268179
    269180Set to the PKCS \#3 encoded Diffie Hellman parameters
     
    2791902048`.  If not set `mod_gnutls` will use the included parameters.
    280191
    281 `GnuTLSSRPPasswdFile`
    282 ---------------------
    283 
    284 Set to the SRP password file for SRP ciphersuites
    285 
    286     GnuTLSSRPPasswdFile FILEPATH
    287 
    288 Default: *none*\
    289 Context: server config, virtual host
    290 
    291 Takes an absolute or relative path to an SRP password file. This is
    292 the same format as used in libsrp.  You can generate such file using
    293 the command `srptool --passwd /etc/tpasswd --passwd-conf
    294 /etc/tpasswd.conf -u test` to set a password for user test.  This
    295 password file holds the username, a password verifier and the
    296 dependency to the SRP parameters.
    297 
    298 `GnuTLSSRPPasswdConfFile`
    299 -------------------------
    300 
    301 Set to the SRP password.conf file for SRP ciphersuites
    302 
    303     GnuTLSSRPPasswdConfFile FILEPATH
    304 
    305 Default: *none*\
    306 Context: server config, virtual host
    307 
    308 Takes an absolute or relative path to an SRP password.conf file. This
    309 is the same format as used in `libsrp`.  You can generate such file
    310 using the command `srptool --create-conf /etc/tpasswd.conf`.  This
    311 file holds the SRP parameters and is associate with the password file
    312 (the verifiers depends on these parameters).
    313 
    314 `GnuTLSPriorities`
    315 ------------------
    316 
    317 Set the allowed ciphers, key exchange algorithms, MACs and compression
    318 methods
     192### GnuTLSPriorities
     193
     194Set the allowed protocol versions, ciphers, key exchange algorithms,
     195MACs and compression methods
    319196
    320197    GnuTLSPriorities NORMAL:+CIPHER_0:+CIPHER_1:...:+CIPHER_N
     
    323200Context: server config, virtual host
    324201
    325 Takes a semi-colon separated list of ciphers, key exchange methods
    326 Message authentication codes and compression methods to enable.
    327 The allowed keywords are specified in the `gnutls_priority_init()`
    328 function of GnuTLS.
    329 
    330 Full details can be found at [the GnuTLS documentation](http://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings).
    331 In brief you can specify a set of ciphersuites from the choices:
    332 
    333 `NONE`
    334 :   The empty list.
    335 
    336 `EXPORT`
    337 :   A list with all the supported cipher combinations
    338     including the `EXPORT` strength algorithms.
     202Takes a colon separated list of protocol version, ciphers, key
     203exchange methods message authentication codes, and compression methods
     204to enable. The allowed keywords are specified in the
     205`gnutls_priority_init()` function of GnuTLS.
     206
     207Please refer to [the GnuTLS documentation](https://gnutls.org/manual/html_node/Priority-Strings.html#Priority-Strings)
     208for details. A few commonly used sets are listed below, note that
     209their exact meaning may change with GnuTLS versions.
    339210
    340211`PERFORMANCE`
    341 :   A list with all the secure cipher combinations sorted in terms of performance.
     212:   A list with all the secure cipher combinations sorted in terms of
     213    performance.
    342214
    343215`NORMAL`
     
    345217    with respect to security margin (subjective term).
    346218
    347 `SECURE`
    348 :   A list with all the secure cipher combinations including
    349     the 256-bit ciphers sorted with respect to security margin.
    350 
    351 Additionally you can add or remove algorithms using the `+` and `!`
    352 prefixes respectively.
    353 
    354 For example, in order to disable the `ARCFOUR` cipher from the `NORMAL` set
    355 you can use the string `NORMAL:!ARCFOUR-128`
    356 
    357 Other options such as the protocol version and the compression method
    358 can be specified using the `VERS-` and `COMP-` prefixes.
    359 
    360 So in order to remove or add a specific TLS version from the `NORMAL`
    361 set, use `NORMAL:!VERS-SSL3.0`.  And to enable zlib compression use
    362 `NORMAL:+COMP-DEFLATE`.
    363 
    364 
    365 However it is recommended not to add compression at this level.  With
    366 the `NONE` set, in order to be usable, you have to specify a complete
    367 set of combinations of protocol versions, cipher algorithms
    368 (`AES-128-CBC`), key exchange algorithms (`RSA`), message
    369 authentication codes (`SHA1`) and compression methods (`COMP-NULL`).
     219`SECURE128`
     220:   A list with all the secure cipher suites that offer a security level
     221    of 128-bit or more.
     222
     223`PFS`
     224:   Only cipher suites offering perfect forward secrecy (ECDHE and DHE),
     225    sorted by security margin.
     226
     227You can add or remove algorithms using the `+` and `!` prefixes
     228respectively. For example, in order to use the `NORMAL` set but
     229disable TLS 1.0 and 1.1 you can use the string
     230`NORMAL:!VERS-TLS1.0:!VERS-TLS1.1`.
    370231
    371232You can find a list of all supported Ciphers, Versions, MACs, etc.  by
    372233running `gnutls-cli --list`.
    373234
    374 The special keyword `%COMPAT` will disable some security features such
    375 as protection against statistical attacks to ciphertext data in order to
    376 achieve maximum compatibility (some broken mobile clients need this).
    377 
    378 `GnuTLSP11Module`
    379 ------------------
     235### GnuTLSP11Module
    380236
    381237Load this PKCS #11 module.
     
    389245defaults. May occur multiple times to load multiple modules.
    390246
    391 `GnuTLSPIN`
    392 ------------------
     247### GnuTLSPIN
    393248
    394249Set the PIN to be used to access encrypted key files or PKCS #11 objects.
     
    403258or openssl encrypted keys.
    404259
    405 `GnuTLSSRKPIN`
    406 ------------------
    407 
    408 Set the SRK PIN to be used to unlaccess the TPM.
     260### GnuTLSSRKPIN
     261
     262Set the SRK PIN to be used to access the TPM.
    409263
    410264    GnuTLSSRKPIN XXXXXX
     
    416270the TPM module.
    417271
    418 `GnuTLSExportCertificates`
    419 --------------------------
     272### GnuTLSExportCertificates
    420273
    421274Export the PEM encoded certificates to CGIs
     
    444297environment variables to the CGI process as `mod_ssl`.
    445298
    446 
    447 `GnuTLSProxyEngine`
    448 --------------
     299X.509 Certificate Authentication
     300--------------------------------
     301
     302### GnuTLSCertificateFile
     303
     304Set to the PEM Encoded Server Certificate
     305
     306    GnuTLSCertificateFile FILEPATH
     307
     308Default: *none*\
     309Context: server config, virtual host
     310
     311Takes an absolute or relative path to a PEM-encoded X.509 certificate to
     312use as this Server's End Entity (EE) certificate. If you need to supply
     313certificates for intermediate Certificate Authorities (iCAs), they
     314should be listed in sequence in the file, from EE to the iCA closest to
     315the root CA. Optionally, you can also include the root CA's certificate
     316as the last certificate in the list.
     317
     318Since version 0.7 this can be a PKCS #11 URL.
     319
     320### GnuTLSKeyFile
     321
     322Set to the PEM Encoded Server Private Key
     323
     324    GnuTLSKeyFile FILEPATH
     325
     326Default: *none*\
     327Context: server config, virtual host
     328
     329Takes an absolute or relative path to the Server Private Key. Set
     330`GnuTLSPIN` if the key file is encrypted.
     331
     332Since version 0.7 this can be a PKCS #11 URL.
     333
     334**Security Warning:**\
     335This private key must be protected. It is read while Apache is still
     336running as root, and does not need to be readable by the nobody or
     337apache user.
     338
     339### GnuTLSClientCAFile
     340
     341Set the PEM encoded Certificate Authority list to use for X.509 base
     342client authentication
     343
     344    GnuTLSClientCAFile FILEPATH
     345
     346Default: *none*
     347Context: server config, virtual host
     348
     349Takes an absolute or relative path to a PEM Encoded Certificate to use
     350as a Certificate Authority with Client Certificate Authentication.
     351This file may contain a list of trusted authorities.
     352
     353OpenPGP Certificate Authentication
     354----------------------------------
     355
     356### GnuTLSPGPCertificateFile
     357
     358Set to a base64 Encoded Server OpenPGP Certificate
     359
     360    GnuTLSPGPCertificateFile FILEPATH
     361
     362Default: *none*\
     363Context: server config, virtual host
     364
     365Takes an absolute or relative path to a base64 Encoded OpenPGP
     366Certificate to use as this Server's Certificate.
     367
     368### GnuTLSPGPKeyFile
     369
     370Set to the Server OpenPGP Secret Key
     371
     372    GnuTLSPGPKeyFile FILEPATH
     373
     374Default: *none*\
     375Context: server config, virtual host
     376
     377Takes an absolute or relative path to the Server Private Key. This key
     378cannot currently be password protected.
     379
     380**Security Warning:**\
     381 This private key must be protected. It is read while Apache is still
     382running as root, and does not need to be readable by the nobody or
     383apache user.
     384
     385### GnuTLSPGPKeyringFile
     386
     387Set to a base64 Encoded key ring
     388
     389    GnuTLSPGPKeyringFile FILEPATH
     390
     391Default: *none*\
     392Context: server config, virtual host
     393
     394Takes an absolute or relative path to a base64 Encoded Certificate
     395list (key ring) to use as a means of verification of Client
     396Certificates.  This file should contain a list of trusted signers.
     397
     398SRP Authentication
     399------------------
     400
     401### GnuTLSSRPPasswdFile
     402
     403Set to the SRP password file for SRP ciphersuites
     404
     405    GnuTLSSRPPasswdFile FILEPATH
     406
     407Default: *none*\
     408Context: server config, virtual host
     409
     410Takes an absolute or relative path to an SRP password file. This is
     411the same format as used in libsrp.  You can generate such file using
     412the command `srptool --passwd /etc/tpasswd --passwd-conf
     413/etc/tpasswd.conf -u test` to set a password for user test.  This
     414password file holds the username, a password verifier and the
     415dependency to the SRP parameters.
     416
     417### GnuTLSSRPPasswdConfFile
     418
     419Set to the SRP password.conf file for SRP ciphersuites
     420
     421    GnuTLSSRPPasswdConfFile FILEPATH
     422
     423Default: *none*\
     424Context: server config, virtual host
     425
     426Takes an absolute or relative path to an SRP password.conf file. This
     427is the same format as used in `libsrp`.  You can generate such file
     428using the command `srptool --create-conf /etc/tpasswd.conf`.  This
     429file holds the SRP parameters and is associate with the password file
     430(the verifiers depends on these parameters).
     431
     432TLS Proxy Configuration
     433-----------------------
     434
     435### GnuTLSProxyEngine
    449436
    450437Enable TLS proxy connections for this virtual host
     
    458445host.
    459446
    460 `GnuTLSProxyCAFile`
    461 --------------------
     447### GnuTLSProxyCAFile
    462448
    463449Set to the PEM encoded Certificate Authority Certificate
     
    474460always fail due to lack of a trusted CA.
    475461
    476 `GnuTLSProxyCRLFile`
    477 --------------------
     462### GnuTLSProxyCRLFile
    478463
    479464Set to the PEM encoded Certificate Revocation List
     
    488473back end servers. The file may contain a list of CRLs.
    489474
    490 `GnuTLSProxyCertificateFile`
    491 -----------------------
     475### GnuTLSProxyCertificateFile
    492476
    493477Set to the PEM encoded Client Certificate
     
    510494provide the matching private key.
    511495
    512 `GnuTLSProxyKeyFile`
    513 ---------------
     496### GnuTLSProxyKeyFile
    514497
    515498Set to the PEM encoded Private Key
     
    529512apache user.
    530513
    531 `GnuTLSProxyPriorities`
    532 ------------------
     514### GnuTLSProxyPriorities
    533515
    534516Set the allowed ciphers, key exchange algorithms, MACs and compression
     
    545527`GnuTLSProxyEngine` is `On`.
    546528
     529OCSP Stapling Configuration
     530---------------------------
     531
     532### GnuTLSOCSPStapling
     533
     534Enable OCSP stapling for this (virtual) host.
     535
     536    GnuTLSOCSPStapling [On|Off]
     537
     538Default: *off*\
     539Context: server config, virtual host
     540
     541OCSP stapling, formally known as the TLS Certificate Status Request
     542extension, allows the server to provide the client with an OCSP
     543response for its certificate during the handshake. This way the client
     544does not have to send an OCSP request to the CA to check the
     545certificate status, which offers privacy and performance advantages.
     546
     547Using OCSP stapling has a few requirements:
     548
     549* Caching OCSP responses requires a cache, so `GnuTLSCache` must not
     550  be `none`.
     551* `GnuTLSCertificateFile` must contain the issuer CA certificate in
     552  addition to the server certificate so responses can be verified.
     553* The certificate must either contain an OCSP access URI using HTTP,
     554  or `GnuTLSOCSPResponseFile` must be set.
     555
     556OCSP cache updates are serialized using the `gnutls-ocsp` mutex.
     557
     558### GnuTLSOCSPCheckNonce
     559
     560Check the nonce in OCSP responses?
     561
     562    GnuTLSOCSPCheckNonce [On|Off]
     563
     564Default: *on*\
     565Context: server config, virtual host
     566
     567Some CAs refuse to send nonces in their OCSP responses, probably
     568because that way they can cache responses. If your CA is one of them
     569you can use this flag to disable nonce verification. Note that
     570`mod_gnutls` will _send_ a nonce either way.
     571
     572### GnuTLSOCSPResponseFile
     573
     574Read the OCSP response for stapling from this file instead of sending
     575a request over HTTP.
     576
     577    GnuTLSOCSPResponseFile /path/to/response.der
     578
     579Default: *empty*\
     580Context: server config, virtual host
     581
     582The response file must be updated externally, for example using a cron
     583job. This option is an alternative to the server fetching OCSP
     584responses over HTTP. Reasons to use this option include:
     585
     586* Performing OCSP requests separate from the web server, to prevent slow
     587  responses from stalling handshakes.
     588* The issuer CA uses an access method other than HTTP.
     589* Testing
     590
     591You can use a GnuTLS `ocsptool` command like the following to create
     592and update the response file:
     593
     594    ocsptool --ask --nonce --load-issuer ca_cert.pem \
     595        --load-cert server_cert.pem --outfile ocsp_response.der
     596
     597Additional error checking is highly recommended. You may have to
     598remove the `--nonce` option if the OCSP responder of your CA does not
     599support nonces.
     600
     601### GnuTLSOCSPCacheTimeout
     602
     603Cache timeout for OCSP responses
     604
     605    GnuTLSOCSPCacheTimeout SECONDS
     606
     607Default: *3600*\
     608Context: server config, virtual host
     609
     610Cached OCSP responses will be refreshed after the configured number of
     611seconds. How long this timeout should reasonably be depends on your
     612CA, namely how often its OCSP responder is updated and how long
     613responses are valid. Note that a response will not be cached beyond
     614its lifetime as denoted in the `nextUpdate` field of the response.
     615
     616### GnuTLSOCSPFailureTimeout
     617
     618Wait this many seconds before retrying a failed OCSP request.
     619
     620    GnuTLSOCSPFailureTimeout SECONDS
     621
     622Default: *300*\
     623Context: server config, virtual host
     624
     625Retries of failed OCSP requests must be rate limited to avoid
     626overloading both the server using mod_gnutls and the CA's OCSP
     627responder. A shorter value increases the load on both sides, a longer
     628one means that stapling will remain disabled for longer after a failed
     629request.
     630
     631### GnuTLSOCSPSocketTimeout
     632
     633Timeout for TCP sockets used to send OCSP requests
     634
     635    GnuTLSOCSPFailureTimeout SECONDS
     636
     637Default: *6*\
     638Context: server config, virtual host
     639
     640Stalled OCSP requests must time out after a while to prevent stalling
     641the server too much. However, if the timeout is too short requests may
     642fail with a slow OCSP responder or high latency network
     643connection. This parameter allows you to adjust the timeout if
     644necessary.
     645
     646Note that this is not an upper limit for the completion of an OCSP
     647request but a socket timeout. The connection will time out if there is
     648no activity (successful send or receive) at all for the configured
     649time.
     650
    547651* * * * *
    548652
     
    550654======================
    551655
    552 Simple Standard SSL Example
     656Simple Standard TLS Example
    553657---------------------------
    554658
    555 The following is an example of standard SSL Hosting, using one IP
    556 Addresses for each virtual host
     659The following is an example of simple TLS hosting, using one IP
     660Addresses for each virtual host.
    557661
    558662     # Load the module into Apache.
     
    560664     GnuTLSCache gdbm /var/cache/www-tls-cache
    561665     GnuTLSCacheTimeout 500
    562      # With normal SSL Websites, you need one IP Address per-site.
    563      Listen 1.2.3.1:443
    564      Listen 1.2.3.2:443
    565      Listen 1.2.3.3:443
    566      Listen 1.2.3.4:443
    567      <VirtualHost 1.2.3.1:443>
    568      GnuTLSEnable on
    569      GnuTLSPriorities NONE:+AES-128-CBC:+3DES-CBC:+ARCFOUR-128:+RSA:+DHE-RSA:+DHE-DSS:+SHA1:+MD5:+COMP-NULL
    570      DocumentRoot /www/site1.example.com/html
    571      ServerName site1.example.com:443
    572      GnuTLSCertificateFile conf/ssl/site1.crt
    573      GnuTLSKeyFile conf/ss/site1.key
     666
     667     # Without SNI you need one IP Address per-site.
     668     Listen 192.0.2.1:443
     669     Listen 192.0.2.2:443
     670     Listen 192.0.2.3:443
     671     Listen 192.0.2.4:443
     672
     673     <VirtualHost 192.0.2.1:443>
     674         GnuTLSEnable on
     675         GnuTLSPriorities SECURE128
     676         DocumentRoot /www/site1.example.com/html
     677         ServerName site1.example.com:443
     678         GnuTLSCertificateFile conf/tls/site1.crt
     679         GnuTLSKeyFile conf/tls/site1.key
    574680     </VirtualHost>
    575      <VirtualHost 1.2.3.2:443>
    576      # This virtual host enables SRP authentication
    577      GnuTLSEnable on
    578      GnuTLSPriorities NORMAL:+SRP
    579      DocumentRoot /www/site2.example.com/html
    580      ServerName site2.example.com:443
    581      GnuTLSSRPPasswdFile conf/ssl/tpasswd.site2
    582      GnuTLSSRPPasswdConfFile conf/ssl/tpasswd.site2.conf
     681
     682     <VirtualHost 192.0.2.2:443>
     683         # This virtual host enables SRP authentication
     684         GnuTLSEnable on
     685         GnuTLSPriorities NORMAL:+SRP
     686         DocumentRoot /www/site2.example.com/html
     687         ServerName site2.example.com:443
     688         GnuTLSSRPPasswdFile conf/tls/tpasswd.site2
     689         GnuTLSSRPPasswdConfFile conf/tls/tpasswd.site2.conf
    583690     </VirtualHost>
    584      <VirtualHost 1.2.3.3:443>
    585      # This server enables SRP, OpenPGP and X.509 authentication.
    586      GnuTLSEnable on
    587      GnuTLSPriorities NORMAL:+SRP:+SRP-RSA:+SRP-DSS
    588      DocumentRoot /www/site3.example.com/html
    589      ServerName site3.example.com:443
    590      GnuTLSCertificateFile conf/ssl/site3.crt
    591      GnuTLSKeyFile conf/ss/site3.key
    592      GnuTLSClientVerify ignore
    593      GnuTLSPGPCertificateFile conf/ss/site3.pub.asc
    594      GnuTLSPGPKeyFile conf/ss/site3.sec.asc
    595      GnuTLSSRPPasswdFile conf/ssl/tpasswd.site3
    596      GnuTLSSRPPasswdConfFile conf/ssl/tpasswd.site3.conf
     691
     692     <VirtualHost 192.0.2.3:443>
     693         # This server enables SRP, OpenPGP and X.509 authentication.
     694         GnuTLSEnable on
     695         GnuTLSPriorities NORMAL:+SRP:+SRP-RSA:+SRP-DSS:+CTYPE-OPENPGP
     696         DocumentRoot /www/site3.example.com/html
     697         ServerName site3.example.com:443
     698         GnuTLSCertificateFile conf/tls/site3.crt
     699         GnuTLSKeyFile conf/tls/site3.key
     700         GnuTLSClientVerify ignore
     701         GnuTLSPGPCertificateFile conf/tls/site3.pub.asc
     702         GnuTLSPGPKeyFile conf/tls/site3.sec.asc
     703         GnuTLSSRPPasswdFile conf/tls/tpasswd.site3
     704         GnuTLSSRPPasswdConfFile conf/tls/tpasswd.site3.conf
    597705     </VirtualHost>
    598      <VirtualHost 1.2.3.4:443>
    599      GnuTLSEnable on
    600      # %COMPAT disables some security features to enable maximum compatibility with clients.
    601      GnuTLSPriorities NONE:+AES-128-CBC:+ARCFOUR-128:+RSA:+SHA1:+MD5:+COMP-NULL:%COMPAT
    602      DocumentRoot /www/site4.example.com/html
    603      ServerName site4.example.com:443
    604      GnuTLSCertificateFile conf/ssl/site4.crt
    605      GnuTLSKeyFile conf/ss/site4.key
     706
     707     <VirtualHost 192.0.2.4:443>
     708         GnuTLSEnable on
     709         # %COMPAT disables some security features to enable maximum
     710         # compatibility with clients. Don't use this if you need strong
     711         # security.
     712         GnuTLSPriorities NORMAL:%COMPAT
     713         DocumentRoot /www/site4.example.com/html
     714         ServerName site4.example.com:443
     715         GnuTLSCertificateFile conf/tls/site4.crt
     716         GnuTLSKeyFile conf/tls/site4.key
    606717     </VirtualHost>
    607718
     
    609720------------------------------
    610721
    611 `mod_gnutls` can also use "Server Name Indication", as specified in
    612 RFC 3546.  This allows hosting many SSL Websites, with a Single IP
    613 Address.  Currently all the recent browsers support this
    614 standard. Here is an example, using SNI: ` `
    615 
     722`mod_gnutls` supports "Server Name Indication", as specified in
     723RFC 3546. This allows hosting many TLS websites with a single IP
     724address. All recent browsers support this standard. Here is an
     725example using SNI:
    616726
    617727     # Load the module into Apache.
    618728     LoadModule gnutls_module modules/mod_gnutls.so
    619      # With normal SSL Websites, you need one IP Address per-site.
    620      Listen 1.2.3.1:443
    621      # This could also be 'Listen *:443',
    622      # just like '*:80' is common for non-https
    623      # No caching. Enable session tickets. Timeout is still used for
    624      # ticket expiration.
    625      GnuTLSCacheTimeout 600
    626      # This tells apache, that for this IP/Port combination, we want to use
    627      # Name Based Virtual Hosting. In the case of Server Name Indication,
    628      # it lets mod_gnutls pick the correct Server Certificate.
    629      NameVirtualHost 1.2.3.1:443
    630      <VirtualHost 1.2.3.1:443>
    631      GnuTLSEnable on
    632      GnuTLSSessionTickets on
    633      GnuTLSPriorities NORMAL
    634      DocumentRoot /www/site1.example.com/html
    635      ServerName site1.example.com:443
    636      GnuTLSCertificateFile conf/ssl/site1.crt
    637      GnuTLSKeyFile conf/ss/site1.key
     729
     730     # SNI allows hosting multiple sites using one IP address. This
     731     # could also be 'Listen *:443', just like '*:80' is common for
     732     # non-HTTPS
     733     Listen 198.51.100.1:443
     734
     735     <VirtualHost _default_:443>
     736         GnuTLSEnable on
     737         GnuTLSSessionTickets on
     738         GnuTLSPriorities NORMAL
     739         DocumentRoot /www/site1.example.com/html
     740         ServerName site1.example.com:443
     741         GnuTLSCertificateFile conf/tls/site1.crt
     742         GnuTLSKeyFile conf/tls/site1.key
    638743     </VirtualHost>
    639      <VirtualHost 1.2.3.1:443>
    640      GnuTLSEnable on
    641      GnuTLSPriorities NORMAL
    642      DocumentRoot /www/site2.example.com/html
    643      ServerName site2.example.com:443
    644      GnuTLSCertificateFile conf/ssl/site2.crt
    645      GnuTLSKeyFile conf/ss/site2.key
     744
     745     <VirtualHost _default_:443>
     746         GnuTLSEnable on
     747         GnuTLSPriorities NORMAL
     748         DocumentRoot /www/site2.example.com/html
     749         ServerName site2.example.com:443
     750         GnuTLSCertificateFile conf/tls/site2.crt
     751         GnuTLSKeyFile conf/tls/site2.key
    646752     </VirtualHost>
    647      <VirtualHost 1.2.3.1:443>
    648      GnuTLSEnable on
    649      GnuTLSPriorities NORMAL
    650      DocumentRoot /www/site3.example.com/html
    651      ServerName site3.example.com:443
    652      GnuTLSCertificateFile conf/ssl/site3.crt
    653      GnuTLSKeyFile conf/ss/site3.key
     753
     754     <VirtualHost _default_:443>
     755         GnuTLSEnable on
     756         GnuTLSPriorities NORMAL
     757         DocumentRoot /www/site3.example.com/html
     758         ServerName site3.example.com:443
     759         GnuTLSCertificateFile conf/tls/site3.crt
     760         GnuTLSKeyFile conf/tls/site3.key
    654761     </VirtualHost>
    655      <VirtualHost 1.2.3.1:443>
    656      GnuTLSEnable on
    657      GnuTLSPriorities NORMAL
    658      DocumentRoot /www/site4.example.com/html
    659      ServerName site4.example.com:443
    660      GnuTLSCertificateFile conf/ssl/site4.crt
    661      GnuTLSKeyFile conf/ss/site4.key
     762
     763     <VirtualHost _default_:443>
     764         GnuTLSEnable on
     765         GnuTLSPriorities NORMAL
     766         DocumentRoot /www/site4.example.com/html
     767         ServerName site4.example.com:443
     768         GnuTLSCertificateFile conf/tls/site4.crt
     769         GnuTLSKeyFile conf/tls/site4.key
    662770     </VirtualHost>
    663771
    664 
    665 * * * * *
    666 
    667 Performance Issues
    668 ==================
    669 
    670 `mod_gnutls` by default uses conservative settings for the server.
    671 You can fine tune the configuration to reduce the load on a busy
    672 server.  The following examples do exactly this:
    673 
     772OCSP Stapling Example
     773---------------------
     774
     775This example uses an X.509 server certificate. The server will fetch
     776OCSP responses from the responder listed in the certificate and store
     777them im a memcached cache shared with another server.
    674778
    675779     # Load the module into Apache.
    676780     LoadModule gnutls_module modules/mod_gnutls.so
    677      # Using 4 memcache servers to distribute the SSL Session Cache.
    678      GnuTLSCache memcache "mc1.example.com mc2.example.com mc3.example.com mc4.example.com"
     781     GnuTLSCache memcache "192.0.2.1:11211 192.0.2.2:11211"
    679782     GnuTLSCacheTimeout 600
    680      Listen 1.2.3.1:443
    681      NameVirtualHost 1.2.3.1:443
    682      <VirtualHost 1.2.3.1:443>
    683      GnuTLSEnable on
    684      # Here we disable the Perfect forward secrecy ciphersuites (DHE)
    685      # and disallow AES-256 since AES-128 is just fine.
    686      GnuTLSPriorities NORMAL:!DHE-RSA:!DHE-DSS:!AES-256-CBC:%COMPAT
    687      DocumentRoot /www/site1.example.com/html
    688      ServerName site1.example.com:443
    689      GnuTLSCertificateFile conf/ssl/site1.crt
    690      GnuTLSKeyFile conf/ss/site1.key
    691      </VirtualHost>
    692      <VirtualHost 1.2.3.1:443>
    693      GnuTLSEnable on
    694      # Here we instead of disabling the DHE ciphersuites we use
    695      # Diffie Hellman parameters of smaller size than the default (2048 bits).
    696      # Using small numbers from 768 to 1024 bits should be ok once they are
    697      # regenerated every few hours.
    698      # Use "certtool --generate-dh-params --bits 1024" to get those
    699      GnuTLSDHFile /etc/apache2/dh.params
    700      GnuTLSPriorities NORMAL:!AES-256-CBC:%COMPAT
    701      DocumentRoot /www/site2.example.com/html
    702      ServerName site2.example.com:443
    703      GnuTLSCertificateFile conf/ssl/site2.crt
    704      GnuTLSKeyFile conf/ss/site2.key
     783
     784     Listen 192.0.2.1:443
     785
     786     <VirtualHost _default_:443>
     787         GnuTLSEnable          On
     788         GnuTLSPriorities      NORMAL
     789         DocumentRoot          /www/site1.example.com/html
     790         ServerName            site1.example.com:443
     791         GnuTLSCertificateFile conf/tls/site1.crt
     792         GnuTLSKeyFile         conf/tls/site1.key
     793         GnuTLSPriorities      NORMAL
     794         GnuTLSOCSPStapling    On
    705795     </VirtualHost>
    706796
  • include/mod_gnutls.h.in

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2014 Nikos Mavrogiannopoulos
    4  *  Copyright 2015 Thomas Klute
     4 *  Copyright 2015-2016 Thomas Klute
    55 *
    66 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    1515 *  See the License for the specific language governing permissions and
    1616 *  limitations under the License.
    17  *
    1817 */
    1918
     
    3332/* GnuTLS Library Headers */
    3433#include <gnutls/gnutls.h>
    35 #if GNUTLS_VERSION_MAJOR == 2
    36 #include <gnutls/extra.h>
    37 #endif
    3834#include <gnutls/abstract.h>
    3935#include <gnutls/openpgp.h>
     
    5955/* Module Debug Mode */
    6056#define MOD_GNUTLS_DEBUG @OOO_MAINTAIN@
    61 
    62 /*
    63  * Recent Versions of 2.1 renamed several hooks.
    64  * This allows us to compile on 2.0.xx
    65  */
    66 #if AP_SERVER_MINORVERSION_NUMBER >= 2 || (AP_SERVER_MINORVERSION_NUMBER == 1 && AP_SERVER_PATCHLEVEL_NUMBER >= 3)
    67         #define USING_2_1_RECENT 1
    68 #else
    69         #define USING_2_1_RECENT 0
    70 #endif
    7157
    7258/* mod_gnutls Cache Types */
     
    8571} mgs_cache_e;
    8672
     73/* Internal cache data, defined in gnutls_cache.h */
     74typedef struct mgs_cache* mgs_cache_t;
     75
    8776typedef enum {
    8877    mgs_cvm_unset,
     
    9584typedef struct {
    9685    int client_verify_mode;
    97     const char* lua_bytecode;
    98     apr_size_t lua_bytecode_len;
    9986} mgs_dirconf_rec;
     87
     88
     89/* Internal per-vhost config for OCSP, defined in gnutls_ocsp.h */
     90typedef struct mgs_ocsp_data* mgs_ocsp_data_t;
    10091
    10192
     
    146137    mgs_cache_e cache_type;
    147138    const char* cache_config;
     139    /* Internal cache data */
     140    mgs_cache_t cache;
    148141
    149142        /* GnuTLS uses Session Tickets */
     
    216209        /* Last Cache timestamp */
    217210    apr_time_t last_cache_check;
     211
     212    /* Enable OCSP stapling */
     213    unsigned char ocsp_staple;
     214    /* Check nonce in OCSP responses? */
     215    unsigned char ocsp_check_nonce;
     216    /* Read OCSP response for stapling from this file instead of
     217     * sending a request over HTTP */
     218    char *ocsp_response_file;
     219    /* Internal OCSP data for this server */
     220    mgs_ocsp_data_t ocsp;
     221    /* Mutex to prevent parallel OCSP requests */
     222    apr_global_mutex_t *ocsp_mutex;
     223    /* Cache timeout for OCSP responses. Note that the nextUpdate
     224     * field of the response takes precedence if shorter. */
     225    apr_interval_time_t ocsp_cache_time;
     226    /* If an OCSP request fails wait this long before trying again. */
     227    apr_interval_time_t ocsp_failure_timeout;
     228    /* Socket timeout for OCSP requests */
     229    apr_interval_time_t ocsp_socket_timeout;
    218230} mgs_srvconf_rec;
    219231
     
    347359
    348360/**
    349  * Init the Cache after Configuration is done
    350  */
    351 int mgs_cache_post_config(apr_pool_t *p, server_rec *s,
    352                                  mgs_srvconf_rec *sc);
    353 /**
    354  * Init the Cache inside each Process
    355  */
    356 int mgs_cache_child_init(apr_pool_t *p, server_rec *s,
    357                                 mgs_srvconf_rec *sc);
    358 /**
    359  * Setup the Session Caching
    360  */
    361 int mgs_cache_session_init(mgs_handle_t *ctxt);
    362 
    363 #define GNUTLS_SESSION_ID_STRING_LEN \
    364     ((GNUTLS_MAX_SESSION_ID + 1) * 2)
    365 
    366 /**
    367361 * Perform any reinitialization required in PKCS #11
    368362 */
    369363int mgs_pkcs11_reinit(server_rec * s);
    370364
    371 /**
    372  * Convert a SSL Session ID into a Null Terminated Hex Encoded String
    373  * @param id raw SSL Session ID
    374  * @param idlen Length of the raw Session ID
    375  * @param str Location to store the Hex Encoded String
    376  * @param strsize The Maximum Length that can be stored in str
    377  */
    378 char *mgs_session_id2sz(unsigned char *id, int idlen,
    379                                 char *str, int strsize);
    380 
    381 /**
    382  * Convert a time_t into a Null Terminated String
    383  * @param t time_t time
    384  * @param str Location to store the Hex Encoded String
    385  * @param strsize The Maximum Length that can be stored in str
    386  */
    387 char *mgs_time2sz(time_t t, char *str, int strsize);
    388365
    389366
     
    391368
    392369/* Loads all files set in the configuration */
    393 int mgs_load_files(apr_pool_t * p, server_rec * s);
     370int mgs_load_files(apr_pool_t *pconf, apr_pool_t *ptemp, server_rec *s)
     371    __attribute__((nonnull));
    394372
    395373const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
     
    414392                          const char *type, const char* arg);
    415393
    416 const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
    417                                   const char *arg);
     394const char *mgs_set_timeout(cmd_parms *parms, void *dummy, const char *arg);
    418395
    419396const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
     
    470447                        apr_pool_t * plog, apr_pool_t * ptemp);
    471448
    472 int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
    473                          apr_pool_t * ptemp,
    474                          server_rec * base_server);
     449int mgs_hook_post_config(apr_pool_t *pconf,
     450                         apr_pool_t *plog,
     451                         apr_pool_t *ptemp,
     452                         server_rec *base_server);
    475453
    476454void mgs_hook_child_init(apr_pool_t *p, server_rec *s);
  • src/Makefile.am

    rce12806 rd8afa3e  
    66endif
    77
    8 mod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c gnutls_config.c gnutls_hooks.c
     8mod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c \
     9        gnutls_config.c gnutls_hooks.c gnutls_ocsp.c gnutls_util.c
    910mod_gnutls_la_CFLAGS = -Wall ${MODULE_CFLAGS}
    1011mod_gnutls_la_LDFLAGS = -module -avoid-version ${MODULE_LIBS}
     12noinst_HEADERS = gnutls_cache.h gnutls_config.h gnutls_ocsp.h gnutls_util.h
    1113
    1214apmodpkglib_LTLIBRARIES = mod_gnutls.la
  • src/gnutls_cache.c

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
     5 *  Copyright 2015-2016 Thomas Klute
    66 *
    77 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    1616 *  See the License for the specific language governing permissions and
    1717 *  limitations under the License.
    18  *
    1918 */
    2019
     20/**
     21 * @file gnutls_cache.c
     22 *
     23 * The signatures of the `(dbm|mc)_cache_...()` functions may be a bit
     24 * confusing: "store" and "expire" take a server_rec, "fetch" an
     25 * mgs_handle_t, and "delete" the `void*` required for a
     26 * `gnutls_db_remove_func`. The first two have matching `..._session`
     27 * functions to fit their respective GnuTLS session cache signatures.
     28 *
     29 * This is because "store", "expire" (dbm only), and "fetch" are also
     30 * needed for the OCSP cache. Their `..._session` variants have been
     31 * created to take care of the session cache specific parts, mainly
     32 * calculating the DB key from the session ID. They have to match the
     33 * appropriate GnuTLS DB function signatures.
     34 *
     35 * Additionally, there are the `mc_cache_(store|fetch)_generic()`
     36 * functions. They exist because memcached requires string keys while
     37 * DBM accepts binary keys, and provide wrappers to turn binary keys
     38 * into hex strings with a `mod_gnutls:` prefix.
     39 *
     40 * To update cached OCSP responses independent of client connections,
     41 * "store" and "expire" have to work without a connection context. On
     42 * the other hand "fetch" does not need to do that, because cached
     43 * OCSP responses will be retrieved for use in client connections.
     44 */
     45
     46#include "gnutls_cache.h"
    2147#include "mod_gnutls.h"
     48#include "gnutls_config.h"
    2249
    2350#if HAVE_APR_MEMCACHE
     
    2653
    2754#include "apr_dbm.h"
     55#include <apr_escape.h>
    2856
    2957#include "ap_mpm.h"
     58#include <util_mutex.h>
    3059
    3160#include <unistd.h>
     
    3665#endif
    3766
    38 /* it seems the default has some strange errors. Use SDBM
    39  */
     67/** Default session cache timeout */
     68#define MGS_DEFAULT_CACHE_TIMEOUT 300
     69
     70/** Prefix for keys used with a memcached cache */
    4071#define MC_TAG "mod_gnutls:"
    41 #define MC_TAG_LEN sizeof(MC_TAG)
    42 #define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN)
     72/** Maximum length of the hex string representation of a GnuTLS
     73 * session ID: two characters per byte, plus one more for `\0` */
     74#if GNUTLS_VERSION_NUMBER >= 0x030400
     75#define GNUTLS_SESSION_ID_STRING_LEN ((GNUTLS_MAX_SESSION_ID_SIZE * 2) + 1)
     76#else
     77#define GNUTLS_SESSION_ID_STRING_LEN ((GNUTLS_MAX_SESSION_ID * 2) + 1)
     78#endif
    4379
    4480#if MODULE_MAGIC_NUMBER_MAJOR < 20081201
     
    5086#endif
    5187
    52 char *mgs_session_id2sz(unsigned char *id, int idlen,
    53         char *str, int strsize) {
    54     char *cp;
    55     int n;
    56 
    57     cp = str;
    58     for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
    59         apr_snprintf(cp, strsize - (cp - str), "%02X", id[n]);
    60         cp += 2;
    61     }
    62     *cp = '\0';
    63     return str;
    64 }
    65 
    66 /* Name the Session ID as:
    67  * server:port.SessionID
    68  * to disallow resuming sessions on different servers
     88/**
     89 * Turn a GnuTLS session ID into the key format we use with DBM
     90 * caches. Name the Session ID as `server:port.SessionID` to disallow
     91 * resuming sessions on different servers.
     92 *
     93 * @return `0` on success, `-1` on failure
    6994 */
    70 static int mgs_session_id2dbm(conn_rec * c, unsigned char *id, int idlen,
    71         apr_datum_t * dbmkey) {
    72     char buf[STR_SESSION_LEN];
    73     char *sz;
    74 
    75     sz = mgs_session_id2sz(id, idlen, buf, sizeof (buf));
    76     if (sz == NULL)
    77         return -1;
    78 
    79     dbmkey->dptr =
    80             apr_psprintf(c->pool, "%s:%d.%s",
    81             c->base_server->server_hostname,
    82             c->base_server->port, sz);
    83     dbmkey->dsize = strlen(dbmkey->dptr);
    84 
     95static int mgs_session_id2dbm(conn_rec *c, unsigned char *id, int idlen,
     96                              gnutls_datum_t *dbmkey)
     97{
     98    char sz[GNUTLS_SESSION_ID_STRING_LEN];
     99    apr_status_t rv = apr_escape_hex(sz, id, idlen, 0, NULL);
     100    if (rv != APR_SUCCESS)
     101        return -1;
     102
     103    char *newkey = apr_psprintf(c->pool, "%s:%d.%s",
     104                                c->base_server->server_hostname,
     105                                c->base_server->port, sz);
     106    dbmkey->size = strlen(newkey);
     107    /* signedness does not matter for arbitrary bits */
     108    dbmkey->data = (unsigned char*) newkey;
    85109    return 0;
    86110}
    87111
    88 #define CTIME "%b %d %k:%M:%S %Y %Z"
    89 
    90 char *mgs_time2sz(time_t in_time, char *str, int strsize) {
     112/** The OPENSSL_TIME_FORMAT macro and mgs_time2sz() serve to print
     113 * time in a format compatible with OpenSSL's `ASN1_TIME_print()`
     114 * function. */
     115#define OPENSSL_TIME_FORMAT "%b %d %k:%M:%S %Y %Z"
     116
     117char *mgs_time2sz(time_t in_time, char *str, int strsize)
     118{
    91119    apr_time_exp_t vtm;
    92120    apr_size_t ret_size;
     
    96124    apr_time_ansi_put(&t, in_time);
    97125    apr_time_exp_gmt(&vtm, t);
    98     apr_strftime(str, &ret_size, strsize - 1, CTIME, &vtm);
     126    apr_strftime(str, &ret_size, strsize - 1, OPENSSL_TIME_FORMAT, &vtm);
    99127
    100128    return str;
     
    103131#if HAVE_APR_MEMCACHE
    104132
    105 /* Name the Session ID as:
    106  * server:port.SessionID
    107  * to disallow resuming sessions on different servers
     133/**
     134 * Turn a GnuTLS session ID into the key format we use with memcached
     135 * caches. Name the Session ID as `server:port.SessionID` to disallow
     136 * resuming sessions on different servers.
     137 *
     138 * @return `0` on success, `-1` on failure
    108139 */
    109 static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen) {
    110     char buf[STR_SESSION_LEN];
    111     char *sz;
    112 
    113     sz = mgs_session_id2sz(id, idlen, buf, sizeof (buf));
    114     if (sz == NULL)
     140static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen)
     141{
     142    char sz[GNUTLS_SESSION_ID_STRING_LEN];
     143    apr_status_t rv = apr_escape_hex(sz, id, idlen, 0, NULL);
     144    if (rv != APR_SUCCESS)
    115145        return NULL;
    116146
     
    150180    if (rv != APR_SUCCESS) {
    151181        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    152                 "[gnutls_cache] Failed to create Memcache Object of '%d' size.",
    153                 nservers);
     182                     "Failed to create Memcache object of size '%d'.",
     183                     nservers);
    154184        return rv;
    155185    }
     
    168198        if (rv != APR_SUCCESS) {
    169199            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    170                     "[gnutls_cache] Failed to Parse Server: '%s'",
    171                     split);
     200                         "Failed to parse server: '%s'", split);
    172201            return rv;
    173202        }
     
    175204        if (host_str == NULL) {
    176205            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    177                     "[gnutls_cache] Failed to Parse Server, "
    178                     "no hostname specified: '%s'", split);
     206                         "Failed to parse server, "
     207                         "no hostname specified: '%s'", split);
    179208            return rv;
    180209        }
     
    191220        if (rv != APR_SUCCESS) {
    192221            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    193                     "[gnutls_cache] Failed to Create Server: %s:%d",
    194                     host_str, port);
     222                         "Failed to create server: %s:%d",
     223                         host_str, port);
    195224            return rv;
    196225        }
     
    199228        if (rv != APR_SUCCESS) {
    200229            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    201                     "[gnutls_cache] Failed to Add Server: %s:%d",
    202                     host_str, port);
     230                         "Failed to add server: %s:%d",
     231                         host_str, port);
    203232            return rv;
    204233        }
     
    209238}
    210239
    211 static int mc_cache_store(void *baton, gnutls_datum_t key,
    212         gnutls_datum_t data) {
     240static int mc_cache_store(server_rec *s, const char *key,
     241                          gnutls_datum_t data, apr_uint32_t timeout)
     242{
     243    apr_status_t rv = apr_memcache_set(mc, key, (char *) data.data,
     244                                       data.size, timeout, 0);
     245
     246    if (rv != APR_SUCCESS)
     247    {
     248        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
     249                     "error storing key '%s' with %d bytes of data",
     250                     key, data.size);
     251        return -1;
     252    }
     253
     254    return 0;
     255}
     256
     257static int mc_cache_store_generic(server_rec *s, gnutls_datum_t key,
     258                                  gnutls_datum_t data, apr_time_t expiry)
     259{
     260    apr_uint32_t timeout = apr_time_sec(expiry - apr_time_now());
     261
     262    apr_pool_t *p;
     263    apr_pool_create(&p, NULL);
     264
     265    const char *hex = apr_pescape_hex(p, key.data, key.size, 1);
     266    if (hex == NULL)
     267    {
     268        apr_pool_destroy(p);
     269        return -1;
     270    }
     271
     272    const char *strkey = apr_psprintf(p, MC_TAG "%s", hex);
     273
     274    int ret = mc_cache_store(s, strkey, data, timeout);
     275
     276    apr_pool_destroy(p);
     277    return ret;
     278}
     279
     280static int mc_cache_store_session(void *baton, gnutls_datum_t key,
     281                                  gnutls_datum_t data)
     282{
     283    mgs_handle_t *ctxt = baton;
     284
     285    const char *strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
     286    if (!strkey)
     287        return -1;
     288
     289    apr_uint32_t timeout = apr_time_sec(ctxt->sc->cache_timeout);
     290
     291    return mc_cache_store(ctxt->c->base_server, strkey, data, timeout);
     292}
     293
     294static gnutls_datum_t mc_cache_fetch(conn_rec *c, const char *key)
     295{
    213296    apr_status_t rv = APR_SUCCESS;
    214     mgs_handle_t *ctxt = baton;
    215     char *strkey = NULL;
    216     apr_uint32_t timeout;
    217 
    218     strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
    219     if (!strkey)
    220         return -1;
    221 
    222     timeout = apr_time_sec(ctxt->sc->cache_timeout);
    223 
    224     rv = apr_memcache_set(mc, strkey, (char *) data.data, data.size, timeout,
    225             0);
    226 
    227     if (rv != APR_SUCCESS) {
    228         ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
    229                 ctxt->c->base_server,
    230                 "[gnutls_cache] error setting key '%s' "
    231                 "with %d bytes of data", strkey, data.size);
    232         return -1;
    233     }
    234 
    235     return 0;
    236 }
    237 
    238 static gnutls_datum_t mc_cache_fetch(void *baton, gnutls_datum_t key) {
    239     apr_status_t rv = APR_SUCCESS;
    240     mgs_handle_t *ctxt = baton;
    241     char *strkey = NULL;
    242297    char *value;
    243298    apr_size_t value_len;
    244299    gnutls_datum_t data = {NULL, 0};
    245300
    246     strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
    247     if (!strkey) {
    248         return data;
    249     }
    250 
    251     rv = apr_memcache_getp(mc, ctxt->c->pool, strkey,
    252             &value, &value_len, NULL);
    253 
    254     if (rv != APR_SUCCESS) {
     301    rv = apr_memcache_getp(mc, c->pool, key, &value, &value_len, NULL);
     302
     303    if (rv != APR_SUCCESS)
     304    {
    255305#if MOD_GNUTLS_DEBUG
    256         ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    257                 ctxt->c->base_server,
    258                 "[gnutls_cache] error fetching key '%s' ",
    259                 strkey);
    260 #endif
    261         data.size = 0;
    262         data.data = NULL;
     306        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c,
     307                      "error fetching key '%s'",
     308                      key);
     309#endif
    263310        return data;
    264311    }
     
    275322}
    276323
     324static gnutls_datum_t mc_cache_fetch_generic(mgs_handle_t *ctxt,
     325                                             gnutls_datum_t key)
     326{
     327    gnutls_datum_t data = {NULL, 0};
     328    const char *hex = apr_pescape_hex(ctxt->c->pool, key.data, key.size, 1);
     329    if (hex == NULL)
     330        return data;
     331
     332    const char *strkey = apr_psprintf(ctxt->c->pool, MC_TAG "%s", hex);
     333    return mc_cache_fetch(ctxt->c, strkey);
     334}
     335
     336static gnutls_datum_t mc_cache_fetch_session(void *baton, gnutls_datum_t key)
     337{
     338    mgs_handle_t *ctxt = baton;
     339    gnutls_datum_t data = {NULL, 0};
     340
     341    const char *strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
     342    if (!strkey)
     343        return data;
     344
     345    return mc_cache_fetch(ctxt->c, strkey);
     346}
     347
    277348static int mc_cache_delete(void *baton, gnutls_datum_t key) {
    278349    apr_status_t rv = APR_SUCCESS;
     
    288359    if (rv != APR_SUCCESS) {
    289360        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    290                 ctxt->c->base_server,
    291                 "[gnutls_cache] error deleting key '%s' ",
    292                 strkey);
     361                     ctxt->c->base_server,
     362                     "error deleting key '%s'",
     363                     strkey);
    293364        return -1;
    294365    }
     
    308379#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
    309380
    310 static void dbm_cache_expire(mgs_handle_t * ctxt) {
     381static void dbm_cache_expire(server_rec *s)
     382{
     383    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     384        ap_get_module_config(s->module_config, &gnutls_module);
     385
    311386    apr_status_t rv;
    312387    apr_dbm_t *dbm;
    313388    apr_datum_t dbmkey;
    314389    apr_datum_t dbmval;
    315     apr_time_t now;
    316390    apr_time_t dtime;
    317391    apr_pool_t *spool;
    318392    int total, deleted;
    319393
    320     now = apr_time_now();
    321 
    322     if (now - ctxt->sc->last_cache_check <
    323             (ctxt->sc->cache_timeout) / 2)
     394    apr_time_t now = apr_time_now();
     395
     396    if (now - sc->last_cache_check < (sc->cache_timeout) / 2)
    324397        return;
    325398
    326     ctxt->sc->last_cache_check = now;
    327 
    328     apr_pool_create(&spool, ctxt->c->pool);
     399    sc->last_cache_check = now;
     400
     401    apr_pool_create(&spool, NULL);
    329402
    330403    total = 0;
    331404    deleted = 0;
    332405
    333     rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
    334             ctxt->sc->cache_config, APR_DBM_RWCREATE,
     406    apr_global_mutex_lock(sc->cache->mutex);
     407
     408    rv = apr_dbm_open_ex(&dbm, db_type(sc),
     409            sc->cache_config, APR_DBM_RWCREATE,
    335410            SSL_DBM_FILE_MODE, spool);
    336411    if (rv != APR_SUCCESS) {
    337         ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    338                 ctxt->c->base_server,
    339                 "[gnutls_cache] error opening cache searcher '%s'",
    340                 ctxt->sc->cache_config);
     412        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s,
     413                     "error opening cache '%s'",
     414                     sc->cache_config);
     415        apr_global_mutex_unlock(sc->cache->mutex);
    341416        apr_pool_destroy(spool);
    342417        return;
     
    364439    apr_dbm_close(dbm);
    365440
    366     ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    367             ctxt->c->base_server,
    368             "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d",
    369             ctxt->sc->cache_config, deleted, total - deleted);
     441    rv = apr_global_mutex_unlock(sc->cache->mutex);
     442
     443    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
     444                 "Cleaned up cache '%s'. Deleted %d and left %d",
     445                 sc->cache_config, deleted, total - deleted);
    370446
    371447    apr_pool_destroy(spool);
     
    374450}
    375451
    376 static gnutls_datum_t dbm_cache_fetch(void *baton, gnutls_datum_t key) {
     452static gnutls_datum_t dbm_cache_fetch(mgs_handle_t *ctxt, gnutls_datum_t key)
     453{
    377454    gnutls_datum_t data = {NULL, 0};
    378455    apr_dbm_t *dbm;
    379     apr_datum_t dbmkey;
     456    apr_datum_t dbmkey = {(char*) key.data, key.size};
    380457    apr_datum_t dbmval;
    381     mgs_handle_t *ctxt = baton;
     458    apr_time_t expiry = 0;
    382459    apr_status_t rv;
    383460
    384     if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
    385         return data;
     461    /* check if it is time for cache expiration */
     462    dbm_cache_expire(ctxt->c->base_server);
     463
     464    apr_global_mutex_lock(ctxt->sc->cache->mutex);
    386465
    387466    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
     
    389468            SSL_DBM_FILE_MODE, ctxt->c->pool);
    390469    if (rv != APR_SUCCESS) {
    391         ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    392                 ctxt->c->base_server,
    393                 "[gnutls_cache] error opening cache '%s'",
    394                 ctxt->sc->cache_config);
     470        ap_log_cerror(APLOG_MARK, APLOG_NOTICE, rv, ctxt->c,
     471                      "error opening cache '%s'",
     472                      ctxt->sc->cache_config);
     473        apr_global_mutex_unlock(ctxt->sc->cache->mutex);
    395474        return data;
    396475    }
     
    398477    rv = apr_dbm_fetch(dbm, dbmkey, &dbmval);
    399478
    400     if (rv != APR_SUCCESS) {
    401         apr_dbm_close(dbm);
     479    if (rv != APR_SUCCESS)
     480        goto close_db;
     481
     482    if (dbmval.dptr == NULL || dbmval.dsize <= sizeof (apr_time_t))
     483        goto cleanup;
     484
     485    data.size = dbmval.dsize - sizeof (apr_time_t);
     486    /* get data expiration tag */
     487    expiry = *((apr_time_t *) dbmval.dptr);
     488
     489    data.data = gnutls_malloc(data.size);
     490    if (data.data == NULL)
     491    {
     492        data.size = 0;
     493        goto cleanup;
     494    }
     495
     496    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, ctxt->c,
     497                  "fetched %ld bytes from cache",
     498                  dbmval.dsize);
     499
     500    memcpy(data.data, dbmval.dptr + sizeof (apr_time_t), data.size);
     501
     502 cleanup:
     503    apr_dbm_freedatum(dbm, dbmval);
     504 close_db:
     505    apr_dbm_close(dbm);
     506    apr_global_mutex_unlock(ctxt->sc->cache->mutex);
     507
     508    /* cache entry might have expired since last cache cleanup */
     509    if (expiry != 0 && expiry < apr_time_now())
     510    {
     511        gnutls_free(data.data);
     512        data.data = NULL;
     513        data.size = 0;
     514        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, ctxt->c,
     515                      "dropped expired cache data");
     516    }
     517
     518    return data;
     519}
     520
     521static gnutls_datum_t dbm_cache_fetch_session(void *baton, gnutls_datum_t key)
     522{
     523    gnutls_datum_t data = {NULL, 0};
     524    gnutls_datum_t dbmkey;
     525    mgs_handle_t *ctxt = baton;
     526
     527    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
    402528        return data;
    403     }
    404 
    405     if (dbmval.dptr == NULL || dbmval.dsize <= sizeof (apr_time_t)) {
    406         apr_dbm_freedatum(dbm, dbmval);
    407         apr_dbm_close(dbm);
    408         return data;
    409     }
    410 
    411     data.size = dbmval.dsize - sizeof (apr_time_t);
    412 
    413     data.data = gnutls_malloc(data.size);
    414     if (data.data == NULL) {
    415         apr_dbm_freedatum(dbm, dbmval);
    416         apr_dbm_close(dbm);
    417         return data;
    418     }
    419 
    420     memcpy(data.data, dbmval.dptr + sizeof (apr_time_t), data.size);
    421 
    422     apr_dbm_freedatum(dbm, dbmval);
    423     apr_dbm_close(dbm);
    424 
    425     return data;
    426 }
    427 
    428 static int dbm_cache_store(void *baton, gnutls_datum_t key,
    429         gnutls_datum_t data) {
     529
     530    return dbm_cache_fetch(ctxt, dbmkey);
     531}
     532
     533static int dbm_cache_store(server_rec *s, gnutls_datum_t key,
     534                           gnutls_datum_t data, apr_time_t expiry)
     535{
     536    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     537        ap_get_module_config(s->module_config, &gnutls_module);
     538
    430539    apr_dbm_t *dbm;
    431     apr_datum_t dbmkey;
     540    apr_datum_t dbmkey = {(char*) key.data, key.size};
    432541    apr_datum_t dbmval;
    433     mgs_handle_t *ctxt = baton;
    434542    apr_status_t rv;
    435     apr_time_t expiry;
    436543    apr_pool_t *spool;
    437544
    438     if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
    439         return -1;
    440 
    441     /* we expire dbm only on every store
    442      */
    443     dbm_cache_expire(ctxt);
    444 
    445     apr_pool_create(&spool, ctxt->c->pool);
     545    /* check if it is time for cache expiration */
     546    dbm_cache_expire(s);
     547
     548    apr_pool_create(&spool, NULL);
    446549
    447550    /* create DBM value */
     
    449552    dbmval.dptr = (char *) apr_palloc(spool, dbmval.dsize);
    450553
    451     expiry = apr_time_now() + ctxt->sc->cache_timeout;
    452 
     554    /* prepend expiration time */
    453555    memcpy((char *) dbmval.dptr, &expiry, sizeof (apr_time_t));
    454556    memcpy((char *) dbmval.dptr + sizeof (apr_time_t),
    455557            data.data, data.size);
     558
     559    apr_global_mutex_lock(sc->cache->mutex);
     560
     561    rv = apr_dbm_open_ex(&dbm, db_type(sc),
     562                         sc->cache_config, APR_DBM_RWCREATE,
     563                         SSL_DBM_FILE_MODE, spool);
     564    if (rv != APR_SUCCESS)
     565    {
     566        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s,
     567                     "error opening cache '%s'",
     568                     sc->cache_config);
     569        apr_global_mutex_unlock(sc->cache->mutex);
     570        apr_pool_destroy(spool);
     571        return -1;
     572    }
     573
     574    rv = apr_dbm_store(dbm, dbmkey, dbmval);
     575    if (rv != APR_SUCCESS)
     576    {
     577        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
     578                     "error storing in cache '%s'",
     579                     sc->cache_config);
     580        apr_dbm_close(dbm);
     581        apr_global_mutex_unlock(sc->cache->mutex);
     582        apr_pool_destroy(spool);
     583        return -1;
     584    }
     585
     586    apr_dbm_close(dbm);
     587    apr_global_mutex_unlock(sc->cache->mutex);
     588
     589    ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, s,
     590                 "stored %ld bytes of data (%ld byte key) in cache '%s'",
     591                 dbmval.dsize, dbmkey.dsize, sc->cache_config);
     592
     593    apr_pool_destroy(spool);
     594
     595    return 0;
     596}
     597
     598static int dbm_cache_store_session(void *baton, gnutls_datum_t key,
     599                                   gnutls_datum_t data)
     600{
     601    mgs_handle_t *ctxt = baton;
     602    gnutls_datum_t dbmkey;
     603
     604    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
     605        return -1;
     606
     607    apr_time_t expiry = apr_time_now() + ctxt->sc->cache_timeout;
     608
     609    return dbm_cache_store(ctxt->c->base_server, dbmkey, data, expiry);
     610}
     611
     612static int dbm_cache_delete(void *baton, gnutls_datum_t key)
     613{
     614    apr_dbm_t *dbm;
     615    gnutls_datum_t tmpkey;
     616    mgs_handle_t *ctxt = baton;
     617    apr_status_t rv;
     618
     619    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &tmpkey) < 0)
     620        return -1;
     621    apr_datum_t dbmkey = {(char*) tmpkey.data, tmpkey.size};
     622
     623    apr_global_mutex_lock(ctxt->sc->cache->mutex);
    456624
    457625    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
     
    460628    if (rv != APR_SUCCESS) {
    461629        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    462                 ctxt->c->base_server,
    463                 "[gnutls_cache] error opening cache '%s'",
    464                 ctxt->sc->cache_config);
    465         apr_pool_destroy(spool);
    466         return -1;
    467     }
    468 
    469     rv = apr_dbm_store(dbm, dbmkey, dbmval);
    470 
    471     if (rv != APR_SUCCESS) {
    472         ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    473                 ctxt->c->base_server,
    474                 "[gnutls_cache] error storing in cache '%s'",
    475                 ctxt->sc->cache_config);
    476         apr_dbm_close(dbm);
    477         apr_pool_destroy(spool);
    478         return -1;
    479     }
    480 
    481     apr_dbm_close(dbm);
    482 
    483     apr_pool_destroy(spool);
    484 
    485     return 0;
    486 }
    487 
    488 static int dbm_cache_delete(void *baton, gnutls_datum_t key) {
    489     apr_dbm_t *dbm;
    490     apr_datum_t dbmkey;
    491     mgs_handle_t *ctxt = baton;
    492     apr_status_t rv;
    493 
    494     if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
    495         return -1;
    496 
    497     rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
    498             ctxt->sc->cache_config, APR_DBM_RWCREATE,
    499             SSL_DBM_FILE_MODE, ctxt->c->pool);
     630                     ctxt->c->base_server,
     631                     "error opening cache '%s'",
     632                     ctxt->sc->cache_config);
     633        apr_global_mutex_unlock(ctxt->sc->cache->mutex);
     634        return -1;
     635    }
     636
     637    rv = apr_dbm_delete(dbm, dbmkey);
     638
    500639    if (rv != APR_SUCCESS) {
    501640        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    502                 ctxt->c->base_server,
    503                 "[gnutls_cache] error opening cache '%s'",
    504                 ctxt->sc->cache_config);
    505         return -1;
    506     }
    507 
    508     rv = apr_dbm_delete(dbm, dbmkey);
    509 
    510     if (rv != APR_SUCCESS) {
    511         ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    512                 ctxt->c->base_server,
    513                 "[gnutls_cache] error deleting from cache '%s'",
    514                 ctxt->sc->cache_config);
     641                     ctxt->c->base_server,
     642                     "error deleting from cache '%s'",
     643                     ctxt->sc->cache_config);
    515644        apr_dbm_close(dbm);
     645        apr_global_mutex_unlock(ctxt->sc->cache->mutex);
    516646        return -1;
    517647    }
    518648
    519649    apr_dbm_close(dbm);
     650    apr_global_mutex_unlock(ctxt->sc->cache->mutex);
    520651
    521652    return 0;
     
    571702        sc->cache_type = mgs_cache_none;
    572703    /* if GnuTLSCacheTimeout was never explicitly set: */
    573     if (sc->cache_timeout == -1)
    574         sc->cache_timeout = apr_time_from_sec(300);
    575 
    576     if (sc->cache_type == mgs_cache_dbm
    577             || sc->cache_type == mgs_cache_gdbm) {
     704    if (sc->cache_timeout == MGS_TIMEOUT_UNSET)
     705        sc->cache_timeout = apr_time_from_sec(MGS_DEFAULT_CACHE_TIMEOUT);
     706
     707    /* initialize mutex only once */
     708    if (sc->cache == NULL)
     709    {
     710        sc->cache = apr_palloc(p, sizeof(struct mgs_cache));
     711        apr_status_t rv = ap_global_mutex_create(&sc->cache->mutex, NULL,
     712                                                 MGS_CACHE_MUTEX_NAME,
     713                                                 NULL, s, p, 0);
     714        if (rv != APR_SUCCESS)
     715            return rv;
     716    }
     717
     718    if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm)
     719    {
     720        sc->cache->store = dbm_cache_store;
     721        sc->cache->fetch = dbm_cache_fetch;
    578722        return dbm_cache_post_config(p, s, sc);
    579723    }
    580     return 0;
    581 }
    582 
    583724#if HAVE_APR_MEMCACHE
     725    else if (sc->cache_type == mgs_cache_memcache)
     726    {
     727        sc->cache->store = mc_cache_store_generic;
     728        sc->cache->fetch = mc_cache_fetch_generic;
     729    }
     730#endif
     731
     732    return APR_SUCCESS;
     733}
     734
    584735int mgs_cache_child_init(apr_pool_t * p,
    585736                         server_rec * s,
    586737                         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 {
     738{
     739    /* reinit cache mutex */
     740    const char *lockfile = apr_global_mutex_lockfile(sc->cache->mutex);
     741    apr_status_t rv = apr_global_mutex_child_init(&sc->cache->mutex,
     742                                                  lockfile, p);
     743    if (rv != APR_SUCCESS)
     744        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
     745                     "Failed to reinit mutex '%s'", MGS_CACHE_MUTEX_NAME);
     746
    593747    if (sc->cache_type == mgs_cache_dbm
    594748            || sc->cache_type == mgs_cache_gdbm) {
     
    609763            || ctxt->sc->cache_type == mgs_cache_gdbm) {
    610764        gnutls_db_set_retrieve_function(ctxt->session,
    611                 dbm_cache_fetch);
     765                dbm_cache_fetch_session);
    612766        gnutls_db_set_remove_function(ctxt->session,
    613767                dbm_cache_delete);
    614768        gnutls_db_set_store_function(ctxt->session,
    615                 dbm_cache_store);
     769                dbm_cache_store_session);
    616770        gnutls_db_set_ptr(ctxt->session, ctxt);
    617771    }
     
    619773    else if (ctxt->sc->cache_type == mgs_cache_memcache) {
    620774        gnutls_db_set_retrieve_function(ctxt->session,
    621                 mc_cache_fetch);
     775                mc_cache_fetch_session);
    622776        gnutls_db_set_remove_function(ctxt->session,
    623777                mc_cache_delete);
    624778        gnutls_db_set_store_function(ctxt->session,
    625                 mc_cache_store);
     779                mc_cache_store_session);
    626780        gnutls_db_set_ptr(ctxt->session, ctxt);
    627781    }
  • src/gnutls_config.c

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2008, 2014 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
     5 *  Copyright 2015-2016 Thomas Klute
    66 *
    77 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    1616 *  See the License for the specific language governing permissions and
    1717 *  limitations under the License.
    18  *
    1918 */
    2019
     20#include "gnutls_config.h"
    2121#include "mod_gnutls.h"
     22#include "gnutls_ocsp.h"
    2223#include "apr_lib.h"
    2324#include <gnutls/abstract.h>
     
    9394        "-----END DH PARAMETERS-----\n";
    9495
    95 int mgs_load_files(apr_pool_t * p, server_rec * s)
     96/*
     97 * Clean up the various GnuTLS data structures allocated from
     98 * mgs_load_files()
     99 */
     100static apr_status_t mgs_pool_free_credentials(void *arg)
     101{
     102    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) arg;
     103
     104    if (sc->certs)
     105    {
     106        gnutls_certificate_free_credentials(sc->certs);
     107        sc->certs = NULL;
     108    }
     109
     110    if (sc->anon_creds)
     111    {
     112        gnutls_anon_free_server_credentials(sc->anon_creds);
     113        sc->anon_creds = NULL;
     114    }
     115
     116#ifdef ENABLE_SRP
     117    if (sc->srp_creds)
     118    {
     119        gnutls_srp_free_server_credentials(sc->srp_creds);
     120        sc->srp_creds = NULL;
     121    }
     122#endif
     123
     124    if (sc->dh_params)
     125    {
     126        gnutls_dh_params_deinit(sc->dh_params);
     127        sc->dh_params = NULL;
     128    }
     129
     130    for (unsigned int i = 0; i < sc->certs_x509_chain_num; i++)
     131    {
     132        gnutls_pcert_deinit(&sc->certs_x509_chain[i]);
     133        gnutls_x509_crt_deinit(sc->certs_x509_crt_chain[i]);
     134    }
     135
     136    if (sc->privkey_x509)
     137    {
     138        gnutls_privkey_deinit(sc->privkey_x509);
     139        sc->privkey_x509 = NULL;
     140    }
     141
     142    if (sc->ca_list)
     143    {
     144        for (unsigned int i = 0; i < sc->ca_list_size; i++)
     145        {
     146            gnutls_x509_crt_deinit(sc->ca_list[i]);
     147        }
     148        gnutls_free(sc->ca_list);
     149        sc->ca_list = NULL;
     150    }
     151
     152    if (sc->cert_pgp)
     153    {
     154        gnutls_pcert_deinit(&sc->cert_pgp[0]);
     155        sc->cert_pgp = NULL;
     156        gnutls_openpgp_crt_deinit(sc->cert_crt_pgp[0]);
     157        sc->cert_crt_pgp = NULL;
     158    }
     159
     160    if (sc->privkey_pgp)
     161    {
     162        gnutls_privkey_deinit(sc->privkey_pgp);
     163        sc->privkey_pgp = NULL;
     164#if GNUTLS_VERSION_NUMBER < 0x030312
     165        gnutls_openpgp_privkey_deinit(sc->privkey_pgp_internal);
     166        sc->privkey_pgp_internal = NULL;
     167#endif
     168    }
     169
     170    if (sc->pgp_list)
     171    {
     172        gnutls_openpgp_keyring_deinit(sc->pgp_list);
     173        sc->pgp_list = NULL;
     174    }
     175
     176    if (sc->priorities)
     177    {
     178        gnutls_priority_deinit(sc->priorities);
     179        sc->priorities = NULL;
     180    }
     181
     182    return APR_SUCCESS;
     183}
     184
     185int mgs_load_files(apr_pool_t *pconf, apr_pool_t *ptemp, server_rec *s)
    96186{
    97187    apr_pool_t *spool;
     
    100190    int ret;
    101191    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;
     192        (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     193                                                 &gnutls_module);
     194
     195    apr_pool_create(&spool, ptemp);
     196
     197    /* Cleanup function for the GnuTLS structures allocated below */
     198    apr_pool_cleanup_register(pconf, sc, mgs_pool_free_credentials,
     199                              apr_pool_cleanup_null);
     200
     201    if (sc->certs == NULL)
     202    {
     203        ret = gnutls_certificate_allocate_credentials(&sc->certs);
     204        if (ret < 0) {
     205            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     206                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     207                         gnutls_strerror(ret));
     208            ret = -1;
     209            goto cleanup;
     210        }
     211    }
     212
     213    if (sc->anon_creds == NULL)
     214    {
     215        ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
     216        if (ret < 0) {
     217            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     218                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     219                         gnutls_strerror(ret));
     220            ret = -1;
     221            goto cleanup;
     222        }
    131223    }
    132224
    133225    /* Load SRP parameters */
    134226#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         }
     227    if (sc->srp_creds == NULL)
     228    {
     229        ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
     230        if (ret < 0) {
     231            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     232                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
     233                         gnutls_strerror(ret));
     234            ret = -1;
     235            goto cleanup;
     236        }
     237    }
     238
     239    if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL)
     240    {
     241        ret = gnutls_srp_set_server_credentials_file
     242            (sc->srp_creds, sc->srp_tpasswd_file,
     243             sc->srp_tpasswd_conf_file);
     244
     245        if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
     246            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     247                         "GnuTLS: Host '%s:%d' is missing a "
     248                         "SRP password or conf File!",
     249                         s->server_hostname, s->port);
     250            ret = -1;
     251            goto cleanup;
     252        }
    158253    }
    159254#endif
    160255
    161     ret = gnutls_dh_params_init(&sc->dh_params);
    162     if (ret < 0) {
    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         }
     256    if (sc->dh_params == NULL)
     257    {
     258        ret = gnutls_dh_params_init(&sc->dh_params);
     259        if (ret < 0) {
     260            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     261                         "GnuTLS: Failed to initialize"
     262                         ": (%d) %s", ret, gnutls_strerror(ret));
     263            ret = -1;
     264            goto cleanup;
     265        }
     266
     267        /* Load DH parameters */
     268        if (sc->dh_file)
     269        {
     270            if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
     271                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     272                             "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
     273                ret = -1;
     274                goto cleanup;
     275            }
     276
     277            ret =
     278                gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
     279                                              GNUTLS_X509_FMT_PEM);
     280            if (ret < 0) {
     281                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     282                             "GnuTLS: Failed to Import "
     283                             "DH params '%s': (%d) %s", sc->dh_file, ret,
     284                             gnutls_strerror(ret));
     285                ret = -1;
     286                goto cleanup;
     287            }
     288        } else {
     289            gnutls_datum_t pdata = {
     290                (void *) static_dh_params,
     291                sizeof(static_dh_params)
     292            };
     293
     294            ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
     295            if (ret < 0) {
     296                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     297                             "GnuTLS: Unable to generate or load DH Params: (%d) %s",
     298                             ret, gnutls_strerror(ret));
     299                ret = -1;
     300                goto cleanup;
     301            }
     302        }
     303    }
     304
     305    if (sc->x509_cert_file != NULL && sc->certs_x509_crt_chain == NULL)
     306    {
     307        sc->certs_x509_chain =
     308            apr_pcalloc(pconf,
     309                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
     310        sc->certs_x509_crt_chain =
     311            apr_pcalloc(pconf,
     312                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
     313        unsigned int chain_num = MAX_CHAIN_SIZE;
     314        unsigned format = GNUTLS_X509_FMT_PEM;
     315
     316        /* Load X.509 certificate */
     317        if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
     318            gnutls_pkcs11_obj_t obj;
     319
     320            file = sc->x509_cert_file;
     321
     322            ret = gnutls_pkcs11_obj_init(&obj);
     323            if (ret < 0) {
     324                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     325                             "GnuTLS: Error Initializing PKCS #11 object");
     326                ret = -1;
     327                goto cleanup;
     328            }
     329
     330            gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
     331
     332            ret = gnutls_pkcs11_obj_import_url(obj, file,
     333                                               GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
     334            if (ret < 0) {
     335                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     336                             "GnuTLS: Error Importing PKCS #11 object: "
     337                             "'%s': %s",
     338                             file, gnutls_strerror(ret));
     339                ret = -1;
     340                goto cleanup;
     341            }
     342
     343            format = GNUTLS_X509_FMT_DER;
     344            ret = gnutls_pkcs11_obj_export2(obj, &data);
     345            if (ret < 0) {
     346                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     347                             "GnuTLS: Error Exporting a PKCS #11 object: "
     348                             "'%s': %s",
     349                             file, gnutls_strerror(ret));
     350                ret = -1;
     351                goto cleanup;
     352            }
     353
     354            gnutls_pkcs11_obj_deinit(obj);
     355        } else {
     356            file = ap_server_root_relative(spool, sc->x509_cert_file);
     357
     358            ret = gnutls_load_file(file, &data);
     359            if (ret < 0) {
     360                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     361                             "GnuTLS: Error Reading Certificate '%s': %s",
     362                             file, gnutls_strerror(ret));
     363                ret = -1;
     364                goto cleanup;
     365            }
     366        }
     367
     368        ret = gnutls_x509_crt_list_import(sc->certs_x509_crt_chain,
     369                                          &chain_num, &data, format,
     370                                          GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
     371        gnutls_free(data.data);
     372        sc->certs_x509_chain_num = chain_num;
     373
     374        if (ret < 0) {
     375            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     376                         "GnuTLS: Failed to Import Certificate Chain "
     377                         "'%s': (%d) %s",
     378                         file, ret, gnutls_strerror(ret));
     379            ret = -1;
     380            goto cleanup;
     381        }
     382
     383        for (unsigned int i = 0; i < chain_num; i++)
     384        {
     385            ret =
     386                gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
     387                                         sc->certs_x509_crt_chain[i], 0);
     388            if (ret < 0) {
     389                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     390                             "GnuTLS: Failed to Import pCertificate "
     391                             "'%s': (%d) %s",
     392                             file, ret, gnutls_strerror(ret));
     393                ret = -1;
     394                goto cleanup;
     395            }
     396        }
     397        sc->certs_x509_chain_num = chain_num;
     398    }
     399
     400    if (sc->x509_key_file && sc->privkey_x509 == NULL)
     401    {
     402        ret = gnutls_privkey_init(&sc->privkey_x509);
     403        if (ret < 0) {
     404            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     405                         "GnuTLS: Failed to initialize: (%d) %s", ret,
     406                         gnutls_strerror(ret));
     407            ret = -1;
     408            goto cleanup;
     409        }
     410
     411        if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
     412            file = sc->x509_key_file;
     413
     414            gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
     415                                            sc);
     416
     417            ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
     418
     419            if (ret < 0) {
     420                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     421                             "GnuTLS: Failed to Import Private Key URL "
     422                             "'%s': (%d) %s",
     423                             file, ret, gnutls_strerror(ret));
     424                ret = -1;
     425                goto cleanup;
     426            }
     427        } else {
     428            file = ap_server_root_relative(spool, sc->x509_key_file);
     429
     430            if (load_datum_from_file(spool, file, &data) != 0) {
     431                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     432                             "GnuTLS: Error Reading Private Key '%s'",
     433                             file);
     434                ret = -1;
     435                goto cleanup;
     436            }
     437
     438            ret =
     439                gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
     440                                               GNUTLS_X509_FMT_PEM, sc->pin,
     441                                               0);
     442
     443            if (ret < 0) {
     444                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     445                             "GnuTLS: Failed to Import Private Key "
     446                             "'%s': (%d) %s",
     447                             file, ret, gnutls_strerror(ret));
     448                ret = -1;
     449                goto cleanup;
     450            }
     451        }
    338452    }
    339453
    340454    /* 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         }
     455    if (sc->x509_ca_file)
     456    {
     457        if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
     458            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     459                         "GnuTLS: Error Reading " "Client CA File '%s'",
     460                         sc->x509_ca_file);
     461            ret = -1;
     462            goto cleanup;
     463        }
     464
     465        ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
     466                                           &data, GNUTLS_X509_FMT_PEM, 0);
     467        if (ret < 0) {
     468            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     469                         "GnuTLS: Failed to load "
     470                         "Client CA File '%s': (%d) %s", sc->x509_ca_file,
     471                         ret, gnutls_strerror(ret));
     472            ret = -1;
     473            goto cleanup;
     474        }
     475    }
     476
     477    if (sc->pgp_cert_file && sc->cert_pgp == NULL)
     478    {
     479        sc->cert_pgp = apr_pcalloc(pconf, sizeof(sc->cert_pgp[0]));
     480        sc->cert_crt_pgp = apr_pcalloc(pconf, sizeof(sc->cert_crt_pgp[0]));
     481
     482        if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
     483            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     484                         "GnuTLS: Error Reading " "Certificate '%s'",
     485                         sc->pgp_cert_file);
     486            ret = -1;
     487            goto cleanup;
     488        }
     489
     490        ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
     491        if (ret < 0) {
     492            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     493                         "GnuTLS: Failed to Init "
     494                         "PGP Certificate: (%d) %s", ret,
     495                         gnutls_strerror(ret));
     496            ret = -1;
     497            goto cleanup;
     498        }
     499
     500        ret = gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
     501                                        GNUTLS_OPENPGP_FMT_BASE64);
     502        if (ret < 0) {
     503            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     504                         "GnuTLS: Failed to Import "
     505                         "PGP Certificate: (%d) %s", ret,
     506                         gnutls_strerror(ret));
     507            ret = -1;
     508            goto cleanup;
     509        }
     510
     511        ret = gnutls_pcert_import_openpgp(sc->cert_pgp,
     512                                          sc->cert_crt_pgp[0], 0);
     513        if (ret < 0) {
     514            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     515                         "GnuTLS: Failed to Import "
     516                         "PGP pCertificate: (%d) %s", ret,
     517                         gnutls_strerror(ret));
     518            ret = -1;
     519            goto cleanup;
     520        }
    404521    }
    405522
    406523    /* 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         }
     524    if (sc->pgp_key_file && sc->privkey_pgp == NULL)
     525    {
     526        if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
     527            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     528                         "GnuTLS: Error Reading " "Private Key '%s'",
     529                         sc->pgp_key_file);
     530            ret = -1;
     531            goto cleanup;
     532        }
     533
     534        ret = gnutls_privkey_init(&sc->privkey_pgp);
     535        if (ret < 0) {
     536            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     537                         "GnuTLS: Failed to initialize"
     538                         ": (%d) %s", ret, gnutls_strerror(ret));
     539            ret = -1;
     540            goto cleanup;
     541        }
    424542
    425543#if GNUTLS_VERSION_NUMBER < 0x030312
     
    433551         * gnutls_privkey_import_openpgp. */
    434552        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         }
     553        if (ret != 0) {
     554            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     555                        "GnuTLS: Failed to initialize "
     556                        "PGP Private Key '%s': (%d) %s",
     557                        sc->pgp_key_file, ret, gnutls_strerror(ret));
     558            ret = -1;
     559            goto cleanup;
     560        }
    443561
    444562        ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data,
    445563                                            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         }
     564        if (ret != 0) {
     565            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     566                        "GnuTLS: Failed to Import "
     567                        "PGP Private Key '%s': (%d) %s",
     568                        sc->pgp_key_file, ret, gnutls_strerror(ret));
     569            ret = -1;
     570            goto cleanup;
     571        }
    454572
    455573        ret = gnutls_privkey_import_openpgp(sc->privkey_pgp,
     
    461579                         "to gnutls_privkey_t structure: (%d) %s",
    462580                         sc->pgp_key_file, ret, gnutls_strerror(ret));
    463             ret = -1;
    464             goto cleanup;
    465         }
     581            ret = -1;
     582            goto cleanup;
     583        }
    466584#else
    467585        ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
    468586                                                GNUTLS_OPENPGP_FMT_BASE64,
    469587                                                NULL, NULL);
    470         if (ret != 0)
     588        if (ret != 0)
    471589        {
    472590            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     
    474592                         "PGP Private Key '%s': (%d) %s",
    475593                         sc->pgp_key_file, ret, gnutls_strerror(ret));
    476             ret = -1;
    477             goto cleanup;
    478         }
     594            ret = -1;
     595            goto cleanup;
     596        }
    479597#endif
    480598    }
    481599
    482600    /* 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) {
     601    if (sc->pgp_ring_file && sc->pgp_list == NULL)
     602    {
     603        if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
     604            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     605                         "GnuTLS: Error Reading " "Keyring File '%s'",
     606                         sc->pgp_ring_file);
     607            ret = -1;
     608            goto cleanup;
     609        }
     610
     611        ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
     612        if (ret < 0) {
     613            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     614                         "GnuTLS: Failed to initialize"
     615                         "keyring: (%d) %s", ret, gnutls_strerror(ret));
     616            ret = -1;
     617            goto cleanup;
     618        }
     619
     620        ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
     621                                            GNUTLS_OPENPGP_FMT_BASE64);
     622        if (ret < 0) {
     623            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     624                         "GnuTLS: Failed to load "
     625                         "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
     626                         ret, gnutls_strerror(ret));
     627            ret = -1;
     628            goto cleanup;
     629        }
     630    }
     631
     632    if (sc->priorities_str && sc->priorities == NULL)
     633    {
    514634        const char *err;
    515635        ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err);
    516636
    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         }
     637        if (ret < 0) {
     638            if (ret == GNUTLS_E_INVALID_REQUEST) {
     639                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     640                             "GnuTLS: Syntax error parsing priorities string at: %s",
     641                             err);
     642            } else {
     643                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     644                             "GnuTLS: error parsing priorities string");
     645
     646            }
     647            ret = -1;
     648            goto cleanup;
     649        }
    530650    }
    531651
    532652    ret = 0;
    533   cleanup:
     653 cleanup:
    534654    apr_pool_destroy(spool);
    535655
     
    727847}
    728848
    729 const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy __attribute__((unused)),
    730         const char *arg) {
    731     int argint;
    732     const char *err;
    733     mgs_srvconf_rec *sc =
    734         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    735                                                  module_config,
    736                                                  &gnutls_module);
    737 
    738     if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    739         return err;
    740     }
    741 
    742     argint = atoi(arg);
    743 
    744     if (argint < 0) {
    745         return "GnuTLSCacheTimeout: Invalid argument";
    746     } else if (argint == 0) {
    747         sc->cache_timeout = 0;
    748     } else {
    749         sc->cache_timeout = apr_time_from_sec(argint);
    750     }
     849const char *mgs_set_timeout(cmd_parms * parms,
     850                            void *dummy __attribute__((unused)),
     851                            const char *arg)
     852{
     853    apr_int64_t argint = apr_atoi64(arg);
     854    /* timeouts cannot be negative */
     855    if (argint < 0)
     856        return apr_psprintf(parms->pool, "%s: Invalid argument",
     857                            parms->directive->directive);
     858
     859    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     860        ap_get_module_config(parms->server->module_config, &gnutls_module);
     861
     862    if (!apr_strnatcasecmp(parms->directive->directive, "GnuTLSCacheTimeout"))
     863    {
     864        const char *err;
     865        if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY)))
     866            return err;
     867        sc->cache_timeout = apr_time_from_sec(argint);
     868    }
     869    else if (!apr_strnatcasecmp(parms->directive->directive,
     870                                "GnuTLSOCSPCacheTimeout"))
     871        sc->ocsp_cache_time = apr_time_from_sec(argint);
     872    else if (!apr_strnatcasecmp(parms->directive->directive,
     873                                "GnuTLSOCSPFailureTimeout"))
     874        sc->ocsp_failure_timeout = apr_time_from_sec(argint);
     875    else if (!apr_strnatcasecmp(parms->directive->directive,
     876                                "GnuTLSOCSPSocketTimeout"))
     877        sc->ocsp_socket_timeout = apr_time_from_sec(argint);
     878    else
     879        /* Can't happen unless there's a serious bug in mod_gnutls or Apache */
     880        return apr_psprintf(parms->pool,
     881                            "mod_gnutls: %s called for invalid option '%s'",
     882                            __func__, parms->directive->directive);
    751883
    752884    return NULL;
     
    9501082
    9511083    sc->privkey_x509 = NULL;
    952     sc->privkey_pgp = NULL;
     1084    sc->anon_creds = NULL;
     1085#ifdef ENABLE_SRP
     1086    sc->srp_creds = NULL;
     1087#endif
     1088    sc->certs = NULL;
     1089    sc->certs_x509_chain = NULL;
     1090    sc->certs_x509_crt_chain = NULL;
    9531091    sc->certs_x509_chain_num = 0;
    9541092    sc->p11_modules = NULL;
    9551093    sc->pin = NULL;
     1094
     1095    sc->cert_pgp = NULL;
     1096    sc->cert_crt_pgp = NULL;
     1097    sc->privkey_pgp = NULL;
     1098#if GNUTLS_VERSION_NUMBER < 0x030312
     1099    sc->privkey_pgp_internal = NULL;
     1100#endif
     1101    sc->pgp_list = NULL;
     1102
    9561103    sc->priorities_str = NULL;
    957     sc->cache_timeout = -1;     /* -1 means "unset" */
     1104    sc->cache_timeout = MGS_TIMEOUT_UNSET;
    9581105    sc->cache_type = mgs_cache_unset;
    9591106    sc->cache_config = NULL;
     1107    sc->cache = NULL;
    9601108    sc->tickets = GNUTLS_ENABLED_UNSET;
    9611109    sc->priorities = NULL;
    9621110    sc->dh_params = NULL;
     1111    sc->ca_list = NULL;
     1112    sc->ca_list_size = 0;
    9631113    sc->proxy_enabled = GNUTLS_ENABLED_UNSET;
    9641114    sc->export_certificates_size = -1;
     
    9701120    sc->proxy_x509_crl_file = NULL;
    9711121    sc->proxy_priorities_str = NULL;
     1122    sc->proxy_x509_creds = NULL;
     1123    sc->anon_client_creds = NULL;
    9721124    sc->proxy_priorities = NULL;
     1125    sc->proxy_x509_tl = NULL;
     1126
     1127    sc->ocsp_staple = GNUTLS_ENABLED_UNSET;
     1128    sc->ocsp_check_nonce = GNUTLS_ENABLED_UNSET;
     1129    sc->ocsp_response_file = NULL;
     1130    sc->ocsp_mutex = NULL;
     1131    sc->ocsp_cache_time = MGS_TIMEOUT_UNSET;
     1132    sc->ocsp_failure_timeout = MGS_TIMEOUT_UNSET;
     1133    sc->ocsp_socket_timeout = MGS_TIMEOUT_UNSET;
    9731134
    9741135/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
     
    10281189    gnutls_srvconf_merge(proxy_priorities, NULL);
    10291190
    1030     /* FIXME: the following items are pre-allocated, and should be
    1031      * properly disposed of before assigning in order to avoid leaks;
    1032      * so at the moment, we can't actually have them in the config.
    1033      * what happens during de-allocation? */
    1034     /* TODO: mgs_load_files takes care of most of these now, verify
    1035      * and clean up the following lines */
     1191    gnutls_srvconf_merge(ocsp_staple, GNUTLS_ENABLED_UNSET);
     1192    gnutls_srvconf_merge(ocsp_check_nonce, GNUTLS_ENABLED_UNSET);
     1193    gnutls_srvconf_assign(ocsp_response_file);
     1194    gnutls_srvconf_merge(ocsp_cache_time, MGS_TIMEOUT_UNSET);
     1195    gnutls_srvconf_merge(ocsp_failure_timeout, MGS_TIMEOUT_UNSET);
     1196    gnutls_srvconf_merge(ocsp_socket_timeout, MGS_TIMEOUT_UNSET);
     1197
    10361198    gnutls_srvconf_assign(ca_list);
    10371199    gnutls_srvconf_assign(ca_list_size);
  • src/gnutls_hooks.c

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2008, 2014 Nikos Mavrogiannopoulos
     
    1717 *  See the License for the specific language governing permissions and
    1818 *  limitations under the License.
    19  *
    2019 */
    2120
    2221#include "mod_gnutls.h"
     22#include "gnutls_cache.h"
     23#include "gnutls_ocsp.h"
    2324#include "http_vhost.h"
    2425#include "ap_mpm.h"
    2526#include "mod_status.h"
     27#include <util_mutex.h>
     28#include <apr_escape.h>
    2629
    2730#ifdef ENABLE_MSVA
     
    3336#endif
    3437
    35 #if !USING_2_1_RECENT
    36 extern server_rec *ap_server_conf;
    37 #endif
    38 
    3938#if MOD_GNUTLS_DEBUG
    4039static apr_file_t *debug_log_fp;
     
    4443    ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "")
    4544
     45/** Key to encrypt session tickets. Must be kept secret. This key is
     46 * generated in the `pre_config` hook and thus constant across
     47 * forks. The problem with this approach is that it does not support
     48 * regular key rotation. */
    4649static gnutls_datum_t session_ticket_key = {NULL, 0};
    4750
     
    5457static const char* mgs_x509_construct_uid(request_rec * pool, gnutls_x509_crt_t cert);
    5558#endif
    56 static int load_proxy_x509_credentials(server_rec *s);
     59static int load_proxy_x509_credentials(apr_pool_t *pconf, apr_pool_t *ptemp, server_rec *s)
     60    __attribute__((nonnull));
    5761
    5862/* Pool Cleanup Function */
    59 apr_status_t mgs_cleanup_pre_config(void *data __attribute__((unused))) {
    60         /* Free all session data */
     63apr_status_t mgs_cleanup_pre_config(void *data __attribute__((unused)))
     64{
     65    /* Free session ticket master key */
     66#if GNUTLS_VERSION_NUMBER >= 0x030400
     67    gnutls_memset(session_ticket_key.data, 0, session_ticket_key.size);
     68#endif
    6169    gnutls_free(session_ticket_key.data);
    6270    session_ticket_key.data = NULL;
     
    126134    AP_OPTIONAL_HOOK(status_hook, mgs_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
    127135
    128         /* Register a pool clean-up function */
     136    ap_mutex_register(pconf, MGS_CACHE_MUTEX_NAME, NULL, APR_LOCK_DEFAULT, 0);
     137    ap_mutex_register(pconf, MGS_OCSP_MUTEX_NAME, NULL, APR_LOCK_DEFAULT, 0);
     138
     139    /* Register a pool clean-up function */
    129140    apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, apr_pool_cleanup_null);
    130141
     
    156167    /* Set Anon credentials */
    157168    gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
     169
     170    if (ctxt->sc->ocsp_staple)
     171    {
     172        gnutls_certificate_set_ocsp_status_request_function(ctxt->sc->certs,
     173                                                            mgs_get_ocsp_response,
     174                                                            ctxt);
     175    }
    158176
    159177#ifdef ENABLE_SRP
     
    295313}
    296314
    297 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) {
    298 
     315/**
     316 * Post config hook.
     317 *
     318 * Must return OK or DECLINED on success, something else on
     319 * error. These codes are defined in Apache httpd.h along with the
     320 * HTTP status codes, so I'm going to use HTTP error codes both for
     321 * fun (and to avoid conflicts).
     322 */
     323int mgs_hook_post_config(apr_pool_t *pconf,
     324                         apr_pool_t *plog __attribute__((unused)),
     325                         apr_pool_t *ptemp,
     326                         server_rec *base_server)
     327{
    299328    int rv;
    300329    server_rec *s;
     
    316345
    317346
    318     rv = mgs_cache_post_config(p, s, sc_base);
    319     if (rv != 0) {
     347    rv = mgs_cache_post_config(pconf, s, sc_base);
     348    if (rv != APR_SUCCESS)
     349    {
    320350        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    321                 "GnuTLS: Post Config for GnuTLSCache Failed."
    322                 " Shutting Down.");
    323         exit(-1);
     351                     "Post config for cache failed.");
     352        return HTTP_INSUFFICIENT_STORAGE;
     353    }
     354
     355    if (sc_base->ocsp_mutex == NULL)
     356    {
     357        rv = ap_global_mutex_create(&sc_base->ocsp_mutex, NULL,
     358                                    MGS_OCSP_MUTEX_NAME, NULL,
     359                                    base_server, pconf, 0);
     360        if (rv != APR_SUCCESS)
     361        {
     362            ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, base_server,
     363                         "Failed to create mutex '" MGS_OCSP_MUTEX_NAME
     364                         "'.");
     365            return HTTP_INTERNAL_SERVER_ERROR;
     366        }
    324367    }
    325368
     
    352395    }
    353396
    354     for (s = base_server; s; s = s->next) {
     397    for (s = base_server; s; s = s->next)
     398    {
    355399        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    356400        sc->cache_type = sc_base->cache_type;
    357401        sc->cache_config = sc_base->cache_config;
    358402        sc->cache_timeout = sc_base->cache_timeout;
    359 
    360         rv = mgs_load_files(p, s);
     403        sc->cache = sc_base->cache;
     404
     405        rv = mgs_load_files(pconf, ptemp, s);
    361406        if (rv != 0) {
    362407            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    363408                "GnuTLS: Loading required files failed."
    364409                " Shutting Down.");
    365             exit(-1);
     410            return HTTP_NOT_FOUND;
     411        }
     412
     413        if (sc->ocsp_staple == GNUTLS_ENABLED_UNSET)
     414            sc->ocsp_staple = GNUTLS_ENABLED_FALSE;
     415
     416        sc->ocsp_mutex = sc_base->ocsp_mutex;
     417        /* init OCSP configuration if OCSP is enabled for this host */
     418        if (sc->ocsp_staple)
     419        {
     420            rv = mgs_ocsp_post_config_server(pconf, ptemp, s);
     421            if (rv != OK && rv != DECLINED)
     422                return rv;
    366423        }
    367424
     
    370427            sc->enabled = GNUTLS_ENABLED_FALSE;
    371428        if (sc->tickets == GNUTLS_ENABLED_UNSET)
    372             sc->tickets = GNUTLS_ENABLED_TRUE;
     429            sc->tickets = GNUTLS_ENABLED_FALSE;
    373430        if (sc->export_certificates_size < 0)
    374431            sc->export_certificates_size = 0;
     
    383440                    "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!",
    384441                    s->server_hostname, s->port);
    385             exit(-1);
     442            return HTTP_NOT_ACCEPTABLE;
    386443        }
    387444
     
    415472                                                "GnuTLS: Host '%s:%d' is missing a Certificate File!",
    416473                                                s->server_hostname, s->port);
    417             exit(-1);
     474            return HTTP_UNAUTHORIZED;
    418475        }
    419476        if (sc->enabled == GNUTLS_ENABLED_TRUE &&
    420477            ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||
    421              (sc->cert_crt_pgp[0] != NULL && sc->privkey_pgp == NULL))) {
     478             (sc->cert_crt_pgp != NULL && sc->privkey_pgp == NULL)))
     479        {
    422480                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    423481                                                "GnuTLS: Host '%s:%d' is missing a Private Key File!",
    424482                                                s->server_hostname, s->port);
    425             exit(-1);
     483            return HTTP_UNAUTHORIZED;
    426484        }
    427485
     
    429487            rv = -1;
    430488            if (sc->certs_x509_chain_num > 0) {
    431                 rv = read_crt_cn(s, p, sc->certs_x509_crt_chain[0], &sc->cert_cn);
     489                rv = read_crt_cn(s, pconf, sc->certs_x509_crt_chain[0], &sc->cert_cn);
    432490            }
    433491            if (rv < 0 && sc->cert_pgp != NULL) {
    434                 rv = read_pgpcrt_cn(s, p, sc->cert_crt_pgp[0], &sc->cert_cn);
     492                rv = read_pgpcrt_cn(s, pconf, sc->cert_crt_pgp[0], &sc->cert_cn);
    435493                        }
    436494
     
    446504        if (sc->enabled == GNUTLS_ENABLED_TRUE
    447505            && sc->proxy_enabled == GNUTLS_ENABLED_TRUE
    448             && load_proxy_x509_credentials(s) != APR_SUCCESS)
     506            && load_proxy_x509_credentials(pconf, ptemp, s) != APR_SUCCESS)
    449507        {
    450508            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     
    452510                         "'%s:%d' failed, exiting!",
    453511                         __func__, s->server_hostname, s->port);
    454             exit(-1);
    455         }
    456     }
    457 
    458 
    459     ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
     512            return HTTP_PROXY_AUTHENTICATION_REQUIRED;
     513        }
     514    }
     515
     516
     517    ap_add_version_component(pconf, "mod_gnutls/" MOD_GNUTLS_VERSION);
    460518
    461519    {
    462520        const char* libvers = gnutls_check_version(NULL);
    463521        char* gnutls_version = NULL;
    464         if(libvers && (gnutls_version = apr_psprintf(p, "GnuTLS/%s", libvers))) {
    465             ap_add_version_component(p, gnutls_version);
     522        if(libvers && (gnutls_version = apr_psprintf(pconf, "GnuTLS/%s", libvers))) {
     523            ap_add_version_component(pconf, gnutls_version);
    466524        } else {
    467525            // In case we could not create the above string go for the static version instead
    468             ap_add_version_component(p, "GnuTLS/" GNUTLS_VERSION "-static");
     526            ap_add_version_component(pconf, "GnuTLS/" GNUTLS_VERSION "-static");
    469527        }
    470528    }
     
    473531}
    474532
    475 void mgs_hook_child_init(apr_pool_t * p, server_rec *s) {
     533void mgs_hook_child_init(apr_pool_t *p, server_rec *s)
     534{
    476535    apr_status_t rv = APR_SUCCESS;
    477     mgs_srvconf_rec *sc =
    478         (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
     536    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     537        ap_get_module_config(s->module_config, &gnutls_module);
    479538
    480539    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     540
    481541    /* if we use PKCS #11 reinitialize it */
    482 
    483542    if (mgs_pkcs11_reinit(s) < 0) {
    484543            ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     
    494553        }
    495554    }
     555
     556    /* reinit OCSP mutex */
     557    const char *lockfile = apr_global_mutex_lockfile(sc->ocsp_mutex);
     558    rv = apr_global_mutex_child_init(&sc->ocsp_mutex, lockfile, p);
     559    if (rv != APR_SUCCESS)
     560        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
     561                     "Failed to reinit mutex '" MGS_OCSP_MUTEX_NAME "'.");
     562
    496563    /* Block SIGPIPE Signals */
    497564    rv = apr_signal_block(SIGPIPE);
     
    541608#define MAX_HOST_LEN 255
    542609
    543 #if USING_2_1_RECENT
    544 
    545610typedef struct {
    546611    mgs_handle_t *ctxt;
     
    554619 * @param x vhost callback record
    555620 * @param s server record
     621 * @param tsc mod_gnutls server data for `s`
     622 *
    556623 * @return true if a match, false otherwise
    557624 *
    558625 */
    559 int check_server_aliases(vhost_cb_rec *x, server_rec * s, mgs_srvconf_rec *tsc) {
     626int check_server_aliases(vhost_cb_rec *x, server_rec * s, mgs_srvconf_rec *tsc)
     627{
    560628        apr_array_header_t *names;
    561629        int rv = 0;
     
    600668}
    601669
    602 static int vhost_cb(void *baton, conn_rec * conn __attribute__((unused)), server_rec * s) {
     670static int vhost_cb(void *baton, conn_rec *conn, server_rec * s)
     671{
    603672    mgs_srvconf_rec *tsc;
    604673    vhost_cb_rec *x = baton;
     
    618687        ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_crt_chain[0], s->server_hostname);
    619688        if (0 == ret)
    620             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
    621                          "GnuTLS: the certificate doesn't match requested hostname "
    622                          "'%s'", s->server_hostname);
     689            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn,
     690                          "GnuTLS: the certificate doesn't match requested "
     691                          "hostname '%s'", s->server_hostname);
    623692    } else {
    624         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    625                      "GnuTLS: SNI request for '%s' but no X.509 certs available at all",
    626                      s->server_hostname);
     693        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, conn,
     694                      "GnuTLS: SNI request for '%s' but no X.509 certs "
     695                      "available at all",
     696                      s->server_hostname);
    627697    }
    628698        return check_server_aliases(x, s, tsc);
    629699}
    630 #endif
    631700
    632701mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
     
    637706    char sni_name[MAX_HOST_LEN];
    638707    mgs_handle_t *ctxt;
    639 #if USING_2_1_RECENT
    640708    vhost_cb_rec cbx;
    641 #else
    642     server_rec *s;
    643     mgs_srvconf_rec *tsc;
    644 #endif
    645709
    646710    if (session == NULL)
     
    658722
    659723    if (sni_type != GNUTLS_NAME_DNS) {
    660         ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
    661                 ctxt->c->base_server,
    662                 "GnuTLS: Unknown type '%d' for SNI: "
    663                 "'%s'", sni_type, sni_name);
     724        ap_log_cerror(APLOG_MARK, APLOG_CRIT, 0, ctxt->c,
     725                      "GnuTLS: Unknown type '%d' for SNI: '%s'",
     726                      sni_type, sni_name);
    664727        return NULL;
    665728    }
     
    669732     * for this IP/Port combo.  Trust that the core did the 'right' thing.
    670733     */
    671 #if USING_2_1_RECENT
    672734    cbx.ctxt = ctxt;
    673735    cbx.sc = NULL;
     
    678740        return cbx.sc;
    679741    }
    680 #else
    681     for (s = ap_server_conf; s; s = s->next) {
    682 
    683         tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    684                                                        &gnutls_module);
    685 
    686         if (tsc->enabled != GNUTLS_ENABLED_TRUE) { continue; }
    687 
    688         if(check_server_aliases(x, s, tsc)) {
    689             return tsc;
    690         }
    691     }
    692 #endif
    693742    return NULL;
    694743}
     
    791840                          gnutls_strerror(err), err);
    792841        /* Initialize Session Tickets */
    793         if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
     842        if (session_ticket_key.data != NULL &&
     843            ctxt->sc->tickets == GNUTLS_ENABLED_TRUE)
    794844        {
    795845            err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
     
    876926int mgs_hook_fixups(request_rec * r) {
    877927    unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
    878     char buf[AP_IOBUFSIZE];
    879928    const char *tmp;
    880929    size_t len;
     
    946995    len = sizeof (sbuf);
    947996    gnutls_session_get_id(ctxt->session, sbuf, &len);
    948     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof (buf));
    949     apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
     997    apr_table_setn(env, "SSL_SESSION_ID",
     998                   apr_pescape_hex(r->pool, sbuf, len, 0));
    950999
    9511000    if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
     
    10821131    len = sizeof (sbuf);
    10831132    gnutls_x509_crt_get_serial(cert, sbuf, &len);
    1084     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof (buf));
    1085     apr_table_setn(env, MGS_SIDE("_M_SERIAL"), apr_pstrdup(r->pool, tmp));
     1133    apr_table_setn(env, MGS_SIDE("_M_SERIAL"),
     1134                   apr_pescape_hex(r->pool, sbuf, len, 0));
    10861135
    10871136    ret = gnutls_x509_crt_get_version(cert);
     
    11991248    len = sizeof (sbuf);
    12001249    gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);
    1201     tmp = mgs_session_id2sz(sbuf, len, buf, sizeof (buf));
    1202     apr_table_setn(env, MGS_SIDE("_FINGERPRINT"), apr_pstrdup(r->pool, tmp));
     1250    apr_table_setn(env, MGS_SIDE("_FINGERPRINT"),
     1251                   apr_pescape_hex(r->pool, sbuf, len, 0));
    12031252
    12041253    ret = gnutls_openpgp_crt_get_version(cert);
     
    17611810    }
    17621811
    1763     gnutls_datum_t * out = gnutls_malloc(sizeof(gnutls_datum_t));
    1764     /* GNUTLS_CRT_X509: ATM, only X509 is supported for proxy certs
    1765      * 0: according to function API, the last argument should be 0 */
    1766     err = gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509,
    1767                                                        out, 0);
    1768     if (err != GNUTLS_E_SUCCESS)
     1812    if (status == 0)
    17691813        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    1770                       "%s: server verify print failed: %s (%d)",
    1771                       __func__, gnutls_strerror(err), err);
     1814                      "%s: server certificate is trusted.",
     1815                      __func__);
    17721816    else
    17731817    {
    1774         /* If the certificate is trusted, logging the result is just
    1775          * nice for debugging. But if the back end server provided an
    1776          * untrusted certificate, warn! */
    1777         int level = (status == 0 ? APLOG_DEBUG : APLOG_WARNING);
    1778         ap_log_cerror(APLOG_MARK, level, 0, ctxt->c,
    1779                       "%s: server certificate verify result: %s",
    1780                       __func__, out->data);
    1781     }
    1782 
    1783     gnutls_free(out);
     1818        gnutls_datum_t out;
     1819        /* GNUTLS_CRT_X509: ATM, only X509 is supported for proxy
     1820         * certs 0: according to function API, the last argument
     1821         * should be 0 */
     1822        err = gnutls_certificate_verification_status_print(status,
     1823                                                           GNUTLS_CRT_X509,
     1824                                                           &out, 0);
     1825        if (err != GNUTLS_E_SUCCESS)
     1826            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, ctxt->c,
     1827                          "%s: server verify print failed: %s (%d)",
     1828                          __func__, gnutls_strerror(err), err);
     1829        else
     1830            ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, ctxt->c,
     1831                          "%s: %s",
     1832                          __func__, out.data);
     1833        gnutls_free(out.data);
     1834    }
     1835
    17841836    return status;
    17851837}
     
    17871839
    17881840
    1789 static apr_status_t load_proxy_x509_credentials(server_rec *s)
     1841static apr_status_t cleanup_proxy_x509_credentials(void *arg)
     1842{
     1843    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) arg;
     1844
     1845    if (sc->proxy_x509_creds)
     1846    {
     1847        /* This implicitly releases the associated trust list
     1848         * sc->proxy_x509_tl, too. */
     1849        gnutls_certificate_free_credentials(sc->proxy_x509_creds);
     1850        sc->proxy_x509_creds = NULL;
     1851        sc->proxy_x509_tl = NULL;
     1852    }
     1853
     1854    if (sc->anon_client_creds)
     1855    {
     1856        gnutls_anon_free_client_credentials(sc->anon_client_creds);
     1857        sc->anon_client_creds = NULL;
     1858    }
     1859
     1860    if (sc->proxy_priorities)
     1861    {
     1862        gnutls_priority_deinit(sc->proxy_priorities);
     1863        sc->proxy_priorities = NULL;
     1864    }
     1865
     1866    return APR_SUCCESS;
     1867}
     1868
     1869
     1870
     1871static apr_status_t load_proxy_x509_credentials(apr_pool_t *pconf,
     1872                                                apr_pool_t *ptemp,
     1873                                                server_rec *s)
    17901874{
    17911875    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
     
    17951879        return APR_EGENERAL;
    17961880
    1797     apr_status_t ret = APR_SUCCESS;
     1881    apr_status_t ret = APR_EINIT;
    17981882    int err = GNUTLS_E_SUCCESS;
     1883
     1884    /* Cleanup function for the GnuTLS structures allocated below */
     1885    apr_pool_cleanup_register(pconf, sc, cleanup_proxy_x509_credentials,
     1886                              apr_pool_cleanup_null);
    17991887
    18001888    /* Function pool, gets destroyed before exit. */
    18011889    apr_pool_t *pool;
    1802     ret = apr_pool_create(&pool, s->process->pool);
     1890    ret = apr_pool_create(&pool, ptemp);
    18031891    if (ret != APR_SUCCESS)
    18041892    {
  • src/gnutls_io.c

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
     5 *  Copyright 2015-2016 Thomas Klute
    66 *
    77 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    1616 *  See the License for the specific language governing permissions and
    1717 *  limitations under the License.
    18  *
    1918 */
    2019
     
    2524#endif
    2625
     26#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     27#include <inttypes.h>
     28#endif
     29
    2730/**
     31 * @file
    2832 * Describe how the GnuTLS Filter system works here
    2933 *  - Basicly the same as what mod_ssl does with OpenSSL.
     
    4347
    4448/**
    45  * Convert APR_EINTR or APR_EAGAIN to the match raw error code. Needed
    46  * to pass the status on to GnuTLS from the pull function.
     49 * Convert `APR_EINTR` or `APR_EAGAIN` to the matching errno. Needed
     50 * to pass the status on to GnuTLS from the pull and push functions.
    4751 */
    4852#define EAI_APR_TO_RAW(s) (APR_STATUS_IS_EAGAIN(s) ? EAGAIN : EINTR)
     
    5963    case HTTP_BAD_REQUEST:
    6064        /* log the situation */
    61         ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    62                      f->c->base_server,
    63                      "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
    64                      "trying to send HTML error page");
     65        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
     66                      "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
     67                      "trying to send HTML error page");
    6568        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    6669            ap_get_module_config(f->c->base_server->module_config,
     
    401404    if (maxtries < 1) {
    402405        ctxt->status = -1;
    403 #if USING_2_1_RECENT
    404406        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, ctxt->c,
    405407                "GnuTLS: Handshake Failed. Hit Maximum Attempts");
    406 #else
    407         ap_log_error(APLOG_MARK, APLOG_ERR, 0,
    408                 ctxt->c->base_server,
    409                 "GnuTLS: Handshake Failed. Hit Maximum Attempts");
    410 #endif
    411408        if (ctxt->session) {
    412409            gnutls_alert_send(ctxt->session, GNUTLS_AL_FATAL,
     
    423420                || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
    424421            errcode = gnutls_alert_get(ctxt->session);
    425             ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    426                     ctxt->c->base_server,
    427                     "GnuTLS: Handshake Alert (%d) '%s'.",
    428                     errcode,
    429                     gnutls_alert_get_name(errcode));
     422            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
     423                          "GnuTLS: Handshake Alert (%d) '%s'.",
     424                          errcode, gnutls_alert_get_name(errcode));
    430425        }
    431426
    432427        if (!gnutls_error_is_fatal(ret)) {
    433             ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    434                     ctxt->c->base_server,
    435                     "GnuTLS: Non-Fatal Handshake Error: (%d) '%s'",
    436                     ret, gnutls_strerror(ret));
     428            ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
     429                          "GnuTLS: Non-Fatal Handshake Error: (%d) '%s'",
     430                          ret, gnutls_strerror(ret));
    437431            goto tryagain;
    438432        }
    439 #if USING_2_1_RECENT
    440433        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
    441434                "GnuTLS: Handshake Failed (%d) '%s'", ret,
    442435                gnutls_strerror(ret));
    443 #else
    444         ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    445                 ctxt->c->base_server,
    446                 "GnuTLS: Handshake Failed (%d) '%s'", ret,
    447                 gnutls_strerror(ret));
    448 #endif
    449436        ctxt->status = -1;
    450437        if (ctxt->session) {
     
    483470    if (rv != 0) {
    484471        /* the client did not want to rehandshake. goodbye */
    485         ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
    486                 ctxt->c->base_server,
    487                 "GnuTLS: Client Refused Rehandshake request.");
     472        ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, ctxt->c,
     473                      "GnuTLS: Client Refused Rehandshake request.");
    488474        return -1;
    489475    }
     
    501487 * Close the TLS session associated with the given connection
    502488 * structure and free its resources
     489 *
     490 * @param ctxt the mod_gnutls session context
     491 *
     492 * @return a GnuTLS status code, hopefully `GNUTLS_E_SUCCESS`
    503493 */
    504494static int mgs_bye(mgs_handle_t* ctxt)
     
    579569            return APR_ENOTIMPL;
    580570        }
    581         /* Err. This is bad. readbytes *can* be a 64bit int! len.. is NOT */
    582         if ((apr_size_t) readbytes < len) {
     571        /* 'readbytes' and 'len' are of different integer types, which
     572         * might have different lengths. Read sizes should be too
     573         * small for 32 or 64 bit to matter, but we have to make
     574         * sure. */
     575#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
     576        if ((apr_size_t) readbytes < len)
     577        {
     578            /* If readbytes is negative the function fails in the
     579             * check above, but the compiler doesn't get that. */
     580            if (__builtin_expect(imaxabs(readbytes) > SIZE_MAX, 0))
     581            {
     582                ap_log_cerror(APLOG_MARK, APLOG_CRIT, APR_EINVAL, ctxt->c,
     583                              "%s: prevented buffer length overflow",
     584                              __func__);
     585                return APR_EINVAL;
     586            }
    583587            len = (apr_size_t) readbytes;
    584588        }
     589#else
     590        if ((apr_size_t) readbytes < len
     591            && __builtin_add_overflow(readbytes, 0, &len))
     592        {
     593            ap_log_cerror(APLOG_MARK, APLOG_CRIT, APR_EINVAL, ctxt->c,
     594                          "%s: prevented buffer length overflow",
     595                          __func__);
     596            return APR_EINVAL;
     597        }
     598#endif
    585599        status =
    586600                gnutls_io_input_read(ctxt, ctxt->input_buffer, &len);
     
    619633}
    620634
     635/**
     636 * Try to flush the output bucket brigade.
     637 *
     638 * @param ctxt the mod_gnutls session context
     639 *
     640 * @return `1` on success, `-1` on failure.
     641 */
    621642static ssize_t write_flush(mgs_handle_t * ctxt) {
    622643    apr_bucket *e;
     
    735756                if (ret < 0) {
    736757                    /* error sending output */
    737                     ap_log_error(APLOG_MARK,
    738                             APLOG_INFO,
    739                             ctxt->output_rc,
    740                             ctxt->c->base_server,
    741                             "GnuTLS: Error writing data."
    742                             " (%d) '%s'",
    743                             (int) ret,
    744                             gnutls_strerror(ret));
     758                    ap_log_cerror(APLOG_MARK, APLOG_INFO, ctxt->output_rc,
     759                                  ctxt->c,
     760                                  "GnuTLS: Error writing data. (%d) '%s'",
     761                                  ret, gnutls_strerror(ret));
    745762                    if (ctxt->output_rc == APR_SUCCESS) {
    746763                        ctxt->output_rc =
     
    766783 * Pull function for GnuTLS
    767784 *
    768  * Generic errnos used for gnutls_transport_set_errno:
    769  * EIO: Unknown I/O error
    770  * ECONNABORTED: Input BB does not exist (NULL)
    771  *
    772  * The reason we are not using APR_TO_OS_ERROR to map apr_status_t to
    773  * errnos is this warning in the APR documentation: "If the statcode
    774  * was not created by apr_get_os_error or APR_FROM_OS_ERROR, the
    775  * results are undefined." We cannot know if this applies to any error
    776  * we might encounter.
     785 * Generic errnos used for `gnutls_transport_set_errno()`:
     786 * * `EAGAIN`: no data available at the moment, try again (maybe later)
     787 * * `EINTR`: read was interrupted, try again
     788 * * `EIO`: Unknown I/O error
     789 * * `ECONNABORTED`: Input BB does not exist (`NULL`)
     790 *
     791 * The reason we are not using `APR_TO_OS_ERROR` to map `apr_status_t`
     792 * to errnos is this warning [in the APR documentation][apr-warn]:
     793 *
     794 * > If the statcode was not created by apr_get_os_error or
     795 * > APR_FROM_OS_ERROR, the results are undefined.
     796 *
     797 * We cannot know if this applies to any error we might encounter.
     798 *
     799 * @param ptr GnuTLS session data pointer (the mod_gnutls context
     800 * structure)
     801 *
     802 * @param buffer buffer for the read data
     803 *
     804 * @param len maximum number of bytes to read (must fit into the
     805 * buffer)
     806 *
     807 * @return The number of bytes read (may be zero on EOF), or `-1` on
     808 * error. Note that some errors may warrant another try (see above).
     809 *
     810 * [apr-warn]: https://apr.apache.org/docs/apr/1.4/group__apr__errno.html#ga2385cae04b04afbdcb65f1a45c4d8506 "Apache Portable Runtime: Error Codes"
    777811 */
    778812ssize_t mgs_transport_read(gnutls_transport_ptr_t ptr,
     
    871905 * Push function for GnuTLS
    872906 *
    873  * In case of unexpected errors gnutls_transport_set_errno is called
    874  * with EIO.  The reason we are not using APR_TO_OS_ERROR to map
    875  * apr_status_t to errnos is this warning in the APR documentation:
    876  * "If the statcode was not created by apr_get_os_error or
    877  * APR_FROM_OS_ERROR, the results are undefined." We cannot know if
    878  * this applies to any error we might encounter.
     907 * `gnutls_transport_set_errno()` will be called with `EAGAIN` or
     908 * `EINTR` on recoverable errors, or `EIO` in case of unexpected
     909 * errors. See the description of mgs_transport_read() for details on
     910 * possible error codes.
     911 *
     912 * @param ptr GnuTLS session data pointer (the mod_gnutls context
     913 * structure)
     914 *
     915 * @param buffer buffer containing the data to send
     916 *
     917 * @param len length of the data
     918 * buffer)
     919 *
     920 * @return The number of written bytes, or `-1` on error. Note that
     921 * some errors may warrant another try (see above).
    879922 */
    880923ssize_t mgs_transport_write(gnutls_transport_ptr_t ptr,
  • src/mod_gnutls.c

    rce12806 rd8afa3e  
    1 /**
     1/*
    22 *  Copyright 2004-2005 Paul Querna
    33 *  Copyright 2008, 2014 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
     5 *  Copyright 2015-2016 Thomas Klute
    66 *
    77 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    1616 *  See the License for the specific language governing permissions and
    1717 *  limitations under the License.
    18  *
    1918 */
    2019
    2120#include "mod_gnutls.h"
     21#include "gnutls_ocsp.h"
    2222
    2323#ifdef APLOG_USE_MODULE
     
    3232                        APR_HOOK_REALLY_LAST);
    3333    /* HTTP Scheme Hook */
    34 #if USING_2_1_RECENT
    3534    ap_hook_http_scheme(mgs_hook_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
    36 #else
    37     ap_hook_http_method(mgs_hook_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
    38 #endif
    3935    /* Default Port Hook */
    4036    ap_hook_default_port(mgs_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE);
     
    7672
    7773
    78 /*
    79  * mod_rewrite calls this function to fill %{HTTPS}. A non-zero return
    80  * value means that HTTPS is in use.
     74/**
     75 * mod_rewrite calls this function to fill %{HTTPS}.
     76 *
     77 * @param c the connection to check
     78 * @return non-zero value if HTTPS is in use, zero if not
    8179 */
    8280int ssl_is_https(conn_rec *c)
     
    229227    "TLS Server SRP Parameters file"),
    230228#endif
    231     AP_INIT_TAKE1("GnuTLSCacheTimeout", mgs_set_cache_timeout,
     229    AP_INIT_TAKE1("GnuTLSCacheTimeout", mgs_set_timeout,
    232230    NULL,
    233231    RSRC_CONF,
     
    275273    "The priorities to enable for proxy connections (ciphers, key exchange, "
    276274    "MACs, compression)."),
     275    AP_INIT_FLAG("GnuTLSOCSPStapling", mgs_ocsp_stapling_enable,
     276                 NULL, RSRC_CONF,
     277                 "Enable OCSP stapling"),
     278    AP_INIT_FLAG("GnuTLSOCSPCheckNonce", mgs_set_ocsp_check_nonce,
     279                 NULL, RSRC_CONF,
     280                 "Check nonce in OCSP responses?"),
     281    AP_INIT_TAKE1("GnuTLSOCSPResponseFile", mgs_store_ocsp_response_path,
     282                  NULL, RSRC_CONF,
     283                  "Read OCSP response for stapling from this file instead "
     284                  "of sending a request over HTTP (must be updated "
     285                  "externally)"),
     286    AP_INIT_TAKE1("GnuTLSOCSPCacheTimeout", mgs_set_timeout,
     287                  NULL, RSRC_CONF,
     288                  "Cache timeout for OCSP responses"),
     289    AP_INIT_TAKE1("GnuTLSOCSPFailureTimeout", mgs_set_timeout,
     290                  NULL, RSRC_CONF,
     291                  "Wait this many seconds before retrying a failed OCSP "
     292                  "request"),
     293    AP_INIT_TAKE1("GnuTLSOCSPSocketTimeout", mgs_set_timeout,
     294                  NULL, RSRC_CONF,
     295                  "Socket timeout for OCSP requests"),
     296#ifdef __clang__
     297    /* Workaround for this clang bug:
     298     * https://llvm.org/bugs/show_bug.cgi?id=21689 */
     299    {},
     300#else
    277301    { NULL },
     302#endif
    278303};
    279304
  • test/Makefile.am

    rce12806 rd8afa3e  
    2929        test-24_pkcs11_cert.bash \
    3030        test-25_Disable_TLS_1.0.bash \
    31         test-26_redirect_HTTP_to_HTTPS.bash
     31        test-26_redirect_HTTP_to_HTTPS.bash \
     32        test-27_OCSP_server.bash
    3233
    3334TESTS = $(dist_check_SCRIPTS)
     
    3536check_PROGRAMS = pgpcrc
    3637pgpcrc_SOURCES = pgpcrc.c
     38
     39# build OCSP database tool
     40if ENABLE_OCSP_TEST
     41check_PROGRAMS += gen_ocsp_index
     42gen_ocsp_index_SOURCES = gen_ocsp_index.c cert_helper.c
     43gen_ocsp_index_LDFLAGS = $(LIBGNUTLS_LIBS)
     44noinst_HEADERS = cert_helper.h
     45endif
    3746
    3847# Identities in the miniature CA, server, and client environment for
     
    4150pgp_identities = $(shared_identities)
    4251x509_only_identities = rogueclient
     52if ENABLE_OCSP_TEST
     53x509_only_identities += ocsp-responder
     54endif
    4355x509_identities = $(shared_identities) $(x509_only_identities)
    4456identities = $(shared_identities) $(x509_only_identities)
     
    7486
    7587cert_templates = authority.template.in client.template.in \
    76         imposter.template.in rogueca.template rogueclient.template.in \
    77         server.template.in
     88        imposter.template.in ocsp-responder.template rogueca.template \
     89        rogueclient.template.in server.template.in
    7890generated_templates = authority.template client.template \
    7991        imposter.template rogueclient.template server.template
     
    117129endif
    118130
     131if ENABLE_OCSP_TEST
     132# rules to build OCSP database
     133check_DATA += authority/ocsp_index.txt
     134MOSTLYCLEANFILES += authority/ocsp_index.txt authority/ocsp_index.txt.attr
     135authority/ocsp_index.txt: $(x509_tokens) gen_ocsp_index authority/ocsp_index.txt.attr
     136        ./gen_ocsp_index server/x509.pem client/x509.pem > $@
     137
     138authority/ocsp_index.txt.attr: authority/secret.key
     139        echo "unique_subject = no" > $@
     140
     141# build certificate chain file for server
     142check_DATA += server/x509-chain.pem
     143MOSTLYCLEANFILES += server/x509-chain.pem
     144%/x509-chain.pem: %/x509.pem authority/x509.pem
     145        cat $< authority/x509.pem > $@
     146endif
    119147
    120148# SoftHSM tokens. Note that the SoftHSM 2 token is a directory and
     
    159187
    160188# Apache configuration and data files
    161 apache_data = base_apache.conf cgi_module.conf data/dump.cgi data/secret.txt data/test.txt mime.types proxy_mods.conf
     189apache_data = base_apache.conf cgi_module.conf data/dump.cgi data/ocsp.cgi \
     190        data/secret.txt data/test.txt mime.types ocsp_server.conf \
     191        proxy_mods.conf
    162192
    163193EXTRA_DIST = $(apache_data) $(cert_templates) $(shared_identities:=.uid.in) \
     
    177207# port for MSVA in test cases that use it
    178208MSVA_PORT ?= 9933
     209# port for OCSP server (Apache vhost if enabled)
     210if ENABLE_OCSP_TEST
     211OCSP_PORT ?= 9936
     212endif
    179213# maximum time to wait for MSVA startup (milliseconds)
    180214TEST_MSVA_MAX_WAIT ?= 10000
     
    202236endif
    203237
     238if ENABLE_OCSP_TEST
     239AM_TESTS_ENVIRONMENT += export OPENSSL="@OPENSSL@"; \
     240        export OCSP_PORT="$(OCSP_PORT)";
     241endif
     242
    204243if ENABLE_NETNS
    205244AM_TESTS_ENVIRONMENT += export UNSHARE="@UNSHARE@"; \
  • test/client.template.in

    rce12806 rd8afa3e  
    55signing_key
    66encryption_key
     7### ocsp_uri=http://__HOSTNAME__:__OCSP_PORT__/ocsp/
  • test/runtests

    rce12806 rd8afa3e  
    189189fi
    190190
     191# check OCSP server
     192if [ -n "${CHECK_OCSP_SERVER}" ]; then
     193    if [ -n "${OCSP_RESPONSE_FILE}" ]; then
     194        store_ocsp="--outfile ${OCSP_RESPONSE_FILE}"
     195    fi
     196    echo "---- Testing OCSP server ----"
     197    ocsptool --ask --nonce --load-issuer authority/x509.pem --load-cert server/x509.pem ${store_ocsp}
     198    echo "---- OCSP test done ----"
     199fi
     200
    191201# PID file for sleep command (explanation below)
    192202sleep_pidfile="$(mktemp mod_gnutls_test-XXXXXX.pid)"
  • test/server.template.in

    rce12806 rd8afa3e  
    55encryption_key
    66dns_name="__HOSTNAME__"
     7### ocsp_uri=http://__HOSTNAME__:__OCSP_PORT__/ocsp/
  • test/test_ca.mk

    rce12806 rd8afa3e  
    99%.template: $(srcdir)/%.template.in
    1010        sed s/__HOSTNAME__/$(TEST_HOST)/ < $< > $@
     11        if test -n "$(OCSP_PORT)"; then \
     12                sed -i -e 's/^### ocsp/ocsp/' \
     13                        -e s/__OCSP_PORT__/$(OCSP_PORT)/ $@; \
     14        fi
    1115
    1216%.uid: $(srcdir)/%.uid.in
     
    3943
    4044# Import and signing modify the shared keyring, which leads to race
    41 # conditions with parallel make. Locking avoids this problem.
    42 %/cert.pgp: %/minimal.pgp authority/gpg.conf
     45# conditions with parallel make. Locking avoids this problem. Building
     46# authority/minimal.pgp (instead of just authority/gpg.conf) before
     47# */cert.pgp avoids having to lock for all */minimal.pgp, too.
     48%/cert.pgp: %/minimal.pgp authority/minimal.pgp
    4349        if test -r $@; then rm $@; fi
    4450        GNUPGHOME=authority $(GPG_FLOCK) gpg --import $<
    4551        GNUPGHOME=authority $(GPG_FLOCK) gpg --batch --sign-key --no-tty --yes "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)"
    46         GNUPGHOME=authority gpg --output $@ --armor --export "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)"
     52        GNUPGHOME=authority $(GPG_FLOCK) gpg --output $@ --armor --export "$$(GNUPGHOME=$(dir $@) gpg --with-colons --list-secret-keys --fingerprint | grep ^fpr: | cut -f 10 -d :)"
    4753
    4854# special cases for the authorities' root certs:
  • test/tests/Makefile.am

    rce12806 rd8afa3e  
    2626        24_pkcs11_cert/apache.conf 24_pkcs11_cert/gnutls-cli.args 24_pkcs11_cert/input 24_pkcs11_cert/output \
    2727        25_Disable_TLS_1.0/apache.conf 25_Disable_TLS_1.0/fail.client 25_Disable_TLS_1.0/gnutls-cli.args 25_Disable_TLS_1.0/input \
    28         26_redirect_HTTP_to_HTTPS/apache.conf
     28        26_redirect_HTTP_to_HTTPS/apache.conf \
     29        27_OCSP_server/apache.conf 27_OCSP_server/gnutls-cli.args 27_OCSP_server/input 27_OCSP_server/output
Note: See TracChangeset for help on using the changeset viewer.