stroke: add exportconn{cert,chain} commands in addition to exportx509
authorMartin Willi <martin@revosec.ch>
Fri, 14 Jun 2013 09:22:14 +0000 (11:22 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 19 Jun 2013 14:27:19 +0000 (16:27 +0200)
The new commands either export a single end entity certificate or the
full trust chain for a specific connection name.

src/libcharon/plugins/stroke/stroke_socket.c
src/stroke/stroke.c
src/stroke/stroke_keywords.h
src/stroke/stroke_keywords.txt
src/stroke/stroke_msg.h

index aa5c73b..d152ecd 100644 (file)
@@ -432,6 +432,20 @@ static void stroke_purge(private_stroke_socket_t *this,
 }
 
 /**
+ * Print a certificate in PEM to out
+ */
+static void print_pem_cert(FILE *out, certificate_t *cert)
+{
+       chunk_t encoded;
+
+       if (cert->get_encoding(cert, CERT_PEM, &encoded))
+       {
+               fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
+               free(encoded.ptr);
+       }
+}
+
+/**
  * Export in-memory credentials
  */
 static void stroke_export(private_stroke_socket_t *this,
@@ -444,22 +458,67 @@ static void stroke_export(private_stroke_socket_t *this,
                enumerator_t *enumerator;
                identification_t *id;
                certificate_t *cert;
-               chunk_t encoded;
 
                id = identification_create_from_string(msg->export.selector);
                enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
                                                                                                CERT_X509, KEY_ANY, id, FALSE);
                while (enumerator->enumerate(enumerator, &cert))
                {
-                       if (cert->get_encoding(cert, CERT_PEM, &encoded))
-                       {
-                               fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
-                               free(encoded.ptr);
-                       }
+                       print_pem_cert(out, cert);
                }
                enumerator->destroy(enumerator);
                id->destroy(id);
        }
+
+       if (msg->export.flags & (EXPORT_CONN_CERT | EXPORT_CONN_CHAIN))
+       {
+               enumerator_t *sas, *auths, *certs;
+               ike_sa_t *ike_sa;
+               auth_cfg_t *auth;
+               certificate_t *cert;
+               auth_rule_t rule;
+
+               sas = charon->ike_sa_manager->create_enumerator(
+                                                                                               charon->ike_sa_manager, TRUE);
+               while (sas->enumerate(sas, &ike_sa))
+               {
+                       if (streq(msg->export.selector, ike_sa->get_name(ike_sa)))
+                       {
+                               auths = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
+                               while (auths->enumerate(auths, &auth))
+                               {
+                                       bool got_subject = FALSE;
+
+                                       certs = auth->create_enumerator(auth);
+                                       while (certs->enumerate(certs, &rule, &cert))
+                                       {
+                                               switch (rule)
+                                               {
+                                                       case AUTH_RULE_CA_CERT:
+                                                       case AUTH_RULE_IM_CERT:
+                                                               if (msg->export.flags & EXPORT_CONN_CHAIN)
+                                                               {
+                                                                       print_pem_cert(out, cert);
+                                                               }
+                                                               break;
+                                                       case AUTH_RULE_SUBJECT_CERT:
+                                                               if (!got_subject)
+                                                               {
+                                                                       print_pem_cert(out, cert);
+                                                                       got_subject = TRUE;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+                                       }
+                                       certs->destroy(certs);
+                               }
+                               auths->destroy(auths);
+                       }
+               }
+               sas->destroy(sas);
+       }
 }
 
 /**
index 3273aed..3edf38e 100644 (file)
@@ -321,6 +321,8 @@ static int purge(stroke_keyword_t kw)
 
 static int export_flags[] = {
        EXPORT_X509,
+       EXPORT_CONN_CERT,
+       EXPORT_CONN_CHAIN,
 };
 
 static int export(stroke_keyword_t kw, char *selector)
@@ -449,6 +451,8 @@ static void exit_usage(char *error)
        printf("    stroke purgeike\n");
        printf("  Export credentials to the console:\n");
        printf("    stroke exportx509 DN\n");
+       printf("    stroke exportconncert connname\n");
+       printf("    stroke exportconnchain connname\n");
        printf("  Show current memory usage:\n");
        printf("    stroke memusage\n");
        printf("  Show leases of a pool:\n");
@@ -587,9 +591,11 @@ int main(int argc, char *argv[])
                        res = purge(token->kw);
                        break;
                case STROKE_EXPORT_X509:
+               case STROKE_EXPORT_CONN_CERT:
+               case STROKE_EXPORT_CONN_CHAIN:
                        if (argc != 3)
                        {
-                               exit_usage("\"exportx509\" needs a distinguished name");
+                               exit_usage("\"export\" needs a name");
                        }
                        res = export(token->kw, argv[2]);
                        break;
index f5979a0..d96dc7a 100644 (file)
@@ -55,6 +55,8 @@ typedef enum {
        STROKE_PURGE_CERTS,
        STROKE_PURGE_IKE,
        STROKE_EXPORT_X509,
+       STROKE_EXPORT_CONN_CERT,
+       STROKE_EXPORT_CONN_CHAIN,
        STROKE_LEASES,
        STROKE_MEMUSAGE,
        STROKE_USER_CREDS,
index 5d2ebd9..17692b1 100644 (file)
@@ -62,6 +62,8 @@ purgecrls,       STROKE_PURGE_CRLS
 purgecerts,      STROKE_PURGE_CERTS
 purgeike,        STROKE_PURGE_IKE
 exportx509,      STROKE_EXPORT_X509
+exportconncert,  STROKE_EXPORT_CONN_CERT
+exportconnchain, STROKE_EXPORT_CONN_CHAIN
 leases,          STROKE_LEASES
 memusage,        STROKE_MEMUSAGE
 user-creds,      STROKE_USER_CREDS
index 5cee916..a4dfc5e 100644 (file)
@@ -123,6 +123,10 @@ typedef enum export_flag_t export_flag_t;
 enum export_flag_t {
        /** export an X509 certificate */
        EXPORT_X509 =           0x0001,
+       /** export an X509 end entity certificate for a connection */
+       EXPORT_CONN_CERT =      0x0002,
+       /** export the complete trust chain of a connection */
+       EXPORT_CONN_CHAIN =     0x0004,
 };
 
 /**