Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

v3nametest.c 12 KiB

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