removed some empty lines
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
ipsec_PROGRAMS = charon
|
||||
|
||||
charon_SOURCES = \
|
||||
|
||||
@@ -50,6 +50,7 @@ utils/iterator.h \
|
||||
utils/leak_detective.c utils/leak_detective.h \
|
||||
utils/lexparser.c utils/lexparser.h \
|
||||
utils/linked_list.c utils/linked_list.h \
|
||||
utils/optionsfrom.c utils/optionsfrom.h \
|
||||
utils/randomizer.c utils/randomizer.h
|
||||
|
||||
if USE_INTEGRITY_TEST
|
||||
|
||||
@@ -344,6 +344,59 @@ void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int lev
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
chunk_t ietfAttr_list_encode(linked_list_t *list)
|
||||
{
|
||||
chunk_t ietfAttributes;
|
||||
size_t size = 0;
|
||||
u_char *pos;
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
ietfAttr_t *attr;
|
||||
bool first = TRUE;
|
||||
|
||||
/* precalculate the total size of all values */
|
||||
while (iterator->iterate(iterator, (void **)&attr))
|
||||
{
|
||||
size_t len = attr->value.len;
|
||||
|
||||
size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
|
||||
|
||||
iterator = list->create_iterator(list, TRUE);
|
||||
while (iterator->iterate(iterator, (void **)&attr))
|
||||
{
|
||||
chunk_t ietfAttribute;
|
||||
asn1_t type = ASN1_NULL;
|
||||
|
||||
switch (attr->kind)
|
||||
{
|
||||
case IETF_ATTRIBUTE_OCTETS:
|
||||
type = ASN1_OCTET_STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_STRING:
|
||||
type = ASN1_UTF8STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_OID:
|
||||
type = ASN1_OID;
|
||||
break;
|
||||
}
|
||||
ietfAttribute = asn1_simple_object(type, attr->value);
|
||||
|
||||
/* copy ietfAttribute into ietfAttributes chunk */
|
||||
memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
|
||||
pos += ietfAttribute.len;
|
||||
free(ietfAttribute.ptr);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
|
||||
@@ -68,6 +68,14 @@ void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
|
||||
*/
|
||||
void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
|
||||
|
||||
/**
|
||||
* @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
|
||||
*
|
||||
* @param list alphabetically-sorted linked list of attributes
|
||||
* @return chunk containing ASN.1-coded attributes
|
||||
*/
|
||||
chunk_t ietfAttr_list_encode(linked_list_t *list);
|
||||
|
||||
/**
|
||||
* @brief Destroys a linked list of ietfAttr_t objects
|
||||
*
|
||||
|
||||
+4
-99
@@ -1,103 +1,8 @@
|
||||
ipsec_PROGRAMS = openac
|
||||
openac_SOURCES = openac.c build.c build.h loglite.c
|
||||
|
||||
PLUTODIR=$(top_srcdir)/src/pluto
|
||||
WHACKDIR=$(top_srcdir)/src/whack
|
||||
LIBSTRONGSWANDIR=$(top_srcdir)/src/libstrongswan
|
||||
LIBFREESWANDIR=$(top_srcdir)/src/libfreeswan
|
||||
LIBCRYPTODIR=$(top_srcdir)/src/libcrypto
|
||||
|
||||
INCLUDES = \
|
||||
-I$(LIBFREESWANDIR) \
|
||||
-I$(LIBSTRONGSWANDIR)\
|
||||
-I$(PLUTODIR) \
|
||||
-I$(LIBCRYPTODIR) \
|
||||
-I$(WHACKDIR)
|
||||
|
||||
AM_CFLAGS = -DDEBUG -DNO_PLUTO -DIPSEC_CONFDIR=\"${confdir}\"
|
||||
openac_LDADD = ac.o asn1.o ca.o certs.o constants.o crl.o defs.o mp_defs.o fetch.o id.o keys.o lex.o \
|
||||
md2.o md5.o ocsp.o oid.o pem.o pgp.o pkcs1.o rnd.o sha1.o smartcard.o x509.o \
|
||||
$(LIBFREESWANDIR)/libfreeswan.a $(LIBCRYPTODIR)/libcrypto.a \
|
||||
-lgmp
|
||||
|
||||
# This compile option activates dynamic URL fetching using libcurl
|
||||
if USE_LIBCURL
|
||||
openac_LDADD += -lcurl
|
||||
endif
|
||||
|
||||
# This compile option activates smartcard support
|
||||
if USE_SMARTCARD
|
||||
openac_LDADD += -ldl
|
||||
endif
|
||||
|
||||
openac_SOURCES = openac.c build.c build.h
|
||||
dist_man_MANS = openac.8
|
||||
|
||||
ac.o : $(PLUTODIR)/ac.c $(PLUTODIR)/ac.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
certs.o : $(PLUTODIR)/certs.c $(PLUTODIR)/certs.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
constants.o : $(PLUTODIR)/constants.c $(PLUTODIR)/constants.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
crl.o : $(PLUTODIR)/crl.c $(PLUTODIR)/crl.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
mp_defs.o : $(PLUTODIR)/mp_defs.c $(PLUTODIR)/mp_defs.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
fetch.o : $(PLUTODIR)/fetch.c $(PLUTODIR)/fetch.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
id.o : $(PLUTODIR)/id.c $(PLUTODIR)/id.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
keys.o : $(PLUTODIR)/keys.c $(PLUTODIR)/keys.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
lex.o : $(PLUTODIR)/lex.c $(PLUTODIR)/lex.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
md2.o : $(PLUTODIR)/md2.c $(PLUTODIR)/md2.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
md5.o : $(PLUTODIR)/md5.c $(PLUTODIR)/md5.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
ocsp.o : $(PLUTODIR)/ocsp.c $(PLUTODIR)/ocsp.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
pem.o : $(PLUTODIR)/pem.c $(PLUTODIR)/pem.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
pgp.o : $(PLUTODIR)/pgp.c $(PLUTODIR)/pgp.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
smartcard.o : $(PLUTODIR)/smartcard.c $(PLUTODIR)/smartcard.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
|
||||
x509.o : $(PLUTODIR)/x509.c $(PLUTODIR)/x509.h
|
||||
$(COMPILE) -c -o $@ $<
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan
|
||||
AM_CFLAGS = -DIPSEC_CONFDIR=\"${confdir}\"
|
||||
openac_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp
|
||||
|
||||
|
||||
+34
-75
@@ -19,15 +19,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include <asn1/oid.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/asn1.h"
|
||||
#include "../pluto/x509.h"
|
||||
#include "../pluto/log.h"
|
||||
#include <asn1/asn1.h>
|
||||
#include <crypto/ietf_attr_list.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
#include "build.h"
|
||||
|
||||
@@ -36,15 +31,15 @@ static u_char ASN1_group_oid_str[] = {
|
||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
|
||||
};
|
||||
|
||||
static const chunk_t ASN1_group_oid = strchunk(ASN1_group_oid_str);
|
||||
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
|
||||
= strchunk(ASN1_authorityKeyIdentifier_oid_str);
|
||||
static const chunk_t ASN1_authorityKeyIdentifier_oid =
|
||||
chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
|
||||
|
||||
static u_char ASN1_noRevAvail_ext_str[] = {
|
||||
0x30, 0x09,
|
||||
@@ -54,7 +49,7 @@ static u_char ASN1_noRevAvail_ext_str[] = {
|
||||
0x05, 0x00
|
||||
};
|
||||
|
||||
static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
|
||||
static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
|
||||
|
||||
/**
|
||||
* build directoryName
|
||||
@@ -62,7 +57,7 @@ static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
|
||||
static chunk_t build_directoryName(asn1_t tag, chunk_t name)
|
||||
{
|
||||
return asn1_wrap(tag, "m",
|
||||
asn1_simple_object(ASN1_CONTEXT_C_4, name));
|
||||
asn1_simple_object(ASN1_CONTEXT_C_4, name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,12 +65,15 @@ static chunk_t build_directoryName(asn1_t tag, chunk_t name)
|
||||
*/
|
||||
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, user->issuer),
|
||||
asn1_simple_object(ASN1_INTEGER, user->serialNumber)
|
||||
),
|
||||
build_directoryName(ASN1_CONTEXT_C_1, user->subject));
|
||||
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)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,8 +81,10 @@ static chunk_t build_holder(void)
|
||||
*/
|
||||
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, signer->subject));
|
||||
build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,50 +97,6 @@ static chunk_t build_attr_cert_validity(void)
|
||||
timetoasn1(¬After, ASN1_GENERALIZEDTIME));
|
||||
}
|
||||
|
||||
/**
|
||||
* build attributes
|
||||
*/
|
||||
static chunk_t build_ietfAttributes(ietfAttrList_t *list)
|
||||
{
|
||||
chunk_t ietfAttributes;
|
||||
ietfAttrList_t *item = list;
|
||||
size_t size = 0;
|
||||
u_char *pos;
|
||||
|
||||
/* precalculate the total size of all values */
|
||||
while (item != NULL)
|
||||
{
|
||||
size_t len = item->attr->value.len;
|
||||
|
||||
size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
|
||||
item = item->next;
|
||||
}
|
||||
pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
|
||||
|
||||
while (list != NULL)
|
||||
{
|
||||
ietfAttr_t *attr = list->attr;
|
||||
asn1_t type = ASN1_NULL;
|
||||
|
||||
switch (attr->kind)
|
||||
{
|
||||
case IETF_ATTRIBUTE_OCTETS:
|
||||
type = ASN1_OCTET_STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_STRING:
|
||||
type = ASN1_UTF8STRING;
|
||||
break;
|
||||
case IETF_ATTRIBUTE_OID:
|
||||
type = ASN1_OID;
|
||||
break;
|
||||
}
|
||||
mv_chunk(&pos, asn1_simple_object(type, attr->value));
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* build attribute type
|
||||
@@ -158,25 +114,26 @@ static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
|
||||
static chunk_t build_attributes(void)
|
||||
{
|
||||
return asn1_wrap(ASN1_SEQUENCE, "m",
|
||||
build_attribute_type(ASN1_group_oid,
|
||||
build_ietfAttributes(groups)));
|
||||
build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(groups)));
|
||||
}
|
||||
|
||||
/**
|
||||
* build authorityKeyIdentifier
|
||||
*/
|
||||
static chunk_t build_authorityKeyID(x509cert_t *signer)
|
||||
static chunk_t build_authorityKeyID(x509_t *signer)
|
||||
{
|
||||
chunk_t keyIdentifier = (signer->subjectKeyID.ptr == NULL)
|
||||
? empty_chunk
|
||||
: asn1_simple_object(ASN1_CONTEXT_S_0,
|
||||
signer->subjectKeyID);
|
||||
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,
|
||||
signer->issuer);
|
||||
issuer->get_encoding(issuer));
|
||||
|
||||
chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
|
||||
signer->serialNumber);
|
||||
signer->get_serialNumber(signer));
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||
ASN1_authorityKeyIdentifier_oid,
|
||||
@@ -196,7 +153,7 @@ static chunk_t build_authorityKeyID(x509cert_t *signer)
|
||||
static chunk_t build_extensions(void)
|
||||
{
|
||||
return asn1_wrap(ASN1_SEQUENCE, "mc",
|
||||
build_authorityKeyID(signer),
|
||||
build_authorityKeyID(signercert),
|
||||
ASN1_noRevAvail_ext);
|
||||
}
|
||||
|
||||
@@ -221,9 +178,11 @@ static chunk_t build_attr_cert_info(void)
|
||||
*/
|
||||
chunk_t build_attr_cert(void)
|
||||
{
|
||||
chunk_t signatureValue;
|
||||
chunk_t attributeCertificateInfo = build_attr_cert_info();
|
||||
chunk_t signatureValue = pkcs1_build_signature(attributeCertificateInfo,
|
||||
OID_SHA1, signerkey, TRUE);
|
||||
|
||||
signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1,
|
||||
attributeCertificateInfo, &signatureValue);
|
||||
|
||||
return asn1_wrap(ASN1_SEQUENCE, "mcm",
|
||||
attributeCertificateInfo,
|
||||
|
||||
+8
-10
@@ -21,22 +21,20 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../pluto/x509.h"
|
||||
#include "../pluto/keys.h"
|
||||
#include "../pluto/ac.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 x509cert_t *user;
|
||||
extern x509cert_t *signer;
|
||||
|
||||
extern ietfAttrList_t *groups;
|
||||
extern struct RSA_private_key *signerkey;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
|
||||
+115
-107
@@ -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')
|
||||
{
|
||||
@@ -92,40 +75,61 @@ usage(const char *mess)
|
||||
exit(mess == NULL? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
passphrase.ptr[0] = '\0';
|
||||
|
||||
pass.secret[0] = '\0';
|
||||
pass.prompt = TRUE;
|
||||
pass.fd = STDIN_FILENO;
|
||||
|
||||
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);
|
||||
/* delete all dynamically allocated objects */
|
||||
DESTROY_IF(signerkey);
|
||||
DESTROY_IF(signercert);
|
||||
DESTROY_IF(usercert);
|
||||
DESTROY_IF(ac);
|
||||
ietfAttr_list_destroy(groups);
|
||||
free(serial.ptr);
|
||||
|
||||
#ifdef LEAK_DETECTIVE
|
||||
report_leaks();
|
||||
#endif /* LEAK_DETECTIVE */
|
||||
close_log();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user