diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2015-12-06 13:28:03 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2015-12-11 18:26:53 +0100 |
commit | 3317d0e77b1a1731028b2a6ff5619c1d62624f35 (patch) | |
tree | 5f4287a4d6416c170c05bb15395aa44cbf1aa6f1 /src/libcharon/plugins/stroke/stroke_list.c | |
parent | 36d42daf4d7190a251a4d24de7c143a8e44023ad (diff) | |
download | strongswan-3317d0e77b1a.tar.bz2 strongswan-3317d0e77b1a.tar.xz |
Standardized printing of certificate information
The certificate_printer class allows the printing of certificate
information to a text file (usually stdout). This class is used
by the pki --print and swanctl --list-certs commands as well as
by the stroke plugin.
Diffstat (limited to 'src/libcharon/plugins/stroke/stroke_list.c')
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_list.c | 513 |
1 files changed, 68 insertions, 445 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index c0192b5c0..e312ae152 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -2,6 +2,9 @@ * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * * 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 @@ -28,17 +31,9 @@ #include <collections/linked_list.h> #include <plugins/plugin.h> #include <credentials/certificates/x509.h> -#include <credentials/certificates/ac.h> -#include <credentials/certificates/crl.h> #include <credentials/certificates/pgp_certificate.h> +#include <credentials/certificates/certificate_printer.h> #include <config/peer_cfg.h> -#include <asn1/asn1.h> -#include <asn1/oid.h> - -/* warning intervals for list functions */ -#define CERT_WARNING_INTERVAL 30 /* days */ -#define CRL_WARNING_INTERVAL 7 /* days */ -#define AC_WARNING_INTERVAL 1 /* day */ typedef struct private_stroke_list_t private_stroke_list_t; @@ -738,14 +733,20 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type) } /** - * Print a single public key. + * Is there a matching private key? */ -static void list_public_key(public_key_t *public, FILE *out) +static bool has_privkey(certificate_t *cert) { + public_key_t *public; private_key_t *private = NULL; chunk_t keyid; identification_t *id; + public = cert->get_public_key(cert); + if (!public) + { + return FALSE; + } if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) { id = identification_create_from_encoding(ID_KEY_ID, keyid); @@ -753,99 +754,23 @@ static void list_public_key(public_key_t *public, FILE *out) public->get_type(public), id, NULL); id->destroy(id); } - - fprintf(out, " pubkey: %N %d bits%s\n", - key_type_names, public->get_type(public), - public->get_keysize(public), - private ? ", has private key" : ""); - if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid)) - { - fprintf(out, " keyid: %#B\n", &keyid); - } - if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) - { - fprintf(out, " subjkey: %#B\n", &keyid); - } + public->destroy(public); DESTROY_IF(private); -} - -/** - * list all raw public keys - */ -static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out) -{ - bool first = TRUE; - time_t now = time(NULL), notBefore, notAfter; - enumerator_t *enumerator; - certificate_t *cert; - - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - identification_t *subject = cert->get_subject(cert); - public_key_t *public = cert->get_public_key(cert); - - if (public) - { - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of Raw Public Keys:\n"); - first = FALSE; - } - fprintf(out, "\n"); - - /* list subject if available */ - if (subject->get_type(subject) != ID_KEY_ID) - { - fprintf(out, " subject: %#Y\n", subject); - } - - /* list validity if available*/ - cert->get_validity(cert, &now, ¬Before, ¬After); - if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME) - { - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - } - list_public_key(public, out); - public->destroy(public); - } - } - enumerator->destroy(enumerator); + return (private != NULL); } /** * list OpenPGP certificates */ -static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out) +static void stroke_list_pgp_certs(linked_list_t *list, char *label, + bool utc, FILE *out) { bool first = TRUE; time_t now = time(NULL); enumerator_t *enumerator = list->create_enumerator(list); certificate_t *cert; + chunk_t keyid; while (enumerator->enumerate(enumerator, (void**)&cert)) { @@ -856,14 +781,12 @@ static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out) if (first) { - fprintf(out, "\n"); - fprintf(out, "List of PGP End Entity Certificates:\n"); - first = FALSE; + fprintf(out, "List of %ss:\n", label); + first = FALSE; } fprintf(out, "\n"); fprintf(out, " userid: '%Y'\n", cert->get_subject(cert)); - fprintf(out, " digest: %#B\n", &fingerprint); /* list validity */ @@ -875,7 +798,19 @@ static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out) public = cert->get_public_key(cert); if (public) { - list_public_key(public, out); + fprintf(out, " pubkey: %N %d bits%s\n", + key_type_names, public->get_type(public), + public->get_keysize(public), + has_privkey(cert) ? ", has private key" : ""); + + if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid)) + { + fprintf(out, " keyid: %#B\n", &keyid); + } + if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) + { + fprintf(out, " subjkey: %#B\n", &keyid); + } public->destroy(public); } } @@ -885,15 +820,17 @@ static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out) /** * list all X.509 certificates matching the flags */ -static void stroke_list_certs(linked_list_t *list, char *label, - x509_flag_t flags, bool utc, FILE *out) +static void stroke_list_x509_certs(linked_list_t *list, char *label, + x509_flag_t flags, bool utc, FILE *out) { bool first = TRUE; - time_t now = time(NULL); enumerator_t *enumerator; certificate_t *cert; + certificate_printer_t *printer; x509_flag_t flag_mask; + printer = certificate_printer_create(out, TRUE, utc), + /* mask all auxiliary flags */ flag_mask = ~(X509_SERVER_AUTH | X509_CLIENT_AUTH | X509_IKE_INTERMEDIATE | X509_SELF_SIGNED | X509_IP_ADDR_BLOCKS); @@ -907,367 +844,49 @@ static void stroke_list_certs(linked_list_t *list, char *label, /* list only if flag is set or flag == 0 */ if ((x509_flags & flags) || (x509_flags == flags)) { - enumerator_t *enumerator; - identification_t *altName; - bool first_altName = TRUE; - u_int pathlen; - chunk_t serial, authkey; - time_t notBefore, notAfter; - public_key_t *public; - if (first) { fprintf(out, "\n"); - fprintf(out, "List of %s:\n", label); + fprintf(out, "List of %ss:\n", label); first = FALSE; } fprintf(out, "\n"); - - /* list subjectAltNames */ - enumerator = x509->create_subjectAltName_enumerator(x509); - while (enumerator->enumerate(enumerator, (void**)&altName)) - { - if (first_altName) - { - fprintf(out, " altNames: "); - first_altName = FALSE; - } - else - { - fprintf(out, ", "); - } - fprintf(out, "%Y", altName); - } - if (!first_altName) - { - fprintf(out, "\n"); - } - enumerator->destroy(enumerator); - - fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert)); - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - serial = chunk_skip_zero(x509->get_serial(x509)); - fprintf(out, " serial: %#B\n", &serial); - - /* list validity */ - cert->get_validity(cert, &now, ¬Before, ¬After); - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - - public = cert->get_public_key(cert); - if (public) - { - list_public_key(public, out); - public->destroy(public); - } - - /* list optional authorityKeyIdentifier */ - authkey = x509->get_authKeyIdentifier(x509); - if (authkey.ptr) - { - fprintf(out, " authkey: %#B\n", &authkey); - } - - /* list optional pathLenConstraint */ - pathlen = x509->get_constraint(x509, X509_PATH_LEN); - if (pathlen != X509_NO_CONSTRAINT) - { - fprintf(out, " pathlen: %u\n", pathlen); - } - - /* list optional ipAddrBlocks */ - if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS) - { - traffic_selector_t *ipAddrBlock; - bool first_ipAddrBlock = TRUE; - - fprintf(out, " addresses: "); - enumerator = x509->create_ipAddrBlock_enumerator(x509); - while (enumerator->enumerate(enumerator, &ipAddrBlock)) - { - if (first_ipAddrBlock) - { - first_ipAddrBlock = FALSE; - } - else - { - fprintf(out, ", "); - } - fprintf(out, "%R", ipAddrBlock); - } - enumerator->destroy(enumerator); - fprintf(out, "\n"); - } + printer->print(printer, cert, has_privkey(cert)); } } enumerator->destroy(enumerator); + + printer->destroy(printer); } /** - * list all X.509 attribute certificates + * list all other certificates types */ -static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out) +static void stroke_list_other_certs(linked_list_t *list, char *label, + bool utc, FILE *out) { bool first = TRUE; - time_t notBefore, notAfter, now = time(NULL); enumerator_t *enumerator; certificate_t *cert; + certificate_printer_t *printer; + + printer = certificate_printer_create(out, TRUE, utc), enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &cert)) { - ac_t *ac = (ac_t*)cert; - ac_group_type_t type; - identification_t *id; - enumerator_t *groups; - chunk_t chunk; - bool firstgroup = TRUE; - - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of X.509 Attribute Certificates:\n"); - first = FALSE; - } - fprintf(out, "\n"); - - id = cert->get_subject(cert); - if (id) - { - fprintf(out, " holder: \"%Y\"\n", id); - } - id = ac->get_holderIssuer(ac); - if (id) - { - fprintf(out, " hissuer: \"%Y\"\n", id); - } - chunk = chunk_skip_zero(ac->get_holderSerial(ac)); - if (chunk.ptr) - { - fprintf(out, " hserial: %#B\n", &chunk); - } - groups = ac->create_group_enumerator(ac); - while (groups->enumerate(groups, &type, &chunk)) - { - int oid; - char *str; - - if (firstgroup) - { - fprintf(out, " groups: "); - firstgroup = FALSE; - } - else - { - fprintf(out, " "); - } - switch (type) - { - case AC_GROUP_TYPE_STRING: - fprintf(out, "%.*s", (int)chunk.len, chunk.ptr); - break; - case AC_GROUP_TYPE_OID: - oid = asn1_known_oid(chunk); - if (oid == OID_UNKNOWN) - { - str = asn1_oid_to_string(chunk); - if (str) - { - fprintf(out, "%s", str); - free(str); - } - else - { - fprintf(out, "OID:%#B", &chunk); - } - } - else - { - fprintf(out, "%s", oid_names[oid].name); - } - break; - case AC_GROUP_TYPE_OCTETS: - fprintf(out, "%#B", &chunk); - break; - } - fprintf(out, "\n"); - } - groups->destroy(groups); - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - chunk = chunk_skip_zero(ac->get_serial(ac)); - fprintf(out, " serial: %#B\n", &chunk); - - /* list validity */ - cert->get_validity(cert, &now, ¬Before, ¬After); - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - AC_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - - /* list optional authorityKeyIdentifier */ - chunk = ac->get_authKeyIdentifier(ac); - if (chunk.ptr) - { - fprintf(out, " authkey: %#B\n", &chunk); - } - } - enumerator->destroy(enumerator); -} - -/** - * list all X.509 CRLs - */ -static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out) -{ - bool first = TRUE; - time_t thisUpdate, nextUpdate, now = time(NULL); - enumerator_t *enumerator = list->create_enumerator(list); - certificate_t *cert; - - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - crl_t *crl = (crl_t*)cert; - chunk_t chunk; - if (first) { fprintf(out, "\n"); - fprintf(out, "List of X.509 CRLs:\n"); + fprintf(out, "List of %ss:\n", label); first = FALSE; } fprintf(out, "\n"); - - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - - /* list optional crlNumber */ - chunk = chunk_skip_zero(crl->get_serial(crl)); - if (chunk.ptr) - { - fprintf(out, " serial: %#B\n", &chunk); - } - if (crl->is_delta_crl(crl, &chunk)) - { - chunk = chunk_skip_zero(chunk); - fprintf(out, " delta for: %#B\n", &chunk); - } - - /* count the number of revoked certificates */ - { - int count = 0; - enumerator_t *enumerator = crl->create_enumerator(crl); - - while (enumerator->enumerate(enumerator, NULL, NULL, NULL)) - { - count++; - } - fprintf(out, " revoked: %d certificate%s\n", count, - (count == 1)? "" : "s"); - enumerator->destroy(enumerator); - } - - /* list validity */ - cert->get_validity(cert, &now, &thisUpdate, &nextUpdate); - fprintf(out, " updates: this %T\n", &thisUpdate, utc); - fprintf(out, " next %T, ", &nextUpdate, utc); - if (now > nextUpdate) - { - fprintf(out, "expired (%V ago)\n", &now, &nextUpdate); - } - else - { - fprintf(out, "ok"); - if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, &nextUpdate); - } - fprintf(out, " \n"); - } - - /* list optional authorityKeyIdentifier */ - chunk = crl->get_authKeyIdentifier(crl); - if (chunk.ptr) - { - fprintf(out, " authkey: %#B\n", &chunk); - } + printer->print(printer, cert, has_privkey(cert)); } enumerator->destroy(enumerator); -} - -/** - * list all OCSP responses - */ -static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out) -{ - bool first = TRUE, ok; - enumerator_t *enumerator = list->create_enumerator(list); - certificate_t *cert; - time_t produced, usable, now = time(NULL); - - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of OCSP responses:\n"); - fprintf(out, "\n"); - first = FALSE; - } - fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert)); - /* check validity */ - ok = cert->get_validity(cert, &now, &produced, &usable); - fprintf(out, " validity: produced at %T\n", &produced, utc); - fprintf(out, " usable till %T, ", &usable, utc); - if (ok) - { - fprintf(out, "ok\n"); - } - else - { - fprintf(out, "expired (%V ago)\n", &now, &usable); - } - } - enumerator->destroy(enumerator); + printer->destroy(printer); } /** @@ -1443,14 +1062,16 @@ METHOD(stroke_list_t, list, void, { linked_list_t *pubkey_list = create_unique_cert_list(CERT_TRUSTED_PUBKEY); - stroke_list_pubkeys(pubkey_list, msg->list.utc, out); + stroke_list_other_certs(pubkey_list, "Raw Public Key", + msg->list.utc, out); pubkey_list->destroy_offset(pubkey_list, offsetof(certificate_t, destroy)); } if (msg->list.flags & LIST_CERTS) { linked_list_t *pgp_list = create_unique_cert_list(CERT_GPG); - stroke_list_pgp(pgp_list, msg->list.utc, out); + stroke_list_pgp_certs(pgp_list, "PGP End Entity Certificate", + msg->list.utc, out); pgp_list->destroy_offset(pgp_list, offsetof(certificate_t, destroy)); } if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS)) @@ -1459,23 +1080,23 @@ METHOD(stroke_list_t, list, void, } if (msg->list.flags & LIST_CERTS) { - stroke_list_certs(cert_list, "X.509 End Entity Certificates", - X509_NONE, msg->list.utc, out); + stroke_list_x509_certs(cert_list, "X.509 End Entity Certificate", + X509_NONE, msg->list.utc, out); } if (msg->list.flags & LIST_CACERTS) { - stroke_list_certs(cert_list, "X.509 CA Certificates", - X509_CA, msg->list.utc, out); + stroke_list_x509_certs(cert_list, "X.509 CA Certificate", + X509_CA, msg->list.utc, out); } if (msg->list.flags & LIST_OCSPCERTS) { - stroke_list_certs(cert_list, "X.509 OCSP Signer Certificates", - X509_OCSP_SIGNER, msg->list.utc, out); + stroke_list_x509_certs(cert_list, "X.509 OCSP Signer Certificate", + X509_OCSP_SIGNER, msg->list.utc, out); } if (msg->list.flags & LIST_AACERTS) { - stroke_list_certs(cert_list, "X.509 AA Certificates", - X509_AA, msg->list.utc, out); + stroke_list_x509_certs(cert_list, "X.509 AA Certificate", + X509_AA, msg->list.utc, out); } DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy)); @@ -1483,22 +1104,24 @@ METHOD(stroke_list_t, list, void, { linked_list_t *ac_list = create_unique_cert_list(CERT_X509_AC); - stroke_list_acerts(ac_list, msg->list.utc, out); + stroke_list_other_certs(ac_list, "X.509 Attribute Certificate", + msg->list.utc, out); ac_list->destroy_offset(ac_list, offsetof(certificate_t, destroy)); } if (msg->list.flags & LIST_CRLS) { linked_list_t *crl_list = create_unique_cert_list(CERT_X509_CRL); - stroke_list_crls(crl_list, msg->list.utc, out); + stroke_list_other_certs(crl_list, "X.509 CRL", + msg->list.utc, out); crl_list->destroy_offset(crl_list, offsetof(certificate_t, destroy)); } if (msg->list.flags & LIST_OCSP) { linked_list_t *ocsp_list = create_unique_cert_list(CERT_X509_OCSP_RESPONSE); - stroke_list_ocsp(ocsp_list, msg->list.utc, out); - + stroke_list_other_certs(ocsp_list, "OCSP Response", + msg->list.utc, out); ocsp_list->destroy_offset(ocsp_list, offsetof(certificate_t, destroy)); } if (msg->list.flags & LIST_ALGS) |