mirror of
https://github.com/strongswan/strongswan.git
synced 2025-12-09 00:00:27 -05:00
changed tab spacing from 8 to 4
This commit is contained in:
parent
00ccb87671
commit
241ab32c10
@ -31,212 +31,201 @@
|
|||||||
#include "build.h"
|
#include "build.h"
|
||||||
|
|
||||||
static u_char ASN1_group_oid_str[] = {
|
static u_char ASN1_group_oid_str[] = {
|
||||||
0x06, 0x08,
|
0x06, 0x08,
|
||||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
|
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 = strchunk(ASN1_group_oid_str);
|
||||||
|
|
||||||
static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
|
static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
|
||||||
0x06, 0x03,
|
0x06, 0x03,
|
||||||
0x55, 0x1d, 0x23
|
0x55, 0x1d, 0x23
|
||||||
};
|
};
|
||||||
|
|
||||||
static const chunk_t ASN1_authorityKeyIdentifier_oid
|
static const chunk_t ASN1_authorityKeyIdentifier_oid
|
||||||
= strchunk(ASN1_authorityKeyIdentifier_oid_str);
|
= strchunk(ASN1_authorityKeyIdentifier_oid_str);
|
||||||
|
|
||||||
static u_char ASN1_noRevAvail_ext_str[] = {
|
static u_char ASN1_noRevAvail_ext_str[] = {
|
||||||
0x30, 0x09,
|
0x30, 0x09,
|
||||||
0x06, 0x03,
|
0x06, 0x03,
|
||||||
0x55, 0x1d, 0x38,
|
0x55, 0x1d, 0x38,
|
||||||
0x04, 0x02,
|
0x04, 0x02,
|
||||||
0x05, 0x00
|
0x05, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
|
static const chunk_t ASN1_noRevAvail_ext = strchunk(ASN1_noRevAvail_ext_str);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build directoryName
|
* build directoryName
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_directoryName(asn1_t tag, chunk_t name)
|
||||||
build_directoryName(asn1_t tag, chunk_t name)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(tag, "m"
|
return asn1_wrap(tag, "m",
|
||||||
, asn1_simple_object(ASN1_CONTEXT_C_4, name));
|
asn1_simple_object(ASN1_CONTEXT_C_4, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build holder
|
* build holder
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_holder(void)
|
||||||
build_holder(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "mm"
|
return asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
, asn1_wrap(ASN1_CONTEXT_C_0, "mm"
|
asn1_wrap(ASN1_CONTEXT_C_0, "mm",
|
||||||
, build_directoryName(ASN1_SEQUENCE, user->issuer)
|
build_directoryName(ASN1_SEQUENCE, user->issuer),
|
||||||
, asn1_simple_object(ASN1_INTEGER, user->serialNumber)
|
asn1_simple_object(ASN1_INTEGER, user->serialNumber)
|
||||||
)
|
),
|
||||||
, build_directoryName(ASN1_CONTEXT_C_1, user->subject));
|
build_directoryName(ASN1_CONTEXT_C_1, user->subject));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build v2Form
|
* build v2Form
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_v2_form(void)
|
||||||
build_v2_form(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_CONTEXT_C_0, "m"
|
return asn1_wrap(ASN1_CONTEXT_C_0, "m",
|
||||||
, build_directoryName(ASN1_SEQUENCE, signer->subject));
|
build_directoryName(ASN1_SEQUENCE, signer->subject));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build attrCertValidityPeriod
|
* build attrCertValidityPeriod
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_attr_cert_validity(void)
|
||||||
build_attr_cert_validity(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "mm"
|
return asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
, timetoasn1(¬Before, ASN1_GENERALIZEDTIME)
|
timetoasn1(¬Before, ASN1_GENERALIZEDTIME),
|
||||||
, timetoasn1(¬After, ASN1_GENERALIZEDTIME));
|
timetoasn1(¬After, ASN1_GENERALIZEDTIME));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build attributes
|
* build attributes
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_ietfAttributes(ietfAttrList_t *list)
|
||||||
build_ietfAttributes(ietfAttrList_t *list)
|
|
||||||
{
|
{
|
||||||
chunk_t ietfAttributes;
|
chunk_t ietfAttributes;
|
||||||
ietfAttrList_t *item = list;
|
ietfAttrList_t *item = list;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
u_char *pos;
|
u_char *pos;
|
||||||
|
|
||||||
/* precalculate the total size of all values */
|
/* precalculate the total size of all values */
|
||||||
while (item != NULL)
|
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:
|
size_t len = item->attr->value.len;
|
||||||
type = ASN1_OCTET_STRING;
|
|
||||||
break;
|
size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
|
||||||
case IETF_ATTRIBUTE_STRING:
|
item = item->next;
|
||||||
type = ASN1_UTF8STRING;
|
|
||||||
break;
|
|
||||||
case IETF_ATTRIBUTE_OID:
|
|
||||||
type = ASN1_OID;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
mv_chunk(&pos, asn1_simple_object(type, attr->value));
|
pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
|
||||||
|
|
||||||
list = list->next;
|
while (list != NULL)
|
||||||
}
|
{
|
||||||
|
ietfAttr_t *attr = list->attr;
|
||||||
|
asn1_t type = ASN1_NULL;
|
||||||
|
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
|
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
|
* build attribute type
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
|
||||||
build_attribute_type(const chunk_t type, chunk_t content)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||||
, type
|
type,
|
||||||
, asn1_wrap(ASN1_SET, "m", content));
|
asn1_wrap(ASN1_SET, "m", content));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build attributes
|
* build attributes
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_attributes(void)
|
||||||
build_attributes(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "m"
|
return asn1_wrap(ASN1_SEQUENCE, "m",
|
||||||
, build_attribute_type(ASN1_group_oid
|
build_attribute_type(ASN1_group_oid,
|
||||||
, build_ietfAttributes(groups)));
|
build_ietfAttributes(groups)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build authorityKeyIdentifier
|
* build authorityKeyIdentifier
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_authorityKeyID(x509cert_t *signer)
|
||||||
build_authorityKeyID(x509cert_t *signer)
|
|
||||||
{
|
{
|
||||||
chunk_t keyIdentifier = (signer->subjectKeyID.ptr == NULL)
|
chunk_t keyIdentifier = (signer->subjectKeyID.ptr == NULL)
|
||||||
? empty_chunk
|
? empty_chunk
|
||||||
: asn1_simple_object(ASN1_CONTEXT_S_0
|
: asn1_simple_object(ASN1_CONTEXT_S_0,
|
||||||
, signer->subjectKeyID);
|
signer->subjectKeyID);
|
||||||
|
|
||||||
chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1
|
chunk_t authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
|
||||||
, signer->issuer);
|
signer->issuer);
|
||||||
|
|
||||||
chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2
|
chunk_t authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
|
||||||
, signer->serialNumber);
|
signer->serialNumber);
|
||||||
|
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cm"
|
return asn1_wrap(ASN1_SEQUENCE, "cm",
|
||||||
, ASN1_authorityKeyIdentifier_oid
|
ASN1_authorityKeyIdentifier_oid,
|
||||||
, asn1_wrap(ASN1_OCTET_STRING, "m"
|
asn1_wrap(ASN1_OCTET_STRING, "m",
|
||||||
, asn1_wrap(ASN1_SEQUENCE, "mmm"
|
asn1_wrap(ASN1_SEQUENCE, "mmm",
|
||||||
, keyIdentifier
|
keyIdentifier,
|
||||||
, authorityCertIssuer
|
authorityCertIssuer,
|
||||||
, authorityCertSerialNumber
|
authorityCertSerialNumber
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build extensions
|
* build extensions
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_extensions(void)
|
||||||
build_extensions(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "mc"
|
return asn1_wrap(ASN1_SEQUENCE, "mc",
|
||||||
, build_authorityKeyID(signer)
|
build_authorityKeyID(signer),
|
||||||
, ASN1_noRevAvail_ext);
|
ASN1_noRevAvail_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build attributeCertificateInfo
|
* build attributeCertificateInfo
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t build_attr_cert_info(void)
|
||||||
build_attr_cert_info(void)
|
|
||||||
{
|
{
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm"
|
return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
|
||||||
, ASN1_INTEGER_1
|
ASN1_INTEGER_1,
|
||||||
, build_holder()
|
build_holder(),
|
||||||
, build_v2_form()
|
build_v2_form(),
|
||||||
, ASN1_sha1WithRSA_id
|
ASN1_sha1WithRSA_id,
|
||||||
, asn1_simple_object(ASN1_INTEGER, serial)
|
asn1_simple_object(ASN1_INTEGER, serial),
|
||||||
, build_attr_cert_validity()
|
build_attr_cert_validity(),
|
||||||
, build_attributes()
|
build_attributes(),
|
||||||
, build_extensions());
|
build_extensions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* build an X.509 attribute certificate
|
* build an X.509 attribute certificate
|
||||||
*/
|
*/
|
||||||
chunk_t
|
chunk_t build_attr_cert(void)
|
||||||
build_attr_cert(void)
|
|
||||||
{
|
{
|
||||||
chunk_t attributeCertificateInfo = build_attr_cert_info();
|
chunk_t attributeCertificateInfo = build_attr_cert_info();
|
||||||
chunk_t signatureValue = pkcs1_build_signature(attributeCertificateInfo
|
chunk_t signatureValue = pkcs1_build_signature(attributeCertificateInfo,
|
||||||
, OID_SHA1, signerkey, TRUE);
|
OID_SHA1, signerkey, TRUE);
|
||||||
|
|
||||||
return asn1_wrap(ASN1_SEQUENCE, "mcm"
|
return asn1_wrap(ASN1_SEQUENCE, "mcm",
|
||||||
, attributeCertificateInfo
|
attributeCertificateInfo,
|
||||||
, ASN1_sha1WithRSA_id
|
ASN1_sha1WithRSA_id,
|
||||||
, signatureValue);
|
signatureValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,107 +57,113 @@ bool pkcs11_keep_state = FALSE;
|
|||||||
static void
|
static void
|
||||||
usage(const char *mess)
|
usage(const char *mess)
|
||||||
{
|
{
|
||||||
if (mess != NULL && *mess != '\0')
|
if (mess != NULL && *mess != '\0')
|
||||||
fprintf(stderr, "%s\n", mess);
|
{
|
||||||
fprintf(stderr
|
fprintf(stderr, "%s\n", mess);
|
||||||
, "Usage: openac"
|
}
|
||||||
" [--help]"
|
fprintf(stderr, "Usage: openac"
|
||||||
" [--version]"
|
" [--help]"
|
||||||
" [--optionsfrom <filename>]"
|
" [--version]"
|
||||||
" [--quiet]"
|
" [--optionsfrom <filename>]"
|
||||||
|
" [--quiet]"
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
" \\\n\t"
|
" \\\n\t"
|
||||||
" [--debug-all]"
|
" [--debug-all]"
|
||||||
" [--debug-parsing]"
|
" [--debug-parsing]"
|
||||||
" [--debug-raw]"
|
" [--debug-raw]"
|
||||||
" [--debug-private]"
|
" [--debug-private]"
|
||||||
#endif
|
#endif
|
||||||
" \\\n\t"
|
" \\\n\t"
|
||||||
" [--days <days>]"
|
" [--days <days>]"
|
||||||
" [--hours <hours>]"
|
" [--hours <hours>]"
|
||||||
" \\\n\t"
|
" \\\n\t"
|
||||||
" [--startdate <YYYYMMDDHHMMSSZ>]"
|
" [--startdate <YYYYMMDDHHMMSSZ>]"
|
||||||
" [--enddate <YYYYMMDDHHMMSSZ>]"
|
" [--enddate <YYYYMMDDHHMMSSZ>]"
|
||||||
" \\\n\t"
|
" \\\n\t"
|
||||||
" --cert <certfile>"
|
" --cert <certfile>"
|
||||||
" --key <keyfile>"
|
" --key <keyfile>"
|
||||||
" [--password <password>]"
|
" [--password <password>]"
|
||||||
" \\\n\t"
|
" \\\n\t"
|
||||||
" --usercert <certfile>"
|
" --usercert <certfile>"
|
||||||
" --groups <attr1,attr2,..>"
|
" --groups <attr1,attr2,..>"
|
||||||
" --out <filename>"
|
" --out <filename>"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
exit(mess == NULL? 0 : 1);
|
exit(mess == NULL? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* read the last serial number from file
|
* read the last serial number from file
|
||||||
*/
|
*/
|
||||||
static chunk_t
|
static chunk_t read_serial(void)
|
||||||
read_serial(void)
|
|
||||||
{
|
{
|
||||||
MP_INT number;
|
MP_INT number;
|
||||||
|
|
||||||
char buf[BUF_LEN];
|
char buf[BUF_LEN];
|
||||||
char bytes[BUF_LEN];
|
char bytes[BUF_LEN];
|
||||||
|
|
||||||
FILE *fd = fopen(OPENAC_SERIAL, "r");
|
FILE *fd = fopen(OPENAC_SERIAL, "r");
|
||||||
|
|
||||||
/* serial number defaults to 0 */
|
/* serial number defaults to 0 */
|
||||||
size_t len = 1;
|
size_t len = 1;
|
||||||
bytes[0] = 0x00;
|
bytes[0] = 0x00;
|
||||||
|
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
|
||||||
if (fscanf(fd, "%s", buf))
|
|
||||||
{
|
{
|
||||||
err_t ugh = ttodata(buf, 0, 16, bytes, BUF_LEN, &len);
|
if (fscanf(fd, "%s", buf))
|
||||||
|
{
|
||||||
|
err_t ugh = ttodata(buf, 0, 16, bytes, BUF_LEN, &len);
|
||||||
|
|
||||||
if (ugh != NULL)
|
if (ugh != NULL)
|
||||||
plog(" error reading serial number from %s: %s"
|
{
|
||||||
, OPENAC_SERIAL, ugh);
|
plog(" error reading serial number from %s: %s"
|
||||||
|
, OPENAC_SERIAL, ugh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fd);
|
||||||
}
|
}
|
||||||
fclose(fd);
|
else
|
||||||
}
|
{
|
||||||
else
|
plog(" file '%s' does not exist yet - serial number set to 01"
|
||||||
plog(" file '%s' does not exist yet - serial number set to 01"
|
|
||||||
, OPENAC_SERIAL);
|
, OPENAC_SERIAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* conversion of read serial number to a multiprecision integer
|
/**
|
||||||
* and incrementing it by one
|
* conversion of read serial number to a multiprecision integer
|
||||||
* and representing it as a two's complement octet string
|
* 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);
|
n_to_mpz(&number, bytes, len);
|
||||||
serial = mpz_to_n(&number, 1 + mpz_sizeinbase(&number, 2)/BITS_PER_BYTE);
|
mpz_add_ui(&number, &number, 0x01);
|
||||||
mpz_clear(&number);
|
serial = mpz_to_n(&number, 1 + mpz_sizeinbase(&number, 2)/BITS_PER_BYTE);
|
||||||
|
mpz_clear(&number);
|
||||||
|
|
||||||
return serial;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* write back the last serial number to file
|
* write back the last serial number to file
|
||||||
*/
|
*/
|
||||||
static void
|
static void write_serial(chunk_t serial)
|
||||||
write_serial(chunk_t serial)
|
|
||||||
{
|
{
|
||||||
char buf[BUF_LEN];
|
char buf[BUF_LEN];
|
||||||
|
|
||||||
FILE *fd = fopen(OPENAC_SERIAL, "w");
|
FILE *fd = fopen(OPENAC_SERIAL, "w");
|
||||||
|
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
datatot(serial.ptr, serial.len, 16, buf, BUF_LEN);
|
datatot(serial.ptr, serial.len, 16, buf, BUF_LEN);
|
||||||
plog(" serial number is %s", buf);
|
plog(" serial number is %s", buf);
|
||||||
fprintf(fd, "%s\n", buf);
|
fprintf(fd, "%s\n", buf);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
plog(" could not open file '%s' for writing", OPENAC_SERIAL);
|
{
|
||||||
|
plog(" could not open file '%s' for writing", OPENAC_SERIAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* global variables accessible by both main() and build.c
|
* global variables accessible by both main() and build.c
|
||||||
*/
|
*/
|
||||||
x509cert_t *user = NULL;
|
x509cert_t *user = NULL;
|
||||||
@ -171,268 +177,264 @@ time_t notAfter = 0;
|
|||||||
|
|
||||||
chunk_t serial;
|
chunk_t serial;
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
char *keyfile = NULL;
|
char *keyfile = NULL;
|
||||||
char *certfile = NULL;
|
char *certfile = NULL;
|
||||||
char *usercertfile = NULL;
|
char *usercertfile = NULL;
|
||||||
char *outfile = NULL;
|
char *outfile = NULL;
|
||||||
|
|
||||||
cert_t signercert = empty_cert;
|
cert_t signercert = empty_cert;
|
||||||
cert_t usercert = empty_cert;
|
cert_t usercert = empty_cert;
|
||||||
|
|
||||||
chunk_t attr_cert = empty_chunk;
|
chunk_t attr_cert = empty_chunk;
|
||||||
x509acert_t *ac = NULL;
|
x509acert_t *ac = NULL;
|
||||||
|
|
||||||
const time_t default_validity = 24*3600; /* 24 hours */
|
const time_t default_validity = 24*3600; /* 24 hours */
|
||||||
time_t validity = 0;
|
time_t validity = 0;
|
||||||
|
|
||||||
prompt_pass_t pass;
|
prompt_pass_t pass;
|
||||||
|
|
||||||
pass.secret[0] = '\0';
|
pass.secret[0] = '\0';
|
||||||
pass.prompt = TRUE;
|
pass.prompt = TRUE;
|
||||||
pass.fd = STDIN_FILENO;
|
pass.fd = STDIN_FILENO;
|
||||||
|
|
||||||
log_to_stderr = TRUE;
|
log_to_stderr = TRUE;
|
||||||
|
|
||||||
/* handle arguments */
|
/* handle arguments */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
|
||||||
# define DBG_OFFSET 256
|
|
||||||
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' },
|
|
||||||
#ifdef DEBUG
|
|
||||||
{ "debug-all", no_argument, NULL, 'A' },
|
|
||||||
{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
|
|
||||||
{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
|
|
||||||
{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
|
|
||||||
#endif
|
|
||||||
{ 0,0,0,0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int c = getopt_long(argc, argv, "hv+:qc:k:p;u:g:D:H:S:E:o:", long_opts, NULL);
|
|
||||||
|
|
||||||
/* Note: "breaking" from case terminates loop */
|
|
||||||
switch (c)
|
|
||||||
{
|
{
|
||||||
case EOF: /* end of flags */
|
# define DBG_OFFSET 256
|
||||||
break;
|
static const struct option long_opts[] = {
|
||||||
|
/* name, has_arg, flag, val */
|
||||||
case 0: /* long option already handled */
|
{ "help", no_argument, NULL, 'h' },
|
||||||
continue;
|
{ "version", no_argument, NULL, 'v' },
|
||||||
|
{ "optionsfrom", required_argument, NULL, '+' },
|
||||||
case ':': /* diagnostic already printed by getopt_long */
|
{ "quiet", no_argument, NULL, 'q' },
|
||||||
case '?': /* diagnostic already printed by getopt_long */
|
{ "cert", required_argument, NULL, 'c' },
|
||||||
usage(NULL);
|
{ "key", required_argument, NULL, 'k' },
|
||||||
break; /* not actually reached */
|
{ "password", required_argument, NULL, 'p' },
|
||||||
|
{ "usercert", required_argument, NULL, 'u' },
|
||||||
case 'h': /* --help */
|
{ "groups", required_argument, NULL, 'g' },
|
||||||
usage(NULL);
|
{ "days", required_argument, NULL, 'D' },
|
||||||
break; /* not actually reached */
|
{ "hours", required_argument, NULL, 'H' },
|
||||||
|
{ "startdate", required_argument, NULL, 'S' },
|
||||||
case 'v': /* --version */
|
{ "enddate", required_argument, NULL, 'E' },
|
||||||
printf("%s\n", openac_version);
|
{ "out", required_argument, NULL, 'o' },
|
||||||
exit(0);
|
|
||||||
break; /* not actually reached */
|
|
||||||
|
|
||||||
case '+': /* --optionsfrom <filename> */
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'c': /* --cert */
|
|
||||||
certfile = optarg;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'k': /* --key */
|
|
||||||
keyfile = optarg;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'p': /* --key */
|
|
||||||
pass.prompt = FALSE;
|
|
||||||
strncpy(pass.secret, optarg, sizeof(pass.secret));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'u': /* --usercert */
|
|
||||||
usercertfile = optarg;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'g': /* --groups */
|
|
||||||
decode_groups(optarg, &groups);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'D': /* --days */
|
|
||||||
if (optarg == NULL || !isdigit(optarg[0]))
|
|
||||||
usage("missing number of days");
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
{
|
|
||||||
chunk_t date = { optarg, 15 };
|
|
||||||
notAfter = asn1totime(&date, ASN1_GENERALIZEDTIME);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'o': /* --outt */
|
|
||||||
outfile = optarg;
|
|
||||||
continue ;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
case 'A': /* --debug-all */
|
{ "debug-all", no_argument, NULL, 'A' },
|
||||||
base_debugging = DBG_ALL;
|
{ "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
|
||||||
continue;
|
{ "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
|
||||||
|
{ "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
|
||||||
#endif
|
#endif
|
||||||
default:
|
{ 0,0,0,0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int c = getopt_long(argc, argv, "hv+:qc:k:p;u:g:D:H:S:E:o:", 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 */
|
||||||
|
usage(NULL);
|
||||||
|
break; /* not actually reached */
|
||||||
|
|
||||||
|
case 'h': /* --help */
|
||||||
|
usage(NULL);
|
||||||
|
break; /* not actually reached */
|
||||||
|
|
||||||
|
case 'v': /* --version */
|
||||||
|
printf("%s\n", openac_version);
|
||||||
|
exit(0);
|
||||||
|
break; /* not actually reached */
|
||||||
|
|
||||||
|
case '+': /* --optionsfrom <filename> */
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'c': /* --cert */
|
||||||
|
certfile = optarg;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'k': /* --key */
|
||||||
|
keyfile = optarg;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'p': /* --key */
|
||||||
|
pass.prompt = FALSE;
|
||||||
|
strncpy(pass.secret, optarg, sizeof(pass.secret));
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'u': /* --usercert */
|
||||||
|
usercertfile = optarg;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'g': /* --groups */
|
||||||
|
decode_groups(optarg, &groups);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'D': /* --days */
|
||||||
|
if (optarg == NULL || !isdigit(optarg[0]))
|
||||||
|
usage("missing number of days");
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
{
|
||||||
|
chunk_t date = { optarg, 15 };
|
||||||
|
notAfter = asn1totime(&date, ASN1_GENERALIZEDTIME);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'o': /* --outt */
|
||||||
|
outfile = optarg;
|
||||||
|
continue;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (c >= DBG_OFFSET)
|
case 'A': /* --debug-all */
|
||||||
{
|
base_debugging = DBG_ALL;
|
||||||
base_debugging |= c - DBG_OFFSET;
|
continue;
|
||||||
continue;
|
#endif
|
||||||
}
|
default:
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (c >= DBG_OFFSET)
|
||||||
|
{
|
||||||
|
base_debugging |= c - DBG_OFFSET;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
#undef DBG_OFFSET
|
#undef DBG_OFFSET
|
||||||
#endif
|
#endif
|
||||||
bad_case(c);
|
bad_case(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_log("openac");
|
init_log("openac");
|
||||||
cur_debugging = base_debugging;
|
cur_debugging = base_debugging;
|
||||||
|
|
||||||
if (optind != argc)
|
if (optind != argc)
|
||||||
usage("unexpected argument");
|
usage("unexpected argument");
|
||||||
|
|
||||||
/* load the signer's RSA private key */
|
/* load the signer's RSA private key */
|
||||||
if (keyfile != NULL)
|
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);
|
|
||||||
|
|
||||||
if (ugh != NULL)
|
|
||||||
{
|
{
|
||||||
free_RSA_private_content(signerkey);
|
err_t ugh = NULL;
|
||||||
pfree(signerkey);
|
|
||||||
plog("%s", ugh);
|
signerkey = alloc_thing(RSA_private_key_t, "RSA private key");
|
||||||
exit(1);
|
ugh = load_rsa_private_key(keyfile, &pass, signerkey);
|
||||||
|
|
||||||
|
if (ugh != NULL)
|
||||||
|
{
|
||||||
|
free_RSA_private_content(signerkey);
|
||||||
|
pfree(signerkey);
|
||||||
|
plog("%s", ugh);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* load the signer's X.509 certificate */
|
/* load the signer's X.509 certificate */
|
||||||
if (certfile != NULL)
|
if (certfile != NULL)
|
||||||
{
|
{
|
||||||
if (!load_cert(certfile, "signer cert", &signercert))
|
if (!load_cert(certfile, "signer cert", &signercert))
|
||||||
exit(1);
|
exit(1);
|
||||||
signer = signercert.u.x509;
|
signer = signercert.u.x509;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load the users's X.509 certificate */
|
/* load the users's X.509 certificate */
|
||||||
if (usercertfile != NULL)
|
if (usercertfile != NULL)
|
||||||
{
|
{
|
||||||
if (!load_cert(usercertfile, "user cert", &usercert))
|
if (!load_cert(usercertfile, "user cert", &usercert))
|
||||||
exit(1);
|
exit(1);
|
||||||
user = usercert.u.x509;
|
user = usercert.u.x509;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute validity interval */
|
|
||||||
validity = (validity)? validity : default_validity;
|
|
||||||
notBefore = (notBefore) ? notBefore : time(NULL);
|
|
||||||
notAfter = (notAfter) ? notAfter : notBefore + validity;
|
|
||||||
|
|
||||||
/* build and parse attribute certificate */
|
/* compute validity interval */
|
||||||
if (user != NULL && signer != NULL && signerkey != NULL)
|
validity = (validity)? validity : default_validity;
|
||||||
{
|
notBefore = (notBefore) ? notBefore : time(NULL);
|
||||||
/* read the serial number and increment it by one */
|
notAfter = (notAfter) ? notAfter : notBefore + validity;
|
||||||
serial = read_serial();
|
|
||||||
|
|
||||||
attr_cert = build_attr_cert();
|
/* build and parse attribute certificate */
|
||||||
ac = alloc_thing(x509acert_t, "x509acert");
|
if (user != NULL && signer != NULL && signerkey != NULL)
|
||||||
*ac = empty_ac;
|
{
|
||||||
parse_ac(attr_cert, ac);
|
/* 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);
|
||||||
|
|
||||||
/* write the attribute certificate to file */
|
/* write the attribute certificate to file */
|
||||||
if (write_chunk(outfile, "attribute cert", attr_cert, 0022, TRUE))
|
if (write_chunk(outfile, "attribute cert", attr_cert, 0022, TRUE))
|
||||||
write_serial(serial);
|
write_serial(serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete all dynamic objects */
|
/* delete all dynamic objects */
|
||||||
if (signerkey != NULL)
|
if (signerkey != NULL)
|
||||||
{
|
{
|
||||||
free_RSA_private_content(signerkey);
|
free_RSA_private_content(signerkey);
|
||||||
pfree(signerkey);
|
pfree(signerkey);
|
||||||
}
|
}
|
||||||
free_x509cert(signercert.u.x509);
|
free_x509cert(signercert.u.x509);
|
||||||
free_x509cert(usercert.u.x509);
|
free_x509cert(usercert.u.x509);
|
||||||
free_ietfAttrList(groups);
|
free_ietfAttrList(groups);
|
||||||
free_acert(ac);
|
free_acert(ac);
|
||||||
pfree(serial.ptr);
|
pfree(serial.ptr);
|
||||||
|
|
||||||
#ifdef LEAK_DETECTIVE
|
#ifdef LEAK_DETECTIVE
|
||||||
report_leaks();
|
report_leaks();
|
||||||
#endif /* LEAK_DETECTIVE */
|
#endif /* LEAK_DETECTIVE */
|
||||||
close_log();
|
close_log();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user