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

Remove netopeer2-cli's CRL from a file support #1599

Merged
merged 1 commit into from
Jul 3, 2024
Merged
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
7 changes: 4 additions & 3 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ trusted store, or use the default directory. To add certificates
to this directory, use the `cert add` command.

## Certificate Revocation Lists
For netopeer-cli to check if a certificate was not revocated by
its issuer, use the `crl add` command to provide
CRLs of your trusted CAs for netopeer-cli.
CRLs are automatically downloaded from URIs specified in the
x509 CRLDistributionPoints extensions of set certificates.
Be wary that if any configured certificate has this extension,
then a CRL issued by the server's CA has to be present for the connection to succeed.

## Certificates

Expand Down
231 changes: 1 addition & 230 deletions cli/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1284,12 +1284,6 @@ cmd_cert_help(void)
printf("cert [--help | display | add <cert_path> | remove <cert_name> | displayown | replaceown (<cert_path.pem> | <cert_path.crt> <key_path.key>)]\n");
}

static void
cmd_crl_help(void)
{
printf("crl [--help | display | add <crl_path> | remove <crl_name>]\n");
}

static int
cmd_auth(const char *arg, char **UNUSED(tmp_config_file))
{
Expand Down Expand Up @@ -1911,85 +1905,6 @@ parse_cert(const char *name, const char *path)
fclose(fp);
}

static void
parse_crl(const char *name, const char *path)
{
int i;
BIO *bio_out;
FILE *fp;
X509_CRL *crl;
const ASN1_INTEGER *bs;
X509_REVOKED *rev;

fp = fopen(path, "r");
if (fp == NULL) {
ERROR("parse_crl", "Unable to open \"%s\": %s", path, strerror(errno));
return;
}
crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
if (crl == NULL) {
ERROR("parse_crl", "Unable to parse certificate: %s", path);
fclose(fp);
return;
}

bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);

BIO_printf(bio_out, "-----%s-----\n", name);

BIO_printf(bio_out, "Issuer: ");
X509_NAME_print(bio_out, X509_CRL_get_issuer(crl), 0);
BIO_printf(bio_out, "\n");

BIO_printf(bio_out, "Last update: ");
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(crl));
#else
ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(crl));
#endif
BIO_printf(bio_out, "\n");

BIO_printf(bio_out, "Next update: ");
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(crl));
#else
ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(crl));
#endif
BIO_printf(bio_out, "\n");

BIO_printf(bio_out, "REVOKED:\n");

if ((rev = sk_X509_REVOKED_pop(X509_CRL_get_REVOKED(crl))) == NULL) {
BIO_printf(bio_out, "\tNone\n");
}
while (rev != NULL) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
bs = rev->serialNumber;
#else
bs = X509_REVOKED_get0_serialNumber(rev);
#endif
BIO_printf(bio_out, "\tSerial no.: ");
for (i = 0; i < bs->length; i++) {
BIO_printf(bio_out, "%02x", bs->data[i]);
}

BIO_printf(bio_out, " Date: ");
#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0
ASN1_TIME_print(bio_out, rev->revocationDate);
#else
ASN1_TIME_print(bio_out, X509_REVOKED_get0_revocationDate(rev));
#endif
BIO_printf(bio_out, "\n");

X509_REVOKED_free(rev);
rev = sk_X509_REVOKED_pop(X509_CRL_get_REVOKED(crl));
}

X509_CRL_free(crl);
BIO_vfree(bio_out);
fclose(fp);
}

static int
cmd_cert(const char *arg, char **UNUSED(tmp_config_file))
{
Expand Down Expand Up @@ -2255,140 +2170,6 @@ cmd_cert(const char *arg, char **UNUSED(tmp_config_file))
return EXIT_FAILURE;
}

static int
cmd_crl(const char *arg, char **UNUSED(tmp_config_file))
{
int ret;
char *args = strdupa(arg);
char *cmd = NULL, *ptr = NULL, *path, *dest = NULL;
char *crl_dir = NULL, *rehash_cmd = NULL;
DIR *dir = NULL;
struct dirent *d;

cmd = strtok_r(args, " ", &ptr);
cmd = strtok_r(NULL, " ", &ptr);
if (!cmd || !strcmp(cmd, "--help") || !strcmp(cmd, "-h")) {
cmd_crl_help();

} else if (!strcmp(cmd, "display")) {
int none = 1;
char *name;

if (!(crl_dir = get_default_CRL_dir(NULL))) {
ERROR("crl display", "Could not get the default CRL directory");
goto error;
}

dir = opendir(crl_dir);
while ((d = readdir(dir))) {
if (!strcmp(d->d_name + strlen(d->d_name) - 4, ".pem")) {
none = 0;
name = strdup(d->d_name);
name[strlen(name) - 4] = '\0';
if (asprintf(&path, "%s/%s", crl_dir, d->d_name) == -1) {
free(name);
break;
}
parse_crl(name, path);
free(name);
free(path);
}
}
closedir(dir);
if (none) {
printf("No CRLs found in the default CRL directory.\n");
}

} else if (!strcmp(cmd, "add")) {
path = strtok_r(NULL, " ", &ptr);
if (!path || (strlen(path) < 5)) {
ERROR("crl add", "Missing or wrong path to the certificate");
goto error;
}
if (eaccess(path, R_OK)) {
ERROR("crl add", "Cannot access certificate \"%s\": %s", path, strerror(errno));
goto error;
}

crl_dir = get_default_CRL_dir(NULL);
if (!crl_dir) {
ERROR("crl add", "Could not get the default CRL directory");
goto error;
}

if ((asprintf(&dest, "%s/%s", crl_dir, strrchr(path, '/') + 1) == -1) ||
(asprintf(&rehash_cmd, "openssl rehash %s &> /dev/null", crl_dir) == -1)) {
ERROR("crl add", "Memory allocation failed");
goto error;
}

if (strcmp(dest + strlen(dest) - 4, ".pem")) {
ERROR("crl add", "CRLs are expected to be in *.pem format");
strcpy(dest + strlen(dest) - 4, ".pem");
}

if (cp(dest, path)) {
ERROR("crl add", "Could not copy the CRL \"%s\": %s", path, strerror(errno));
goto error;
}

if (((ret = system(rehash_cmd)) == -1) || WEXITSTATUS(ret)) {
ERROR("crl add", "openssl rehash execution failed");
goto error;
}

} else if (!strcmp(cmd, "remove")) {
path = strtok_r(NULL, " ", &ptr);
if (!path) {
ERROR("crl remove", "Missing the certificate name");
goto error;
}

// delete ".pem" if the user unnecessarily included it
if ((strlen(path) > 4) && !strcmp(path + strlen(path) - 4, ".pem")) {
path[strlen(path) - 4] = '\0';
}

crl_dir = get_default_CRL_dir(NULL);
if (!crl_dir) {
ERROR("crl remove", "Could not get the default CRL directory");
goto error;
}

if ((asprintf(&dest, "%s/%s.pem", crl_dir, path) == -1) ||
(asprintf(&rehash_cmd, "openssl rehash %s &> /dev/null", crl_dir) == -1)) {
ERROR("crl remove", "Memory allocation failed");
goto error;
}

if (remove(dest)) {
ERROR("crl remove", "Cannot remove CRL \"%s\": %s (use the name from \"crl display\" output)",
path, strerror(errno));
goto error;
}

if (((ret = system(rehash_cmd)) == -1) || WEXITSTATUS(ret)) {
ERROR("crl remove", "openssl rehash execution failed");
goto error;
}

} else {
ERROR("crl", "Unknown argument %s", cmd);
goto error;
}

free(dest);
free(rehash_cmd);
free(crl_dir);
return EXIT_SUCCESS;

error:
free(dest);
free(rehash_cmd);
free(crl_dir);
return EXIT_FAILURE;
}

static int
cmd_connect_listen_tls(struct arglist *cmd, int is_connect)
{
Expand All @@ -2397,7 +2178,7 @@ cmd_connect_listen_tls(struct arglist *cmd, int is_connect)
DIR *dir = NULL;
struct dirent *d;
int c, n, timeout = 0, ret = EXIT_FAILURE;
char *cert = NULL, *key = NULL, *trusted_dir = NULL, *crl_dir = NULL;
char *cert = NULL, *key = NULL, *trusted_dir = NULL;
unsigned short port = 0;
int option_index = 0;
struct option long_options[] = {
Expand Down Expand Up @@ -2510,15 +2291,10 @@ cmd_connect_listen_tls(struct arglist *cmd, int is_connect)
goto error_cleanup;
}
}
if (!(crl_dir = get_default_CRL_dir(NULL))) {
ERROR(func_name, "Could not use the CRL directory.");
goto error_cleanup;
}

if (is_connect) {
nc_client_tls_set_cert_key_paths(cert, key);
nc_client_tls_set_trusted_ca_paths(trusted_store, trusted_dir);
nc_client_tls_set_crl_paths(NULL, crl_dir);

/* default port */
if (!port) {
Expand All @@ -2539,7 +2315,6 @@ cmd_connect_listen_tls(struct arglist *cmd, int is_connect)
} else {
nc_client_tls_ch_set_cert_key_paths(cert, key);
nc_client_tls_ch_set_trusted_ca_paths(trusted_store, trusted_dir);
nc_client_tls_ch_set_crl_paths(NULL, crl_dir);

/* default timeout */
if (!timeout) {
Expand Down Expand Up @@ -2575,7 +2350,6 @@ cmd_connect_listen_tls(struct arglist *cmd, int is_connect)

error_cleanup:
free(trusted_dir);
free(crl_dir);
free(cert);
free(key);
return ret;
Expand Down Expand Up @@ -6742,9 +6516,6 @@ COMMAND commands[] = {
{"commit", cmd_commit, cmd_commit_help, "ietf-netconf <commit> operation"},
{"connect", cmd_connect, cmd_connect_help, "Connect to a NETCONF server"},
{"copy-config", cmd_copyconfig, cmd_copyconfig_help, "ietf-netconf <copy-config> operation"},
#ifdef NC_ENABLED_SSH_TLS
{"crl", cmd_crl, cmd_crl_help, "Manage Certificate Revocation List directory"},
#endif
{"delete-config", cmd_deleteconfig, cmd_deleteconfig_help, "ietf-netconf <delete-config> operation"},
{"delete-sub", cmd_deletesub, cmd_deletesub_help, "ietf-subscribed-notifications <delete-subscription> operation"},
{"discard-changes", cmd_discardchanges, cmd_discardchanges_help, "ietf-netconf <discard-changes> operation"},
Expand Down
5 changes: 2 additions & 3 deletions cli/completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,8 @@ complete_cmd(const char *buf, const char *hint, linenoiseCompletions *lc)

if (!strncmp(buf, "searchpath ", 11)
#ifdef NC_ENABLED_SSH_TLS
|| !strncmp(buf, "auth keys add ", 14) ||
!strncmp(buf, "cert add ", 9) || !strncmp(buf, "cert remove ", 12) || !strncmp(buf, "cert replaceown ", 16) ||
!strncmp(buf, "crl add ", 8) || !strncmp(buf, "crl remove ", 11)
|| !strncmp(buf, "auth keys add ", 14) || !strncmp(buf, "cert add ", 9) ||
!strncmp(buf, "cert remove ", 12) || !strncmp(buf, "cert replaceown ", 16)
#endif
) {
linenoisePathCompletion(buf, hint, lc);
Expand Down
45 changes: 0 additions & 45 deletions cli/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ struct cli_opts opts = {.output_format = LYD_XML};
#define NCC_DIR ".netopeer2-cli"
/* all these appended to NCC_DIR */
#define CA_DIR "certs"
#define CRL_DIR "crl"
#define CERT_CRT "client.crt"
#define CERT_PEM "client.pem"
#define CERT_KEY "client.key"
Expand Down Expand Up @@ -200,50 +199,6 @@ get_default_trustedCA_dir(DIR **ret_dir)
return cert_dir;
}

char *
get_default_CRL_dir(DIR **ret_dir)
{
char *netconf_dir, *crl_dir;

if (!(netconf_dir = get_netconf_dir())) {
return NULL;
}

if (asprintf(&crl_dir, "%s/%s", netconf_dir, CRL_DIR) == -1) {
ERROR(__func__, "asprintf() failed (%s:%d).", __FILE__, __LINE__);
ERROR(__func__, "Unable to use the trusted CA directory due to the previous error.");
free(netconf_dir);
return NULL;
}
free(netconf_dir);

if (ret_dir) {
if (!(*ret_dir = opendir(crl_dir))) {
ERROR(__func__, "Unable to open the default CRL directory (%s).", strerror(errno));
}
free(crl_dir);
return NULL;
}

errno = 0;
if (eaccess(crl_dir, R_OK | W_OK | X_OK)) {
if (errno == ENOENT) {
ERROR(__func__, "Default CRL dir does not exist, creating it.");
if (mkdir(crl_dir, 00777)) {
ERROR(__func__, "Failed to create the default CRL directory (%s).", strerror(errno));
free(crl_dir);
return NULL;
}
} else {
ERROR(__func__, "Unable to access the default CRL directory (%s).", strerror(errno));
free(crl_dir);
return NULL;
}
}

return crl_dir;
}

void
load_history(void)
{
Expand Down
Loading
Loading