Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

363 Zeilen
11 KiB

  1. /* v3_lib.c */
  2. /*
  3. * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  4. * 1999.
  5. */
  6. /* ====================================================================
  7. * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in
  18. * the documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * 3. All advertising materials mentioning features or use of this
  22. * software must display the following acknowledgment:
  23. * "This product includes software developed by the OpenSSL Project
  24. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  25. *
  26. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  27. * endorse or promote products derived from this software without
  28. * prior written permission. For written permission, please contact
  29. * licensing@OpenSSL.org.
  30. *
  31. * 5. Products derived from this software may not be called "OpenSSL"
  32. * nor may "OpenSSL" appear in their names without prior written
  33. * permission of the OpenSSL Project.
  34. *
  35. * 6. Redistributions of any form whatsoever must retain the following
  36. * acknowledgment:
  37. * "This product includes software developed by the OpenSSL Project
  38. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  41. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  43. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  44. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  45. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  46. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  49. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  50. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  51. * OF THE POSSIBILITY OF SUCH DAMAGE.
  52. * ====================================================================
  53. *
  54. * This product includes cryptographic software written by Eric Young
  55. * (eay@cryptsoft.com). This product includes software written by Tim
  56. * Hudson (tjh@cryptsoft.com).
  57. *
  58. */
  59. /* X509 v3 extension utilities */
  60. #include <stdio.h>
  61. #include <openssl/conf.h>
  62. #include <openssl/err.h>
  63. #include <openssl/mem.h>
  64. #include <openssl/obj.h>
  65. #include <openssl/x509v3.h>
  66. #include "ext_dat.h"
  67. static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
  68. static void ext_list_free(X509V3_EXT_METHOD *ext);
  69. static int ext_stack_cmp(const X509V3_EXT_METHOD **a,
  70. const X509V3_EXT_METHOD **b)
  71. {
  72. return ((*a)->ext_nid - (*b)->ext_nid);
  73. }
  74. int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
  75. {
  76. if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
  77. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  78. ext_list_free(ext);
  79. return 0;
  80. }
  81. if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
  82. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  83. ext_list_free(ext);
  84. return 0;
  85. }
  86. return 1;
  87. }
  88. static int ext_cmp(const void *void_a, const void *void_b)
  89. {
  90. const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a;
  91. const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b;
  92. return ext_stack_cmp(a, b);
  93. }
  94. const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
  95. {
  96. X509V3_EXT_METHOD tmp;
  97. const X509V3_EXT_METHOD *t = &tmp, *const *ret;
  98. size_t idx;
  99. if (nid < 0)
  100. return NULL;
  101. tmp.ext_nid = nid;
  102. ret =
  103. bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT,
  104. sizeof(X509V3_EXT_METHOD *), ext_cmp);
  105. if (ret)
  106. return *ret;
  107. if (!ext_list)
  108. return NULL;
  109. if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
  110. return NULL;
  111. return sk_X509V3_EXT_METHOD_value(ext_list, idx);
  112. }
  113. const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
  114. {
  115. int nid;
  116. if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
  117. return NULL;
  118. return X509V3_EXT_get_nid(nid);
  119. }
  120. int X509V3_EXT_free(int nid, void *ext_data)
  121. {
  122. const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
  123. if (ext_method == NULL) {
  124. OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
  125. return 0;
  126. }
  127. if (ext_method->it != NULL)
  128. ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
  129. else if (ext_method->ext_free != NULL)
  130. ext_method->ext_free(ext_data);
  131. else {
  132. OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
  133. return 0;
  134. }
  135. return 1;
  136. }
  137. int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
  138. {
  139. for (; extlist->ext_nid != -1; extlist++)
  140. if (!X509V3_EXT_add(extlist))
  141. return 0;
  142. return 1;
  143. }
  144. int X509V3_EXT_add_alias(int nid_to, int nid_from)
  145. {
  146. const X509V3_EXT_METHOD *ext;
  147. X509V3_EXT_METHOD *tmpext;
  148. if (!(ext = X509V3_EXT_get_nid(nid_from))) {
  149. OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
  150. return 0;
  151. }
  152. if (!
  153. (tmpext =
  154. (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
  155. OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
  156. return 0;
  157. }
  158. *tmpext = *ext;
  159. tmpext->ext_nid = nid_to;
  160. tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
  161. return X509V3_EXT_add(tmpext);
  162. }
  163. void X509V3_EXT_cleanup(void)
  164. {
  165. sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
  166. ext_list = NULL;
  167. }
  168. static void ext_list_free(X509V3_EXT_METHOD *ext)
  169. {
  170. if (ext->ext_flags & X509V3_EXT_DYNAMIC)
  171. OPENSSL_free(ext);
  172. }
  173. /*
  174. * Legacy function: we don't need to add standard extensions any more because
  175. * they are now kept in ext_dat.h.
  176. */
  177. int X509V3_add_standard_extensions(void)
  178. {
  179. return 1;
  180. }
  181. /* Return an extension internal structure */
  182. void *X509V3_EXT_d2i(X509_EXTENSION *ext)
  183. {
  184. const X509V3_EXT_METHOD *method;
  185. const unsigned char *p;
  186. if (!(method = X509V3_EXT_get(ext)))
  187. return NULL;
  188. p = ext->value->data;
  189. if (method->it)
  190. return ASN1_item_d2i(NULL, &p, ext->value->length,
  191. ASN1_ITEM_ptr(method->it));
  192. return method->d2i(NULL, &p, ext->value->length);
  193. }
  194. /*
  195. * Get critical flag and decoded version of extension from a NID. The "idx"
  196. * variable returns the last found extension and can be used to retrieve
  197. * multiple extensions of the same NID. However multiple extensions with the
  198. * same NID is usually due to a badly encoded certificate so if idx is NULL
  199. * we choke if multiple extensions exist. The "crit" variable is set to the
  200. * critical value. The return value is the decoded extension or NULL on
  201. * error. The actual error can have several different causes, the value of
  202. * *crit reflects the cause: >= 0, extension found but not decoded (reflects
  203. * critical value). -1 extension not found. -2 extension occurs more than
  204. * once.
  205. */
  206. void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
  207. int *idx)
  208. {
  209. int lastpos;
  210. size_t i;
  211. X509_EXTENSION *ex, *found_ex = NULL;
  212. if (!x) {
  213. if (idx)
  214. *idx = -1;
  215. if (crit)
  216. *crit = -1;
  217. return NULL;
  218. }
  219. if (idx)
  220. lastpos = *idx + 1;
  221. else
  222. lastpos = 0;
  223. if (lastpos < 0)
  224. lastpos = 0;
  225. for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
  226. ex = sk_X509_EXTENSION_value(x, i);
  227. if (OBJ_obj2nid(ex->object) == nid) {
  228. if (idx) {
  229. *idx = i;
  230. found_ex = ex;
  231. break;
  232. } else if (found_ex) {
  233. /* Found more than one */
  234. if (crit)
  235. *crit = -2;
  236. return NULL;
  237. }
  238. found_ex = ex;
  239. }
  240. }
  241. if (found_ex) {
  242. /* Found it */
  243. if (crit)
  244. *crit = X509_EXTENSION_get_critical(found_ex);
  245. return X509V3_EXT_d2i(found_ex);
  246. }
  247. /* Extension not found */
  248. if (idx)
  249. *idx = -1;
  250. if (crit)
  251. *crit = -1;
  252. return NULL;
  253. }
  254. /*
  255. * This function is a general extension append, replace and delete utility.
  256. * The precise operation is governed by the 'flags' value. The 'crit' and
  257. * 'value' arguments (if relevant) are the extensions internal structure.
  258. */
  259. int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
  260. int crit, unsigned long flags)
  261. {
  262. int extidx = -1;
  263. int errcode;
  264. X509_EXTENSION *ext, *extmp;
  265. unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
  266. /*
  267. * If appending we don't care if it exists, otherwise look for existing
  268. * extension.
  269. */
  270. if (ext_op != X509V3_ADD_APPEND)
  271. extidx = X509v3_get_ext_by_NID(*x, nid, -1);
  272. /* See if extension exists */
  273. if (extidx >= 0) {
  274. /* If keep existing, nothing to do */
  275. if (ext_op == X509V3_ADD_KEEP_EXISTING)
  276. return 1;
  277. /* If default then its an error */
  278. if (ext_op == X509V3_ADD_DEFAULT) {
  279. errcode = X509V3_R_EXTENSION_EXISTS;
  280. goto err;
  281. }
  282. /* If delete, just delete it */
  283. if (ext_op == X509V3_ADD_DELETE) {
  284. if (!sk_X509_EXTENSION_delete(*x, extidx))
  285. return -1;
  286. return 1;
  287. }
  288. } else {
  289. /*
  290. * If replace existing or delete, error since extension must exist
  291. */
  292. if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
  293. (ext_op == X509V3_ADD_DELETE)) {
  294. errcode = X509V3_R_EXTENSION_NOT_FOUND;
  295. goto err;
  296. }
  297. }
  298. /*
  299. * If we get this far then we have to create an extension: could have
  300. * some flags for alternative encoding schemes...
  301. */
  302. ext = X509V3_EXT_i2d(nid, crit, value);
  303. if (!ext) {
  304. OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
  305. return 0;
  306. }
  307. /* If extension exists replace it.. */
  308. if (extidx >= 0) {
  309. extmp = sk_X509_EXTENSION_value(*x, extidx);
  310. X509_EXTENSION_free(extmp);
  311. if (!sk_X509_EXTENSION_set(*x, extidx, ext))
  312. return -1;
  313. return 1;
  314. }
  315. if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
  316. return -1;
  317. if (!sk_X509_EXTENSION_push(*x, ext))
  318. return -1;
  319. return 1;
  320. err:
  321. if (!(flags & X509V3_ADD_SILENT))
  322. OPENSSL_PUT_ERROR(X509V3, errcode);
  323. return 0;
  324. }