Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

404 rindas
14 KiB

  1. /*
  2. * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  3. * 1999.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com). */
  56. #include <stdarg.h>
  57. #include <string.h>
  58. #include <gtest/gtest.h>
  59. #include <openssl/crypto.h>
  60. #include <openssl/mem.h>
  61. #include <openssl/x509.h>
  62. #include <openssl/x509v3.h>
  63. #include "../internal.h"
  64. static const char *const names[] = {
  65. "a", "b", ".", "*", "@",
  66. ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
  67. "-example.com", "example-.com",
  68. "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
  69. "*@example.com", "test@*.example.com", "example.com", "www.example.com",
  70. "test.www.example.com", "*.example.com", "*.www.example.com",
  71. "test.*.example.com", "www.*.com",
  72. ".www.example.com", "*www.example.com",
  73. "example.net", "xn--rger-koa.example.com",
  74. "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com",
  75. "*.good--example.com", "www.good--example.com",
  76. "*.xn--bar.com", "xn--foo.xn--bar.com",
  77. "a.example.com", "b.example.com",
  78. "postmaster@example.com", "Postmaster@example.com",
  79. "postmaster@EXAMPLE.COM",
  80. NULL
  81. };
  82. static const char *const exceptions[] = {
  83. "set CN: host: [*.example.com] matches [a.example.com]",
  84. "set CN: host: [*.example.com] matches [b.example.com]",
  85. "set CN: host: [*.example.com] matches [www.example.com]",
  86. "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
  87. "set CN: host: [*.www.example.com] matches [test.www.example.com]",
  88. "set CN: host: [*.www.example.com] matches [.www.example.com]",
  89. "set CN: host: [*www.example.com] matches [www.example.com]",
  90. "set CN: host: [test.www.example.com] matches [.www.example.com]",
  91. "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
  92. "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
  93. "set CN: host: [*.good--example.com] matches [www.good--example.com]",
  94. "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
  95. "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
  96. "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
  97. "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
  98. "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@example.com]",
  99. "set emailAddress: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
  100. "set dnsName: host: [*.example.com] matches [www.example.com]",
  101. "set dnsName: host: [*.example.com] matches [a.example.com]",
  102. "set dnsName: host: [*.example.com] matches [b.example.com]",
  103. "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
  104. "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
  105. "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
  106. "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
  107. "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
  108. "set dnsName: host: [*www.example.com] matches [www.example.com]",
  109. "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
  110. "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
  111. "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
  112. "set dnsName: host: [*.good--example.com] matches [www.good--example.com]",
  113. "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
  114. "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@example.com]",
  115. "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@EXAMPLE.COM]",
  116. "set rfc822Name: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@example.com]",
  117. NULL
  118. };
  119. static int is_exception(const char *msg)
  120. {
  121. const char *const *p;
  122. for (p = exceptions; *p; ++p)
  123. if (strcmp(msg, *p) == 0)
  124. return 1;
  125. return 0;
  126. }
  127. static int set_cn(X509 *crt, ...)
  128. {
  129. int ret = 0;
  130. X509_NAME *n = NULL;
  131. va_list ap;
  132. va_start(ap, crt);
  133. n = X509_NAME_new();
  134. if (n == NULL)
  135. goto out;
  136. while (1) {
  137. int nid;
  138. const char *name;
  139. nid = va_arg(ap, int);
  140. if (nid == 0)
  141. break;
  142. name = va_arg(ap, const char *);
  143. if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
  144. (unsigned char *)name, -1, -1, 1))
  145. goto out;
  146. }
  147. if (!X509_set_subject_name(crt, n))
  148. goto out;
  149. ret = 1;
  150. out:
  151. X509_NAME_free(n);
  152. va_end(ap);
  153. return ret;
  154. }
  155. /*
  156. * int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); X509_EXTENSION
  157. * *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit,
  158. * ASN1_OCTET_STRING *data); int X509_add_ext(X509 *x, X509_EXTENSION *ex,
  159. * int loc);
  160. */
  161. static int set_altname(X509 *crt, ...)
  162. {
  163. int ret = 0;
  164. GENERAL_NAMES *gens = NULL;
  165. GENERAL_NAME *gen = NULL;
  166. ASN1_IA5STRING *ia5 = NULL;
  167. va_list ap;
  168. va_start(ap, crt);
  169. gens = sk_GENERAL_NAME_new_null();
  170. if (gens == NULL)
  171. goto out;
  172. while (1) {
  173. int type;
  174. const char *name;
  175. type = va_arg(ap, int);
  176. if (type == 0)
  177. break;
  178. name = va_arg(ap, const char *);
  179. gen = GENERAL_NAME_new();
  180. if (gen == NULL)
  181. goto out;
  182. ia5 = ASN1_IA5STRING_new();
  183. if (ia5 == NULL)
  184. goto out;
  185. if (!ASN1_STRING_set(ia5, name, -1))
  186. goto out;
  187. switch (type) {
  188. case GEN_EMAIL:
  189. case GEN_DNS:
  190. GENERAL_NAME_set0_value(gen, type, ia5);
  191. ia5 = NULL;
  192. break;
  193. default:
  194. abort();
  195. }
  196. sk_GENERAL_NAME_push(gens, gen);
  197. gen = NULL;
  198. }
  199. if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
  200. goto out;
  201. ret = 1;
  202. out:
  203. ASN1_IA5STRING_free(ia5);
  204. GENERAL_NAME_free(gen);
  205. GENERAL_NAMES_free(gens);
  206. va_end(ap);
  207. return ret;
  208. }
  209. static int set_cn1(X509 *crt, const char *name)
  210. {
  211. return set_cn(crt, NID_commonName, name, 0);
  212. }
  213. static int set_cn_and_email(X509 *crt, const char *name)
  214. {
  215. return set_cn(crt, NID_commonName, name,
  216. NID_pkcs9_emailAddress, "dummy@example.com", 0);
  217. }
  218. static int set_cn2(X509 *crt, const char *name)
  219. {
  220. return set_cn(crt, NID_commonName, "dummy value",
  221. NID_commonName, name, 0);
  222. }
  223. static int set_cn3(X509 *crt, const char *name)
  224. {
  225. return set_cn(crt, NID_commonName, name,
  226. NID_commonName, "dummy value", 0);
  227. }
  228. static int set_email1(X509 *crt, const char *name)
  229. {
  230. return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
  231. }
  232. static int set_email2(X509 *crt, const char *name)
  233. {
  234. return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
  235. NID_pkcs9_emailAddress, name, 0);
  236. }
  237. static int set_email3(X509 *crt, const char *name)
  238. {
  239. return set_cn(crt, NID_pkcs9_emailAddress, name,
  240. NID_pkcs9_emailAddress, "dummy@example.com", 0);
  241. }
  242. static int set_email_and_cn(X509 *crt, const char *name)
  243. {
  244. return set_cn(crt, NID_pkcs9_emailAddress, name,
  245. NID_commonName, "www.example.org", 0);
  246. }
  247. static int set_altname_dns(X509 *crt, const char *name)
  248. {
  249. return set_altname(crt, GEN_DNS, name, 0);
  250. }
  251. static int set_altname_email(X509 *crt, const char *name)
  252. {
  253. return set_altname(crt, GEN_EMAIL, name, 0);
  254. }
  255. struct set_name_fn {
  256. int (*fn) (X509 *, const char *);
  257. const char *name;
  258. int host;
  259. int email;
  260. };
  261. static const struct set_name_fn name_fns[] = {
  262. {set_cn1, "set CN", 1, 0},
  263. {set_cn2, "set CN", 1, 0},
  264. {set_cn3, "set CN", 1, 0},
  265. {set_cn_and_email, "set CN", 1, 0},
  266. {set_email1, "set emailAddress", 0, 1},
  267. {set_email2, "set emailAddress", 0, 1},
  268. {set_email3, "set emailAddress", 0, 1},
  269. {set_email_and_cn, "set emailAddress", 0, 1},
  270. {set_altname_dns, "set dnsName", 1, 0},
  271. {set_altname_email, "set rfc822Name", 0, 1},
  272. {NULL, NULL, 0, 0},
  273. };
  274. static X509 *make_cert(void)
  275. {
  276. X509 *ret = NULL;
  277. X509 *crt = NULL;
  278. X509_NAME *issuer = NULL;
  279. crt = X509_new();
  280. if (crt == NULL)
  281. goto out;
  282. if (!X509_set_version(crt, 3))
  283. goto out;
  284. ret = crt;
  285. crt = NULL;
  286. out:
  287. X509_NAME_free(issuer);
  288. return ret;
  289. }
  290. static int errors;
  291. static void check_message(const struct set_name_fn *fn, const char *op,
  292. const char *nameincert, int match, const char *name)
  293. {
  294. char msg[1024];
  295. if (match < 0)
  296. return;
  297. BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
  298. fn->name, op, nameincert,
  299. match ? "matches" : "does not match", name);
  300. if (is_exception(msg))
  301. return;
  302. puts(msg);
  303. ++errors;
  304. }
  305. static void run_cert(X509 *crt, const char *nameincert,
  306. const struct set_name_fn *fn)
  307. {
  308. const char *const *pname = names;
  309. while (*pname) {
  310. int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
  311. size_t namelen = strlen(*pname);
  312. char *name = (char *)malloc(namelen);
  313. int match, ret;
  314. OPENSSL_memcpy(name, *pname, namelen);
  315. ret = X509_check_host(crt, name, namelen, 0, NULL);
  316. match = -1;
  317. if (ret < 0) {
  318. fprintf(stderr, "internal error in X509_check_host");
  319. ++errors;
  320. } else if (fn->host) {
  321. if (ret == 1 && !samename)
  322. match = 1;
  323. if (ret == 0 && samename)
  324. match = 0;
  325. } else if (ret == 1)
  326. match = 1;
  327. check_message(fn, "host", nameincert, match, *pname);
  328. ret = X509_check_host(crt, name, namelen,
  329. X509_CHECK_FLAG_NO_WILDCARDS, NULL);
  330. match = -1;
  331. if (ret < 0) {
  332. fprintf(stderr, "internal error in X509_check_host");
  333. ++errors;
  334. } else if (fn->host) {
  335. if (ret == 1 && !samename)
  336. match = 1;
  337. if (ret == 0 && samename)
  338. match = 0;
  339. } else if (ret == 1)
  340. match = 1;
  341. check_message(fn, "host-no-wildcards", nameincert, match, *pname);
  342. ret = X509_check_email(crt, name, namelen, 0);
  343. match = -1;
  344. if (fn->email) {
  345. if (ret && !samename)
  346. match = 1;
  347. if (!ret && samename && strchr(nameincert, '@') != NULL)
  348. match = 0;
  349. } else if (ret)
  350. match = 1;
  351. check_message(fn, "email", nameincert, match, *pname);
  352. ++pname;
  353. free(name);
  354. }
  355. }
  356. // TOOD(davidben): Convert this test to GTest more thoroughly.
  357. TEST(X509V3Test, NameTest) {
  358. const struct set_name_fn *pfn = name_fns;
  359. while (pfn->name) {
  360. const char *const *pname = names;
  361. while (*pname) {
  362. bssl::UniquePtr<X509> crt(make_cert());
  363. ASSERT_TRUE(crt);
  364. ASSERT_TRUE(pfn->fn(crt.get(), *pname));
  365. run_cert(crt.get(), *pname, pfn);
  366. ++pname;
  367. }
  368. ++pfn;
  369. }
  370. EXPECT_EQ(0, errors);
  371. }