Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced CRL checking and automatic CRL retrieval for libEST/examples #41

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 65 additions & 9 deletions example/client/estclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@

#include <est.h>
#include "../util/utils.h"
#include "../util/crl.c" // TODO include properly into Makefile

#define EST_UT_MAX_CMD_LEN 255
#define MAX_SERVER_LEN 255
#define MAX_FILENAME_LEN 255
#define MAX_CN 64

/*
* The CRL retrieval code in crl.c and client_manual_cert_verify() need this BIO to send errors to
*/
BIO *bio_err = NULL;

/*
* Global variables to hold command line options
*/
Expand All @@ -44,6 +50,10 @@ static char est_server[MAX_SERVER_LEN];
static char est_auth_token[MAX_AUTH_TOKEN_LEN+1];
static int est_port;
static int verbose = 0;
static int enable_crl = 0;
static int require_crl = 0;
static int use_cdp = 0;
static char default_cdp[MAX_FILENAME_LEN] = "";
static int srp = 0;
static int token_auth_mode = 0;
static int pem_out = 0;
Expand Down Expand Up @@ -106,6 +116,9 @@ static void show_usage_and_exit (void)
" -y <csrfile> Use existing CSR in the given file\n"
" -s <server> Enrollment server IP address\n"
" -p <port> TCP port number for enrollment server\n"
" -l[+] Enable CRL checks; +: require strict CRL checking\n"
" -L Use CDPs, which may be specified in certificates, for CRL checking\n"
" --cdp <url> Default CDP; URLs may start with 'http://' or 'file:'\n"
" -o <dir> Directory where pkcs7 certs will be written\n"
" -w <count> Timeout in seconds to wait for server response (default=10)\n" //EST_SSL_READ_TIMEOUT_DEF
" -f Runs EST Client in FIPS MODE = ON\n"
Expand Down Expand Up @@ -235,12 +248,10 @@ EST_HTTP_AUTH_CRED_RC auth_credentials_token_cb (EST_HTTP_AUTH_HDR *auth_credent

static int client_manual_cert_verify (X509 *cur_cert, int openssl_cert_error)
{
if (openssl_cert_error == X509_V_ERR_UNABLE_TO_GET_CRL) {
if (openssl_cert_error == X509_V_ERR_UNABLE_TO_GET_CRL && !require_crl) { // this part could now be handled by the library alone
return 1; // accepted
}

BIO *bio_err;
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
int approve = 0;

/*
Expand All @@ -259,8 +270,6 @@ static int client_manual_cert_verify (X509 *cur_cert, int openssl_cert_error)
*/
X509_signature_print(bio_err, cur_cert->sig_alg, cur_cert->signature);

BIO_free(bio_err);

return approve;
}

Expand Down Expand Up @@ -634,6 +643,11 @@ static void retry_enroll_delay (int retry_delay, time_t retry_time)
}
}

static STACK_OF(X509_CRL) *lookup_crls_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
{
return load_crls_from_cdps(ctx, nm, default_cdp);
}


static void do_operation ()
{
Expand All @@ -655,6 +669,25 @@ static void do_operation ()
exit(1);
}

if (enable_crl) {
rv = est_enable_crl(ectx);
if (rv != EST_ERR_NONE) {
printf("\nUnable to enable CRL checking. Aborting!!!\n");
exit(1);
}
}
rv = est_set_crl_strictness_lookup(ectx, require_crl, use_cdp ? lookup_crls_cb : NULL);
if (rv != EST_ERR_NONE) {
printf("\nUnable to set CRL checking. Aborting!!!\n");
exit(1);
}

if (rv != EST_ERR_NONE) {
printf("\nUnable to enable CRL checking. Aborting!!!\n");
printf("EST error code %d (%s)\n", rv, EST_ERR_NUM_TO_STR(rv));
exit(1);
}

rv = est_client_set_read_timeout(ectx, read_timeout);
if (rv != EST_ERR_NONE) {
printf("\nUnable to configure read timeout from server. Aborting!!!\n");
Expand Down Expand Up @@ -852,6 +885,7 @@ int main (int argc, char **argv)
BIO *certin;
static struct option long_options[] = {
{ "trustanchor", 1, 0, 0 },
{ "cdp", 1, 0, 0 },
{ "srp", 0, 0, 0 },
{ "srp-user", 1, 0, 0 },
{ "srp-password", 1, 0, 0 },
Expand All @@ -864,6 +898,12 @@ int main (int argc, char **argv)
int trustanchor = 1; /* default to require a trust anchor */
char *trustanchor_file = NULL;

bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
if (!bio_err) {
printf("\nBIO not working\n");
exit(1);
}

est_http_uid[0] = 0x0;
est_http_pwd[0] = 0x0;

Expand All @@ -878,7 +918,7 @@ int main (int argc, char **argv)
memset(client_cert_file, 0, 1);
memset(out_dir, 0, 1);

while ((c = getopt_long(argc, argv, "?zfvagerx:y:k:s:p:o:c:w:u:h:", long_options, &option_index)) != -1) {
while ((c = getopt_long(argc, argv, "?zfvagerx:y:k:s:p:o:c:w:u:h:l::L", long_options, &option_index)) != -1) {
switch (c) {
case 0:
#if 0
Expand All @@ -895,6 +935,10 @@ int main (int argc, char **argv)
trustanchor_file = optarg;
}
}
if (!strcmp(long_options[option_index].name, "cdp")) {
use_cdp = 1;
strncpy(default_cdp, optarg, MAX_FILENAME_LEN);
}
if (!strncmp(long_options[option_index].name, "srp", strlen("srp"))) {
srp = 1;
}
Expand All @@ -918,6 +962,20 @@ int main (int argc, char **argv)
case 'v':
verbose = 1;
break;
case 'l':
enable_crl = 1;
if (optarg) {
if (!strcmp(optarg, "+")) {
require_crl = 1;
} else {
fprintf(stderr, "Unrecognized -l option parameter '%s'. Aborting!!!\n", optarg);
exit(1);
}
}
break;
case 'L':
use_cdp = 1;
break;
case 'z':
force_pop = 1;
break;
Expand Down Expand Up @@ -1172,13 +1230,11 @@ int main (int argc, char **argv)
est_apps_shutdown();

#if DEBUG_OSSL_LEAKS
BIO *bio_err;
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
CRYPTO_mem_leaks(bio_err);
BIO_free(bio_err);
#endif

printf("\n");
BIO_free(bio_err);
return 0;
}

3 changes: 1 addition & 2 deletions example/server/apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ long app_RAND_load_files(char *file); /* `file' is a list of files to read,
* (see e_os.h). The string is
* destroyed! */

CONF *config=NULL;

extern CONF *config;
extern char *default_config_file;
extern BIO *bio_err;
Expand Down Expand Up @@ -235,6 +233,7 @@ typedef struct ca_db_st
#define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */
#define FORMAT_MSBLOB 11 /* MS Key blob format */
#define FORMAT_PVK 12 /* MS PVK file format */
#define FORMAT_HTTP 13 /* Download using HTTP */

#define EXT_COPY_NONE 0
#define EXT_COPY_ADD 1
Expand Down
3 changes: 2 additions & 1 deletion example/server/estExampleCA.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ serialNumber = optional
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
keyUsage=digitalSignature
crlDistributionPoints=URI:http://example.com/crl.pem
crlDistributionPoints=URI:file:../server/estCA/crl.pem
# Add the id-kp-cmcRA usage. This isn't defined in OpenSSL, so we
# Need to use the OID value
#extendedKeyUsage=critical,serverAuth,clientAuth,1.3.6.1.5.5.7.3.28
Expand All @@ -67,6 +67,7 @@ x509_extensions = v3_ca
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier=hash
crlDistributionPoints=URI:file:../server/estCA/crl.pem

[ req ]
default_bits = 2048
Expand Down
67 changes: 61 additions & 6 deletions example/server/estserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,26 @@
#include <est.h>
#include "ossl_srv.h"
#include "../util/utils.h"
#include "../util/crl.c" // TODO include properly into Makefile
#include "../util/simple_server.h"

#define MAX_FILENAME_LEN 255

/*
* The OpenSSL CA needs this BIO to send errors too
* The CRL retrieval code in crl.c and the OpenSSL CA need this BIO to send errors to
*/
BIO *bio_err = NULL;
CONF *config=NULL;

/*
* These are the command line options with defaults provided below
*/
static int verbose = 0;
static int write_csr = 0;
static int crl = 0;
static int enable_crl = 0;
static int require_crl = 0;
static int use_cdp = 0;
static char default_cdp[MAX_FILENAME_LEN] = "";
static int pop = 0;
static int v6 = 0;
static int srp = 0;
Expand Down Expand Up @@ -143,7 +148,9 @@ static void show_usage_and_exit (void)
" -c <file> PEM file to use for server cert\n"
" -k <file> PEM file to use for server key\n"
" -r <value> HTTP realm to present to clients\n"
" -l Enable CRL checks\n"
" -l[+] Enable CRL checks; +: require strict CRL checking\n"
" -L Use CDPs, which may be specified in certificates, for CRL checking\n"
" --cdp <url> Default CDP; URLs may start with 'http://' or 'file:'\n"
" -t Enable check for binding client PoP to the TLS UID\n"
#ifndef DISABLE_TSEARCH
" -m <seconds> Simulate manual CA enrollment\n"
Expand Down Expand Up @@ -640,6 +647,31 @@ void cleanup (void)
}


static int server_strong_cert_verify(EST_CTX *ectx, X509_STORE_CTX *store_ctx, int ok) // just a demo
{
if (store_ctx->untrusted) {
printf("Subjects of currently untrusted certs:\n");
for (int i = 0; i<sk_X509_num(store_ctx->untrusted); i++)
printf("%s\n", sk_X509_value(store_ctx->untrusted, i)->name);
} else {
printf("No currently untrusted certs\n");
}

printf("Current CRL score: 0x%04x\n", store_ctx->current_crl_score);
if (store_ctx->current_crl && store_ctx->current_crl->crl) {
printf("Issuer of currently used CRL: %s\n", X509_NAME_oneline(store_ctx->current_crl->crl->issuer, NULL, 0));
} else {
printf("No currently used CRL\n");
}

return ok;
}

static STACK_OF(X509_CRL) *lookup_crls_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
{
return load_crls_from_cdps(ctx, nm, default_cdp);
}

/*
* This is the main entry point into the example EST server.
* This routine parses the command line options, reads in the
Expand All @@ -662,6 +694,7 @@ int main (int argc, char **argv)
char vfile[255];
int option_index = 0;
static struct option long_options[] = {
{"cdp", 1, 0, 0},
{"srp", 1, NULL, 0},
{"enforce-csr", 0, NULL, 0},
{"token", 1, 0, 0},
Expand All @@ -674,7 +707,7 @@ int main (int argc, char **argv)
show_usage_and_exit();
}

while ((c = getopt_long(argc, argv, "?fhbwnovr:c:k:m:p:d:lt6", long_options, &option_index)) != -1) {
while ((c = getopt_long(argc, argv, "?fhbwnovr:c:k:m:p:d:l::Lt6", long_options, &option_index)) != -1) {
switch (c) {
case 0:
#if 0
Expand All @@ -684,6 +717,10 @@ int main (int argc, char **argv)
}
printf ("\n");
#endif
if (!strcmp(long_options[option_index].name, "cdp")) {
use_cdp = 1;
strncpy(default_cdp, optarg, MAX_FILENAME_LEN);
}
if (!strncmp(long_options[option_index].name,"srp", strlen("srp"))) {
srp = 1;
strncpy(vfile, optarg, 255);
Expand Down Expand Up @@ -722,7 +759,18 @@ int main (int argc, char **argv)
verbose = 1;
break;
case 'l':
crl = 1;
enable_crl = 1;
if (optarg) {
if (!strcmp(optarg, "+")) {
require_crl = 1;
} else {
fprintf(stderr, "Unrecognized -l option parameter '%s'. Aborting!!!\n", optarg);
exit(1);
}
}
break;
case 'L':
use_cdp = 1;
break;
case 't':
pop = 1;
Expand Down Expand Up @@ -868,6 +916,7 @@ int main (int argc, char **argv)
exit(1);
}
est_set_ex_data(ectx, &test_app_data);
est_set_strong_cert_verify_cb(ectx, server_strong_cert_verify);

if (enforce_csr) {
est_server_enforce_csrattr(ectx);
Expand All @@ -880,9 +929,15 @@ int main (int argc, char **argv)
if (verbose) printf("\nRetry period being set to: %d \n", retry_period);
est_server_set_retry_period(ectx, retry_period);

if (crl) {
if (enable_crl) {
est_enable_crl(ectx);
}
rv = est_set_crl_strictness_lookup(ectx, require_crl, use_cdp ? lookup_crls_cb : NULL);
if (rv != EST_ERR_NONE) {
printf("\nUnable to set CRL checking. Aborting!!!\n");
exit(1);
}

if (!pop) {
if (verbose) printf("\nDisabling PoP check");
est_server_disable_pop(ectx);
Expand Down
Loading