diff options
author | Martin Willi <martin@strongswan.org> | 2006-05-19 06:44:08 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2006-05-19 06:44:08 +0000 |
commit | 86a7937b45b624867af996e30642d6be70f37988 (patch) | |
tree | 3a4aa31ae4c7e54d1757d64f63823b20516a6890 /src | |
parent | 3e61d63a3a468586b89a5dcf0d6579a58ad5009e (diff) | |
download | strongswan-86a7937b45b624867af996e30642d6be70f37988.tar.bz2 strongswan-86a7937b45b624867af996e30642d6be70f37988.tar.xz |
- applied patch from andreas, which allows certificate listing via stroke
Diffstat (limited to 'src')
-rwxr-xr-x | src/charon/config/credentials/credential_store.h | 10 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.c | 27 | ||||
-rw-r--r-- | src/charon/config/credentials/local_credential_store.h | 8 | ||||
-rwxr-xr-x | src/charon/threads/stroke_interface.c | 58 | ||||
-rwxr-xr-x | src/ipsec/ipsec.in | 22 | ||||
-rw-r--r-- | src/libstrongswan/asn1/asn1.c | 20 | ||||
-rw-r--r-- | src/libstrongswan/asn1/asn1.h | 1 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_public_key.c | 74 | ||||
-rw-r--r-- | src/libstrongswan/crypto/rsa/rsa_public_key.h | 8 | ||||
-rwxr-xr-x | src/libstrongswan/crypto/x509.c | 128 | ||||
-rwxr-xr-x | src/libstrongswan/crypto/x509.h | 14 | ||||
-rw-r--r-- | src/libstrongswan/types.c | 28 | ||||
-rw-r--r-- | src/libstrongswan/types.h | 6 | ||||
-rw-r--r-- | src/libstrongswan/utils/iterator.h | 7 | ||||
-rw-r--r-- | src/libstrongswan/utils/linked_list.c | 11 | ||||
-rw-r--r-- | src/stroke/stroke.c | 33 | ||||
-rw-r--r-- | src/stroke/stroke.h | 5 |
17 files changed, 343 insertions, 117 deletions
diff --git a/src/charon/config/credentials/credential_store.h b/src/charon/config/credentials/credential_store.h index 2339469c0..df128fad6 100755 --- a/src/charon/config/credentials/credential_store.h +++ b/src/charon/config/credentials/credential_store.h @@ -27,6 +27,7 @@ #include <crypto/rsa/rsa_private_key.h> #include <crypto/rsa/rsa_public_key.h> #include <utils/identification.h> +#include <utils/logger.h> typedef struct credential_store_t credential_store_t; @@ -81,6 +82,15 @@ struct credential_store_t { rsa_private_key_t *(*get_rsa_private_key) (credential_store_t *this, identification_t *identification); /** + * @brief Lists all certificates kept in the local credential store. + * + * @param this calling object + * @param logger logger to be used + * @param utc log dates either in UTC or local time + */ + void (*log_certificates) (credential_store_t *this, logger_t *logger, bool utc); + + /** * @brief Destroys a credential_store_t object. * * @param this calling object diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 2554eec4a..ab17c0d1c 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -141,6 +141,30 @@ static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t * } /** + * Implements credential_store_t.log_certificates + */ +static void log_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc) +{ + iterator_t *iterator = this->certificates->create_iterator(this->certificates, TRUE); + + if (iterator->get_count(iterator)) + { + logger->log(logger, CONTROL, ""); + logger->log(logger, CONTROL, "List of X.509 End Entity Certificates:"); + logger->log(logger, CONTROL, ""); + } + + while (iterator->has_next(iterator)) + { + x509_t *cert; + + iterator->current(iterator, (void**)&cert); + cert->log_certificate(cert, logger, utc); + } + iterator->destroy(iterator); +} + +/** * Implements local_credential_store_t.load_certificates */ static void load_certificates(private_local_credential_store_t *this, const char *path) @@ -187,8 +211,8 @@ static void load_certificates(private_local_credential_store_t *this, const char */ static identification_t *get_id_for_private_key(private_local_credential_store_t *this, rsa_private_key_t *private_key) { - iterator_t *iterator; x509_t *cert; + iterator_t *iterator; identification_t *found = NULL; rsa_public_key_t *public_key; @@ -368,6 +392,7 @@ local_credential_store_t * local_credential_store_create(void) this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret; this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,identification_t*))get_rsa_private_key; this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key; + this->public.credential_store.log_certificates = (void(*)(credential_store_t*,logger_t*,bool))log_certificates; this->public.load_certificates = (void(*)(local_credential_store_t*,const char*))load_certificates; this->public.load_private_keys = (void(*)(local_credential_store_t*,const char*, const char*))load_private_keys; this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy; diff --git a/src/charon/config/credentials/local_credential_store.h b/src/charon/config/credentials/local_credential_store.h index 81b7568d7..db71341d0 100644 --- a/src/charon/config/credentials/local_credential_store.h +++ b/src/charon/config/credentials/local_credential_store.h @@ -52,7 +52,7 @@ struct local_credential_store_t { /** * @brief Loads trusted certificates from a folder. * - * Currently, all keys must be in binary DER format. + * Certificates in both DER and PEM format are accepted * * @param this calling object * @param path directory to load certificates from @@ -60,10 +60,10 @@ struct local_credential_store_t { void (*load_certificates) (local_credential_store_t *this, const char *path); /** - * @brief Loads RSA private keys from a folder. + * @brief Loads RSA private keys defined in ipsec.secrets * - * Currently, all keys must be unencrypted in binary DER format. Anything - * other gets ignored. Further, a certificate for the specific private + * Currently, all keys must be unencrypted in either DER or PEM format. + * Other formats are ignored. Further, a certificate for the specific private * key must already be loaded to get the ID from. * * @param this calling object diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index f8db7ad8e..8a0d22097 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -358,6 +358,16 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg) charon->ike_sa_manager->log_status(charon->ike_sa_manager, this->stroke_logger, msg->status.name); } +/** + * list various information + */ +static void stroke_list(private_stroke_t *this, stroke_msg_t *msg, bool utc) +{ + if (msg->type = STR_LIST_CERTS) + { + charon->credentials->log_certificates(charon->credentials, this->stroke_logger, utc); + } +} logger_context_t get_context(char *context) { if (strcasecmp(context, "ALL") == 0) return ALL_LOGGERS; @@ -399,11 +409,16 @@ static void stroke_logtype(private_stroke_t *this, stroke_msg_t *msg) return; } - if (strcasecmp(msg->logtype.type, "CONTROL") == 0) level = CONTROL; - else if (strcasecmp(msg->logtype.type, "ERROR") == 0) level = ERROR; - else if (strcasecmp(msg->logtype.type, "AUDIT") == 0) level = AUDIT; - else if (strcasecmp(msg->logtype.type, "RAW") == 0) level = RAW; - else if (strcasecmp(msg->logtype.type, "PRIVATE") == 0) level = PRIVATE; + if (strcasecmp(msg->logtype.type, "CONTROL") == 0) + level = CONTROL; + else if (strcasecmp(msg->logtype.type, "ERROR") == 0) + level = ERROR; + else if (strcasecmp(msg->logtype.type, "AUDIT") == 0) + level = AUDIT; + else if (strcasecmp(msg->logtype.type, "RAW") == 0) + level = RAW; + else if (strcasecmp(msg->logtype.type, "PRIVATE") == 0) + level = PRIVATE; else { this->stroke_logger->log(this->stroke_logger, ERROR, "invalid type (%s)!", msg->logtype.type); @@ -425,13 +440,13 @@ static void stroke_logtype(private_stroke_t *this, stroke_msg_t *msg) */ static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg) { + log_level_t level; + logger_context_t context; + pop_string(msg, &(msg->loglevel.context)); - this->logger->log(this->logger, CONTROL, "received stroke: loglevel for %s", msg->loglevel.context); - log_level_t level; - logger_context_t context = get_context(msg->loglevel.context); - + context = get_context(msg->loglevel.context); if (context == -2) { this->stroke_logger->log(this->stroke_logger, ERROR, "invalid context (%s)!", msg->loglevel.context); @@ -439,21 +454,13 @@ static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg) } if (msg->loglevel.level == 0) - { level = LEVEL0; - } else if (msg->loglevel.level == 1) - { level = LEVEL1; - } else if (msg->loglevel.level == 2) - { level = LEVEL2; - } else if (msg->loglevel.level == 3) - { level = LEVEL3; - } else { this->stroke_logger->log(this->stroke_logger, ERROR, "invalid level (%d)!", msg->loglevel.level); @@ -529,41 +536,30 @@ static void stroke_receive(private_stroke_t *this) switch (msg->type) { case STR_INITIATE: - { stroke_initiate(this, msg); break; - } case STR_TERMINATE: - { stroke_terminate(this, msg); break; - } case STR_STATUS: - { stroke_status(this, msg); break; - } case STR_STATUS_ALL: - { this->stroke_logger->enable_level(this->stroke_logger, LEVEL1); stroke_status(this, msg); break; - } case STR_ADD_CONN: - { stroke_add_conn(this, msg); break; - } case STR_LOGTYPE: - { stroke_logtype(this, msg); break; - } case STR_LOGLEVEL: - { stroke_loglevel(this, msg); break; - } + case STR_LIST_CERTS: + stroke_list(this, msg, FALSE); + break; default: this->logger->log(this->logger, ERROR, "received invalid stroke"); } diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in index 9c4ec4780..6fd57776c 100755 --- a/src/ipsec/ipsec.in +++ b/src/ipsec/ipsec.in @@ -106,10 +106,10 @@ down) fi exit 0 ;; -listalgs|listpubkeys|listcerts|listcacerts|\ -listaacerts|listocspcerts|listacerts|listgroups|\ +listalgs|listpubkeys|listcacerts|listaacerts|\ +listocspcerts|listacerts|listgroups|\ listcainfos|listcrls|listocsp|listcards|\ -listall|purgeocsp|rereadsecrets|rereadgroups|\ +purgeocsp|rereadsecrets|rereadgroups|\ rereadcacerts|rereadaacerts|rereadocspcerts|\ rereadacerts|rereadcrls|rereadall) op="$1" @@ -118,10 +118,18 @@ rereadacerts|rereadcrls|rereadall) then $IPSEC_WHACK "$@" "--$op" fi - #if test -e $IPSEC_CHARON_PID - #then - # $IPSEC_STROKE "$op" - #fi + ;; +listcerts|listall) + op="$1" + shift + if test -e $IPSEC_PLUTO_PID + then + $IPSEC_WHACK "$@" "--$op" + fi + if test -e $IPSEC_CHARON_PID + then + $IPSEC_STROKE "$op" + fi exit 0 ;; ready) diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 662f7fc1a..c52fb2dce 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -216,22 +216,19 @@ bool is_printablestring(chunk_t str) /** * Display a date either in local or UTC time - * TODO: Does not seem to be thread safe */ -char* timetoa(const time_t *time, bool utc) +void timetoa(char *buf, size_t buflen, const time_t *time, bool utc) { - static char buf[30]; - if (*time == 0) - sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" "); + snprintf(buf, buflen, "--- -- --:--:--%s----", (utc)?" UTC ":" "); else { struct tm *t = (utc)? gmtime(time) : localtime(time); - sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d", + + snprintf(buf, buflen, "%s %02d %02d:%02d:%02d%s%04d", months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, (utc)?" UTC ":" ", t->tm_year + 1900); } - return buf; } /** @@ -349,8 +346,13 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type) return; case ASN1_UTCTIME: case ASN1_GENERALIZEDTIME: - time = asn1totime(&object, type); - logger->log(logger, CONTROL|LEVEL1, " '%s'", timetoa(&time, TRUE)); + { + char buf[TIMETOA_BUF]; + time_t time = asn1totime(&object, type); + + timetoa(buf, TIMETOA_BUF, &time, TRUE); + logger->log(logger, CONTROL|LEVEL1, " '%s'", buf); + } return; default: break; diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h index 556bb2b05..ee905be4d 100644 --- a/src/libstrongswan/asn1/asn1.h +++ b/src/libstrongswan/asn1/asn1.h @@ -121,6 +121,7 @@ extern int known_oid(chunk_t object); extern u_int asn1_length(chunk_t *blob); extern bool is_printablestring(chunk_t str); extern time_t asn1totime(const chunk_t *utctime, asn1_t type); +extern void timetoa(char *buf, size_t buflen, const time_t *time, bool utc); extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit); extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx); extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name); diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c index 2f8c6fd8f..8fd02d2ef 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.c +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.c @@ -40,39 +40,58 @@ * TODO: We may move them in asn1 sometime... */ -u_int8_t md2_oid[] = { - 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86, - 0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00, - 0x04,0x10 +const u_int8_t md2_oid[] = { + 0x30,0x20, + 0x30,0x0c, + 0x06,0x08, + 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02, + 0x05,0x00, + 0x04,0x10 }; -u_int8_t md5_oid[] = { - 0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86, - 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00, - 0x04,0x10 +const u_int8_t md5_oid[] = { + 0x30,0x20, + 0x30,0x0c, + 0x06,0x08, + 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05, + 0x05,0x00, + 0x04,0x10 }; -u_int8_t sha1_oid[] = { - 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e, - 0x03,0x02,0x1a,0x05,0x00,0x04,0x14 +const u_int8_t sha1_oid[] = { + 0x30,0x21, + 0x30,0x09, + 0x06,0x05, + 0x2b,0x0e,0x03,0x02,0x1a, + 0x05,0x00, + 0x04,0x14 }; -u_int8_t sha256_oid[] = { - 0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86, - 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05, - 0x00,0x04,0x20 +const u_int8_t sha256_oid[] = { + 0x30,0x31, + 0x30,0x0d, + 0x06,0x09, + 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, + 0x05,0x00, + 0x04,0x20 }; -u_int8_t sha384_oid[] = { - 0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86, - 0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05, - 0x00,0x04,0x30 +const u_int8_t sha384_oid[] = { + 0x30,0x41, + 0x30,0x0d, + 0x06,0x09, + 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02, + 0x05,0x00, + 0x04,0x30 }; -u_int8_t sha512_oid[] = { - 0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86, - 0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05, - 0x00,0x04,0x40 +const u_int8_t sha512_oid[] = { + 0x30,0x51, + 0x30,0x0d, + 0x06,0x09, + 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03, + 0x05,0x00, + 0x04,0x40 }; /* ASN.1 definition public key */ @@ -338,6 +357,14 @@ static mpz_t *get_modulus(private_rsa_public_key_t *this) } /** + * Implementation of rsa_public_key.get_keysize. + */ +static size_t get_keysize(private_rsa_public_key_t *this) +{ + return this->k; +} + +/** * Implementation of rsa_public_key.clone. */ static rsa_public_key_t* _clone(private_rsa_public_key_t *this) @@ -373,6 +400,7 @@ private_rsa_public_key_t *rsa_public_key_create_empty(void) this->public.get_key = (status_t (*) (rsa_public_key_t*,chunk_t*))get_key; this->public.save_key = (status_t (*) (rsa_public_key_t*,char*))save_key; this->public.get_modulus = (mpz_t *(*) (rsa_public_key_t*))get_modulus; + this->public.get_keysize = (size_t (*) (rsa_public_key_t*))get_keysize; this->public.clone = (rsa_public_key_t* (*) (rsa_public_key_t*))_clone; this->public.destroy = (void (*) (rsa_public_key_t*))destroy; diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h index ef79153d6..12c01bf29 100644 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.h +++ b/src/libstrongswan/crypto/rsa/rsa_public_key.h @@ -105,6 +105,14 @@ struct rsa_public_key_t { mpz_t *(*get_modulus) (rsa_public_key_t *this); /** + * @brief Get the size of the modulus in bytes. + * + * @param this calling object + * @return size of the modulus (n) in bytes + */ + size_t (*get_keysize) (rsa_public_key_t *this); + + /** * @brief Clone the public key. * * @param this public key to clone diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c index b65327b5d..ec3828741 100755 --- a/src/libstrongswan/crypto/x509.c +++ b/src/libstrongswan/crypto/x509.c @@ -34,9 +34,10 @@ #include <utils/linked_list.h> #define BUF_LEN 512 -#define RSA_MIN_OCTETS (512 / 8) -#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits" -#define RSA_MAX_OCTETS (8192 / 8) +#define BITS_PER_BYTE 8 +#define RSA_MIN_OCTETS (1024 / BITS_PER_BYTE) +#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 1024 bits" +#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE) #define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits" logger_t *logger; @@ -81,21 +82,46 @@ struct private_x509_t { x509_t public; /** - * Version of the X509 certificate + * Time when certificate was installed + */ + time_t installed; + + /** + * X.509 Certificate in DER format + */ + chunk_t certificate; + + /** + * Version of the X.509 certificate */ u_int version; /** - * ID representing the certificates subject + * Serial number of the X.509 certificate */ - identification_t *subject; - + chunk_t serialNumber; + /** * ID representing the certificate issuer */ identification_t *issuer; /** + * Start time of certificate validity + */ + time_t notBefore; + + /** + * End time of certificate validity + */ + time_t notAfter; + + /** + * ID representing the certificate subject + */ + identification_t *subject; + + /** * List of identification_t's representing subjectAltNames */ linked_list_t *subjectAltNames; @@ -109,41 +135,34 @@ struct private_x509_t { * List of identification_t's representing crlDistributionPoints */ linked_list_t *crlDistributionPoints; - /** - * Subjects RSA public key, if subjectPublicKeyAlgorithm == RSA + * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA */ rsa_public_key_t *public_key; + /** + * Subject Key Identifier + */ + chunk_t subjectKeyID; + + /** + * Authority Key Identifier + */ + chunk_t authKeyID; + + /** + * Authority Key Serial Number + */ + chunk_t authKeySerialNumber; - - - time_t installed; u_char authority_flags; - chunk_t x509; chunk_t tbsCertificate; - chunk_t serialNumber; /* signature */ int sigAlg; - /* validity */ - time_t notBefore; - time_t notAfter; - /* subjectPublicKeyInfo */ chunk_t subjectPublicKey; - /* issuerUniqueID */ - /* subjectUniqueID */ - /* v3 extensions */ - /* extension */ - /* extension */ - /* extnID */ - /* critical */ - /* extnValue */ bool isCA; bool isOcspSigner; /* ocsp */ - chunk_t subjectKeyID; - chunk_t authKeyID; - chunk_t authKeySerialNumber; chunk_t accessLocation; /* ocsp */ /* signatureAlgorithm */ int algorithm; @@ -649,7 +668,7 @@ bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert) level++; switch (objectID) { case X509_OBJ_CERTIFICATE: - cert->x509 = object; + cert->certificate = object; break; case X509_OBJ_TBS_CERTIFICATE: cert->tbsCertificate = object; @@ -843,9 +862,50 @@ static void destroy(private_x509_t *this) { this->public_key->destroy(this->public_key); } + free(this->certificate.ptr); free(this); } +/** + * log certificate + */ +static void log_certificate(private_x509_t *this, logger_t *logger, bool utc) +{ + identification_t *subject = this->subject; + identification_t *issuer = this->issuer; + + rsa_public_key_t *rsa_key = this->public_key; + + char buf[BUF_LEN]; + + timetoa(buf, BUF_LEN, &this->installed, utc); + logger->log(logger, CONTROL, "%s", buf); + logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject)); + logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer)); + chunk_to_hex(buf, BUF_LEN, this->serialNumber); + logger->log(logger, CONTROL, " serial: %s", buf); + timetoa(buf, BUF_LEN, &this->notBefore, utc); + logger->log(logger, CONTROL, " validity: not before %s", buf); + timetoa(buf, BUF_LEN, &this->notAfter, utc); + logger->log(logger, CONTROL, " not after %s", buf); + logger->log(logger, CONTROL, " pubkey: RSA %d bits", BITS_PER_BYTE * rsa_key->get_keysize(rsa_key)); + if (this->subjectKeyID.ptr != NULL) + { + chunk_to_hex(buf, BUF_LEN, this->subjectKeyID); + logger->log(logger, CONTROL, " subjkey: %s", buf); + } + if (this->authKeyID.ptr != NULL) + { + chunk_to_hex(buf, BUF_LEN, this->authKeyID); + logger->log(logger, CONTROL, " authkey: %s", buf); + } + if (this->authKeySerialNumber.ptr != NULL) + { + chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber); + logger->log(logger, CONTROL, " aserial: %s", buf); + } +} + /* * Described in header. */ @@ -859,6 +919,7 @@ x509_t *x509_create_from_chunk(chunk_t chunk) this->public.get_public_key = (rsa_public_key_t* (*) (x509_t*))get_public_key; this->public.get_subject = (identification_t* (*) (x509_t*))get_subject; this->public.get_issuer = (identification_t* (*) (x509_t*))get_issuer; + this->public.log_certificate = (void (*) (x509_t*,logger_t*,bool))log_certificate; /* initialize */ this->subjectPublicKey = CHUNK_INITIALIZER; @@ -892,7 +953,7 @@ x509_t *x509_create_from_chunk(chunk_t chunk) /* * Described in header. */ -x509_t *x509_create_from_file(char *filename) +x509_t *x509_create_from_file(const char *filename) { bool pgp = FALSE; chunk_t chunk = CHUNK_INITIALIZER; @@ -902,6 +963,9 @@ x509_t *x509_create_from_file(char *filename) return NULL; cert = x509_create_from_chunk(chunk); - free(chunk.ptr); + if (cert == NULL) + { + free(chunk.ptr); + } return cert; } diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h index 077238eab..9caf0ab13 100755 --- a/src/libstrongswan/crypto/x509.h +++ b/src/libstrongswan/crypto/x509.h @@ -28,6 +28,7 @@ #include <crypto/rsa/rsa_public_key.h> #include <utils/identification.h> #include <utils/iterator.h> +#include <utils/logger.h> typedef struct x509_t x509_t; @@ -103,7 +104,7 @@ struct x509_t { * @param other second cert for compare * @return TRUE if signature is equal */ - bool (*equals) (x509_t *this, x509_t *other); + bool (*equals) (x509_t *this, x509_t *that); /** * @brief Destroys the certificate. @@ -111,6 +112,15 @@ struct x509_t { * @param this certificate to destroy */ void (*destroy) (x509_t *this); + + /** + * @brief Log x509 certificate info. + * + * @param this certificate to log + * @param logger logger to be used + * @param utc log dates either in UTC or local time + */ + void (*log_certificate) (x509_t *this, logger_t *logger, bool utc); }; /** @@ -131,6 +141,6 @@ x509_t *x509_create_from_chunk(chunk_t chunk); * * @ingroup transforms */ -x509_t *x509_create_from_file(char *filename); +x509_t *x509_create_from_file(const char *filename); #endif /* X509_H_ */ diff --git a/src/libstrongswan/types.c b/src/libstrongswan/types.c index 09ebf7310..3427b9433 100644 --- a/src/libstrongswan/types.c +++ b/src/libstrongswan/types.c @@ -104,6 +104,34 @@ bool chunk_equals(chunk_t a, chunk_t b) /** * Described in header. */ +void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk) +{ + bool first = TRUE; + + buflen--; /* reserve space for null termination */ + + while (chunk.len >0 && buflen > 2) + { + static char hexdig[] = "0123456789abcdef"; + + if (first) + { + first = FALSE; + } + else + { + *buf++ = ':'; buflen--; + } + *buf++ = hexdig[(*chunk.ptr >> 4) & 0x0f]; + *buf++ = hexdig[ *chunk.ptr++ & 0x0f]; + buflen -= 2; chunk.len--; + } + *buf = '\0'; +} + +/** + * Described in header. + */ void *clalloc(void * pointer, size_t size) { void *data; diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h index 4af9bc43d..0498bdae5 100644 --- a/src/libstrongswan/types.h +++ b/src/libstrongswan/types.h @@ -183,6 +183,12 @@ chunk_t chunk_alloc(size_t bytes); bool chunk_equals(chunk_t a, chunk_t b); /** + * Print a chunk in hexadecimal form + * with each byte separated by a colon + */ +void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk); + +/** * Clone a data to a newly allocated buffer */ void *clalloc(void *pointer, size_t size); diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h index de81db8e9..7cc22c24b 100644 --- a/src/libstrongswan/utils/iterator.h +++ b/src/libstrongswan/utils/iterator.h @@ -44,6 +44,13 @@ typedef struct iterator_t iterator_t; struct iterator_t { /** + * @brief Return number of list items. + * + * @param this calling object + * @return number of list items + */ + int (*get_count) (iterator_t *this); + /** * @brief Iterate over all items. * * The easy way to iterate over items. diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 64443434b..2d2917454 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -152,7 +152,15 @@ struct private_iterator_t { }; /** - * Implementation of iterator_t.has_next. + * Implementation of iterator_t.get_count. + */ +static int get_list_count(private_iterator_t *this) +{ + return this->list->count; +} + +/** + * Implementation of iterator_t.iterate. */ static bool iterate(private_iterator_t *this, void** value) { @@ -665,6 +673,7 @@ static iterator_t *create_iterator (private_linked_list_t *linked_list,bool forw { private_iterator_t *this = malloc_thing(private_iterator_t); + this->public.get_count = (bool (*) (iterator_t *this)) get_list_count; this->public.iterate = (bool (*) (iterator_t *this, void **value)) iterate; this->public.has_next = (bool (*) (iterator_t *this)) iterator_has_next; this->public.current = (status_t (*) (iterator_t *this, void **value)) iterator_current; diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index f53d88f06..b65a757d0 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -26,6 +26,8 @@ #include "stroke.h" +#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */ + static char* push_string(stroke_msg_t **strm, char *string) { stroke_msg_t *stroke_msg; @@ -166,6 +168,18 @@ static int show_status(char *mode, char *connection) return res; } +static int list_certs(void) +{ + stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); + int res; + + msg->length = sizeof(stroke_msg_t); + msg->type = STR_LIST_CERTS; + res = send_stroke_msg(msg); + free(msg); + return res; +} + static int set_logtype(char *context, char *type, int enable) { stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); @@ -233,6 +247,8 @@ static void exit_usage(char *error) printf(" LEVEL is 0|1|2|3\n"); printf(" Show connection status:\n"); printf(" stroke status\n"); + printf(" Show list of locally loaded certificates:\n"); + printf(" stroke listcerts\n"); exit_error(error); } @@ -248,12 +264,15 @@ int main(int argc, char *argv[]) op = argv[1]; - if (strcmp(op, "status") == 0 || - strcmp(op, "statusall") == 0) + if (streq(op, "status") || streq(op, "statusall")) { res = show_status(op, argc > 2 ? argv[2] : NULL); } - else if (strcmp(op, "up") == 0) + else if (streq(op, "listcerts") || streq(op, "listall")) + { + res = list_certs(); + } + else if (streq(op, "up")) { if (argc < 3) { @@ -261,7 +280,7 @@ int main(int argc, char *argv[]) } res = initiate_connection(argv[2]); } - else if (strcmp(op, "down") == 0) + else if (streq(op, "down")) { if (argc < 3) { @@ -269,7 +288,7 @@ int main(int argc, char *argv[]) } res = terminate_connection(argv[2]); } - else if (strcmp(op, "add") == 0) + else if (streq(op, "add")) { if (argc < 11) { @@ -281,7 +300,7 @@ int main(int argc, char *argv[]) argv[7], argv[8], atoi(argv[9]), atoi(argv[10])); } - else if (strcmp(op, "logtype") == 0) + else if (streq(op, "logtype")) { if (argc < 5) { @@ -289,7 +308,7 @@ int main(int argc, char *argv[]) } res = set_logtype(argv[2], argv[3], atoi(argv[4])); } - else if (strcmp(op, "loglevel") == 0) + else if (streq(op, "loglevel")) { if (argc < 4) { diff --git a/src/stroke/stroke.h b/src/stroke/stroke.h index cb40cf843..566d2c10c 100644 --- a/src/stroke/stroke.h +++ b/src/stroke/stroke.h @@ -37,6 +37,7 @@ typedef struct stroke_msg_t stroke_msg_t; struct stroke_msg_t { /* length of this message with all strings */ u_int16_t length; + /* type of the message */ enum { /* initiate a connection */ @@ -57,8 +58,11 @@ struct stroke_msg_t { STR_LOGTYPE, /* set the verbosity of a logging context */ STR_LOGLEVEL, + /* show list of locally loaded certificates */ + STR_LIST_CERTS /* more to come */ } type; + union { /* data for STR_INITIATE, STR_INSTALL, STR_UP, STR_DOWN */ struct { @@ -85,6 +89,7 @@ struct stroke_msg_t { u_int level; } loglevel; }; + u_int8_t buffer[]; }; |