Added certificatePolicy options to pki tool
authorMartin Willi <martin@revosec.ch>
Wed, 15 Dec 2010 13:31:04 +0000 (14:31 +0100)
committerMartin Willi <martin@revosec.ch>
Wed, 5 Jan 2011 15:46:02 +0000 (16:46 +0100)
src/pki/command.h
src/pki/commands/issue.c
src/pki/commands/print.c
src/pki/commands/self.c

index f221df2..a6f8bc7 100644 (file)
@@ -29,7 +29,7 @@
 /**
  * Maximum number of options in a command (+1)
  */
-#define MAX_OPTIONS 24
+#define MAX_OPTIONS 32
 
 /**
  * Maximum number of usage summary lines (+1)
index 6fa3ff9..aa62a07 100644 (file)
 #include "pki.h"
 
 #include <debug.h>
+#include <asn1/asn1.h>
 #include <utils/linked_list.h>
 #include <credentials/certificates/certificate.h>
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/pkcs10.h>
 
 /**
+ * Free cert policy with OID
+ */
+static void destroy_cert_policy(x509_cert_policy_t *policy)
+{
+       free(policy->oid.ptr);
+       free(policy);
+}
+
+/**
  * Issue a certificate using a CA certificate and key
  */
 static int issue()
@@ -37,7 +47,7 @@ static int issue()
        char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
        char *error = NULL, *keyid = NULL;
        identification_t *id = NULL, *crl_issuer = NULL;;
-       linked_list_t *san, *cdps, *ocsp, *permitted, *excluded;
+       linked_list_t *san, *cdps, *ocsp, *permitted, *excluded, *policies;
        int lifetime = 1095;
        int pathlen = X509_NO_PATH_LEN_CONSTRAINT;
        chunk_t serial = chunk_empty;
@@ -45,6 +55,7 @@ static int issue()
        time_t not_before, not_after;
        x509_flag_t flags = 0;
        x509_t *x509;
+       x509_cert_policy_t *policy = NULL;
        char *arg;
 
        san = linked_list_create();
@@ -52,6 +63,7 @@ static int issue()
        ocsp = linked_list_create();
        permitted = linked_list_create();
        excluded = linked_list_create();
+       policies = linked_list_create();
 
        while (TRUE)
        {
@@ -121,6 +133,35 @@ static int issue()
                                excluded->insert_last(excluded,
                                                                          identification_create_from_string(arg));
                                continue;
+                       case 'P':
+                       {
+                               chunk_t oid;
+
+                               oid = asn1_oid_from_string(arg);
+                               if (!oid.len)
+                               {
+                                       return command_usage("--cert-policy OID invalid");
+                               }
+                               INIT(policy,
+                                       .oid = oid,
+                               );
+                               policies->insert_last(policies, policy);
+                               continue;
+                       }
+                       case 'C':
+                               if (!policy)
+                               {
+                                       return command_usage("--cps-uri must follow a --cert-policy");
+                               }
+                               policy->cps_uri = arg;
+                               continue;
+                       case 'U':
+                               if (!policy)
+                               {
+                                       return command_usage("--user-notice must follow a --cert-policy");
+                               }
+                               policy->unotice_text = arg;
+                               continue;
                        case 'e':
                                if (streq(arg, "serverAuth"))
                                {
@@ -337,7 +378,8 @@ static int issue()
                                        BUILD_CRL_DISTRIBUTION_POINTS, cdps,
                                        BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
                                        BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
-                                       BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded, BUILD_END);
+                                       BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded,
+                                       BUILD_CERTIFICATE_POLICIES, policies, BUILD_END);
        if (!cert)
        {
                error = "generating certificate failed";
@@ -364,6 +406,7 @@ end:
        san->destroy_offset(san, offsetof(identification_t, destroy));
        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
+       policies->destroy_function(policies, (void*)destroy_cert_policy);
        cdps->destroy(cdps);
        ocsp->destroy(ocsp);
        DESTROY_IF(crl_issuer);
@@ -381,6 +424,7 @@ usage:
        san->destroy_offset(san, offsetof(identification_t, destroy));
        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
+       policies->destroy_function(policies, (void*)destroy_cert_policy);
        cdps->destroy(cdps);
        ocsp->destroy(ocsp);
        DESTROY_IF(crl_issuer);
@@ -400,6 +444,7 @@ static void __attribute__ ((constructor))reg()
                 "[--lifetime days] [--serial hex] [--crl uri]+ [--ocsp uri]+",
                 "[--ca] [--pathlen len] [--flag serverAuth|clientAuth|crlSign|ocspSigning]+",
                 "[--nc-permitted name] [--nc-excluded name]",
+                "[--cert-policy oid [--cps-uri uri] [--user-notice text] ]+",
                 "[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"},
                {
                        {"help",                'h', 0, "show usage information"},
@@ -416,6 +461,9 @@ static void __attribute__ ((constructor))reg()
                        {"pathlen",             'p', 1, "set path length constraint"},
                        {"nc-permitted",'n', 1, "add permitted NameConstraint"},
                        {"nc-excluded", 'N', 1, "add excluded NameConstraint"},
+                       {"cert-policy", 'P', 1, "certificatePolicy OID to include"},
+                       {"cps-uri",             'C', 1, "Certification Practice statement URI for certificatePolicy"},
+                       {"user-notice", 'U', 1, "user notice for certificatePolicy"},
                        {"flag",                'e', 1, "include extendedKeyUsage flag"},
                        {"crl",                 'u', 1, "CRL distribution point URI to include"},
                        {"crlissuer",   'I', 1, "CRL Issuer for CRL at distribution point"},
index 0eb51cc..af0c92c 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "pki.h"
 
+#include <asn1/asn1.h>
 #include <credentials/certificates/certificate.h>
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/crl.h>
@@ -74,6 +75,7 @@ static void print_x509(x509_t *x509)
        char *uri;
        int len;
        x509_flag_t flags;
+       x509_cert_policy_t *policy;
 
        chunk = x509->get_serial(x509);
        printf("serial:    %#B\n", &chunk);
@@ -203,6 +205,39 @@ static void print_x509(x509_t *x509)
        }
        enumerator->destroy(enumerator);
 
+       first = TRUE;
+       enumerator = x509->create_cert_policy_enumerator(x509);
+       while (enumerator->enumerate(enumerator, &policy))
+       {
+               char *oid;
+
+               if (first)
+               {
+                       printf("CertificatePolicies:\n");
+                       first = FALSE;
+               }
+               oid = asn1_oid_to_string(policy->oid);
+               if (oid)
+               {
+                       printf("           %s\n", oid);
+                       free(oid);
+               }
+               else
+               {
+                       printf("           %#B\n", &policy->oid);
+               }
+               if (policy->cps_uri)
+               {
+                       printf("             CPS: %s\n", policy->cps_uri);
+               }
+               if (policy->unotice_text)
+               {
+                       printf("             Notice: %s\n", policy->unotice_text);
+
+               }
+       }
+       enumerator->destroy(enumerator);
+
        chunk = x509->get_authKeyIdentifier(x509);
        if (chunk.ptr)
        {
index b073b07..4749032 100644 (file)
 #include <utils/linked_list.h>
 #include <credentials/certificates/certificate.h>
 #include <credentials/certificates/x509.h>
+#include <asn1/asn1.h>
+
+/**
+ * Free cert policy with OID
+ */
+static void destroy_cert_policy(x509_cert_policy_t *policy)
+{
+       free(policy->oid.ptr);
+       free(policy);
+}
 
 /**
  * Create a self signed certificate.
@@ -34,19 +44,21 @@ static int self()
        public_key_t *public = NULL;
        char *file = NULL, *dn = NULL, *hex = NULL, *error = NULL, *keyid = NULL;
        identification_t *id = NULL;
-       linked_list_t *san, *ocsp, *permitted, *excluded;
+       linked_list_t *san, *ocsp, *permitted, *excluded, *policies;
        int lifetime = 1095;
        int pathlen = X509_NO_PATH_LEN_CONSTRAINT;
        chunk_t serial = chunk_empty;
        chunk_t encoding = chunk_empty;
        time_t not_before, not_after;
        x509_flag_t flags = 0;
+       x509_cert_policy_t *policy = NULL;
        char *arg;
 
        san = linked_list_create();
        ocsp = linked_list_create();
        permitted = linked_list_create();
        excluded = linked_list_create();
+       policies = linked_list_create();
 
        while (TRUE)
        {
@@ -114,6 +126,35 @@ static int self()
                                excluded->insert_last(excluded,
                                                                          identification_create_from_string(arg));
                                continue;
+                       case 'P':
+                       {
+                               chunk_t oid;
+
+                               oid = asn1_oid_from_string(arg);
+                               if (!oid.len)
+                               {
+                                       return command_usage("--cert-policy OID invalid");
+                               }
+                               INIT(policy,
+                                       .oid = oid,
+                               );
+                               policies->insert_last(policies, policy);
+                               continue;
+                       }
+                       case 'C':
+                               if (!policy)
+                               {
+                                       return command_usage("--cps-uri must follow a --cert-policy");
+                               }
+                               policy->cps_uri = arg;
+                               continue;
+                       case 'U':
+                               if (!policy)
+                               {
+                                       return command_usage("--user-notice must follow a --cert-policy");
+                               }
+                               policy->unotice_text = arg;
+                               continue;
                        case 'e':
                                if (streq(arg, "serverAuth"))
                                {
@@ -222,7 +263,8 @@ static int self()
                                                BUILD_PATHLEN, pathlen, BUILD_SUBJECT_ALTNAMES, san,
                                                BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
                                                BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
-                                               BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded, BUILD_END);
+                                               BUILD_EXCLUDED_NAME_CONSTRAINTS, excluded,
+                                               BUILD_CERTIFICATE_POLICIES, policies, BUILD_END);
        if (!cert)
        {
                error = "generating certificate failed";
@@ -247,6 +289,7 @@ end:
        san->destroy_offset(san, offsetof(identification_t, destroy));
        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
+       policies->destroy_function(policies, (void*)destroy_cert_policy);
        ocsp->destroy(ocsp);
        free(encoding.ptr);
        free(serial.ptr);
@@ -262,6 +305,7 @@ usage:
        san->destroy_offset(san, offsetof(identification_t, destroy));
        permitted->destroy_offset(permitted, offsetof(identification_t, destroy));
        excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
+       policies->destroy_function(policies, (void*)destroy_cert_policy);
        ocsp->destroy(ocsp);
        return command_usage(error);
 }
@@ -279,6 +323,7 @@ static void __attribute__ ((constructor))reg()
                 "[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
                 "[--flag serverAuth|clientAuth|crlSign|ocspSigning]+",
                 "[--nc-permitted name] [--nc-excluded name]",
+                "[--cert-policy oid [--cps-uri uri] [--user-notice text] ]+",
                 "[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"},
                {
                        {"help",                'h', 0, "show usage information"},
@@ -293,6 +338,9 @@ static void __attribute__ ((constructor))reg()
                        {"pathlen",             'p', 1, "set path length constraint"},
                        {"nc-permitted",'n', 1, "add permitted NameConstraint"},
                        {"nc-excluded", 'N', 1, "add excluded NameConstraint"},
+                       {"cert-policy", 'P', 1, "certificatePolicy OID to include"},
+                       {"cps-uri",             'C', 1, "Certification Practice statement URI for certificatePolicy"},
+                       {"user-notice", 'U', 1, "user notice for certificatePolicy"},
                        {"flag",                'e', 1, "include extendedKeyUsage flag"},
                        {"ocsp",                'o', 1, "OCSP AuthorityInfoAccess URI to include"},
                        {"digest",              'g', 1, "digest for signature creation, default: sha1"},