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.
 
 
 
 
 
 

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