diff options
Diffstat (limited to 'src/openac')
-rw-r--r-- | src/openac/Makefile.am | 2 | ||||
-rw-r--r-- | src/openac/build.c | 193 | ||||
-rw-r--r-- | src/openac/build.h | 45 | ||||
-rwxr-xr-x | src/openac/openac.c | 147 |
4 files changed, 114 insertions, 273 deletions
diff --git a/src/openac/Makefile.am b/src/openac/Makefile.am index 4b88d8b2d..1d8c8de9a 100644 --- a/src/openac/Makefile.am +++ b/src/openac/Makefile.am @@ -1,5 +1,5 @@ ipsec_PROGRAMS = openac -openac_SOURCES = openac.c build.c build.h +openac_SOURCES = openac.c dist_man_MANS = openac.8 INCLUDES = -I$(top_srcdir)/src/libstrongswan diff --git a/src/openac/build.c b/src/openac/build.c deleted file mode 100644 index 3dcd3f762..000000000 --- a/src/openac/build.c +++ /dev/null @@ -1,193 +0,0 @@ -/* Build a X.509 attribute certificate - * 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. - * - * RCSID $Id$ - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include <asn1/oid.h> -#include <asn1/asn1.h> -#include <crypto/ietf_attr_list.h> -#include <utils/identification.h> - -#include "build.h" - -static u_char ASN1_group_oid_str[] = { - 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04 -}; - -static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str); - -static u_char ASN1_authorityKeyIdentifier_oid_str[] = { - 0x06, 0x03, - 0x55, 0x1d, 0x23 -}; - -static const chunk_t ASN1_authorityKeyIdentifier_oid = - chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str); - -static u_char ASN1_noRevAvail_ext_str[] = { - 0x30, 0x09, - 0x06, 0x03, - 0x55, 0x1d, 0x38, - 0x04, 0x02, - 0x05, 0x00 -}; - -static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str); - -/** - * build directoryName - */ -static chunk_t build_directoryName(asn1_t tag, chunk_t name) -{ - return asn1_wrap(tag, "m", - asn1_simple_object(ASN1_CONTEXT_C_4, name)); -} - -/** - * build holder - */ -static chunk_t build_holder(void) -{ - identification_t *issuer = usercert->get_issuer(usercert); - identification_t *subject = usercert->get_subject(usercert); - - return asn1_wrap(ASN1_SEQUENCE, "mm", - asn1_wrap(ASN1_CONTEXT_C_0, "mm", - build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)), - asn1_simple_object(ASN1_INTEGER, usercert->get_serialNumber(usercert)) - ), - build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject))); -} - -/** - * build v2Form - */ -static chunk_t build_v2_form(void) -{ - identification_t *subject = signercert->get_subject(signercert); - - return asn1_wrap(ASN1_CONTEXT_C_0, "m", - build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject))); -} - -/** - * build attrCertValidityPeriod - */ -static chunk_t build_attr_cert_validity(void) -{ - return asn1_wrap(ASN1_SEQUENCE, "mm", - timetoasn1(¬Before, ASN1_GENERALIZEDTIME), - timetoasn1(¬After, ASN1_GENERALIZEDTIME)); -} - - -/** - * build attribute type - */ -static chunk_t build_attribute_type(const chunk_t type, chunk_t content) -{ - return asn1_wrap(ASN1_SEQUENCE, "cm", - type, - asn1_wrap(ASN1_SET, "m", content)); -} - -/** - * build attributes - */ -static chunk_t build_attributes(void) -{ - return asn1_wrap(ASN1_SEQUENCE, "m", - build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(groups))); -} - -/** - * build authorityKeyIdentifier - */ -static chunk_t build_authorityKeyID(x509_t *signer) -{ - identification_t *issuer = signer->get_issuer(signer); - chunk_t subjectKeyID = signer->get_subjectKeyID(signer); - - chunk_t keyIdentifier = (subjectKeyID.ptr == NULL) - ? chunk_empty - : asn1_simple_object(ASN1_CONTEXT_S_0, subjectKeyID); - - chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1, - issuer->get_encoding(issuer)); - - chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2, - signer->get_serialNumber(signer)); - - return asn1_wrap(ASN1_SEQUENCE, "cm", - ASN1_authorityKeyIdentifier_oid, - asn1_wrap(ASN1_OCTET_STRING, "m", - asn1_wrap(ASN1_SEQUENCE, "mmm", - keyIdentifier, - authorityCertIssuer, - authorityCertSerialNumber - ) - ) - ); -} - -/** - * build extensions - */ -static chunk_t build_extensions(void) -{ - return asn1_wrap(ASN1_SEQUENCE, "mc", - build_authorityKeyID(signercert), - ASN1_noRevAvail_ext); -} - -/** - * build attributeCertificateInfo - */ -static chunk_t build_attr_cert_info(void) -{ - return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm", - ASN1_INTEGER_1, - build_holder(), - build_v2_form(), - asn1_algorithmIdentifier(OID_SHA1_WITH_RSA), - asn1_simple_object(ASN1_INTEGER, serial), - build_attr_cert_validity(), - build_attributes(), - build_extensions()); -} - - -/** - * build an X.509 attribute certificate - */ -chunk_t build_attr_cert(void) -{ - chunk_t signatureValue; - chunk_t attributeCertificateInfo = build_attr_cert_info(); - - signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1, - attributeCertificateInfo, &signatureValue); - - return asn1_wrap(ASN1_SEQUENCE, "mcm", - attributeCertificateInfo, - asn1_algorithmIdentifier(OID_SHA1_WITH_RSA), - asn1_bitstring("m", signatureValue)); -} diff --git a/src/openac/build.h b/src/openac/build.h deleted file mode 100644 index 66ec86213..000000000 --- a/src/openac/build.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Build a X.509 attribute certificate - * 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. - * - * RCSID $Id$ - */ - -#ifndef _BUILD_H -#define _BUILD_H - -#include <time.h> - -#include <library.h> -#include <crypto/x509.h> -#include <crypto/rsa/rsa_private_key.h> -#include <utils/linked_list.h> - -/* - * global variables accessible by both main() and build.c - */ -extern x509_t *usercert; -extern x509_t *signercert; -extern rsa_private_key_t *signerkey; -extern linked_list_t *groups; -extern time_t notBefore; -extern time_t notAfter; -extern chunk_t serial; - -/* - * exported functions - */ -extern chunk_t build_attr_cert(void); - -#endif /* _BUILD_H */ diff --git a/src/openac/openac.c b/src/openac/openac.c index 6f19effe7..c5a7cd26c 100755 --- a/src/openac/openac.c +++ b/src/openac/openac.c @@ -36,8 +36,8 @@ #include <debug.h> #include <asn1/asn1.h> #include <asn1/ttodata.h> -#include <crypto/ac.h> -#include <crypto/ietf_attr_list.h> +#include <credentials/certificates/x509.h> +#include <credentials/certificates/ac.h> #include <utils/optionsfrom.h> #ifdef INTEGRITY_TEST @@ -47,8 +47,10 @@ #include "build.h" -#define OPENAC_PATH IPSEC_CONFDIR "/openac" -#define OPENAC_SERIAL IPSEC_CONFDIR "/openac/serial" +#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 @@ -175,18 +177,79 @@ static void write_serial(chunk_t serial) } /** - * global variables accessible by both main() and build.c + * Load and parse a private key file */ -x509_t *usercert = NULL; -x509_t *signercert = NULL; +static private_key_t* private_key_create_from_file(char *path, chunk_t *secret) +{ + bool pgp = FALSE; + chunk_t chunk = chunk_empty; + private_key_t *key = NULL; + + if (!pem_asn1_load_file(path, &secret, &chunk, &pgp)) + { + DBG1(" could not load private key file '%s'", path); + return NULL; + } + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk, BUILD_END); + if (key == NULL) + { + DBG1(" could not parse loaded private key file '%s'", path); + return NULL; + } + DBG1(" loaded private key file '%s'", path); + return key; +} -linked_list_t *groups = NULL; -rsa_private_key_t *signerkey = NULL; +/** + * Load and parse an X.509 certificate file + */ +static x509_t* x509_create_from_file(char *path, char *label, x509_flag_t flag) +{ -time_t notBefore = UNDEFINED_TIME; -time_t notAfter = UNDEFINED_TIME; + bool pgp = FALSE; + chunk_t chunk; + x509_t *x509; + certificate_t *cert; + time_t notBefore, notAfter, now; + + if (!pem_asn1_load_file(path, NULL, &chunk, &pgp)) + { + DBG1(" could not load %s file '%s'", label, path); + return NULL; + } + x509 = (x509_t*)lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, chunk, + BUILD_X509_FLAG, flag, + BUILD_END); + if (x509 == NULL) + { + DBG1(" could not parse loaded %s file '%s'",label, path); + return NULL; + } + DBG1(" loaded %s file '%s'", label, path); + + /* check validity */ + cert = &x509->interface; + now = time(NULL); + cert->get_validity(cert, &now, ¬Before, ¬After); + if (now > notAfter) + { + DBG1(" certificate expired at %T, discarded", ¬After); + cert->destroy(cert); + return NULL; + } + if (now < notBefore) + { + DBG1(" certificate not valid before %T", ¬Before); + } + return x509; +} -chunk_t serial; +/** + * global variables accessible by both main() and build.c + */ static int debug_level = 1; static bool stderr_quiet = FALSE; @@ -220,18 +283,26 @@ static void openac_dbg(int level, char *fmt, ...) */ int main(int argc, char **argv) { + certificate_t *attr_cert = NULL; + certificate_t *user_cert = NULL; + certificate_t *signer_cert = NULL; + private_key_t *signer_key = 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 serial; chunk_t passphrase = { buf, 0 }; - chunk_t attr_cert = chunk_empty; - x509ac_t *ac = NULL; + chunk_t attr_chunk = chunk_empty; - const time_t default_validity = 24*3600; /* 24 hours */ - time_t validity = 0; int status = 1; options_t *options = options_create(); @@ -240,7 +311,6 @@ int main(int argc, char **argv) dbg = openac_dbg; passphrase.ptr[0] = '\0'; - groups = linked_list_create(); openlog("openac", 0, LOG_AUTHPRIV); @@ -337,7 +407,7 @@ int main(int argc, char **argv) continue; case 'g': /* --groups */ - ietfAttr_list_create_from_string(optarg, groups); + groups = optarg; continue; case 'D': /* --days */ @@ -449,9 +519,9 @@ int main(int argc, char **argv) /* load the signer's RSA private key */ if (keyfile != NULL) { - signerkey = rsa_private_key_create_from_file(keyfile, &passphrase); + signer_key = private_key_create_from_file(keyfile, &passphrase); - if (signerkey == NULL) + if (signer_key == NULL) { goto end; } @@ -460,41 +530,50 @@ int main(int argc, char **argv) /* load the signer's X.509 certificate */ if (certfile != NULL) { - signercert = x509_create_from_file(certfile, "signer cert"); + x509_t *x509 = x509_create_from_file(certfile, "signer cert", 0); - if (signercert == NULL) + if (x509 == NULL) { goto end; } + signer_cert = &x509->interface; } /* load the users's X.509 certificate */ if (usercertfile != NULL) { - usercert = x509_create_from_file(usercertfile, "user cert"); + x509_t *x509 = x509_create_from_file(usercertfile, "user cert", 0); - if (usercert == NULL) + if (x509 == NULL) { goto end; } + user_cert = &x509->interface; } /* compute validity interval */ - validity = (validity)? validity : default_validity; + 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) + if (user_cert != NULL && signer_cert != NULL && signer_key != NULL) { /* read the serial number and increment it by one */ serial = read_serial(); - attr_cert = build_attr_cert(); - ac = x509ac_create_from_chunk(attr_cert); + attr_cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_X509_AC, + BUILD_CERT, user_cert, + BUILD_NOT_BEFORE_TIME, ¬Before, + BUILD_NOT_AFTER_TIME, ¬After, + BUILD_SIGNING_CERT, signer_cert, + BUILD_SIGNING_KEY, signer_key, + BUILD_END); + attr_chunk = attr_cert->get_encoding(attr_cert); /* write the attribute certificate to file */ - if (chunk_write(attr_cert, outfile, "attribute cert", 0022, TRUE)) + if (chunk_write(attr_chunk, outfile, "attribute cert", 0022, TRUE)) { write_serial(serial); status = 0; @@ -503,11 +582,11 @@ int main(int argc, char **argv) end: /* delete all dynamically allocated objects */ - DESTROY_IF(signerkey); - DESTROY_IF(signercert); - DESTROY_IF(usercert); - DESTROY_IF(ac); - ietfAttr_list_destroy(groups); + DESTROY_IF(signer_key); + DESTROY_IF(signer_cert); + DESTROY_IF(user_cert); + DESTROY_IF(attr_cert); + free(attr_chunk.ptr); free(serial.ptr); closelog(); dbg = dbg_default; |