identification: Support prefixes in string constructors for an explicit type
authorMartin Willi <martin@revosec.ch>
Wed, 29 Oct 2014 10:18:35 +0000 (11:18 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 30 Oct 2014 10:05:44 +0000 (11:05 +0100)
src/libstrongswan/tests/suites/test_identification.c
src/libstrongswan/utils/identification.c
src/libstrongswan/utils/identification.h

index 9b14b28..d20ad9b 100644 (file)
@@ -174,6 +174,10 @@ static struct {
                .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
                                                                   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
        {"C=CH, O",                                     ID_KEY_ID,              { .type = ENC_SIMPLE }},
+       {"IPv4:#c0a80101",                      ID_IPV4_ADDR,   { .type = ENC_CHUNK,
+               .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+       { "email:tester",                       ID_RFC822_ADDR, { .type = ENC_STRING,
+               .data.s = "tester" }},
 };
 
 START_TEST(test_from_string)
index 46ac7e8..43aa090 100644 (file)
@@ -927,6 +927,49 @@ static private_identification_t *identification_create(id_type_t type)
        return this;
 }
 
+/**
+ * Create an identity for a specific type, determined by prefix
+ */
+static private_identification_t* create_from_string_with_prefix_type(char *str)
+{
+       struct {
+               const char *str;
+               id_type_t type;
+       } prefixes[] = {
+               { "ipv4:",                      ID_IPV4_ADDR                    },
+               { "ipv6:",                      ID_IPV6_ADDR                    },
+               { "rfc822:",            ID_RFC822_ADDR                  },
+               { "email:",                     ID_RFC822_ADDR                  },
+               { "userfqdn:",          ID_USER_FQDN                    },
+               { "fqdn:",                      ID_FQDN                                 },
+               { "dns:",                       ID_FQDN                                 },
+               { "asn1dn:",            ID_DER_ASN1_DN                  },
+               { "asn1gn:",            ID_DER_ASN1_GN                  },
+               { "keyid:",                     ID_KEY_ID                               },
+       };
+       private_identification_t *this;
+       int i;
+
+       for (i = 0; i < countof(prefixes); i++)
+       {
+               if (strcasepfx(str, prefixes[i].str))
+               {
+                       this = identification_create(prefixes[i].type);
+                       str += strlen(prefixes[i].str);
+                       if (*str == '#')
+                       {
+                               this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
+                       }
+                       else
+                       {
+                               this->encoded = chunk_clone(chunk_from_str(str));
+                       }
+                       return this;
+               }
+       }
+       return NULL;
+}
+
 /*
  * Described in header.
  */
@@ -939,6 +982,11 @@ identification_t *identification_create_from_string(char *string)
        {
                string = "%any";
        }
+       this = create_from_string_with_prefix_type(string);
+       if (this)
+       {
+               return &this->public;
+       }
        if (strchr(string, '=') != NULL)
        {
                /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN.
index e624468..3e89974 100644 (file)
@@ -302,6 +302,12 @@ struct identification_t {
  * N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
  * unstructuredName, TCGID.
  *
+ * To skip automatic type detection the following prefixes may be used to
+ * enforce a specific type: ipv4:, ipv6:, rfc822:, email:, userfqdn:, fqdn:,
+ * dns:, asn1dn:, asn1gn: and keyid:. If a # follows the :, the remaining data
+ * is interpreted as hex encoded binary data for that ID, otherwise the raw
+ * string following the prefix is used as identity data, without conversion.
+ *
  * This constructor never returns NULL. If it does not find a suitable
  * conversion function, it will copy the string to an ID_KEY_ID.
  *