pki: Add --dn command to extract the subject DN of a certificate

This commit is contained in:
Tobias Brunner 2015-08-06 18:04:38 +02:00
parent 18662e9694
commit 6ef4668626
8 changed files with 135 additions and 82 deletions

View File

@ -1868,17 +1868,18 @@ AC_CONFIG_FILES([
man/ipsec.secrets.5
src/charon-cmd/charon-cmd.8
src/pki/man/pki.1
src/pki/man/pki---acert.1
src/pki/man/pki---dn.1
src/pki/man/pki---gen.1
src/pki/man/pki---issue.1
src/pki/man/pki---keyid.1
src/pki/man/pki---pkcs7.1
src/pki/man/pki---pkcs12.1
src/pki/man/pki---pkcs7.1
src/pki/man/pki---print.1
src/pki/man/pki---pub.1
src/pki/man/pki---req.1
src/pki/man/pki---self.1
src/pki/man/pki---signcrl.1
src/pki/man/pki---acert.1
src/pki/man/pki---verify.1
src/swanctl/swanctl.8
src/swanctl/swanctl.conf.5.head

View File

@ -5,7 +5,7 @@ AM_CPPFLAGS = \
noinst_PROGRAMS = bin2array bin2sql id2sql key2keyid keyid2sql oid2der \
thread_analysis dh_speed pubkey_speed crypt_burn hash_burn fetch \
dnssec malloc_speed aes-test settings-test timeattack extract-dn
dnssec malloc_speed aes-test settings-test timeattack
if USE_TLS
noinst_PROGRAMS += tls_test
@ -30,7 +30,6 @@ fetch_SOURCES = fetch.c
dnssec_SOURCES = dnssec.c
timeattack_SOURCES = timeattack.c
id2sql_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
extract_dn_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
key2keyid_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
keyid2sql_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
oid2der_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la

View File

@ -3,17 +3,18 @@ SUBDIRS = man
bin_PROGRAMS = pki
pki_SOURCES = pki.c pki.h command.c command.h \
commands/acert.c \
commands/dn.c \
commands/gen.c \
commands/issue.c \
commands/keyid.c \
commands/pkcs12.c \
commands/pkcs7.c \
commands/print.c \
commands/pub.c \
commands/req.c \
commands/self.c \
commands/print.c \
commands/signcrl.c \
commands/acert.c \
commands/pkcs7.c \
commands/pkcs12.c \
commands/verify.c
pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la

View File

@ -24,7 +24,7 @@
/**
* Maximum number of commands (+1).
*/
#define MAX_COMMANDS 13
#define MAX_COMMANDS 14
/**
* Maximum number of options in a command (+3)

View File

@ -12,31 +12,17 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include "pki.h"
#include <credentials/certificates/certificate.h>
#include <errno.h>
#include <getopt.h>
#include <library.h>
static void usage(FILE *out, char *name)
{
fprintf(out, "Extract the ASN.1 subject DN from a certificate\n\n");
fprintf(out, "%s [OPTIONS]\n\n", name);
fprintf(out, "Options:\n");
fprintf(out, " -h, --help print this help.\n");
fprintf(out, " -i, --in=FILE certificate file (default STDIN).\n");
fprintf(out, " -f, --format=FORMAT output format (config, hex, base64, binary).\n");
fprintf(out, "\n");
}
/**
* Extract the binary ASN.1 subject DN from a certificate
* Extract subject DN
*/
int main(int argc, char *argv[])
static int dn()
{
identification_t *id;
certificate_t *cert;
@ -47,76 +33,64 @@ int main(int argc, char *argv[])
FORMAT_BASE64,
FORMAT_BINARY,
} format = FORMAT_CONFIG;
int fd = 0;
char *fmt;
char *arg, *file = NULL, *fmt;
library_init(NULL, "extract-dn");
atexit(library_deinit);
while (true)
while (TRUE)
{
struct option long_opts[] = {
{"help", no_argument, NULL, 'h' },
{"in", required_argument, NULL, 'i' },
{"format", required_argument, NULL, 'f' },
{0,0,0,0 },
};
switch (getopt_long(argc, argv, "hi:f:", long_opts, NULL))
switch (command_getopt(&arg))
{
case EOF:
break;
case 'h':
usage(stdout, argv[0]);
return 0;
case 'i':
fd = open(optarg, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "failed to open '%s': %s\n", optarg,
strerror(errno));
usage(stderr, argv[0]);
return 1;
}
continue;
return command_usage(NULL);
case 'f':
if (streq(optarg, "hex"))
if (streq(arg, "hex"))
{
format = FORMAT_HEX;
}
else if (streq(optarg, "base64"))
else if (streq(arg, "base64"))
{
format = FORMAT_BASE64;
}
else if (streq(optarg, "bin"))
else if (streq(arg, "bin"))
{
format = FORMAT_BINARY;
}
else if (!streq(arg, "config"))
{
return command_usage( "invalid output format");
}
continue;
case 'i':
file = arg;
continue;
case EOF:
break;
default:
usage(stderr, argv[0]);
return 1;
return command_usage("invalid --print option");
}
break;
}
/* TODO: maybe make plugins configurable */
lib->plugins->load(lib->plugins, PLUGINS);
if (!chunk_from_fd(fd, &chunk))
if (file)
{
fprintf(stderr, "reading input failed: %s\n", strerror(errno));
return 1;
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, file, BUILD_END);
}
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB, chunk, BUILD_END);
chunk_free(&chunk);
if (fd != 0)
else
{
close(fd);
}
chunk_t chunk;
set_file_mode(stdin, CERT_ASN1_DER);
if (!chunk_from_fd(0, &chunk))
{
fprintf(stderr, "reading input failed: %s\n", strerror(errno));
return 1;
}
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB, chunk, BUILD_END);
free(chunk.ptr);
}
if (!cert)
{
fprintf(stderr, "failed to read certificate\n");
fprintf(stderr, "parsing input failed\n");
return 1;
}
id = cert->get_subject(cert);
@ -153,3 +127,20 @@ int main(int argc, char *argv[])
cert->destroy(cert);
return 0;
}
/**
* Register the command.
*/
static void __attribute__ ((constructor))reg()
{
command_register((command_t)
{ dn, 'd', "dn",
"extract the subject DN of an X.509 certificate",
{"[--in file] [--format config|hex|base64|bin]"},
{
{"help", 'h', 0, "show usage information"},
{"in", 'i', 1, "input file, default: stdin"},
{"format", 'f', 1, "output format, default: config"},
}
});
}

View File

@ -1,15 +1,16 @@
man1_MANS = \
pki.1 \
pki---gen.1 \
pki---self.1 \
pki---issue.1 \
pki---signcrl.1 \
pki---acert.1 \
pki---req.1 \
pki---pkcs7.1 \
pki---dn.1 \
pki---gen.1 \
pki---issue.1 \
pki---keyid.1 \
pki---pkcs7.1 \
pki---print.1 \
pki---pub.1 \
pki---req.1 \
pki---self.1 \
pki---signcrl.1 \
pki---verify.1
CLEANFILES = $(man1_MANS)

56
src/pki/man/pki---dn.1.in Normal file
View File

@ -0,0 +1,56 @@
.TH "PKI \-\-DN" 1 "2015-08-06" "@PACKAGE_VERSION@" "strongSwan"
.
.SH "NAME"
.
pki \-\-dn \- Extract the subject DN of an X.509 certificate
.
.SH "SYNOPSIS"
.
.SY pki\ \-\-dn
.OP \-\-in file
.OP \-\-format format
.OP \-\-debug level
.YS
.
.SY pki\ \-\-dn
.BI \-\-options\~ file
.YS
.
.SY "pki \-\-dn"
.B \-h
|
.B \-\-help
.YS
.
.SH "DESCRIPTION"
.
This sub-command of
.BR pki (1)
extracts the ASN.1-encoded subject DistinguishedName (DN) of an X.509
certificate and exports it in different formats. This may be useful when
strongSwan's identity parser is unable to produce the correct binary encoding
from a string.
.
.SH "OPTIONS"
.
.TP
.B "\-h, \-\-help"
Print usage information with a summary of the available options.
.TP
.BI "\-v, \-\-debug " level
Set debug level, default: 1.
.TP
.BI "\-+, \-\-options " file
Read command line options from \fIfile\fR.
.TP
.BI "\-i, \-\-in " file
Input file. If not given the input is read from \fISTDIN\fR.
.TP
.BI "\-t, \-\-format " format
Output format. One of \fIconfig\fR (strongSwan configuration compatible),
\fIhex\fR (hexadecimal encoding, no prefix), \fIbase64\fR (Base64 encoding,
no prefix), \fIbin\fR (raw binary data), defaults to \fIconfig\fR.
.
.SH "SEE ALSO"
.
.BR pki (1)

View File

@ -1,4 +1,4 @@
.TH PKI 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan"
.TH PKI 1 "2015-08-06" "@PACKAGE_VERSION@" "strongSwan"
.
.SH "NAME"
.
@ -64,6 +64,9 @@ Calculate key identifiers of a key or certificate.
.B "\-a, \-\-print"
Print a credential (key, certificate etc.) in human readable form.
.TP
.B "\-d, \-\-dn"
Extract the subject DN of an X.509 certificate.
.TP
.B "\-p, \-\-pub"
Extract a public key from a private key or certificate.
.TP
@ -156,5 +159,6 @@ certificates with the \-\-crl option.
.BR pki\ \-\-pkcs7 (1),
.BR pki\ \-\-keyid (1),
.BR pki\ \-\-print (1),
.BR pki\ \-\-dn (1),
.BR pki\ \-\-pub (1),
.BR pki\ \-\-verify (1)