diff options
Diffstat (limited to 'src/openac/openac.c')
-rwxr-xr-x | src/openac/openac.c | 224 |
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); } |