#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>
/*
* 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.
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);
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;
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);
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;
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:
if (op == OP_RESPOND && !cacert)
{
- error = "respond mode requires a ca certificate";
+ error = "respond mode requires a CA certificate";
goto end;
}
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);
return res;
usage:
+ array_destroy_offset(index_responders, offsetof(ocsp_responder_t, destroy));
+ DESTROY_IF(cacert);
creds->destroy(creds);
return command_usage(error);
}
{
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]"},
{
{"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)"},
.BI \-\-cacert\~ file
.BI \-\-key\~ file
.OP \-\-cert file
+.OP \-\-index file
.OP \-\-lifetime minutes
.OP \-\-digest digest
.OP \-\-rsa\-padding padding
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
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: