openac: Remove obsolete openac utility

The same functionality is now provided by the pki --acert subcommand.
This commit is contained in:
Martin Willi 2014-03-31 11:30:51 +02:00
parent 3941d55f01
commit dbd4fc074a
10 changed files with 21 additions and 772 deletions

View File

@ -1,6 +1,3 @@
openac.load =
Plugins to load in ipsec openac tool.
pki.load =
Plugins to load in ipsec pki tool.

View File

@ -265,7 +265,7 @@ ARG_ENABL_SET([medsrv], [enable mediation server web frontend and daemon
ARG_ENABL_SET([nm], [enable NetworkManager backend.])
ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).])
ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.])
ARG_DISBL_SET([tools], [disable additional utilities (openac, scepclient and pki).])
ARG_DISBL_SET([tools], [disable additional utilities (scepclient and pki).])
# optional features
ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.])
ARG_DISBL_SET([ikev1], [disable IKEv1 protocol support in charon.])
@ -1053,7 +1053,6 @@ charon_plugins=
starter_plugins=
pool_plugins=
attest_plugins=
openac_plugins=
scepclient_plugins=
pki_plugins=
scripts_plugins=
@ -1069,7 +1068,7 @@ h_plugins=
s_plugins=
t_plugins=
ADD_PLUGIN([test-vectors], [s charon openac scepclient pki])
ADD_PLUGIN([test-vectors], [s charon scepclient pki])
ADD_PLUGIN([curl], [s charon scepclient scripts nm cmd])
ADD_PLUGIN([soup], [s charon scripts nm cmd])
ADD_PLUGIN([unbound], [s charon scripts])
@ -1077,38 +1076,38 @@ ADD_PLUGIN([ldap], [s charon scepclient scripts nm cmd])
ADD_PLUGIN([mysql], [s charon pool manager medsrv attest])
ADD_PLUGIN([sqlite], [s charon pool manager medsrv attest])
ADD_PLUGIN([pkcs11], [s charon pki nm cmd])
ADD_PLUGIN([aes], [s charon openac scepclient pki scripts nm cmd])
ADD_PLUGIN([des], [s charon openac scepclient pki scripts nm cmd])
ADD_PLUGIN([blowfish], [s charon openac scepclient pki scripts nm cmd])
ADD_PLUGIN([rc2], [s charon openac scepclient pki scripts nm cmd])
ADD_PLUGIN([sha1], [s charon openac scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([sha2], [s charon openac scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([md4], [s charon openac manager scepclient pki nm cmd])
ADD_PLUGIN([md5], [s charon openac scepclient pki scripts attest nm cmd])
ADD_PLUGIN([rdrand], [s charon openac scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([random], [s charon openac scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([aes], [s charon scepclient pki scripts nm cmd])
ADD_PLUGIN([des], [s charon scepclient pki scripts nm cmd])
ADD_PLUGIN([blowfish], [s charon scepclient pki scripts nm cmd])
ADD_PLUGIN([rc2], [s charon scepclient pki scripts nm cmd])
ADD_PLUGIN([sha1], [s charon scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([sha2], [s charon scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([md4], [s charon manager scepclient pki nm cmd])
ADD_PLUGIN([md5], [s charon scepclient pki scripts attest nm cmd])
ADD_PLUGIN([rdrand], [s charon scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([random], [s charon scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([nonce], [s charon nm cmd])
ADD_PLUGIN([x509], [s charon openac scepclient pki scripts attest nm cmd])
ADD_PLUGIN([x509], [s charon scepclient pki scripts attest nm cmd])
ADD_PLUGIN([revocation], [s charon nm cmd])
ADD_PLUGIN([constraints], [s charon nm cmd])
ADD_PLUGIN([acert], [s charon])
ADD_PLUGIN([pubkey], [s charon cmd])
ADD_PLUGIN([pkcs1], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([pkcs1], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([pkcs7], [s charon scepclient pki scripts nm cmd])
ADD_PLUGIN([pkcs8], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([pkcs8], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([pkcs12], [s charon scepclient pki scripts cmd])
ADD_PLUGIN([pgp], [s charon])
ADD_PLUGIN([dnskey], [s charon pki])
ADD_PLUGIN([sshkey], [s charon pki nm cmd])
ADD_PLUGIN([dnscert], [c charon])
ADD_PLUGIN([ipseckey], [c charon])
ADD_PLUGIN([pem], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([pem], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([padlock], [s charon])
ADD_PLUGIN([openssl], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([gcrypt], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([af-alg], [s charon openac scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([openssl], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([gcrypt], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([af-alg], [s charon scepclient pki scripts medsrv attest nm cmd])
ADD_PLUGIN([fips-prf], [s charon nm cmd])
ADD_PLUGIN([gmp], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([gmp], [s charon scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([agent], [s charon nm cmd])
ADD_PLUGIN([keychain], [s charon cmd])
ADD_PLUGIN([xcbc], [s charon nm cmd])
@ -1190,7 +1189,6 @@ AC_SUBST(charon_plugins)
AC_SUBST(starter_plugins)
AC_SUBST(pool_plugins)
AC_SUBST(attest_plugins)
AC_SUBST(openac_plugins)
AC_SUBST(scepclient_plugins)
AC_SUBST(pki_plugins)
AC_SUBST(scripts_plugins)
@ -1586,7 +1584,6 @@ AC_CONFIG_FILES([
src/_updown/Makefile
src/_updown_espmark/Makefile
src/_copyright/Makefile
src/openac/Makefile
src/scepclient/Makefile
src/pki/Makefile
src/pki/man/Makefile

View File

@ -1,5 +1,3 @@
usr/lib/strongswan/scepclient usr/lib/strongswan/
usr/lib/strongswan/openac usr/lib/strongswan/
usr/lib/strongswan/pki usr/lib/strongswan/
usr/share/man/man8/scepclient.8 usr/share/man/man8/
usr/share/man/man8/openac.8 usr/share/man/man8/

View File

@ -73,7 +73,7 @@ if USE_UPDOWN
endif
if USE_TOOLS
SUBDIRS += openac scepclient pki
SUBDIRS += scepclient pki
endif
if USE_CONFTEST

View File

@ -100,7 +100,6 @@ if USE_CMD
endif
if USE_TOOLS
exes += $(DESTDIR)$(ipsecdir)/openac
exes += $(DESTDIR)$(ipsecdir)/scepclient
exes += $(DESTDIR)$(bindir)/pki
endif

View File

@ -70,7 +70,6 @@ case "$1" in
echo " rereadcacerts|rereadaacerts|rereadocspcerts"
echo " rereadacerts|rereadcrls|rereadall"
echo " purgeocsp|purgecrls|purgecerts|purgeike"
echo " openac"
echo " scepclient"
echo " secrets"
echo " starter"

View File

@ -1 +0,0 @@
openac

View File

@ -1,11 +0,0 @@
ipsec_PROGRAMS = openac
openac_SOURCES = openac.c
dist_man_MANS = openac.8
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-DIPSEC_CONFDIR=\"${sysconfdir}\" \
-DPLUGINS=\""${openac_plugins}\""
openac_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
openac.o : $(top_builddir)/config.status

View File

@ -1,165 +0,0 @@
.TH IPSEC_OPENAC 8 "22 September 2007"
.SH NAME
ipsec openac \- Generation of X.509 attribute certificates
.SH SYNOPSIS
.B ipsec
.B openac
[
.B \-\-help
] [
.B \-\-version
] [
.B \-\-optionsfrom
\fIfilename\fP
]
.br
\ \ \ [
.B \-\-quiet
] [
.B \-\-debug
\fIlevel\fP
]
.br
\ \ \ [
.B \-\-days
\fIdays\fP
] [
.B \-\-hours
\fIhours\fP
]
.br
\ \ \ [
.B \-\-startdate
\fIYYYYMMDDHHMMSSZ\fP
] [
.B \-\-stopdate
\fIYYYYMMDDHHMMSSZ\fP
]
.br
.B \ \ \ \-\-cert
\fIcertfile\fP
.B \-\-key
\fIkeyfile\fP
[
.B \-\-password
\fIpassword\fP
]
.br
.B \ \ \ \-\-usercert
\fIcertfile\fP
.B \-\-groups
\fIattr1,attr2,...\fP
.B \-\-out
\fIfilename\fP
.SH DESCRIPTION
.BR openac
is intended to be used by an Authorization Authority (AA) to generate and sign
X.509 attribute certificates. Currently only the inclusion of one ore several group
attributes is supported. An attribute certificate is linked to a holder by
including the issuer and serial number of the holder's X.509 certificate.
.SH OPTIONS
.TP
\fB\-\-help\fP
display the usage message.
.TP
\fB\-\-version\fP
display the version of \fBopenac\fP.
.TP
\fB\-\-optionsfrom\fP\ \fIfilename\fP
adds the contents of the file to the argument list.
If \fIfilename\fP is a relative path then the file is searched in the directory
\fI/etc/openac\fP.
.TP
\fB\-\-quiet\fP
By default \fBopenac\fP logs all control output both to syslog and stderr.
With the \fB\-\-quiet\fP option no output is written to stderr.
.TP
\fB\-\-days\fP\ \fIdays\fP
Validity of the X.509 attribute certificate in days. If neiter the \fB\-\-days\fP\ nor
the \fB\-\-hours\fP\ option is specified then a default validity interval of 1 day is assumed.
The \fB\-\-days\fP\ option can be combined with the \fB\-\-hours\fP\ option.
.TP
\fB\-\-hours\fP\ \fIhours\fP
Validity of the X.509 attribute certificate in hours. If neiter the \fB\-\-hours\fP\ nor
the \fB\-\-days\fP\ option is specified then a default validity interval of 24 hours is assumed.
The \fB\-\-hours\fP\ option can be combined with the \fB\-\-days\fP\ option.
.TP
\fB\-\-startdate\fP\ \fIYYYYMMDDHHMMSSZ\fP
defines the \fBnotBefore\fP date when the X.509 attribute certificate becomes valid.
The date \fIYYYYMMDDHHMMSS\fP must be specified in UTC (\fIZ\fPulu time).
If the \fB\-\-startdate\fP option is not specified then the current date is taken as a default.
.TP
\fB\-\-stopdate\fP\ \fIYYYYMMDDHHMMSSZ\fP
defines the \fBnotAfter\fP date when the X.509 attribute certificate will expire.
The date \fIYYYYMMDDHHMMSS\fP must be specified in UTC (\fIZ\fPulu time).
If the \fB\-\-stopdate\fP option is not specified then the default \fBnotAfter\fP value is computed
by adding the validity interval specified by the \fB\-\-days\fP\ and/or \fB\-\-days\fP\ options
to the \fBnotBefore\fP date.
.TP
\fB\-\-cert\fP\ \fIcertfile\fP
specifies the file containing the X.509 certificate of the Authorization Authority.
The certificate is stored either in PEM or DER format.
.TP
\fB\-\-key\fP\ \fIkeyfile\fP
specifies the encrypted file containing the private RSA key of the Authoritzation
Authority. The private key is stored in PKCS#1 format.
.TP
\fB\-\-password\fP\ \fIpassword\fP
specifies the password with which the private RSA keyfile defined by the
\fB\-\-key\fP option has been protected. If the option is missing then the
password is prompted for on the command line.
.TP
\fB\-\-usercert\fP\ \fIcertfile\fP
specifies file containing the X.509 certificate of the user to which the generated attribute
certificate will apply. The certificate file is stored either in PEM or DER format.
.TP
\fB\-\-groups\fP\ \fIattr1,attr2\fP
specifies a comma-separated list of group attributes that will go into the
X.509 attribute certificate.
.TP
\fB\-\-out\fP\ \fIfilename\fP
specifies the file where the generated X.509 attribute certificate will be stored to.
.SS Debugging
.LP
\fBopenac\fP produces a prodigious amount of debugging information. To do so,
it must be compiled with \-DDEBUG. There are several classes of debugging output,
and \fBopenac\fP may be directed to produce a selection of them. All lines of
debugging output are prefixed with ``|\ '' to distinguish them from error messages.
.LP
When \fBopenac\fP is invoked, it may be given arguments to specify
which classes to output. The current options are:
.TP
\fB\-\-debug\fP\ \fIlevel\fP
sets the debug level to 0 (none), 1 (normal), 2 (more), 3 (raw), and 4 (private),
the default level being 1.
.SH EXIT STATUS
.LP
The execution of \fBopenac\fP terminates with one of the following two exit codes:
.TP
0
means that the attribute certificate was successfully generated and stored.
.TP
1
means that something went wrong.
.SH FILES
\fI/etc/openac/serial\fP\ \ \ serial number of latest attribute certificate
.SH SEE ALSO
.LP
The X.509 attribute certificates generated with \fBopenac\fP can be used to
enforce group policies defined by \fIipsec.conf\fP(5). Use \fIipsec_auto\fP(8)
to load and list X.509 attribute certificates.
.LP
For more information on X.509 attribute certificates, refer to the following
IETF RFC:
.IP
RFC 3281 An Internet Attribute Certificate Profile for Authorization
.SH HISTORY
The \fBopenac\fP program was originally written by Ariane Seiler and Ueli Galizzi.
The software was recoded by Andreas Steffen using strongSwan's X.509 library and
the ASN.1 code synthesis functions written by Christoph Gysin and Christoph Zwahlen.
All authors were with the Zurich University of Applied Sciences in Winterthur,
Switzerland.
.LP
.SH BUGS
Bugs should be reported to the <users@lists.strongswan.org> mailing list.

View File

@ -1,564 +0,0 @@
/**
* @file openac.c
*
* @brief Generation of X.509 attribute certificates.
*
*/
/*
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2004,2007 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <getopt.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include <library.h>
#include <utils/debug.h>
#include <asn1/asn1.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/ac.h>
#include <credentials/keys/private_key.h>
#include <credentials/sets/mem_cred.h>
#include <utils/optionsfrom.h>
#define OPENAC_PATH IPSEC_CONFDIR "/openac"
#define OPENAC_SERIAL IPSEC_CONFDIR "/openac/serial"
#define DEFAULT_VALIDITY 24*3600 /* seconds */
/**
* @brief prints the usage of the program to the stderr
*/
static void usage(const char *message)
{
if (message != NULL && *message != '\0')
{
fprintf(stderr, "%s\n", message);
}
fprintf(stderr, "Usage: openac"
" [--help]"
" [--version]"
" [--optionsfrom <filename>]"
" [--quiet]"
" \\\n\t"
" [--debug <level 0..4>]"
" \\\n\t"
" [--days <days>]"
" [--hours <hours>]"
" \\\n\t"
" [--startdate <YYYYMMDDHHMMSSZ>]"
" [--enddate <YYYYMMDDHHMMSSZ>]"
" \\\n\t"
" --cert <certfile>"
" --key <keyfile>"
" [--password <password>]"
" \\\n\t"
" --usercert <certfile>"
" --groups <attr1,attr2,..>"
" --out <filename>"
"\n"
);
}
/**
* read the last serial number from file
*/
static chunk_t read_serial(void)
{
chunk_t hex, serial = chunk_empty;
char one[] = {0x01};
FILE *fd;
fd = fopen(OPENAC_SERIAL, "r");
if (fd)
{
hex = chunk_alloca(64);
hex.len = fread(hex.ptr, 1, hex.len, fd);
if (hex.len)
{
/* remove any terminating newline character */
if (hex.ptr[hex.len-1] == '\n')
{
hex.len--;
}
serial = chunk_alloca((hex.len / 2) + (hex.len % 2));
serial = chunk_from_hex(hex, serial.ptr);
}
fclose(fd);
}
else
{
DBG1(DBG_LIB, " file '%s' does not exist yet - serial number "
"set to 01", OPENAC_SERIAL);
}
if (!serial.len)
{
return chunk_clone(chunk_create(one, 1));
}
if (chunk_increment(serial))
{ /* overflow, prepend 0x01 */
return chunk_cat("cc", chunk_create(one, 1), serial);
}
return chunk_clone(serial);
}
/**
* write back the last serial number to file
*/
static void write_serial(chunk_t serial)
{
FILE *fd = fopen(OPENAC_SERIAL, "w");
if (fd)
{
chunk_t hex_serial;
DBG1(DBG_LIB, " serial number is %#B", &serial);
hex_serial = chunk_to_hex(serial, NULL, FALSE);
fprintf(fd, "%.*s\n", (int)hex_serial.len, hex_serial.ptr);
fclose(fd);
free(hex_serial.ptr);
}
else
{
DBG1(DBG_LIB, " could not open file '%s' for writing", OPENAC_SERIAL);
}
}
/**
* global variables accessible by both main() and build.c
*/
static int debug_level = 1;
static bool stderr_quiet = FALSE;
/**
* openac dbg function
*/
static void openac_dbg(debug_t group, level_t level, char *fmt, ...)
{
int priority = LOG_INFO;
char buffer[8192];
char *current = buffer, *next;
va_list args;
if (level <= debug_level)
{
if (!stderr_quiet)
{
va_start(args, fmt);
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
}
/* write in memory buffer first */
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
/* do a syslog with every line */
while (current)
{
next = strchr(current, '\n');
if (next)
{
*(next++) = '\0';
}
syslog(priority, "%s\n", current);
current = next;
}
}
}
/**
* @brief openac main program
*
* @param argc number of arguments
* @param argv pointer to the argument values
*/
int main(int argc, char **argv)
{
certificate_t *attr_cert = NULL;
certificate_t *userCert = NULL;
certificate_t *signerCert = NULL;
private_key_t *signerKey = NULL;
time_t notBefore = UNDEFINED_TIME;
time_t notAfter = UNDEFINED_TIME;
time_t validity = 0;
char *keyfile = NULL;
char *certfile = NULL;
char *usercertfile = NULL;
char *outfile = NULL;
char *groups = "";
char buf[BUF_LEN];
chunk_t passphrase = { buf, 0 };
chunk_t serial = chunk_empty;
chunk_t attr_chunk = chunk_empty;
int status = 1;
/* enable openac debugging hook */
dbg = openac_dbg;
passphrase.ptr[0] = '\0';
openlog("openac", 0, LOG_AUTHPRIV);
/* initialize library */
atexit(library_deinit);
if (!library_init(NULL, "openac"))
{
exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
}
if (lib->integrity &&
!lib->integrity->check_file(lib->integrity, "openac", argv[0]))
{
fprintf(stderr, "integrity check of openac failed\n");
exit(SS_RC_DAEMON_INTEGRITY);
}
if (!lib->plugins->load(lib->plugins,
lib->settings->get_str(lib->settings, "openac.load", PLUGINS)))
{
exit(SS_RC_INITIALIZATION_FAILED);
}
/* initialize optionsfrom */
options_t *options = options_create();
/* handle arguments */
for (;;)
{
static const struct option long_opts[] = {
/* name, has_arg, flag, val */
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "optionsfrom", required_argument, NULL, '+' },
{ "quiet", no_argument, NULL, 'q' },
{ "cert", required_argument, NULL, 'c' },
{ "key", required_argument, NULL, 'k' },
{ "password", required_argument, NULL, 'p' },
{ "usercert", required_argument, NULL, 'u' },
{ "groups", required_argument, NULL, 'g' },
{ "days", required_argument, NULL, 'D' },
{ "hours", required_argument, NULL, 'H' },
{ "startdate", required_argument, NULL, 'S' },
{ "enddate", required_argument, NULL, 'E' },
{ "out", required_argument, NULL, 'o' },
{ "debug", required_argument, NULL, 'd' },
{ 0,0,0,0 }
};
int c = getopt_long(argc, argv, "hv+:qc:k:p;u:g:D:H:S:E:o:d:", long_opts, NULL);
/* Note: "breaking" from case terminates loop */
switch (c)
{
case EOF: /* end of flags */
break;
case 0: /* long option already handled */
continue;
case ':': /* diagnostic already printed by getopt_long */
case '?': /* diagnostic already printed by getopt_long */
case 'h': /* --help */
usage(NULL);
status = 1;
goto end;
case 'v': /* --version */
printf("openac (strongSwan %s)\n", VERSION);
status = 0;
goto end;
case '+': /* --optionsfrom <filename> */
{
char path[BUF_LEN];
if (*optarg == '/') /* absolute pathname */
{
strncpy(path, optarg, BUF_LEN);
path[BUF_LEN-1] = '\0';
}
else /* relative pathname */
{
snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg);
}
if (!options->from(options, path, &argc, &argv, optind))
{
status = 1;
goto end;
}
}
continue;
case 'q': /* --quiet */
stderr_quiet = TRUE;
continue;
case 'c': /* --cert */
certfile = optarg;
continue;
case 'k': /* --key */
keyfile = optarg;
continue;
case 'p': /* --key */
if (strlen(optarg) >= BUF_LEN)
{
usage("passphrase too long");
goto end;
}
strncpy(passphrase.ptr, optarg, BUF_LEN);
passphrase.len = min(strlen(optarg), BUF_LEN);
continue;
case 'u': /* --usercert */
usercertfile = optarg;
continue;
case 'g': /* --groups */
groups = optarg;
continue;
case 'D': /* --days */
if (optarg == NULL || !isdigit(optarg[0]))
{
usage("missing number of days");
goto end;
}
else
{
char *endptr;
long days = strtol(optarg, &endptr, 0);
if (*endptr != '\0' || endptr == optarg || days <= 0)
{
usage("<days> must be a positive number");
goto end;
}
validity += 24*3600*days;
}
continue;
case 'H': /* --hours */
if (optarg == NULL || !isdigit(optarg[0]))
{
usage("missing number of hours");
goto end;
}
else
{
char *endptr;
long hours = strtol(optarg, &endptr, 0);
if (*endptr != '\0' || endptr == optarg || hours <= 0)
{
usage("<hours> must be a positive number");
goto end;
}
validity += 3600*hours;
}
continue;
case 'S': /* --startdate */
if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
{
usage("date format must be YYYYMMDDHHMMSSZ");
goto end;
}
else
{
chunk_t date = { optarg, 15 };
notBefore = asn1_to_time(&date, ASN1_GENERALIZEDTIME);
}
continue;
case 'E': /* --enddate */
if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
{
usage("date format must be YYYYMMDDHHMMSSZ");
goto end;
}
else
{
chunk_t date = { optarg, 15 };
notAfter = asn1_to_time(&date, ASN1_GENERALIZEDTIME);
}
continue;
case 'o': /* --out */
outfile = optarg;
continue;
case 'd': /* --debug */
debug_level = atoi(optarg);
continue;
default:
usage("");
status = 0;
goto end;
}
/* break from loop */
break;
}
if (optind != argc)
{
usage("unexpected argument");
goto end;
}
DBG1(DBG_LIB, "starting openac (strongSwan Version %s)", VERSION);
/* load the signer's RSA private key */
if (keyfile != NULL)
{
mem_cred_t *mem;
shared_key_t *shared;
mem = mem_cred_create();
lib->credmgr->add_set(lib->credmgr, &mem->set);
shared = shared_key_create(SHARED_PRIVATE_KEY_PASS,
chunk_clone(passphrase));
mem->add_shared(mem, shared, NULL);
signerKey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
BUILD_FROM_FILE, keyfile,
BUILD_END);
lib->credmgr->remove_set(lib->credmgr, &mem->set);
mem->destroy(mem);
if (signerKey == NULL)
{
goto end;
}
DBG1(DBG_LIB, " loaded private key file '%s'", keyfile);
}
/* load the signer's X.509 certificate */
if (certfile != NULL)
{
signerCert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, certfile,
BUILD_END);
if (signerCert == NULL)
{
goto end;
}
}
/* load the users's X.509 certificate */
if (usercertfile != NULL)
{
userCert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, usercertfile,
BUILD_END);
if (userCert == NULL)
{
goto end;
}
}
/* compute validity interval */
validity = (validity)? validity : DEFAULT_VALIDITY;
notBefore = (notBefore == UNDEFINED_TIME) ? time(NULL) : notBefore;
notAfter = (notAfter == UNDEFINED_TIME) ? time(NULL) + validity : notAfter;
/* build and parse attribute certificate */
if (userCert != NULL && signerCert != NULL && signerKey != NULL &&
outfile != NULL)
{
linked_list_t *group_list;
enumerator_t *enumerator;
char *group;
group_list = linked_list_create();
enumerator = enumerator_create_token(groups, ",", " ");
while (enumerator->enumerate(enumerator, &group))
{
group_list->insert_last(group_list, strdup(group));
}
enumerator->destroy(enumerator);
/* read the serial number and increment it by one */
serial = read_serial();
attr_cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509_AC,
BUILD_CERT, userCert,
BUILD_NOT_BEFORE_TIME, notBefore,
BUILD_NOT_AFTER_TIME, notAfter,
BUILD_SERIAL, serial,
BUILD_AC_GROUP_STRINGS, group_list,
BUILD_SIGNING_CERT, signerCert,
BUILD_SIGNING_KEY, signerKey,
BUILD_END);
group_list->destroy_function(group_list, free);
if (!attr_cert)
{
goto end;
}
/* write the attribute certificate to file */
if (attr_cert->get_encoding(attr_cert, CERT_ASN1_DER, &attr_chunk))
{
if (chunk_write(attr_chunk, outfile, 0022, TRUE))
{
DBG1(DBG_APP, " written attribute cert file '%s' (%d bytes)",
outfile, attr_chunk.len);
write_serial(serial);
status = 0;
}
else
{
DBG1(DBG_APP, " writing attribute cert file '%s' failed: %s",
outfile, strerror(errno));
}
}
}
else
{
usage("some of the mandatory parameters --usercert --cert --key --out "
"are missing");
}
end:
/* delete all dynamically allocated objects */
DESTROY_IF(signerKey);
DESTROY_IF(signerCert);
DESTROY_IF(userCert);
DESTROY_IF(attr_cert);
free(attr_chunk.ptr);
free(serial.ptr);
closelog();
dbg = dbg_default;
options->destroy(options);
exit(status);
}