aboutsummaryrefslogtreecommitdiffstats
path: root/src/openac/openac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openac/openac.c')
-rwxr-xr-xsrc/openac/openac.c224
1 files changed, 116 insertions, 108 deletions
diff --git a/src/openac/openac.c b/src/openac/openac.c
index e3f92fbd2..3dbbd2a65 100755
--- a/src/openac/openac.c
+++ b/src/openac/openac.c
@@ -25,37 +25,20 @@
#include <time.h>
#include <gmp.h>
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/mp_defs.h"
-#include "../pluto/log.h"
-#include "../pluto/asn1.h"
-#include "../pluto/certs.h"
-#include "../pluto/x509.h"
-#include "../pluto/crl.h"
-#include "../pluto/keys.h"
-#include "../pluto/ac.h"
+#include <debug.h>
+#include <asn1/asn1.h>
+#include <asn1/ttodata.h>
+#include <crypto/ac.h>
+#include <utils/optionsfrom.h>
#include "build.h"
#define OPENAC_PATH IPSEC_CONFDIR "/openac"
#define OPENAC_SERIAL IPSEC_CONFDIR "/openac/serial"
-const char openac_version[] = "openac 0.3";
+const char openac_version[] = "openac 0.4";
-/* by default the CRL policy is lenient */
-bool strict_crl_policy = FALSE;
-
-/* by default pluto does not check crls dynamically */
-long crl_check_interval = 0;
-
-/* by default pluto logs out after every smartcard use */
-bool pkcs11_keep_state = FALSE;
-
-static void
-usage(const char *mess)
+static void usage(const char *mess)
{
if (mess != NULL && *mess != '\0')
{
@@ -93,39 +76,60 @@ usage(const char *mess)
}
/**
+ * convert a chunk into a multi-precision integer
+ */
+static void chunk_to_mpz(chunk_t chunk, mpz_t number)
+{
+ mpz_import(number, chunk.len, 1, 1, 1, 0, chunk.ptr);
+}
+
+/**
+ * convert a multi-precision integer into a chunk
+ */
+static chunk_t mpz_to_chunk(mpz_t number)
+{
+ chunk_t chunk;
+
+ chunk.len = 1 + mpz_sizeinbase(number, 2)/BITS_PER_BYTE;
+ chunk.ptr = mpz_export(NULL, NULL, 1, chunk.len, 1, 0, number);
+ return chunk;
+}
+
+/**
* read the last serial number from file
*/
static chunk_t read_serial(void)
{
- MP_INT number;
+ mpz_t number;
- char buf[BUF_LEN];
- char bytes[BUF_LEN];
+ char buf[BUF_LEN], buf1[BUF_LEN];
+ chunk_t last_serial = { buf1, BUF_LEN};
+ chunk_t serial;
FILE *fd = fopen(OPENAC_SERIAL, "r");
- /* serial number defaults to 0 */
- size_t len = 1;
- bytes[0] = 0x00;
+ /* last serial number defaults to 0 */
+ *last_serial.ptr = 0x00;
+ last_serial.len = 1;
if (fd)
{
if (fscanf(fd, "%s", buf))
{
- err_t ugh = ttodata(buf, 0, 16, bytes, BUF_LEN, &len);
+ err_t ugh = ttodata(buf, 0, 16, last_serial.ptr, BUF_LEN, &last_serial.len);
if (ugh != NULL)
{
- plog(" error reading serial number from %s: %s"
- , OPENAC_SERIAL, ugh);
+ DBG1(" error reading serial number from %s: %s",
+ OPENAC_SERIAL, ugh);
}
}
fclose(fd);
}
else
{
- plog(" file '%s' does not exist yet - serial number set to 01"
- , OPENAC_SERIAL);
+ DBG1(" file '%s' does not exist yet - serial number set to 01",
+ OPENAC_SERIAL);
}
/**
@@ -133,10 +137,11 @@ static chunk_t read_serial(void)
* and incrementing it by one
* and representing it as a two's complement octet string
*/
- n_to_mpz(&number, bytes, len);
- mpz_add_ui(&number, &number, 0x01);
- serial = mpz_to_n(&number, 1 + mpz_sizeinbase(&number, 2)/BITS_PER_BYTE);
- mpz_clear(&number);
+ mpz_init(number);
+ chunk_to_mpz(last_serial, number);
+ mpz_add_ui(number, number, 0x01);
+ serial = mpz_to_chunk(number);
+ mpz_clear(number);
return serial;
}
@@ -152,28 +157,27 @@ static void write_serial(chunk_t serial)
if (fd)
{
- datatot(serial.ptr, serial.len, 16, buf, BUF_LEN);
- plog(" serial number is %s", buf);
- fprintf(fd, "%s\n", buf);
+ DBG1(" serial number is %#B", &serial);
+ fprintf(fd, "%#B\n", &serial);
fclose(fd);
}
else
{
- plog(" could not open file '%s' for writing", OPENAC_SERIAL);
+ DBG1(" could not open file '%s' for writing", OPENAC_SERIAL);
}
}
/**
* global variables accessible by both main() and build.c
*/
-x509cert_t *user = NULL;
-x509cert_t *signer = NULL;
+x509_t *usercert = NULL;
+x509_t *signercert = NULL;
-ietfAttrList_t *groups = NULL;
-struct RSA_private_key *signerkey = NULL;
+linked_list_t *groups = NULL;
+rsa_private_key_t *signerkey = NULL;
-time_t notBefore = 0;
-time_t notAfter = 0;
+time_t notBefore = UNDEFINED_TIME;
+time_t notAfter = UNDEFINED_TIME;
chunk_t serial;
@@ -183,23 +187,18 @@ int main(int argc, char **argv)
char *certfile = NULL;
char *usercertfile = NULL;
char *outfile = NULL;
+ char buf[BUF_LEN];
- cert_t signercert = empty_cert;
- cert_t usercert = empty_cert;
-
- chunk_t attr_cert = empty_chunk;
- x509acert_t *ac = NULL;
+ chunk_t passphrase = { buf, 0 };
+ chunk_t attr_cert = chunk_empty;
+ x509ac_t *ac = NULL;
const time_t default_validity = 24*3600; /* 24 hours */
time_t validity = 0;
- prompt_pass_t pass;
-
- pass.secret[0] = '\0';
- pass.prompt = TRUE;
- pass.fd = STDIN_FILENO;
+ passphrase.ptr[0] = '\0';
- log_to_stderr = TRUE;
+ groups = linked_list_create();
/* handle arguments */
for (;;)
@@ -260,16 +259,20 @@ int main(int argc, char **argv)
char path[BUF_LEN];
if (*optarg == '/') /* absolute pathname */
+ {
strncpy(path, optarg, BUF_LEN);
+ }
else /* relative pathname */
+ {
snprintf(path, BUF_LEN, "%s/%s", OPENAC_PATH, optarg);
+ }
optionsfrom(path, &argc, &argv, optind, stderr);
/* does not return on error */
}
continue;
case 'q': /* --quiet */
- log_to_stderr = TRUE;
+ /* TODO log to syslog only */
continue;
case 'c': /* --cert */
@@ -281,8 +284,12 @@ int main(int argc, char **argv)
continue;
case 'p': /* --key */
- pass.prompt = FALSE;
- strncpy(pass.secret, optarg, sizeof(pass.secret));
+ if (strlen(optarg) > BUF_LEN)
+ {
+ usage("passphrase too long");
+ }
+ strncpy(passphrase.ptr, optarg, BUF_LEN);
+ passphrase.len = min(strlen(optarg), BUF_LEN);
continue;
case 'u': /* --usercert */
@@ -290,47 +297,64 @@ int main(int argc, char **argv)
continue;
case 'g': /* --groups */
- decode_groups(optarg, &groups);
+ ietfAttr_list_create_from_string(optarg, groups);
continue;
case 'D': /* --days */
if (optarg == NULL || !isdigit(optarg[0]))
+ {
usage("missing number of days");
+ }
+ else
{
char *endptr;
long days = strtol(optarg, &endptr, 0);
if (*endptr != '\0' || endptr == optarg || days <= 0)
+ {
usage("<days> must be a positive number");
+ }
validity += 24*3600*days;
}
continue;
case 'H': /* --hours */
if (optarg == NULL || !isdigit(optarg[0]))
+ {
usage("missing number of hours");
+ }
+ else
{
char *endptr;
long hours = strtol(optarg, &endptr, 0);
if (*endptr != '\0' || endptr == optarg || hours <= 0)
+ {
usage("<hours> must be a positive number");
+ }
validity += 3600*hours;
}
continue;
case 'S': /* --startdate */
if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
+ {
usage("date format must be YYYYMMDDHHMMSSZ");
+ }
+ else
{
chunk_t date = { optarg, 15 };
+
notBefore = asn1totime(&date, ASN1_GENERALIZEDTIME);
}
continue;
case 'E': /* --enddate */
if (optarg == NULL || strlen(optarg) != 15 || optarg[14] != 'Z')
+ {
usage("date format must be YYYYMMDDHHMMSSZ");
+ }
+ else
{
chunk_t date = { optarg, 15 };
notAfter = asn1totime(&date, ASN1_GENERALIZEDTIME);
@@ -347,38 +371,25 @@ int main(int argc, char **argv)
continue;
#endif
default:
-#ifdef DEBUG
- if (c >= DBG_OFFSET)
- {
- base_debugging |= c - DBG_OFFSET;
- continue;
- }
-#undef DBG_OFFSET
-#endif
- bad_case(c);
+ usage("");
}
break;
}
- init_log("openac");
- cur_debugging = base_debugging;
-
if (optind != argc)
+ {
usage("unexpected argument");
+ }
/* load the signer's RSA private key */
if (keyfile != NULL)
{
err_t ugh = NULL;
- signerkey = alloc_thing(RSA_private_key_t, "RSA private key");
- ugh = load_rsa_private_key(keyfile, &pass, signerkey);
+ signerkey = rsa_private_key_create_from_file(keyfile, &passphrase);
- if (ugh != NULL)
+ if (signerkey == NULL)
{
- free_RSA_private_content(signerkey);
- pfree(signerkey);
- plog("%s", ugh);
exit(1);
}
}
@@ -386,17 +397,22 @@ int main(int argc, char **argv)
/* load the signer's X.509 certificate */
if (certfile != NULL)
{
- if (!load_cert(certfile, "signer cert", &signercert))
+ signercert = x509_create_from_file(certfile, "signer cert");
+
+ if (signercert == NULL)
+ {
exit(1);
- signer = signercert.u.x509;
+ }
}
/* load the users's X.509 certificate */
if (usercertfile != NULL)
{
- if (!load_cert(usercertfile, "user cert", &usercert))
+ usercert = x509_create_from_file(usercertfile, "signer cert");
+ if (usercert == NULL)
+ {
exit(1);
- user = usercert.u.x509;
+ }
}
/* compute validity interval */
@@ -405,36 +421,28 @@ int main(int argc, char **argv)
notAfter = (notAfter) ? notAfter : notBefore + validity;
/* build and parse attribute certificate */
- if (user != NULL && signer != NULL && signerkey != NULL)
+ if (usercert != NULL && signercert != NULL && signerkey != NULL)
{
/* read the serial number and increment it by one */
serial = read_serial();
attr_cert = build_attr_cert();
- ac = alloc_thing(x509acert_t, "x509acert");
- *ac = empty_ac;
- parse_ac(attr_cert, ac);
+ ac = x509ac_create_from_chunk(attr_cert);
/* write the attribute certificate to file */
- if (write_chunk(outfile, "attribute cert", attr_cert, 0022, TRUE))
- write_serial(serial);
+ if (chunk_write(attr_cert, outfile, "attribute cert", 0022, TRUE))
+ {
+ write_serial(serial);
+ }
}
- /* delete all dynamic objects */
- if (signerkey != NULL)
- {
- free_RSA_private_content(signerkey);
- pfree(signerkey);
- }
- free_x509cert(signercert.u.x509);
- free_x509cert(usercert.u.x509);
- free_ietfAttrList(groups);
- free_acert(ac);
- pfree(serial.ptr);
-
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
+ /* delete all dynamically allocated objects */
+ DESTROY_IF(signerkey);
+ DESTROY_IF(signercert);
+ DESTROY_IF(usercert);
+ DESTROY_IF(ac);
+ ietfAttr_list_destroy(groups);
+ free(serial.ptr);
+
exit(0);
}