diff options
-rw-r--r-- | src/pki/commands/issue.c | 2 | ||||
-rw-r--r-- | src/pki/commands/print.c | 27 | ||||
-rw-r--r-- | src/pki/commands/signcrl.c | 80 |
3 files changed, 91 insertions, 18 deletions
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c index 2c0f1e04c..2ebb56594 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -244,7 +244,7 @@ static int issue() continue; case 'u': INIT(cdp, - .uri = strdup(arg), + .uri = arg, ); cdps->insert_last(cdps, cdp); continue; diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c index f0795ea2c..185895ec2 100644 --- a/src/pki/commands/print.c +++ b/src/pki/commands/print.c @@ -318,14 +318,41 @@ static void print_crl(crl_t *crl) crl_reason_t reason; chunk_t chunk; int count = 0; + bool first; char buf[64]; struct tm tm; + x509_cdp_t *cdp; chunk = crl->get_serial(crl); printf("serial: %#B\n", &chunk); + if (crl->is_delta_crl(crl, &chunk)) + { + printf("delta CRL: for serial %#B\n", &chunk); + } chunk = crl->get_authKeyIdentifier(crl); printf("authKeyId: %#B\n", &chunk); + first = TRUE; + enumerator = crl->create_delta_crl_uri_enumerator(crl); + while (enumerator->enumerate(enumerator, &cdp)) + { + if (first) + { + printf("freshest: %s", cdp->uri); + first = FALSE; + } + else + { + printf(" %s", cdp->uri); + } + if (cdp->issuer) + { + printf(" (CRL issuer: %Y)", cdp->issuer); + } + printf("\n"); + } + enumerator->destroy(enumerator); + enumerator = crl->create_enumerator(crl); while (enumerator->enumerate(enumerator, &chunk, &ts, &reason)) { diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index 87d585363..07f4a1343 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -98,6 +98,15 @@ static int read_serial(char *file, char *buf, int buflen) } /** + * Destroy a CDP + */ +static void cdp_destroy(x509_cdp_t *this) +{ + free(this->uri); + free(this); +} + +/** * Sign a CRL */ static int sign_crl() @@ -110,16 +119,19 @@ static int sign_crl() x509_t *x509; hash_algorithm_t digest = HASH_SHA1; char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL; + char *basecrl = NULL; char serial[512], crl_serial[8], *keyid = NULL; int serial_len = 0; crl_reason_t reason = CRL_REASON_UNSPECIFIED; time_t thisUpdate, nextUpdate, date = time(NULL); int lifetime = 15; - linked_list_t *list; + linked_list_t *list, *cdps; enumerator_t *enumerator, *lastenum = NULL; - chunk_t encoding = chunk_empty; + x509_cdp_t *cdp; + chunk_t encoding = chunk_empty, baseCrlNumber = chunk_empty; list = linked_list_create(); + cdps = linked_list_create(); memset(crl_serial, 0, sizeof(crl_serial)); @@ -190,6 +202,15 @@ static int sign_crl() reason = CRL_REASON_UNSPECIFIED; continue; } + case 'b': + basecrl = arg; + continue; + case 'u': + INIT(cdp, + .uri = strdup(arg), + ); + cdps->insert_last(cdps, cdp); + continue; case 'r': if (streq(arg, "key-compromise")) { @@ -302,6 +323,20 @@ static int sign_crl() thisUpdate = time(NULL); nextUpdate = thisUpdate + lifetime * 24 * 60 * 60; + if (basecrl) + { + lastcrl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, + BUILD_FROM_FILE, basecrl, BUILD_END); + if (!lastcrl) + { + error = "loading base CRL failed"; + goto error; + } + baseCrlNumber = chunk_clone(lastcrl->get_serial(lastcrl)); + DESTROY_IF((certificate_t*)lastcrl); + lastcrl = NULL; + } + if (lastupdate) { lastcrl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, @@ -315,6 +350,10 @@ static int sign_crl() min(lastcrl->get_serial(lastcrl).len, sizeof(crl_serial))); lastenum = lastcrl->create_enumerator(lastcrl); } + else + { + lastenum = enumerator_create_empty(); + } chunk_increment(chunk_create(crl_serial, sizeof(crl_serial))); @@ -324,11 +363,12 @@ static int sign_crl() BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca, BUILD_SERIAL, chunk_create(crl_serial, sizeof(crl_serial)), BUILD_NOT_BEFORE_TIME, thisUpdate, BUILD_NOT_AFTER_TIME, nextUpdate, - BUILD_REVOKED_ENUMERATOR, enumerator, BUILD_DIGEST_ALG, digest, - lastenum ? BUILD_REVOKED_ENUMERATOR : BUILD_END, lastenum, + BUILD_REVOKED_ENUMERATOR, enumerator, + BUILD_REVOKED_ENUMERATOR, lastenum, BUILD_DIGEST_ALG, digest, + BUILD_CRL_DISTRIBUTION_POINTS, cdps, BUILD_BASE_CRL, baseCrlNumber, BUILD_END); enumerator->destroy(enumerator); - DESTROY_IF(lastenum); + lastenum->destroy(lastenum); DESTROY_IF((certificate_t*)lastcrl); if (!crl) @@ -353,7 +393,9 @@ error: DESTROY_IF(ca); DESTROY_IF(crl); free(encoding.ptr); + free(baseCrlNumber.ptr); list->destroy_function(list, (void*)revoked_destroy); + cdps->destroy_function(cdps, (void*)cdp_destroy); if (error) { fprintf(stderr, "%s\n", error); @@ -363,6 +405,7 @@ error: usage: list->destroy_function(list, (void*)revoked_destroy); + cdps->destroy_function(cdps, (void*)cdp_destroy); return command_usage(error); } @@ -375,24 +418,27 @@ static void __attribute__ ((constructor))reg() sign_crl, 'c', "signcrl", "issue a CRL using a CA certificate and key", {"--cacert file --cakey file | --cakeyid hex --lifetime days", + "[--lastcrl crl] [--basecrl crl] [--crluri uri ]+", "[ [--reason key-compromise|ca-compromise|affiliation-changed|", " superseded|cessation-of-operation|certificate-hold]", " [--date timestamp]", " --cert file | --serial hex ]*", "[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"}, { - {"help", 'h', 0, "show usage information"}, - {"cacert", 'c', 1, "CA certificate file"}, - {"cakey", 'k', 1, "CA private key file"}, - {"cakeyid", 'x', 1, "keyid on smartcard of CA private key"}, - {"lifetime",'l', 1, "days the CRL gets a nextUpdate, default: 15"}, - {"lastcrl", 'a', 1, "CRL of lastUpdate to copy revocations from"}, - {"cert", 'z', 1, "certificate file to revoke"}, - {"serial", 's', 1, "hex encoded certificate serial number to revoke"}, - {"reason", 'r', 1, "reason for certificate revocation"}, - {"date", 'd', 1, "revocation date as unix timestamp, default: now"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, - {"outform", 'f', 1, "encoding of generated crl, default: der"}, + {"help", 'h', 0, "show usage information"}, + {"cacert", 'c', 1, "CA certificate file"}, + {"cakey", 'k', 1, "CA private key file"}, + {"cakeyid", 'x', 1, "keyid on smartcard of CA private key"}, + {"lifetime", 'l', 1, "days the CRL gets a nextUpdate, default: 15"}, + {"lastcrl", 'a', 1, "CRL of lastUpdate to copy revocations from"}, + {"basecrl", 'b', 1, "base CRL to create a delta CRL for"}, + {"crluri", 'u', 1, "freshest delta CRL URI to include"}, + {"cert", 'z', 1, "certificate file to revoke"}, + {"serial", 's', 1, "hex encoded certificate serial number to revoke"}, + {"reason", 'r', 1, "reason for certificate revocation"}, + {"date", 'd', 1, "revocation date as unix timestamp, default: now"}, + {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"outform", 'f', 1, "encoding of generated crl, default: der"}, } }); } |