Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

411 linhas
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 <openssl/crypto.h>
  59. #include <openssl/mem.h>
  60. #include <openssl/x509.h>
  61. #include <openssl/x509v3.h>
  62. static const char *const names[] = {
  63. "a", "b", ".", "*", "@",
  64. ".a", "a.", ".b", "b.", ".*", "*.", "*@", "@*", "a@", "@a", "b@", "..",
  65. "-example.com", "example-.com",
  66. "@@", "**", "*.com", "*com", "*.*.com", "*com", "com*", "*example.com",
  67. "*@example.com", "test@*.example.com", "example.com", "www.example.com",
  68. "test.www.example.com", "*.example.com", "*.www.example.com",
  69. "test.*.example.com", "www.*.com",
  70. ".www.example.com", "*www.example.com",
  71. "example.net", "xn--rger-koa.example.com",
  72. "*.xn--rger-koa.example.com", "www.xn--rger-koa.example.com",
  73. "*.good--example.com", "www.good--example.com",
  74. "*.xn--bar.com", "xn--foo.xn--bar.com",
  75. "a.example.com", "b.example.com",
  76. "postmaster@example.com", "Postmaster@example.com",
  77. "postmaster@EXAMPLE.COM",
  78. NULL
  79. };
  80. static const char *const exceptions[] = {
  81. "set CN: host: [*.example.com] matches [a.example.com]",
  82. "set CN: host: [*.example.com] matches [b.example.com]",
  83. "set CN: host: [*.example.com] matches [www.example.com]",
  84. "set CN: host: [*.example.com] matches [xn--rger-koa.example.com]",
  85. "set CN: host: [*.www.example.com] matches [test.www.example.com]",
  86. "set CN: host: [*.www.example.com] matches [.www.example.com]",
  87. "set CN: host: [*www.example.com] matches [www.example.com]",
  88. "set CN: host: [test.www.example.com] matches [.www.example.com]",
  89. "set CN: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
  90. "set CN: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
  91. "set CN: host: [*.good--example.com] matches [www.good--example.com]",
  92. "set CN: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
  93. "set CN: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
  94. "set emailAddress: email: [postmaster@example.com] does not match [Postmaster@example.com]",
  95. "set emailAddress: email: [postmaster@EXAMPLE.COM] does not match [Postmaster@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 dnsName: host: [*.example.com] matches [www.example.com]",
  99. "set dnsName: host: [*.example.com] matches [a.example.com]",
  100. "set dnsName: host: [*.example.com] matches [b.example.com]",
  101. "set dnsName: host: [*.example.com] matches [xn--rger-koa.example.com]",
  102. "set dnsName: host: [*.www.example.com] matches [test.www.example.com]",
  103. "set dnsName: host-no-wildcards: [*.www.example.com] matches [.www.example.com]",
  104. "set dnsName: host-no-wildcards: [test.www.example.com] matches [.www.example.com]",
  105. "set dnsName: host: [*.www.example.com] matches [.www.example.com]",
  106. "set dnsName: host: [*www.example.com] matches [www.example.com]",
  107. "set dnsName: host: [test.www.example.com] matches [.www.example.com]",
  108. "set dnsName: host: [*.xn--rger-koa.example.com] matches [www.xn--rger-koa.example.com]",
  109. "set dnsName: host: [*.xn--bar.com] matches [xn--foo.xn--bar.com]",
  110. "set dnsName: host: [*.good--example.com] matches [www.good--example.com]",
  111. "set rfc822Name: email: [postmaster@example.com] does not match [Postmaster@example.com]",
  112. "set rfc822Name: email: [Postmaster@example.com] does not match [postmaster@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. NULL
  116. };
  117. static int is_exception(const char *msg)
  118. {
  119. const char *const *p;
  120. for (p = exceptions; *p; ++p)
  121. if (strcmp(msg, *p) == 0)
  122. return 1;
  123. return 0;
  124. }
  125. static int set_cn(X509 *crt, ...)
  126. {
  127. int ret = 0;
  128. X509_NAME *n = NULL;
  129. va_list ap;
  130. va_start(ap, crt);
  131. n = X509_NAME_new();
  132. if (n == NULL)
  133. goto out;
  134. while (1) {
  135. int nid;
  136. const char *name;
  137. nid = va_arg(ap, int);
  138. if (nid == 0)
  139. break;
  140. name = va_arg(ap, const char *);
  141. if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,
  142. (unsigned char *)name, -1, -1, 1))
  143. goto out;
  144. }
  145. if (!X509_set_subject_name(crt, n))
  146. goto out;
  147. ret = 1;
  148. out:
  149. X509_NAME_free(n);
  150. va_end(ap);
  151. return ret;
  152. }
  153. /*
  154. * int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); X509_EXTENSION
  155. * *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit,
  156. * ASN1_OCTET_STRING *data); int X509_add_ext(X509 *x, X509_EXTENSION *ex,
  157. * int loc);
  158. */
  159. static int set_altname(X509 *crt, ...)
  160. {
  161. int ret = 0;
  162. GENERAL_NAMES *gens = NULL;
  163. GENERAL_NAME *gen = NULL;
  164. ASN1_IA5STRING *ia5 = NULL;
  165. va_list ap;
  166. va_start(ap, crt);
  167. gens = sk_GENERAL_NAME_new_null();
  168. if (gens == NULL)
  169. goto out;
  170. while (1) {
  171. int type;
  172. const char *name;
  173. type = va_arg(ap, int);
  174. if (type == 0)
  175. break;
  176. name = va_arg(ap, const char *);
  177. gen = GENERAL_NAME_new();
  178. if (gen == NULL)
  179. goto out;
  180. ia5 = ASN1_IA5STRING_new();
  181. if (ia5 == NULL)
  182. goto out;
  183. if (!ASN1_STRING_set(ia5, name, -1))
  184. goto out;
  185. switch (type) {
  186. case GEN_EMAIL:
  187. case GEN_DNS:
  188. GENERAL_NAME_set0_value(gen, type, ia5);
  189. ia5 = NULL;
  190. break;
  191. default:
  192. abort();
  193. }
  194. sk_GENERAL_NAME_push(gens, gen);
  195. gen = NULL;
  196. }
  197. if (!X509_add1_ext_i2d(crt, NID_subject_alt_name, gens, 0, 0))
  198. goto out;
  199. ret = 1;
  200. out:
  201. ASN1_IA5STRING_free(ia5);
  202. GENERAL_NAME_free(gen);
  203. GENERAL_NAMES_free(gens);
  204. va_end(ap);
  205. return ret;
  206. }
  207. static int set_cn1(X509 *crt, const char *name)
  208. {
  209. return set_cn(crt, NID_commonName, name, 0);
  210. }
  211. static int set_cn_and_email(X509 *crt, const char *name)
  212. {
  213. return set_cn(crt, NID_commonName, name,
  214. NID_pkcs9_emailAddress, "dummy@example.com", 0);
  215. }
  216. static int set_cn2(X509 *crt, const char *name)
  217. {
  218. return set_cn(crt, NID_commonName, "dummy value",
  219. NID_commonName, name, 0);
  220. }
  221. static int set_cn3(X509 *crt, const char *name)
  222. {
  223. return set_cn(crt, NID_commonName, name,
  224. NID_commonName, "dummy value", 0);
  225. }
  226. static int set_email1(X509 *crt, const char *name)
  227. {
  228. return set_cn(crt, NID_pkcs9_emailAddress, name, 0);
  229. }
  230. static int set_email2(X509 *crt, const char *name)
  231. {
  232. return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com",
  233. NID_pkcs9_emailAddress, name, 0);
  234. }
  235. static int set_email3(X509 *crt, const char *name)
  236. {
  237. return set_cn(crt, NID_pkcs9_emailAddress, name,
  238. NID_pkcs9_emailAddress, "dummy@example.com", 0);
  239. }
  240. static int set_email_and_cn(X509 *crt, const char *name)
  241. {
  242. return set_cn(crt, NID_pkcs9_emailAddress, name,
  243. NID_commonName, "www.example.org", 0);
  244. }
  245. static int set_altname_dns(X509 *crt, const char *name)
  246. {
  247. return set_altname(crt, GEN_DNS, name, 0);
  248. }
  249. static int set_altname_email(X509 *crt, const char *name)
  250. {
  251. return set_altname(crt, GEN_EMAIL, name, 0);
  252. }
  253. struct set_name_fn {
  254. int (*fn) (X509 *, const char *);
  255. const char *name;
  256. int host;
  257. int email;
  258. };
  259. static const struct set_name_fn name_fns[] = {
  260. {set_cn1, "set CN", 1, 0},
  261. {set_cn2, "set CN", 1, 0},
  262. {set_cn3, "set CN", 1, 0},
  263. {set_cn_and_email, "set CN", 1, 0},
  264. {set_email1, "set emailAddress", 0, 1},
  265. {set_email2, "set emailAddress", 0, 1},
  266. {set_email3, "set emailAddress", 0, 1},
  267. {set_email_and_cn, "set emailAddress", 0, 1},
  268. {set_altname_dns, "set dnsName", 1, 0},
  269. {set_altname_email, "set rfc822Name", 0, 1},
  270. {NULL, NULL, 0, 0},
  271. };
  272. static X509 *make_cert(void)
  273. {
  274. X509 *ret = NULL;
  275. X509 *crt = NULL;
  276. X509_NAME *issuer = NULL;
  277. crt = X509_new();
  278. if (crt == NULL)
  279. goto out;
  280. if (!X509_set_version(crt, 3))
  281. goto out;
  282. ret = crt;
  283. crt = NULL;
  284. out:
  285. X509_NAME_free(issuer);
  286. return ret;
  287. }
  288. static int errors;
  289. static void check_message(const struct set_name_fn *fn, const char *op,
  290. const char *nameincert, int match, const char *name)
  291. {
  292. char msg[1024];
  293. if (match < 0)
  294. return;
  295. BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]",
  296. fn->name, op, nameincert,
  297. match ? "matches" : "does not match", name);
  298. if (is_exception(msg))
  299. return;
  300. puts(msg);
  301. ++errors;
  302. }
  303. static void run_cert(X509 *crt, const char *nameincert,
  304. const struct set_name_fn *fn)
  305. {
  306. const char *const *pname = names;
  307. while (*pname) {
  308. int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
  309. size_t namelen = strlen(*pname);
  310. char *name = malloc(namelen);
  311. int match, ret;
  312. memcpy(name, *pname, namelen);
  313. ret = X509_check_host(crt, name, namelen, 0, NULL);
  314. match = -1;
  315. if (ret < 0) {
  316. fprintf(stderr, "internal error in X509_check_host");
  317. ++errors;
  318. } else if (fn->host) {
  319. if (ret == 1 && !samename)
  320. match = 1;
  321. if (ret == 0 && samename)
  322. match = 0;
  323. } else if (ret == 1)
  324. match = 1;
  325. check_message(fn, "host", nameincert, match, *pname);
  326. ret = X509_check_host(crt, name, namelen,
  327. X509_CHECK_FLAG_NO_WILDCARDS, NULL);
  328. match = -1;
  329. if (ret < 0) {
  330. fprintf(stderr, "internal error in X509_check_host");
  331. ++errors;
  332. } else if (fn->host) {
  333. if (ret == 1 && !samename)
  334. match = 1;
  335. if (ret == 0 && samename)
  336. match = 0;
  337. } else if (ret == 1)
  338. match = 1;
  339. check_message(fn, "host-no-wildcards", nameincert, match, *pname);
  340. ret = X509_check_email(crt, name, namelen, 0);
  341. match = -1;
  342. if (fn->email) {
  343. if (ret && !samename)
  344. match = 1;
  345. if (!ret && samename && strchr(nameincert, '@') != NULL)
  346. match = 0;
  347. } else if (ret)
  348. match = 1;
  349. check_message(fn, "email", nameincert, match, *pname);
  350. ++pname;
  351. free(name);
  352. }
  353. }
  354. int main(void)
  355. {
  356. CRYPTO_library_init();
  357. const struct set_name_fn *pfn = name_fns;
  358. while (pfn->name) {
  359. const char *const *pname = names;
  360. while (*pname) {
  361. X509 *crt = make_cert();
  362. if (crt == NULL) {
  363. fprintf(stderr, "make_cert failed\n");
  364. return 1;
  365. }
  366. if (!pfn->fn(crt, *pname)) {
  367. fprintf(stderr, "X509 name setting failed\n");
  368. return 1;
  369. }
  370. run_cert(crt, *pname, pfn);
  371. X509_free(crt);
  372. ++pname;
  373. }
  374. ++pfn;
  375. }
  376. if (errors == 0) {
  377. printf("PASS\n");
  378. }
  379. return errors > 0 ? 1 : 0;
  380. }