Support TLS client authentication Extended Key Usage in x509 generation
authorMartin Willi <martin@strongswan.org>
Thu, 14 Jan 2010 11:00:43 +0000 (12:00 +0100)
committerMartin Willi <martin@strongswan.org>
Thu, 14 Jan 2010 11:00:43 +0000 (12:00 +0100)
src/charon/plugins/stroke/stroke_list.c
src/libstrongswan/asn1/oid.txt
src/libstrongswan/credentials/certificates/x509.c
src/libstrongswan/credentials/certificates/x509.h
src/libstrongswan/plugins/x509/x509_cert.c
src/pki/commands/issue.c

index 470f8e9..c2a98da 100644 (file)
@@ -661,7 +661,7 @@ static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out)
                if (first)
                {
 
-                       fprintf(out, "\n"); 
+                       fprintf(out, "\n");
                                fprintf(out, "List of PGP End Entity Certificates:\n");
                                first = FALSE;
                }
@@ -699,7 +699,8 @@ static void stroke_list_certs(linked_list_t *list, char *label,
        x509_flag_t flag_mask;
 
        /* mask all auxiliary flags */
-       flag_mask = ~(X509_SELF_SIGNED | X509_SERVER_AUTH | X509_IP_ADDR_BLOCKS ); 
+       flag_mask = ~(X509_SERVER_AUTH | X509_CLIENT_AUTH |
+                                 X509_SELF_SIGNED | X509_IP_ADDR_BLOCKS );
 
        enumerator = list->create_enumerator(list);
        while (enumerator->enumerate(enumerator, (void**)&cert))
index 87922f6..203bc1f 100644 (file)
               0x02           "unotice"
             0x03             "id-kp"
               0x01           "serverAuth"                              OID_SERVER_AUTH
-              0x02           "clientAuth"
+              0x02           "clientAuth"                              OID_CLIENT_AUTH
               0x03           "codeSigning"
               0x04           "emailProtection"
               0x05           "ipsecEndSystem"
index b881988..66dc192 100644 (file)
 
 #include "x509.h"
 
-ENUM(x509_flag_names, X509_NONE, X509_SELF_SIGNED,
+ENUM(x509_flag_names, X509_NONE, X509_IP_ADDR_BLOCKS,
        "X509_NONE",
        "X509_CA",
        "X509_AA",
        "X509_OCSP_SIGNER",
        "X509_SERVER_AUTH",
+       "X509_CLIENT_AUTH",
        "X509_SELF_SIGNED",
+       "X509_IP_ADDR_BLOCKS",
 );
 
index ebe660d..172bd96 100644 (file)
@@ -35,19 +35,21 @@ typedef enum x509_flag_t x509_flag_t;
  */
 enum x509_flag_t {
        /** cert has no constraints */
-       X509_NONE =                        0, 
+       X509_NONE =                             0,
        /** cert has CA constraint */
-       X509_CA =                         (1<<0),
+       X509_CA =                               (1<<0),
        /** cert has AA constraint */
-       X509_AA =                         (1<<1),
+       X509_AA =                               (1<<1),
        /** cert has OCSP signer constraint */
-       X509_OCSP_SIGNER =        (1<<2),
-       /** cert has serverAuth constraint */
-       X509_SERVER_AUTH =        (1<<3),
+       X509_OCSP_SIGNER =              (1<<2),
+       /** cert has serverAuth key usage */
+       X509_SERVER_AUTH =              (1<<3),
+       /** cert has clientAuth key usage */
+       X509_CLIENT_AUTH =              (1<<4),
        /** cert is self-signed */
-       X509_SELF_SIGNED =    (1<<4),
+       X509_SELF_SIGNED =              (1<<5),
        /** cert has an ipAddrBlocks extension */
-       X509_IP_ADDR_BLOCKS = (1<<5),
+       X509_IP_ADDR_BLOCKS =   (1<<6),
 };
 
 /**
index 199d593..ff8bcb2 100644 (file)
@@ -596,6 +596,9 @@ static void parse_extendedKeyUsage(chunk_t blob, int level0,
                                case OID_SERVER_AUTH:
                                        this->flags |= X509_SERVER_AUTH;
                                        break;
+                               case OID_CLIENT_AUTH:
+                                       this->flags |= X509_CLIENT_AUTH;
+                                       break;
                                case OID_OCSP_SIGNING:
                                        this->flags |= X509_OCSP_SIGNER;
                                        break;
@@ -804,7 +807,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
                }
        }
        this->flags |= X509_IP_ADDR_BLOCKS;
-       
+
 end:
        parser->destroy(parser);
 }
@@ -891,7 +894,7 @@ static bool parse_certificate(private_x509_cert_t *this)
                                if (this->version < 1 || this->version > 3)
                                {
                                        DBG1("X.509v%d not supported", this->version);
-                                       goto end; 
+                                       goto end;
                                }
                                else
                                {
@@ -993,7 +996,7 @@ static bool parse_certificate(private_x509_cert_t *this)
                                                {
                                                        DBG1("critical %s extension not supported",
                                                                 (extn_oid == OID_UNKNOWN) ? "unknown" :
-                                                                (char*)oid_names[extn_oid].name); 
+                                                                (char*)oid_names[extn_oid].name);
                                                        goto end;
                                                }
                                                break;
@@ -1281,7 +1284,7 @@ static chunk_t get_subjectKeyIdentifier(private_x509_cert_t *this)
                {
                        return chunk_empty;
                }
-       }                                       
+       }
 }
 
 /**
@@ -1476,7 +1479,8 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
                                         private_key_t *sign_key, int digest_alg)
 {
        chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
-       chunk_t serverAuth = chunk_empty, ocspSigning = chunk_empty;
+       chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
+       chunk_t ocspSigning = chunk_empty;
        chunk_t basicConstraints = chunk_empty, subjectAltNames = chunk_empty;
        chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
        chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
@@ -1606,6 +1610,10 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
        {
                serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
        }
+       if (cert->flags & X509_CLIENT_AUTH)
+       {
+               clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
+       }
 
        /* add ocspSigning extendedKeyUsage flag */
        if (cert->flags & X509_OCSP_SIGNER)
@@ -1613,13 +1621,13 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
                ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
        }
 
-       if (serverAuth.ptr || ocspSigning.ptr)
+       if (serverAuth.ptr || clientAuth.ptr || ocspSigning.ptr)
        {
                extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
                                                                asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
                                                                asn1_wrap(ASN1_OCTET_STRING, "m",
-                                                                       asn1_wrap(ASN1_SEQUENCE, "mm",
-                                                                               serverAuth, ocspSigning)));
+                                                                       asn1_wrap(ASN1_SEQUENCE, "mmm",
+                                                                               serverAuth, clientAuth, ocspSigning)));
        }
 
        /* add subjectKeyIdentifier to CA and OCSP signer certificates */
index 89c9cc7..07ab906 100644 (file)
@@ -112,6 +112,10 @@ static int issue()
                                {
                                        flags |= X509_SERVER_AUTH;
                                }
+                               else if (streq(arg, "clientAuth"))
+                               {
+                                       flags |= X509_CLIENT_AUTH;
+                               }
                                else if (streq(arg, "ocspSigning"))
                                {
                                        flags |= X509_OCSP_SIGNER;
@@ -342,7 +346,7 @@ static void __attribute__ ((constructor))reg()
                {"[--in file] [--type pub|pkcs10]",
                 " --cacert file --cakey file --dn subject-dn [--san subjectAltName]+",
                 "[--lifetime days] [--serial hex] [--crl uri]+ [--ocsp uri]+",
-                "[--ca] [--pathlen len] [--flag serverAuth|ocspSigning]+",
+                "[--ca] [--pathlen len] [--flag serverAuth|clientAuth|ocspSigning]+",
                 "[--digest md5|sha1|sha224|sha256|sha384|sha512]"},
                {
                        {"help",        'h', 0, "show usage information"},