|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2011-2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
* Author: Simon Josefsson
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This file is part of GnuTLS.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit Service |
4684c1 |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
4684c1 |
* the License, or (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This library is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* Lesser General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Online Certificate Status Protocol - RFC 2560
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include <global.h>
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include <libtasn1.h>
|
|
Packit Service |
4684c1 |
#include <pk.h>
|
|
Packit Service |
4684c1 |
#include <str.h>
|
|
Packit Service |
4684c1 |
#include "algorithms.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <gnutls/ocsp.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define addf _gnutls_buffer_append_printf
|
|
Packit Service |
4684c1 |
#define adds _gnutls_buffer_append_str
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void print_req(gnutls_buffer_st * str, gnutls_ocsp_req_const_t req)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
unsigned indx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Version. */
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int version = gnutls_ocsp_req_get_version(req);
|
|
Packit Service |
4684c1 |
if (version < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: get_version: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(version));
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\tVersion: %d\n"), version);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* XXX requestorName */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* requestList */
|
|
Packit Service |
4684c1 |
addf(str, "\tRequest List:\n");
|
|
Packit Service |
4684c1 |
for (indx = 0;; indx++) {
|
|
Packit Service |
4684c1 |
gnutls_digest_algorithm_t digest;
|
|
Packit Service |
4684c1 |
gnutls_datum_t in, ik, sn;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_ocsp_req_get_cert_id(req, indx, &digest, &in,
|
|
Packit Service |
4684c1 |
&ik, &sn;;
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
addf(str, "\t\tCertificate ID:\n");
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_cert_id: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
addf(str, "\t\t\tHash Algorithm: %s\n",
|
|
Packit Service |
4684c1 |
_gnutls_digest_get_name(hash_to_entry(digest)));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tIssuer Name Hash: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, in.data, in.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tIssuer Key Hash: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, ik.data, ik.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tSerial Number: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, sn.data, sn.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(in.data);
|
|
Packit Service |
4684c1 |
gnutls_free(ik.data);
|
|
Packit Service |
4684c1 |
gnutls_free(sn.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* XXX singleRequestExtensions */
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (indx = 0;; indx++) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t oid;
|
|
Packit Service |
4684c1 |
unsigned int critical;
|
|
Packit Service |
4684c1 |
gnutls_datum_t data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_ocsp_req_get_extension(req, indx, &oid,
|
|
Packit Service |
4684c1 |
&critical, &data);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
else if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_extension: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (indx == 0)
|
|
Packit Service |
4684c1 |
adds(str, "\tExtensions:\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (oid.size == sizeof(GNUTLS_OCSP_NONCE) &&
|
|
Packit Service |
4684c1 |
memcmp(oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t nonce;
|
|
Packit Service |
4684c1 |
unsigned int ncrit;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_ocsp_req_get_nonce(req, &ncrit,
|
|
Packit Service |
4684c1 |
&nonce);
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_nonce: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "\t\tNonce%s: ",
|
|
Packit Service |
4684c1 |
ncrit ? " (critical)" : "");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, nonce.data,
|
|
Packit Service |
4684c1 |
nonce.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
gnutls_free(nonce.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "\t\tUnknown extension %s (%s):\n",
|
|
Packit Service |
4684c1 |
oid.data,
|
|
Packit Service |
4684c1 |
critical ? "critical" : "not critical");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, _("\t\t\tASCII: "));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_asciiprint(str, (char *) data.data,
|
|
Packit Service |
4684c1 |
data.size);
|
|
Packit Service |
4684c1 |
addf(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, _("\t\t\tHexdump: "));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, (char *) data.data,
|
|
Packit Service |
4684c1 |
data.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(oid.data);
|
|
Packit Service |
4684c1 |
gnutls_free(data.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* XXX Signature */
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_ocsp_req_print:
|
|
Packit Service |
4684c1 |
* @req: The data to be printed
|
|
Packit Service |
4684c1 |
* @format: Indicate the format to use
|
|
Packit Service |
4684c1 |
* @out: Newly allocated datum with (0) terminated string.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will pretty print a OCSP request, suitable for
|
|
Packit Service |
4684c1 |
* display to a human.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the format is %GNUTLS_OCSP_PRINT_FULL then all fields of the
|
|
Packit Service |
4684c1 |
* request will be output, on multiple lines.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The output @out->data needs to be deallocate using gnutls_free().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_ocsp_req_print(gnutls_ocsp_req_const_t req,
|
|
Packit Service |
4684c1 |
gnutls_ocsp_print_formats_t format,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * out)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st str;
|
|
Packit Service |
4684c1 |
int rc;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (format != GNUTLS_OCSP_PRINT_FULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_init(&str);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_str(&str, _("OCSP Request Information:\n"));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
print_req(&str, req);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
rc = _gnutls_buffer_to_datum(&str, out, 1);
|
|
Packit Service |
4684c1 |
if (rc != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return rc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SUCCESS;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void
|
|
Packit Service |
4684c1 |
print_resp(gnutls_buffer_st * str, gnutls_ocsp_resp_const_t resp,
|
|
Packit Service |
4684c1 |
gnutls_ocsp_print_formats_t format)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
unsigned indx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_status(resp);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
addf(str, "error: ocsp_resp_get_status: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\tResponse Status: ");
|
|
Packit Service |
4684c1 |
switch (ret) {
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_SUCCESSFUL:
|
|
Packit Service |
4684c1 |
adds(str, "Successful\n");
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
|
|
Packit Service |
4684c1 |
adds(str, "malformedRequest\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_INTERNALERROR:
|
|
Packit Service |
4684c1 |
adds(str, "internalError\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_TRYLATER:
|
|
Packit Service |
4684c1 |
adds(str, "tryLater\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_SIGREQUIRED:
|
|
Packit Service |
4684c1 |
adds(str, "sigRequired\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_RESP_UNAUTHORIZED:
|
|
Packit Service |
4684c1 |
adds(str, "unauthorized\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
adds(str, "unknown\n");
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t oid;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_response(resp, &oid, NULL);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_response: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\tResponse Type: ");
|
|
Packit Service |
4684c1 |
#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (oid.size == sizeof(OCSP_BASIC)
|
|
Packit Service |
4684c1 |
&& memcmp(oid.data, OCSP_BASIC, oid.size) == 0) {
|
|
Packit Service |
4684c1 |
adds(str, "Basic OCSP Response\n");
|
|
Packit Service |
4684c1 |
gnutls_free(oid.data);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "Unknown response type (%.*s)\n",
|
|
Packit Service |
4684c1 |
oid.size, oid.data);
|
|
Packit Service |
4684c1 |
gnutls_free(oid.data);
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Version. */
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int version = gnutls_ocsp_resp_get_version(resp);
|
|
Packit Service |
4684c1 |
if (version < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: get_version: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(version));
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\tVersion: %d\n"), version);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* responderID */
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t dn = {NULL, 0};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_responder2(resp, &dn, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_KEY, &dn;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret >= 0) {
|
|
Packit Service |
4684c1 |
addf(str, _("\tResponder Key ID: "));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, dn.data, dn.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_free(dn.data);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_responder2: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, _("\tResponder ID: %s\n"), dn.data);
|
|
Packit Service |
4684c1 |
gnutls_free(dn.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
char s[42];
|
|
Packit Service |
4684c1 |
size_t max = sizeof(s);
|
|
Packit Service |
4684c1 |
struct tm t;
|
|
Packit Service |
4684c1 |
time_t tim = gnutls_ocsp_resp_get_produced(resp);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (tim == (time_t) - 1)
|
|
Packit Service |
4684c1 |
addf(str, "error: ocsp_resp_get_produced\n");
|
|
Packit Service |
4684c1 |
else if (gmtime_r(&tim, &t) == NULL)
|
|
Packit Service |
4684c1 |
addf(str, "error: gmtime_r (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) tim);
|
|
Packit Service |
4684c1 |
else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t)
|
|
Packit Service |
4684c1 |
== 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: strftime (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) tim);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\tProduced At: %s\n"), s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
addf(str, "\tResponses:\n");
|
|
Packit Service |
4684c1 |
for (indx = 0;; indx++) {
|
|
Packit Service |
4684c1 |
gnutls_digest_algorithm_t digest;
|
|
Packit Service |
4684c1 |
gnutls_datum_t in, ik, sn;
|
|
Packit Service |
4684c1 |
unsigned int cert_status;
|
|
Packit Service |
4684c1 |
time_t this_update;
|
|
Packit Service |
4684c1 |
time_t next_update;
|
|
Packit Service |
4684c1 |
time_t revocation_time;
|
|
Packit Service |
4684c1 |
unsigned int revocation_reason;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_single(resp,
|
|
Packit Service |
4684c1 |
indx,
|
|
Packit Service |
4684c1 |
&digest, &in, &ik, &sn,
|
|
Packit Service |
4684c1 |
&cert_status,
|
|
Packit Service |
4684c1 |
&this_update,
|
|
Packit Service |
4684c1 |
&next_update,
|
|
Packit Service |
4684c1 |
&revocation_time,
|
|
Packit Service |
4684c1 |
&revocation_reason);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
addf(str, "\t\tCertificate ID:\n");
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_singleresponse: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
addf(str, "\t\t\tHash Algorithm: %s\n",
|
|
Packit Service |
4684c1 |
_gnutls_digest_get_name(hash_to_entry(digest)));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tIssuer Name Hash: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, in.data, in.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tIssuer Key Hash: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, ik.data, ik.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\t\t\tSerial Number: ");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, sn.data, sn.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(in.data);
|
|
Packit Service |
4684c1 |
gnutls_free(ik.data);
|
|
Packit Service |
4684c1 |
gnutls_free(sn.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
const char *p = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (cert_status) {
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_CERT_GOOD:
|
|
Packit Service |
4684c1 |
p = "good";
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_CERT_REVOKED:
|
|
Packit Service |
4684c1 |
p = "revoked";
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
case GNUTLS_OCSP_CERT_UNKNOWN:
|
|
Packit Service |
4684c1 |
p = "unknown";
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
addf(str,
|
|
Packit Service |
4684c1 |
"\t\tCertificate Status: unexpected value %d\n",
|
|
Packit Service |
4684c1 |
cert_status);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (p)
|
|
Packit Service |
4684c1 |
addf(str, "\t\tCertificate Status: %s\n",
|
|
Packit Service |
4684c1 |
p);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* XXX revocation reason */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
|
|
Packit Service |
4684c1 |
char s[42];
|
|
Packit Service |
4684c1 |
size_t max = sizeof(s);
|
|
Packit Service |
4684c1 |
struct tm t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (revocation_time == (time_t) - 1)
|
|
Packit Service |
4684c1 |
addf(str, "error: revocation_time\n");
|
|
Packit Service |
4684c1 |
else if (gmtime_r(&revocation_time, &t) == NULL)
|
|
Packit Service |
4684c1 |
addf(str, "error: gmtime_r (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) revocation_time);
|
|
Packit Service |
4684c1 |
else if (strftime
|
|
Packit Service |
4684c1 |
(s, max, "%a %b %d %H:%M:%S UTC %Y",
|
|
Packit Service |
4684c1 |
&t) == 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: strftime (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) revocation_time);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\t\tRevocation time: %s\n"),
|
|
Packit Service |
4684c1 |
s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
char s[42];
|
|
Packit Service |
4684c1 |
size_t max = sizeof(s);
|
|
Packit Service |
4684c1 |
struct tm t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (this_update == (time_t) - 1)
|
|
Packit Service |
4684c1 |
addf(str, "error: this_update\n");
|
|
Packit Service |
4684c1 |
else if (gmtime_r(&this_update, &t) == NULL)
|
|
Packit Service |
4684c1 |
addf(str, "error: gmtime_r (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) this_update);
|
|
Packit Service |
4684c1 |
else if (strftime
|
|
Packit Service |
4684c1 |
(s, max, "%a %b %d %H:%M:%S UTC %Y",
|
|
Packit Service |
4684c1 |
&t) == 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: strftime (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) this_update);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\t\tThis Update: %s\n"), s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
char s[42];
|
|
Packit Service |
4684c1 |
size_t max = sizeof(s);
|
|
Packit Service |
4684c1 |
struct tm t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (next_update != (time_t) - 1) {
|
|
Packit Service |
4684c1 |
if (gmtime_r(&next_update, &t) == NULL)
|
|
Packit Service |
4684c1 |
addf(str, "error: gmtime_r (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) next_update);
|
|
Packit Service |
4684c1 |
else if (strftime
|
|
Packit Service |
4684c1 |
(s, max, "%a %b %d %H:%M:%S UTC %Y",
|
|
Packit Service |
4684c1 |
&t) == 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: strftime (%ld)\n",
|
|
Packit Service |
4684c1 |
(unsigned long) next_update);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
addf(str, _("\t\tNext Update: %s\n"), s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* XXX singleRequestExtensions */
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, "\tExtensions:\n");
|
|
Packit Service |
4684c1 |
for (indx = 0;; indx++) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t oid;
|
|
Packit Service |
4684c1 |
unsigned int critical;
|
|
Packit Service |
4684c1 |
gnutls_datum_t data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_ocsp_resp_get_extension(resp, indx, &oid,
|
|
Packit Service |
4684c1 |
&critical, &data);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
else if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_extension: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (oid.size == sizeof(GNUTLS_OCSP_NONCE) &&
|
|
Packit Service |
4684c1 |
memcmp(oid.data, GNUTLS_OCSP_NONCE, oid.size) == 0) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t nonce;
|
|
Packit Service |
4684c1 |
unsigned int ncrit;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_ocsp_resp_get_nonce(resp, &ncrit,
|
|
Packit Service |
4684c1 |
&nonce);
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
addf(str, "error: get_nonce: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "\t\tNonce%s: ",
|
|
Packit Service |
4684c1 |
ncrit ? " (critical)" : "");
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, nonce.data,
|
|
Packit Service |
4684c1 |
nonce.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
gnutls_free(nonce.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
addf(str, "\t\tUnknown extension %s (%s):\n",
|
|
Packit Service |
4684c1 |
oid.data,
|
|
Packit Service |
4684c1 |
critical ? "critical" : "not critical");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, _("\t\t\tASCII: "));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_asciiprint(str, (char *) data.data,
|
|
Packit Service |
4684c1 |
data.size);
|
|
Packit Service |
4684c1 |
addf(str, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
adds(str, _("\t\t\tHexdump: "));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexprint(str, (char *) data.data,
|
|
Packit Service |
4684c1 |
data.size);
|
|
Packit Service |
4684c1 |
adds(str, "\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(oid.data);
|
|
Packit Service |
4684c1 |
gnutls_free(data.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_signature_algorithm(resp);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: get_signature_algorithm: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
const char *name =
|
|
Packit Service |
4684c1 |
gnutls_sign_algorithm_get_name(ret);
|
|
Packit Service |
4684c1 |
if (name == NULL)
|
|
Packit Service |
4684c1 |
name = _("unknown");
|
|
Packit Service |
4684c1 |
addf(str, _("\tSignature Algorithm: %s\n"), name);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_SIGN_UNKNOWN && gnutls_sign_is_secure(ret) == 0) {
|
|
Packit Service |
4684c1 |
adds(str,
|
|
Packit Service |
4684c1 |
_("warning: signed using a broken signature "
|
|
Packit Service |
4684c1 |
"algorithm that can be forged.\n"));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Signature. */
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_OCSP_PRINT_FULL) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t sig;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_signature(resp, &sig);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: get_signature: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
adds(str, _("\tSignature:\n"));
|
|
Packit Service |
4684c1 |
_gnutls_buffer_hexdump(str, sig.data, sig.size,
|
|
Packit Service |
4684c1 |
"\t\t");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(sig.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* certs */
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_OCSP_PRINT_FULL) {
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t *certs;
|
|
Packit Service |
4684c1 |
size_t ncerts, i;
|
|
Packit Service |
4684c1 |
gnutls_datum_t out;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_certs(resp, &certs, &ncerts);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: get_certs: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
if (ncerts > 0)
|
|
Packit Service |
4684c1 |
addf(str, "\tAdditional certificates:\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i = 0; i < ncerts; i++) {
|
|
Packit Service |
4684c1 |
size_t s = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_print(certs[i],
|
|
Packit Service |
4684c1 |
GNUTLS_CRT_PRINT_FULL,
|
|
Packit Service |
4684c1 |
&out;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
addf(str, "error: crt_print: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
addf(str, "%.*s", out.size,
|
|
Packit Service |
4684c1 |
out.data);
|
|
Packit Service |
4684c1 |
gnutls_free(out.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_export(certs[i],
|
|
Packit Service |
4684c1 |
GNUTLS_X509_FMT_PEM,
|
|
Packit Service |
4684c1 |
NULL, &s);
|
|
Packit Service |
4684c1 |
if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
|
|
Packit Service |
4684c1 |
addf(str,
|
|
Packit Service |
4684c1 |
"error: crt_export: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
out.data = gnutls_malloc(s);
|
|
Packit Service |
4684c1 |
if (out.data == NULL)
|
|
Packit Service |
4684c1 |
addf(str,
|
|
Packit Service |
4684c1 |
"error: malloc: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror
|
|
Packit Service |
4684c1 |
(GNUTLS_E_MEMORY_ERROR));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_export
|
|
Packit Service |
4684c1 |
(certs[i],
|
|
Packit Service |
4684c1 |
GNUTLS_X509_FMT_PEM,
|
|
Packit Service |
4684c1 |
out.data, &s);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
addf(str,
|
|
Packit Service |
4684c1 |
"error: crt_export: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror
|
|
Packit Service |
4684c1 |
(ret));
|
|
Packit Service |
4684c1 |
else {
|
|
Packit Service |
4684c1 |
out.size = s;
|
|
Packit Service |
4684c1 |
addf(str, "%.*s",
|
|
Packit Service |
4684c1 |
out.size,
|
|
Packit Service |
4684c1 |
out.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_free(out.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(certs[i]);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_free(certs);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_ocsp_resp_print:
|
|
Packit Service |
4684c1 |
* @resp: The data to be printed
|
|
Packit Service |
4684c1 |
* @format: Indicate the format to use
|
|
Packit Service |
4684c1 |
* @out: Newly allocated datum with (0) terminated string.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will pretty print a OCSP response, suitable for
|
|
Packit Service |
4684c1 |
* display to a human.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the format is %GNUTLS_OCSP_PRINT_FULL then all fields of the
|
|
Packit Service |
4684c1 |
* response will be output, on multiple lines.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The output @out->data needs to be deallocate using gnutls_free().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit Service |
4684c1 |
* negative error value.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_ocsp_resp_print(gnutls_ocsp_resp_const_t resp,
|
|
Packit Service |
4684c1 |
gnutls_ocsp_print_formats_t format,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * out)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st str;
|
|
Packit Service |
4684c1 |
int rc;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_init(&str);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_str(&str, _("OCSP Response Information:\n"));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
print_resp(&str, resp, format);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
rc = _gnutls_buffer_to_datum(&str, out, 1);
|
|
Packit Service |
4684c1 |
if (rc != GNUTLS_E_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return rc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SUCCESS;
|
|
Packit Service |
4684c1 |
}
|