|
Packit |
549fdc |
/*
|
|
Packit |
549fdc |
* Copyright (C) 2012-2014 Free Software Foundation, Inc.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* This file is part of GnuTLS.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* GnuTLS is free software: you can redistribute it and/or modify it
|
|
Packit |
549fdc |
* under the terms of the GNU General Public License as published by
|
|
Packit |
549fdc |
* the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
549fdc |
* (at your option) any later version.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* GnuTLS is distributed in the hope that it will be useful, but
|
|
Packit |
549fdc |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
549fdc |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
549fdc |
* General Public License for more details.
|
|
Packit |
549fdc |
*
|
|
Packit |
549fdc |
* You should have received a copy of the GNU General Public License
|
|
Packit |
549fdc |
* along with this program. If not, see
|
|
Packit |
549fdc |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#include <config.h>
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#include <stdio.h>
|
|
Packit |
549fdc |
#include <stdlib.h>
|
|
Packit |
549fdc |
#include <string.h>
|
|
Packit |
549fdc |
#include <errno.h>
|
|
Packit |
549fdc |
#include "common.h"
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#include <gnutls/gnutls.h>
|
|
Packit |
549fdc |
#include <gnutls/ocsp.h>
|
|
Packit |
549fdc |
#include <gnutls/x509.h>
|
|
Packit |
549fdc |
#include <gnutls/crypto.h>
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* Gnulib portability files. */
|
|
Packit |
549fdc |
#include <read-file.h>
|
|
Packit |
549fdc |
#include <socket.h>
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#include <ocsptool-common.h>
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
#define MAX_BUF 4*1024
|
|
Packit |
549fdc |
#define HEADER_PATTERN "POST /%s HTTP/1.0\r\n" \
|
|
Packit |
549fdc |
"Host: %s\r\n" \
|
|
Packit |
549fdc |
"Accept: */*\r\n" \
|
|
Packit |
549fdc |
"Content-Type: application/ocsp-request\r\n" \
|
|
Packit |
549fdc |
"Content-Length: %u\r\n" \
|
|
Packit |
549fdc |
"Connection: close\r\n\r\n"
|
|
Packit |
549fdc |
static char buffer[MAX_BUF + 1];
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* returns the host part of a URL */
|
|
Packit |
549fdc |
static const char *host_from_url(const char *url, unsigned int *port, const char **path)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
static char hostname[512];
|
|
Packit |
549fdc |
char *p;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
*port = 0;
|
|
Packit |
549fdc |
*path = "";
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if ((p = strstr(url, "http://")) != NULL) {
|
|
Packit |
549fdc |
snprintf(hostname, sizeof(hostname), "%s", p + 7);
|
|
Packit |
549fdc |
p = strchr(hostname, '/');
|
|
Packit |
549fdc |
if (p != NULL) {
|
|
Packit |
549fdc |
*p = 0;
|
|
Packit |
549fdc |
*path = p+1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
p = strchr(hostname, ':');
|
|
Packit |
549fdc |
if (p != NULL) {
|
|
Packit |
549fdc |
*p = 0;
|
|
Packit |
549fdc |
*port = atoi(p + 1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return hostname;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
return url;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
void
|
|
Packit |
549fdc |
_generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
|
|
Packit |
549fdc |
gnutls_datum_t * rdata, gnutls_datum_t *nonce)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_ocsp_req_t req;
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_req_init(&req;;
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "ocsp_req_init: %s", gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_req_add_cert(req, GNUTLS_DIG_SHA1, issuer, cert);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "ocsp_req_add_cert: %s",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (nonce) {
|
|
Packit |
549fdc |
ret = gnutls_ocsp_req_set_nonce(req, 0, nonce);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "ocsp_req_set_nonce: %s",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_req_export(req, rdata);
|
|
Packit |
549fdc |
if (ret != 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "ocsp_req_export: %s",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
gnutls_ocsp_req_deinit(req);
|
|
Packit |
549fdc |
return;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
static size_t get_data(void *buf, size_t size, size_t nmemb,
|
|
Packit |
549fdc |
void *userp)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_datum_t *ud = userp;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
size *= nmemb;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ud->data = realloc(ud->data, size + ud->size);
|
|
Packit |
549fdc |
if (ud->data == NULL) {
|
|
Packit |
549fdc |
fprintf(stderr, "Not enough memory for the request\n");
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
memcpy(&ud->data[ud->size], buf, size);
|
|
Packit |
549fdc |
ud->size += size;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return size;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* Returns 0 on ok, and -1 on error */
|
|
Packit |
549fdc |
int send_ocsp_request(const char *server,
|
|
Packit |
549fdc |
gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
|
|
Packit |
549fdc |
gnutls_datum_t * resp_data, gnutls_datum_t *nonce)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_datum_t ud;
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
gnutls_datum_t req;
|
|
Packit |
549fdc |
char *url = (void *) server;
|
|
Packit |
549fdc |
char headers[1024];
|
|
Packit |
549fdc |
char service[16];
|
|
Packit |
549fdc |
unsigned char *p;
|
|
Packit |
549fdc |
const char *hostname;
|
|
Packit |
549fdc |
const char *path = "";
|
|
Packit |
549fdc |
unsigned i;
|
|
Packit |
549fdc |
unsigned int headers_size = 0, port;
|
|
Packit |
549fdc |
socket_st hd;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
sockets_init();
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (url == NULL) {
|
|
Packit |
549fdc |
/* try to read URL from issuer certificate */
|
|
Packit |
549fdc |
gnutls_datum_t data;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
i = 0;
|
|
Packit |
549fdc |
do {
|
|
Packit |
549fdc |
ret = gnutls_x509_crt_get_authority_info_access(cert, i++,
|
|
Packit |
549fdc |
GNUTLS_IA_OCSP_URI,
|
|
Packit |
549fdc |
&data,
|
|
Packit |
549fdc |
NULL);
|
|
Packit |
549fdc |
} while(ret == GNUTLS_E_UNKNOWN_ALGORITHM);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
i = 0;
|
|
Packit |
549fdc |
do {
|
|
Packit |
549fdc |
ret =
|
|
Packit |
549fdc |
gnutls_x509_crt_get_authority_info_access
|
|
Packit |
549fdc |
(issuer, i++, GNUTLS_IA_OCSP_URI, &data, NULL);
|
|
Packit |
549fdc |
} while(ret == GNUTLS_E_UNKNOWN_ALGORITHM);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr,
|
|
Packit |
549fdc |
"*** Cannot find OCSP server URI in certificate: %s\n",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
url = malloc(data.size + 1);
|
|
Packit |
549fdc |
memcpy(url, data.data, data.size);
|
|
Packit |
549fdc |
url[data.size] = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
gnutls_free(data.data);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
hostname = host_from_url(url, &port, &path);
|
|
Packit |
549fdc |
if (port != 0)
|
|
Packit |
549fdc |
snprintf(service, sizeof(service), "%u", port);
|
|
Packit |
549fdc |
else
|
|
Packit |
549fdc |
strcpy(service, "80");
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
fprintf(stderr, "Connecting to OCSP server: %s...\n", hostname);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
memset(&ud, 0, sizeof(ud));
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
_generate_request(cert, issuer, &req, nonce);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
snprintf(headers, sizeof(headers), HEADER_PATTERN, path, hostname,
|
|
Packit |
549fdc |
(unsigned int) req.size);
|
|
Packit |
549fdc |
headers_size = strlen(headers);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
socket_open(&hd, hostname, service, NULL, SOCKET_FLAG_RAW|SOCKET_FLAG_SKIP_INIT, CONNECT_MSG, NULL);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
socket_send(&hd, headers, headers_size);
|
|
Packit |
549fdc |
socket_send(&hd, req.data, req.size);
|
|
Packit |
549fdc |
gnutls_free(req.data);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
do {
|
|
Packit |
549fdc |
ret = socket_recv(&hd, buffer, sizeof(buffer));
|
|
Packit |
549fdc |
if (ret > 0)
|
|
Packit |
549fdc |
get_data(buffer, ret, 1, &ud);
|
|
Packit |
549fdc |
} while (ret > 0);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0 || ud.size == 0) {
|
|
Packit |
549fdc |
perror("recv");
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
socket_bye(&hd, 0);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
p = memmem(ud.data, ud.size, "\r\n\r\n", 4);
|
|
Packit |
549fdc |
if (p == NULL) {
|
|
Packit |
549fdc |
fprintf(stderr, "Cannot interpret HTTP response\n");
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
p += 4;
|
|
Packit |
549fdc |
resp_data->size = ud.size - (p - ud.data);
|
|
Packit |
549fdc |
resp_data->data = malloc(resp_data->size);
|
|
Packit |
549fdc |
if (resp_data->data == NULL) {
|
|
Packit |
549fdc |
perror("recv");
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
memcpy(resp_data->data, p, resp_data->size);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
free(ud.data);
|
|
Packit |
549fdc |
if (url != server)
|
|
Packit |
549fdc |
free(url);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
void print_ocsp_verify_res(unsigned int output)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
int comma = 0;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output) {
|
|
Packit |
549fdc |
printf("Failure");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
printf("Success");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signer cert not found");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signer cert keyusage error");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signer cert is not trusted");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Insecure algorithm");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signature failure");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signer cert not yet activated");
|
|
Packit |
549fdc |
comma = 1;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (output & GNUTLS_OCSP_VERIFY_CERT_EXPIRED) {
|
|
Packit |
549fdc |
if (comma)
|
|
Packit |
549fdc |
printf(", ");
|
|
Packit |
549fdc |
printf("Signer cert expired");
|
|
Packit |
549fdc |
/*comma = 1;*/
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* three days */
|
|
Packit |
549fdc |
#define OCSP_VALIDITY_SECS (3*60*60*24)
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* Returns:
|
|
Packit |
549fdc |
* 0: certificate is revoked
|
|
Packit |
549fdc |
* 1: certificate is ok
|
|
Packit |
549fdc |
* -1: dunno
|
|
Packit |
549fdc |
*/
|
|
Packit |
549fdc |
int
|
|
Packit |
549fdc |
check_ocsp_response(gnutls_x509_crt_t cert,
|
|
Packit |
549fdc |
gnutls_x509_crt_t issuer, gnutls_datum_t * data,
|
|
Packit |
549fdc |
gnutls_datum_t * nonce, int verbose)
|
|
Packit |
549fdc |
{
|
|
Packit |
549fdc |
gnutls_ocsp_resp_t resp;
|
|
Packit |
549fdc |
int ret;
|
|
Packit |
549fdc |
unsigned int status, cert_status;
|
|
Packit |
549fdc |
time_t rtime, vtime, ntime, now;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
now = time(0);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_init(&resp);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "ocsp_resp_init: %s",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_import(resp, data);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "importing response: %s",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_check_crt(resp, 0, cert);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
Packit |
549fdc |
printf
|
|
Packit |
549fdc |
("*** Got OCSP response with no data (ignoring)\n");
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
printf
|
|
Packit |
549fdc |
("*** Got OCSP response on an unrelated certificate (ignoring)\n");
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_verify_direct(resp, issuer, &status, 0);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "OCSP verification: %s\n",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (status != 0) {
|
|
Packit |
549fdc |
printf("*** Verifying OCSP Response: ");
|
|
Packit |
549fdc |
print_ocsp_verify_res(status);
|
|
Packit |
549fdc |
printf(".\n");
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
/* do not print revocation data if response was not verified */
|
|
Packit |
549fdc |
if (status != 0) {
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
|
|
Packit |
549fdc |
&cert_status, &vtime, &ntime,
|
|
Packit |
549fdc |
&rtime, NULL);
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "reading response: %s\n",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
|
|
Packit |
549fdc |
printf("*** Certificate was revoked at %s", ctime(&rtime);;
|
|
Packit |
549fdc |
ret = 0;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ntime == -1) {
|
|
Packit |
549fdc |
if (now - vtime > OCSP_VALIDITY_SECS) {
|
|
Packit |
549fdc |
printf
|
|
Packit |
549fdc |
("*** The OCSP response is old (was issued at: %s) ignoring",
|
|
Packit |
549fdc |
ctime(&vtime));
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
} else {
|
|
Packit |
549fdc |
/* there is a newer OCSP answer, don't trust this one */
|
|
Packit |
549fdc |
if (ntime < now) {
|
|
Packit |
549fdc |
printf
|
|
Packit |
549fdc |
("*** The OCSP response was issued at: %s, but there is a newer issue at %s",
|
|
Packit |
549fdc |
ctime(&vtime), ctime(&ntime));
|
|
Packit |
549fdc |
ret = -1;
|
|
Packit |
549fdc |
goto cleanup;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (nonce) {
|
|
Packit |
549fdc |
gnutls_datum_t rnonce;
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
ret = gnutls_ocsp_resp_get_nonce(resp, NULL, &rnonce);
|
|
Packit |
549fdc |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
Packit |
549fdc |
if (verbose)
|
|
Packit |
549fdc |
fprintf(stderr, "*** The OCSP reply did not include the requested nonce.\n");
|
|
Packit |
549fdc |
goto finish_ok;
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (ret < 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "could not read response's nonce: %s\n",
|
|
Packit |
549fdc |
gnutls_strerror(ret));
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
if (rnonce.size != nonce->size || memcmp(nonce->data, rnonce.data,
|
|
Packit |
549fdc |
nonce->size) != 0) {
|
|
Packit |
549fdc |
fprintf(stderr, "nonce in the response doesn't match\n");
|
|
Packit |
549fdc |
exit(1);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
gnutls_free(rnonce.data);
|
|
Packit |
549fdc |
}
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
finish_ok:
|
|
Packit |
549fdc |
printf("- OCSP server flags certificate not revoked as of %s",
|
|
Packit |
549fdc |
ctime(&vtime));
|
|
Packit |
549fdc |
ret = 1;
|
|
Packit |
549fdc |
cleanup:
|
|
Packit |
549fdc |
gnutls_ocsp_resp_deinit(resp);
|
|
Packit |
549fdc |
|
|
Packit |
549fdc |
return ret;
|
|
Packit |
549fdc |
}
|