x509 certificates support encoding of email, DNS and IP subjectAltNames
authorMartin Willi <martin@strongswan.org>
Tue, 8 Sep 2009 11:17:41 +0000 (13:17 +0200)
committerMartin Willi <martin@strongswan.org>
Tue, 8 Sep 2009 11:17:41 +0000 (13:17 +0200)
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/credentials/credential_factory.c
src/libstrongswan/plugins/x509/x509_cert.c

index 88df476..dc9829a 100644 (file)
@@ -30,9 +30,9 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_SIGNING_CERT",
        "BUILD_PUBLIC_KEY",
        "BUILD_SUBJECT",
-       "BUILD_SUBJECT_ALTNAME",
+       "BUILD_SUBJECT_ALTNAMES",
        "BUILD_ISSUER",
-       "BUILD_ISSUER_ALTNAME",
+       "BUILD_ISSUER_ALTNAMES",
        "BUILD_NOT_BEFORE_TIME",
        "BUILD_NOT_AFTER_TIME",
        "BUILD_SERIAL",
index a5ce7e1..6dbae98 100644 (file)
@@ -68,12 +68,12 @@ enum builder_part_t {
        BUILD_PUBLIC_KEY,
        /** subject for e.g. certificates, identification_t* */
        BUILD_SUBJECT,
-       /** additional subject name, identification_t* */
-       BUILD_SUBJECT_ALTNAME,
+       /** additional subject names, linked_list_t* containing identification_t* */
+       BUILD_SUBJECT_ALTNAMES,
        /** issuer for e.g. certificates, identification_t* */
        BUILD_ISSUER,
-       /** additional issuer name, identification_t* */
-       BUILD_ISSUER_ALTNAME,
+       /** additional issuer names, linked_list_t* containing identification_t* */
+       BUILD_ISSUER_ALTNAMES,
        /** notBefore, time_t* */
        BUILD_NOT_BEFORE_TIME,
        /** notAfter, time_t* */
index 6201cd6..aae280f 100644 (file)
@@ -210,9 +210,9 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
                                case BUILD_SIGNING_KEY:
                                case BUILD_PUBLIC_KEY:
                                case BUILD_SUBJECT:
-                               case BUILD_SUBJECT_ALTNAME:
+                               case BUILD_SUBJECT_ALTNAMES:
                                case BUILD_ISSUER:
-                               case BUILD_ISSUER_ALTNAME:
+                               case BUILD_ISSUER_ALTNAMES:
                                case BUILD_SIGNING_CERT:
                                case BUILD_CA_CERT:
                                case BUILD_CERT:
index b8e02ae..ae2ba19 100644 (file)
@@ -1215,6 +1215,8 @@ static bool generate(private_builder_t *this)
        chunk_t key_info;
        signature_scheme_t scheme;
        hasher_t *hasher;
+       enumerator_t *enumerator;
+       identification_t *id;
 
        subject = this->cert->subject;
        if (this->sign_cert)
@@ -1303,10 +1305,45 @@ static bool generate(private_builder_t *this)
                return FALSE;
        }
 
-       if (this->cert->subjectAltNames->get_count(this->cert->subjectAltNames))
+       enumerator = this->cert->subjectAltNames->create_enumerator(
+                                                                                                       this->cert->subjectAltNames);
+       while (enumerator->enumerate(enumerator, &id))
+       {
+               int context;
+               chunk_t name;
+
+               switch (id->get_type(id))
+               {
+                       case ID_RFC822_ADDR:
+                               context = ASN1_CONTEXT_S_1;
+                               break;
+                       case ID_FQDN:
+                               context = ASN1_CONTEXT_S_2;
+                               break;
+                       case ID_IPV4_ADDR:
+                       case ID_IPV6_ADDR:
+                               context = ASN1_CONTEXT_S_7;
+                               break;
+                       default:
+                               DBG1("encoding %N as subjectAltName not supported",
+                                        id_type_names, id->get_type(id));
+                               enumerator->destroy(enumerator);
+                               free(key_info.ptr);
+                               free(subjectAltNames.ptr);
+                               return FALSE;
+               }
+               name = asn1_wrap(context, "c", id->get_encoding(id));
+               subjectAltNames = chunk_cat("mm", subjectAltNames, name);
+       }
+       enumerator->destroy(enumerator);
+       if (subjectAltNames.ptr)
        {
-               /* TODO: encode subjectAltNames */
+               subjectAltNames = asn1_wrap(ASN1_SEQUENCE, "mm",
+                                                       asn1_build_known_oid(OID_SUBJECT_ALT_NAME),
+                                                       asn1_wrap(ASN1_OCTET_STRING, "m",
+                                                               asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)));
        }
+
        if (this->flags & X509_CA)
        {
                chunk_t yes, keyid;
@@ -1462,11 +1499,19 @@ static void add(private_builder_t *this, builder_part_t part, ...)
                        this->cert->subject = id->clone(id);
                        break;
                }
-               case BUILD_SUBJECT_ALTNAME:
+               case BUILD_SUBJECT_ALTNAMES:
                {
-                       identification_t *id = va_arg(args, identification_t*);
-                       this->cert->subjectAltNames->insert_last(
+                       identification_t *id;
+                       enumerator_t *enumerator;
+                       linked_list_t *list = va_arg(args, linked_list_t*);
+
+                       enumerator = list->create_enumerator(list);
+                       while (enumerator->enumerate(enumerator, &id))
+                       {
+                               this->cert->subjectAltNames->insert_last(
                                                                        this->cert->subjectAltNames, id->clone(id));
+                       }
+                       enumerator->destroy(enumerator);
                        break;
                }
                case BUILD_NOT_BEFORE_TIME: