1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/* OCSP initialization for NSS
*
* Copyright (C) 2015 Matt Rogers <mrogers@libreswan.org>
* Copyright (C) 2016 Paul Wouters <pwouters@redhat.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/
#include "x509.h"
#include "nss_ocsp.h"
/* NSS needs */
#include <secerr.h>
#include <ocsp.h>
#include "lswnss.h"
#include "defs.h" /* for so_serial_t */
#include "log.h"
/* note: returning a diag is fatal! */
diag_t init_nss_ocsp(const char *responder_url, const char *trust_cert_name,
deltatime_t timeout, bool strict, int cache_size,
deltatime_t cache_min, deltatime_t cache_max,
bool ocsp_post, struct logger *logger)
{
SECStatus rv;
/*
* CERT_GetDefaultCertDB() simply returns the contents of a
* static variable set by NSS_Initialize(). It doesn't check
* the value and doesn't set PR error. Short of calling
* CERT_SetDefaultCertDB(NULL), the value can never be NULL.
*/
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
passert(handle != NULL);
rv = CERT_EnableOCSPChecking(handle);
if (rv != SECSuccess) {
return diag_nss_error("error enabling OCSP checking");
}
dbg("NSS OCSP checking enabled");
/*
* enable a default responder
*/
if (responder_url != NULL && trust_cert_name != NULL) {
dbg("OCSP default responder url: %s", responder_url);
dbg("OCSP responder cert NSS nickname: %s", trust_cert_name);
rv = CERT_SetOCSPDefaultResponder(handle, responder_url,
trust_cert_name);
if (rv == SECSuccess) {
rv = CERT_EnableOCSPDefaultResponder(handle);
if (rv != SECSuccess) {
int err = PORT_GetError();
if (err == SEC_ERROR_OCSP_RESPONDER_CERT_INVALID) {
llog(RC_LOG, logger,
"responder certificate %s is invalid. please verify its keyUsage extensions for OCSP",
trust_cert_name);
} else {
llog_nss_error(RC_LOG, logger,
"error enabling OCSP default responder");
}
}
} else {
int err = PORT_GetError();
if (err == SEC_ERROR_UNKNOWN_CERT) {
llog(RC_LOG, logger,
"OCSP responder cert \"%s\" not found in NSS",
trust_cert_name);
} else {
/* uses global value */
llog_nss_error(RC_LOG, logger, "error setting default responder");
}
}
}
if (deltatime_cmp(timeout, >, deltatime_zero)) {
dbg("OCSP timeout of %ju seconds", deltasecs(timeout));
if (CERT_SetOCSPTimeout(deltasecs(timeout)) != SECSuccess) {
/* don't shoot pluto over this */
llog_nss_error(RC_LOG, logger, "error setting OCSP timeout to %ju", deltasecs(timeout));
}
}
if (strict) {
rv = CERT_SetOCSPFailureMode(ocspMode_FailureIsVerificationFailure);
} else {
rv = CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure);
}
if (rv != SECSuccess) {
return diag_nss_error("error setting OCSP failure mode");
}
if (ocsp_post) {
rv = CERT_ForcePostMethodForOCSP(true);
dbg("OCSP will use POST method");
} else {
rv = CERT_ForcePostMethodForOCSP(false);
}
if (rv != SECSuccess) {
/* don't shoot pluto over this */
llog_nss_error(RC_LOG, logger, "error enabling OCSP POST method");
}
/*
* NSS uses 0 for unlimited and -1 for disabled. We use 0 for
* disabled and just a large number for a large cache.
*/
int nss_max = deltasecs(cache_max);
if (nss_max == 0) {
nss_max = -1;
}
rv = CERT_OCSPCacheSettings(cache_size, deltasecs(cache_min), nss_max);
if (rv != SECSuccess) {
/* don't shoot pluto over this */
deltatime_buf minb, maxb;
llog_nss_error(RC_LOG, logger,
"error setting OCSP cache parameters (size=%d, min=%s, max=%s)",
cache_size,
str_deltatime(cache_min, &minb),
str_deltatime(cache_max, &maxb));
}
return NULL;
}
|