- applied patch from andreas, which allows certificate listing via stroke
authorMartin Willi <martin@strongswan.org>
Fri, 19 May 2006 06:44:08 +0000 (06:44 -0000)
committerMartin Willi <martin@strongswan.org>
Fri, 19 May 2006 06:44:08 +0000 (06:44 -0000)
17 files changed:
src/charon/config/credentials/credential_store.h
src/charon/config/credentials/local_credential_store.c
src/charon/config/credentials/local_credential_store.h
src/charon/threads/stroke_interface.c
src/ipsec/ipsec.in
src/libstrongswan/asn1/asn1.c
src/libstrongswan/asn1/asn1.h
src/libstrongswan/crypto/rsa/rsa_public_key.c
src/libstrongswan/crypto/rsa/rsa_public_key.h
src/libstrongswan/crypto/x509.c
src/libstrongswan/crypto/x509.h
src/libstrongswan/types.c
src/libstrongswan/types.h
src/libstrongswan/utils/iterator.h
src/libstrongswan/utils/linked_list.c
src/stroke/stroke.c
src/stroke/stroke.h

index 2339469..df128fa 100755 (executable)
@@ -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
index 2554eec..ab17c0d 100644 (file)
@@ -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;
index 81b7568..db71341 100644 (file)
@@ -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
index f8db7ad..8a0d220 100755 (executable)
@@ -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");
                }
index 9c4ec47..6fd5777 100755 (executable)
@@ -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)
index 662f7fc..c52fb2d 100644 (file)
@@ -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;
index 556bb2b..ee905be 100644 (file)
@@ -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);
index 2f8c6fd..8fd02d2 100644 (file)
  * 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;
        
index ef79153..12c01bf 100644 (file)
@@ -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
index b65327b..ec38287 100755 (executable)
 #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;
 }
index 077238e..9caf0ab 100755 (executable)
@@ -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_ */
index 09ebf73..3427b94 100644 (file)
@@ -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;
index 4af9bc4..0498bda 100644 (file)
@@ -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);
index de81db8..7cc22c2 100644 (file)
@@ -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.
index 6444343..2d29174 100644 (file)
@@ -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;
index f53d88f..b65a757 100644 (file)
@@ -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)
                {
index cb40cf8..566d2c1 100644 (file)
@@ -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[];
 };