|  | @@ -1,6 +1,6 @@
 | 
	
		
			
				|  |  |  /*
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | - * Copyright 2015, Google Inc.
 | 
	
		
			
				|  |  | + * Copyright 2015-2016, Google Inc.
 | 
	
		
			
				|  |  |   * All rights reserved.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * Redistribution and use in source and binary forms, with or without
 | 
	
	
		
			
				|  | @@ -61,35 +61,37 @@ typedef struct {
 | 
	
		
			
				|  |  |       of '#' will be replaced with a null character before processing. */
 | 
	
		
			
				|  |  |    const char *dns_names;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  /* Comma separated list of IP SANs to match aggainst */
 | 
	
		
			
				|  |  | +  const char *ip_names;
 | 
	
		
			
				|  |  |  } cert_name_test_entry;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* Largely inspired from:
 | 
	
		
			
				|  |  |     chromium/src/net/cert/x509_certificate_unittest.cc.
 | 
	
		
			
				|  |  |     TODO(jboeuf) uncomment test cases as we fix tsi_ssl_peer_matches_name. */
 | 
	
		
			
				|  |  |  const cert_name_test_entry cert_name_test_entries[] = {
 | 
	
		
			
				|  |  | -    {1, "foo.com", "foo.com", NULL},
 | 
	
		
			
				|  |  | -    {1, "f", "f", NULL},
 | 
	
		
			
				|  |  | -    {0, "h", "i", NULL},
 | 
	
		
			
				|  |  | -    {1, "bar.foo.com", "*.foo.com", NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.com", "foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "f", "f", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "h", "i", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "bar.foo.com", "*.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  |      {1, "www.test.fr", "common.name",
 | 
	
		
			
				|  |  | -     "*.test.com,*.test.co.uk,*.test.de,*.test.fr"},
 | 
	
		
			
				|  |  | +     "*.test.com,*.test.co.uk,*.test.de,*.test.fr", NULL},
 | 
	
		
			
				|  |  |      /*
 | 
	
		
			
				|  |  |         {1, "wwW.tESt.fr", "common.name", ",*.*,*.test.de,*.test.FR,www"},
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    {0, "f.uk", ".uk", NULL},
 | 
	
		
			
				|  |  | -    {0, "w.bar.foo.com", "?.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "www.foo.com", "(www|ftp).foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "www.foo.com", "www.foo.com#", NULL}, /* # = null char. */
 | 
	
		
			
				|  |  | -    {0, "www.foo.com", "", "www.foo.com#*.foo.com,#,#"},
 | 
	
		
			
				|  |  | -    {0, "www.house.example", "ww.house.example", NULL},
 | 
	
		
			
				|  |  | -    {0, "test.org", "", "www.test.org,*.test.org,*.org"},
 | 
	
		
			
				|  |  | -    {0, "w.bar.foo.com", "w*.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "www.bar.foo.com", "ww*ww.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "wwww.bar.foo.com", "ww*ww.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "wwww.bar.foo.com", "w*w.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "wwww.bar.foo.com", "w*w.bar.foo.c0m", NULL},
 | 
	
		
			
				|  |  | -    {0, "WALLY.bar.foo.com", "wa*.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "wally.bar.foo.com", "*Ly.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | +    {0, "f.uk", ".uk", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "w.bar.foo.com", "?.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "www.foo.com", "(www|ftp).foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "www.foo.com", "www.foo.com#", NULL, NULL}, /* # = null char. */
 | 
	
		
			
				|  |  | +    {0, "www.foo.com", "", "www.foo.com#*.foo.com,#,#", NULL},
 | 
	
		
			
				|  |  | +    {0, "www.house.example", "ww.house.example", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "test.org", "", "www.test.org,*.test.org,*.org", NULL},
 | 
	
		
			
				|  |  | +    {0, "w.bar.foo.com", "w*.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "www.bar.foo.com", "ww*ww.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "wwww.bar.foo.com", "ww*ww.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "wwww.bar.foo.com", "w*w.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "wwww.bar.foo.com", "w*w.bar.foo.c0m", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "WALLY.bar.foo.com", "wa*.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "wally.bar.foo.com", "*Ly.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  |      /*
 | 
	
		
			
				|  |  |         {1, "ww%57.foo.com", "", "www.foo.com"},
 | 
	
		
			
				|  |  |         {1, "www&.foo.com", "www%26.foo.com", NULL},
 | 
	
	
		
			
				|  | @@ -97,94 +99,108 @@ const cert_name_test_entry cert_name_test_entries[] = {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Common name must not be used if subject alternative name was provided. */
 | 
	
		
			
				|  |  |      {0, "www.test.co.jp", "www.test.co.jp",
 | 
	
		
			
				|  |  | -     "*.test.de,*.jp,www.test.co.uk,www.*.co.jp"},
 | 
	
		
			
				|  |  | +     "*.test.de,*.jp,www.test.co.uk,www.*.co.jp", NULL},
 | 
	
		
			
				|  |  |      {0, "www.bar.foo.com", "www.bar.foo.com",
 | 
	
		
			
				|  |  | -     "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com,"},
 | 
	
		
			
				|  |  | +     "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com,", NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* IDN tests */
 | 
	
		
			
				|  |  | -    {1, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br", NULL},
 | 
	
		
			
				|  |  | -    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL},
 | 
	
		
			
				|  |  | +    {1, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL, NULL},
 | 
	
		
			
				|  |  |      {0, "xn--poema-9qae5a.com.br", "",
 | 
	
		
			
				|  |  |       "*.xn--poema-9qae5a.com.br,"
 | 
	
		
			
				|  |  |       "xn--poema-*.com.br,"
 | 
	
		
			
				|  |  |       "xn--*-9qae5a.com.br,"
 | 
	
		
			
				|  |  | -     "*--poema-9qae5a.com.br"},
 | 
	
		
			
				|  |  | +     "*--poema-9qae5a.com.br",
 | 
	
		
			
				|  |  | +     NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* The following are adapted from the  examples quoted from
 | 
	
		
			
				|  |  |         http://tools.ietf.org/html/rfc6125#section-6.4.3
 | 
	
		
			
				|  |  |         (e.g., *.example.com would match foo.example.com but
 | 
	
		
			
				|  |  |         not bar.foo.example.com or example.com). */
 | 
	
		
			
				|  |  | -    {1, "foo.example.com", "*.example.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "bar.foo.example.com", "*.example.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "example.com", "*.example.com", NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.example.com", "*.example.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "bar.foo.example.com", "*.example.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "example.com", "*.example.com", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Partial wildcards are disallowed, though RFC 2818 rules allow them.
 | 
	
		
			
				|  |  |         That is, forms such as baz*.example.net, *baz.example.net, and
 | 
	
		
			
				|  |  |         b*z.example.net should NOT match domains. Instead, the wildcard must
 | 
	
		
			
				|  |  |         always be the left-most label, and only a single label. */
 | 
	
		
			
				|  |  | -    {0, "baz1.example.net", "baz*.example.net", NULL},
 | 
	
		
			
				|  |  | -    {0, "foobaz.example.net", "*baz.example.net", NULL},
 | 
	
		
			
				|  |  | -    {0, "buzz.example.net", "b*z.example.net", NULL},
 | 
	
		
			
				|  |  | -    {0, "www.test.example.net", "www.*.example.net", NULL},
 | 
	
		
			
				|  |  | +    {0, "baz1.example.net", "baz*.example.net", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foobaz.example.net", "*baz.example.net", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "buzz.example.net", "b*z.example.net", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "www.test.example.net", "www.*.example.net", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Wildcards should not be valid for public registry controlled domains,
 | 
	
		
			
				|  |  |         and unknown/unrecognized domains, at least three domain components must
 | 
	
		
			
				|  |  |         be present. */
 | 
	
		
			
				|  |  | -    {1, "www.test.example", "*.test.example", NULL},
 | 
	
		
			
				|  |  | -    {1, "test.example.co.uk", "*.example.co.uk", NULL},
 | 
	
		
			
				|  |  | -    {0, "test.example", "*.example", NULL},
 | 
	
		
			
				|  |  | +    {1, "www.test.example", "*.test.example", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "test.example.co.uk", "*.example.co.uk", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "test.example", "*.example", NULL, NULL},
 | 
	
		
			
				|  |  |      /*
 | 
	
		
			
				|  |  |         {0, "example.co.uk", "*.co.uk", NULL},
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    {0, "foo.com", "*.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "foo.us", "*.us", NULL},
 | 
	
		
			
				|  |  | -    {0, "foo", "*", NULL},
 | 
	
		
			
				|  |  | +    {0, "foo.com", "*.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foo.us", "*.us", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foo", "*", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* IDN variants of wildcards and registry controlled domains. */
 | 
	
		
			
				|  |  | -    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL},
 | 
	
		
			
				|  |  | -    {1, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h", NULL},
 | 
	
		
			
				|  |  | +    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h", NULL, NULL},
 | 
	
		
			
				|  |  |      /*
 | 
	
		
			
				|  |  |         {0, "xn--poema-9qae5a.com.br", "*.com.br", NULL},
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    {0, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h", NULL},
 | 
	
		
			
				|  |  | +    {0, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Wildcards should be permissible for 'private' registry controlled
 | 
	
		
			
				|  |  |         domains. */
 | 
	
		
			
				|  |  | -    {1, "www.appspot.com", "*.appspot.com", NULL},
 | 
	
		
			
				|  |  | -    {1, "foo.s3.amazonaws.com", "*.s3.amazonaws.com", NULL},
 | 
	
		
			
				|  |  | +    {1, "www.appspot.com", "*.appspot.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.s3.amazonaws.com", "*.s3.amazonaws.com", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Multiple wildcards are not valid. */
 | 
	
		
			
				|  |  | -    {0, "foo.example.com", "*.*.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "foo.bar.example.com", "*.bar.*.com", NULL},
 | 
	
		
			
				|  |  | +    {0, "foo.example.com", "*.*.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foo.bar.example.com", "*.bar.*.com", NULL, NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* Absolute vs relative DNS name tests. Although not explicitly specified
 | 
	
		
			
				|  |  |         in RFC 6125, absolute reference names (those ending in a .) should
 | 
	
		
			
				|  |  |         match either absolute or relative presented names. */
 | 
	
		
			
				|  |  | -    {1, "foo.com", "foo.com.", NULL},
 | 
	
		
			
				|  |  | -    {1, "foo.com.", "foo.com", NULL},
 | 
	
		
			
				|  |  | -    {1, "foo.com.", "foo.com.", NULL},
 | 
	
		
			
				|  |  | -    {1, "f", "f.", NULL},
 | 
	
		
			
				|  |  | -    {1, "f.", "f", NULL},
 | 
	
		
			
				|  |  | -    {1, "f.", "f.", NULL},
 | 
	
		
			
				|  |  | -    {1, "www-3.bar.foo.com", "*.bar.foo.com.", NULL},
 | 
	
		
			
				|  |  | -    {1, "www-3.bar.foo.com.", "*.bar.foo.com", NULL},
 | 
	
		
			
				|  |  | -    {1, "www-3.bar.foo.com.", "*.bar.foo.com.", NULL},
 | 
	
		
			
				|  |  | -    {0, ".", ".", NULL},
 | 
	
		
			
				|  |  | -    {0, "example.com", "*.com.", NULL},
 | 
	
		
			
				|  |  | -    {0, "example.com.", "*.com", NULL},
 | 
	
		
			
				|  |  | -    {0, "example.com.", "*.com.", NULL},
 | 
	
		
			
				|  |  | -    {0, "foo.", "*.", NULL},
 | 
	
		
			
				|  |  | -    {0, "foo", "*.", NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.com", "foo.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.com.", "foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "foo.com.", "foo.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "f", "f.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "f.", "f", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "f.", "f.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "www-3.bar.foo.com", "*.bar.foo.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "www-3.bar.foo.com.", "*.bar.foo.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {1, "www-3.bar.foo.com.", "*.bar.foo.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, ".", ".", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "example.com", "*.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "example.com.", "*.com", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "example.com.", "*.com.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foo.", "*.", NULL, NULL},
 | 
	
		
			
				|  |  | +    {0, "foo", "*.", NULL, NULL},
 | 
	
		
			
				|  |  |      /*
 | 
	
		
			
				|  |  |         {0, "foo.co.uk", "*.co.uk.", NULL},
 | 
	
		
			
				|  |  |         {0, "foo.co.uk.", "*.co.uk.", NULL},
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* An empty CN is OK. */
 | 
	
		
			
				|  |  | -    {1, "test.foo.com", "", "test.foo.com"},
 | 
	
		
			
				|  |  | +    {1, "test.foo.com", "", "test.foo.com", NULL},
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /* An IP should not be used for the CN. */
 | 
	
		
			
				|  |  | -    {0, "173.194.195.139", "173.194.195.139", NULL},
 | 
	
		
			
				|  |  | +    {0, "173.194.195.139", "173.194.195.139", NULL, NULL},
 | 
	
		
			
				|  |  | +    /* An IP can be used if the SAN IP is present */
 | 
	
		
			
				|  |  | +    {1, "173.194.195.139", "foo.example.com", NULL, "173.194.195.139"},
 | 
	
		
			
				|  |  | +    {0, "173.194.195.139", "foo.example.com", NULL, "8.8.8.8"},
 | 
	
		
			
				|  |  | +    {0, "173.194.195.139", "foo.example.com", NULL, "8.8.8.8,8.8.4.4"},
 | 
	
		
			
				|  |  | +    {1, "173.194.195.139", "foo.example.com", NULL, "8.8.8.8,173.194.195.139"},
 | 
	
		
			
				|  |  | +    {0, "173.194.195.139", "foo.example.com", NULL, "173.194.195.13"},
 | 
	
		
			
				|  |  | +    {0, "2001:db8:a0b:12f0::1", "foo.example.com", NULL, "173.194.195.13"},
 | 
	
		
			
				|  |  | +    {1, "2001:db8:a0b:12f0::1", "foo.example.com", NULL,
 | 
	
		
			
				|  |  | +     "2001:db8:a0b:12f0::1"},
 | 
	
		
			
				|  |  | +    {0, "2001:db8:a0b:12f0::1", "foo.example.com", NULL,
 | 
	
		
			
				|  |  | +     "2001:db8:a0b:12f0::2"},
 | 
	
		
			
				|  |  | +    {1, "2001:db8:a0b:12f0::1", "foo.example.com", NULL,
 | 
	
		
			
				|  |  | +     "2001:db8:a0b:12f0::2,2001:db8:a0b:12f0::1,8.8.8.8"},
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  typedef struct name_list {
 | 
	
	
		
			
				|  | @@ -196,7 +212,7 @@ typedef struct {
 | 
	
		
			
				|  |  |    size_t name_count;
 | 
	
		
			
				|  |  |    char *buffer;
 | 
	
		
			
				|  |  |    name_list *names;
 | 
	
		
			
				|  |  | -} parsed_dns_names;
 | 
	
		
			
				|  |  | +} parsed_names;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  name_list *name_list_add(const char *n) {
 | 
	
		
			
				|  |  |    name_list *result = gpr_malloc(sizeof(name_list));
 | 
	
	
		
			
				|  | @@ -205,18 +221,18 @@ name_list *name_list_add(const char *n) {
 | 
	
		
			
				|  |  |    return result;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static parsed_dns_names parse_dns_names(const char *dns_names_str) {
 | 
	
		
			
				|  |  | -  parsed_dns_names result;
 | 
	
		
			
				|  |  | +static parsed_names parse_names(const char *names_str) {
 | 
	
		
			
				|  |  | +  parsed_names result;
 | 
	
		
			
				|  |  |    name_list *current_nl;
 | 
	
		
			
				|  |  |    size_t i;
 | 
	
		
			
				|  |  | -  memset(&result, 0, sizeof(parsed_dns_names));
 | 
	
		
			
				|  |  | -  if (dns_names_str == 0) return result;
 | 
	
		
			
				|  |  | +  memset(&result, 0, sizeof(parsed_names));
 | 
	
		
			
				|  |  | +  if (names_str == 0) return result;
 | 
	
		
			
				|  |  |    result.name_count = 1;
 | 
	
		
			
				|  |  | -  result.buffer = gpr_strdup(dns_names_str);
 | 
	
		
			
				|  |  | +  result.buffer = gpr_strdup(names_str);
 | 
	
		
			
				|  |  |    result.names = name_list_add(result.buffer);
 | 
	
		
			
				|  |  |    current_nl = result.names;
 | 
	
		
			
				|  |  | -  for (i = 0; i < strlen(dns_names_str); i++) {
 | 
	
		
			
				|  |  | -    if (dns_names_str[i] == ',') {
 | 
	
		
			
				|  |  | +  for (i = 0; i < strlen(names_str); i++) {
 | 
	
		
			
				|  |  | +    if (names_str[i] == ',') {
 | 
	
		
			
				|  |  |        result.buffer[i] = '\0';
 | 
	
		
			
				|  |  |        result.name_count++;
 | 
	
		
			
				|  |  |        i++;
 | 
	
	
		
			
				|  | @@ -227,7 +243,7 @@ static parsed_dns_names parse_dns_names(const char *dns_names_str) {
 | 
	
		
			
				|  |  |    return result;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void destruct_parsed_dns_names(parsed_dns_names *pdn) {
 | 
	
		
			
				|  |  | +static void destruct_parsed_names(parsed_names *pdn) {
 | 
	
		
			
				|  |  |    name_list *nl = pdn->names;
 | 
	
		
			
				|  |  |    if (pdn->buffer != NULL) gpr_free(pdn->buffer);
 | 
	
		
			
				|  |  |    while (nl != NULL) {
 | 
	
	
		
			
				|  | @@ -237,8 +253,8 @@ static void destruct_parsed_dns_names(parsed_dns_names *pdn) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static char *processed_dns_name(const char *dns_name) {
 | 
	
		
			
				|  |  | -  char *result = gpr_strdup(dns_name);
 | 
	
		
			
				|  |  | +static char *processed_name(const char *name) {
 | 
	
		
			
				|  |  | +  char *result = gpr_strdup(name);
 | 
	
		
			
				|  |  |    size_t i;
 | 
	
		
			
				|  |  |    for (i = 0; i < strlen(result); i++) {
 | 
	
		
			
				|  |  |      if (result[i] == '#') {
 | 
	
	
		
			
				|  | @@ -253,31 +269,48 @@ static tsi_peer peer_from_cert_name_test_entry(
 | 
	
		
			
				|  |  |    size_t i;
 | 
	
		
			
				|  |  |    tsi_peer peer;
 | 
	
		
			
				|  |  |    name_list *nl;
 | 
	
		
			
				|  |  | -  parsed_dns_names dns_entries = parse_dns_names(entry->dns_names);
 | 
	
		
			
				|  |  | +  parsed_names dns_entries = parse_names(entry->dns_names);
 | 
	
		
			
				|  |  | +  parsed_names ip_entries = parse_names(entry->ip_names);
 | 
	
		
			
				|  |  |    nl = dns_entries.names;
 | 
	
		
			
				|  |  | -  GPR_ASSERT(tsi_construct_peer(1 + dns_entries.name_count, &peer) == TSI_OK);
 | 
	
		
			
				|  |  | +  GPR_ASSERT(tsi_construct_peer(
 | 
	
		
			
				|  |  | +                 1 + dns_entries.name_count + ip_entries.name_count, &peer) ==
 | 
	
		
			
				|  |  | +             TSI_OK);
 | 
	
		
			
				|  |  |    GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
 | 
	
		
			
				|  |  |                   TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, entry->common_name,
 | 
	
		
			
				|  |  |                   &peer.properties[0]) == TSI_OK);
 | 
	
		
			
				|  |  |    i = 1;
 | 
	
		
			
				|  |  |    while (nl != NULL) {
 | 
	
		
			
				|  |  | -    char *processed = processed_dns_name(nl->name);
 | 
	
		
			
				|  |  | +    char *processed = processed_name(nl->name);
 | 
	
		
			
				|  |  |      GPR_ASSERT(tsi_construct_string_peer_property(
 | 
	
		
			
				|  |  |                     TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, processed,
 | 
	
		
			
				|  |  |                     strlen(nl->name), &peer.properties[i++]) == TSI_OK);
 | 
	
		
			
				|  |  |      nl = nl->next;
 | 
	
		
			
				|  |  |      gpr_free(processed);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  destruct_parsed_dns_names(&dns_entries);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  nl = ip_entries.names;
 | 
	
		
			
				|  |  | +  while (nl != NULL) {
 | 
	
		
			
				|  |  | +    char *processed = processed_name(nl->name);
 | 
	
		
			
				|  |  | +    GPR_ASSERT(tsi_construct_string_peer_property(
 | 
	
		
			
				|  |  | +                   TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, processed,
 | 
	
		
			
				|  |  | +                   strlen(nl->name), &peer.properties[i++]) == TSI_OK);
 | 
	
		
			
				|  |  | +    nl = nl->next;
 | 
	
		
			
				|  |  | +    gpr_free(processed);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  destruct_parsed_names(&dns_entries);
 | 
	
		
			
				|  |  | +  destruct_parsed_names(&ip_entries);
 | 
	
		
			
				|  |  |    return peer;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  char *cert_name_test_entry_to_string(const cert_name_test_entry *entry) {
 | 
	
		
			
				|  |  |    char *s;
 | 
	
		
			
				|  |  | -  gpr_asprintf(
 | 
	
		
			
				|  |  | -      &s, "{ success = %s, host_name = %s, common_name = %s, dns_names = %s}",
 | 
	
		
			
				|  |  | -      entry->expected ? "true" : "false", entry->host_name, entry->common_name,
 | 
	
		
			
				|  |  | -      entry->dns_names != NULL ? entry->dns_names : "");
 | 
	
		
			
				|  |  | +  gpr_asprintf(&s,
 | 
	
		
			
				|  |  | +               "{ success = %s, host_name = %s, common_name = %s, dns_names = "
 | 
	
		
			
				|  |  | +               "%s, ip_names = %s}",
 | 
	
		
			
				|  |  | +               entry->expected ? "true" : "false", entry->host_name,
 | 
	
		
			
				|  |  | +               entry->common_name,
 | 
	
		
			
				|  |  | +               entry->dns_names != NULL ? entry->dns_names : "",
 | 
	
		
			
				|  |  | +               entry->ip_names != NULL ? entry->ip_names : "");
 | 
	
		
			
				|  |  |    return s;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |