pki: Add option to load certificate status information from index.txt
Each index.txt is associated with the most recently loaded CA certificate.
This commit is contained in:
+31
-5
@@ -18,7 +18,9 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "pki.h"
|
||||
#include "ocsp/index_responder.h"
|
||||
|
||||
#include <collections/array.h>
|
||||
#include <credentials/sets/mem_cred.h>
|
||||
#include <credentials/certificates/ocsp_request.h>
|
||||
#include <credentials/certificates/ocsp_response.h>
|
||||
@@ -155,7 +157,7 @@ static bool find_issuer_cacert(hash_algorithm_t hashAlgorithm,
|
||||
|
||||
/*
|
||||
* Find an OCSP signer certificate. Either the certificate of the CA itself that
|
||||
* issued the end entitity certificate, the certificate of an OCSP signer
|
||||
* issued the end-entity certificate, the certificate of an OCSP signer
|
||||
* delegated by the CA via the standard OCSPSigning Extended Key Usage (EKU)
|
||||
* flag or a self-signed OCSP signer certificate when multiple issuer OCSP
|
||||
* requests have to be supported.
|
||||
@@ -180,7 +182,7 @@ static void find_ocsp_signer(certificate_t *first_issuer, bool *self_signed,
|
||||
KEY_ANY, NULL, TRUE);
|
||||
while (certs->enumerate(certs, &candidate))
|
||||
{
|
||||
/* get the flags and key identfiers of the candidate certificate */
|
||||
/* get the flags and key identifiers of the candidate certificate */
|
||||
x509 = (x509_t*)candidate;
|
||||
flags = x509->get_flags(x509);
|
||||
subKeyId = x509->get_subjectKeyIdentifier(x509);
|
||||
@@ -228,7 +230,9 @@ static int ocsp()
|
||||
certificate_t *cacert = NULL, *first_issuer = NULL;
|
||||
ocsp_request_t *ocsp_request;
|
||||
ocsp_status_t ocsp_status = OCSP_SUCCESSFUL;
|
||||
ocsp_responder_t *index_responder = NULL;
|
||||
linked_list_t *responses = NULL;
|
||||
array_t *index_responders = NULL;
|
||||
chunk_t encoding = chunk_empty, nonce = chunk_empty;
|
||||
chunk_t issuerNameHash, issuerKeyHash, serialNumber;
|
||||
hash_algorithm_t hashAlgorithm = HASH_SHA1, digest = HASH_UNKNOWN;
|
||||
@@ -284,6 +288,7 @@ static int ocsp()
|
||||
creds->add_cert(creds, TRUE, cert);
|
||||
continue;
|
||||
case 'C':
|
||||
DESTROY_IF(cacert);
|
||||
cacert = lib->creds->create(lib->creds,
|
||||
CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_FROM_FILE, arg, BUILD_END);
|
||||
@@ -292,7 +297,7 @@ static int ocsp()
|
||||
error = "parsing CA certificate failed";
|
||||
goto usage;
|
||||
}
|
||||
creds->add_cert(creds, TRUE, cacert);
|
||||
cacert = creds->add_cert_ref(creds, TRUE, cacert);
|
||||
continue;
|
||||
case 'l':
|
||||
lifetime = atoi(arg) * 60;
|
||||
@@ -316,6 +321,21 @@ static int ocsp()
|
||||
goto usage;
|
||||
}
|
||||
continue;
|
||||
case 'x':
|
||||
if (!cacert)
|
||||
{
|
||||
error = "--index must follow --cacert of corresponding CA";
|
||||
goto usage;
|
||||
}
|
||||
index_responder = index_responder_create(cacert, arg);
|
||||
if (!index_responder)
|
||||
{
|
||||
error = "invalid ---index value";
|
||||
goto usage;
|
||||
}
|
||||
array_insert_create(&index_responders, ARRAY_TAIL,
|
||||
index_responder);
|
||||
continue;
|
||||
case EOF:
|
||||
break;
|
||||
default:
|
||||
@@ -331,7 +351,7 @@ static int ocsp()
|
||||
|
||||
if (op == OP_RESPOND && !cacert)
|
||||
{
|
||||
error = "respond mode requires a ca certificate";
|
||||
error = "respond mode requires a CA certificate";
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -542,6 +562,8 @@ gen:
|
||||
res = 0;
|
||||
|
||||
end:
|
||||
array_destroy_offset(index_responders, offsetof(ocsp_responder_t, destroy));
|
||||
DESTROY_IF(cacert);
|
||||
DESTROY_IF(key);
|
||||
lib->credmgr->remove_local_set(lib->credmgr, &creds->set);
|
||||
creds->destroy(creds);
|
||||
@@ -558,6 +580,8 @@ end:
|
||||
return res;
|
||||
|
||||
usage:
|
||||
array_destroy_offset(index_responders, offsetof(ocsp_responder_t, destroy));
|
||||
DESTROY_IF(cacert);
|
||||
creds->destroy(creds);
|
||||
return command_usage(error);
|
||||
}
|
||||
@@ -569,7 +593,8 @@ static void __attribute__ ((constructor))reg()
|
||||
{
|
||||
command_register((command_t) {
|
||||
ocsp, 'o', "ocsp", "OCSP responder",
|
||||
{"[--in file] [--respond] [--cert file]+ [--key file]+ [--cacert file]+ ",
|
||||
{"[--in file] [--respond] [--cert file]+ [--key file]+ ",
|
||||
"[--cacert file [--index file]]+",
|
||||
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
|
||||
"[--rsa-padding pkcs1|pss] [--lifetime minutes]"},
|
||||
{
|
||||
@@ -579,6 +604,7 @@ static void __attribute__ ((constructor))reg()
|
||||
{"key", 'k', 1, "path to OCSP signing private key (can be used multiple times)"},
|
||||
{"cert", 'c', 1, "path to OCSP signing certificate (can be used multiple times"},
|
||||
{"cacert", 'C', 1, "CA certificate (can be used multiple times"},
|
||||
{"index", 'x', 1, "OpenSSL-style index.txt to check status of certificates"},
|
||||
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
|
||||
{"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
|
||||
{"lifetime", 'l', 1, "validity in minutes of the OCSP response (if missing, nextUpdate is omitted)"},
|
||||
|
||||
@@ -18,6 +18,7 @@ pki \-\-ocsp \- OCSP request parser and OCSP responder.
|
||||
.BI \-\-cacert\~ file
|
||||
.BI \-\-key\~ file
|
||||
.OP \-\-cert file
|
||||
.OP \-\-index file
|
||||
.OP \-\-lifetime minutes
|
||||
.OP \-\-digest digest
|
||||
.OP \-\-rsa\-padding padding
|
||||
@@ -87,6 +88,14 @@ OCSP signer key. Can be used multiple times.
|
||||
OCSP signer certificate (if it is not a CA certificate). Can be used
|
||||
multiple times.
|
||||
.TP
|
||||
.BI "\-x, \-\-index " file
|
||||
OpenSSL-style index.txt providing information about the status of certificates
|
||||
issued by the CA certificate loaded immediately before. Can be used multiple
|
||||
times if the status for multiple CAs should be provided, just make sure to
|
||||
pass each index.txt file right after the corresponding CA certificate.
|
||||
|
||||
See below for a description of the structure of these files.
|
||||
.TP
|
||||
.BI "\-l, \-\-lifetime " minutes
|
||||
Validity in minutes of the OCSP response (if missing, nextUpdate is omitted).
|
||||
.TP
|
||||
@@ -94,12 +103,52 @@ Validity in minutes of the OCSP response (if missing, nextUpdate is omitted).
|
||||
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
|
||||
\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR, \fIsha3_224\fR,
|
||||
\fIsha3_256\fR, \fIsha3_384\fR, \fIsha3_512\fR. The default is
|
||||
determined based on the type and size of the ocsp signing key.
|
||||
determined based on the type and size of the OCSP signing key.
|
||||
.TP
|
||||
.BI "\-R, \-\-rsa\-padding " padding
|
||||
Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
|
||||
to \fIpkcs1\fR.
|
||||
.
|
||||
.SH "INDEX.TXT DESCRIPTION"
|
||||
.
|
||||
Each line in an index.txt file consists of six columns that are separated by
|
||||
tab characters:
|
||||
|
||||
The first column denotes the certificate status, which can be either "V" (for
|
||||
valid), "E" (for expired, treated like valid), or "R" (for revoked).
|
||||
|
||||
The second column contains the certificate's expiration date and time in UTC in
|
||||
the format YYMMDDHHMMSSZ. This field is ignored by the command but must not be
|
||||
empty.
|
||||
|
||||
The third column is the revocation date and time in UTC in the format
|
||||
YYMMDDHHMMSSZ and an optional revocation reason that immediately follows it,
|
||||
separated by a comma. Valid reasons are "keyCompromise", "CACompromise",
|
||||
"affiliationChanged", "superseded", "cessationOfOperation", "certificateHold",
|
||||
and "removeFromCRL", any other value or omitting a reason results in
|
||||
"unspecified".
|
||||
|
||||
The fourth column contains the certificate's serial number in
|
||||
hexadecimal encoding.
|
||||
|
||||
The fifth and sixth columns are both ignored by the command, so they may be
|
||||
omitted completely. They can contain a path to the certificate (usually set to
|
||||
"unknown") and the certificate's subject DN with slashes separating the RDNs.
|
||||
|
||||
Example index.txt:
|
||||
.PP
|
||||
.EX
|
||||
V 310930122422Z 03 unknown /C=CH/O=strongSwan/CN=moon...
|
||||
V 310930122422Z 04 unknown /C=CH/O=strongSwan/CN=sun...
|
||||
R 310930122422Z 231002122422Z,keyCompromise 88
|
||||
V Z 05
|
||||
.EE
|
||||
.PP
|
||||
Note that the fields are separated by tabs. So if a certificate is valid, two
|
||||
tabs follow after the expiration date. The third line in this example only
|
||||
specifies the relevant first four columns, the fourth even uses a dummy
|
||||
expiration date.
|
||||
.
|
||||
.SH "EXAMPLES"
|
||||
.
|
||||
Show the raw content of an OCSP request:
|
||||
|
||||
Reference in New Issue
Block a user