Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

x_x509.c 10 KiB

Switch OPENSSL_VERSION_NUMBER to 1.1.0. Although we are derived from 1.0.2, we mimic 1.1.0 in some ways around our FOO_up_ref functions and opaque libssl types. This causes some difficulties when porting third-party code as any OPENSSL_VERSION_NUMBER checks for 1.1.0 APIs we have will be wrong. Moreover, adding accessors without changing OPENSSL_VERSION_NUMBER can break external projects. It is common to implement a compatibility version of an accessor under #ifdef as a static function. This then conflicts with our headers if we, unlike OpenSSL 1.0.2, have this function. This change switches OPENSSL_VERSION_NUMBER to 1.1.0 and atomically adds enough accessors for software with 1.1.0 support already. The hope is this will unblock hiding SSL_CTX and SSL_SESSION, which will be especially useful with C++-ficiation. The cost is we will hit some growing pains as more 1.1.0 consumers enter the ecosystem and we converge on the right set of APIs to import from upstream. It does not remove any 1.0.2 APIs, so we will not require that all projects support 1.1.0. The exception is APIs which changed in 1.1.0 but did not change the function signature. Those are breaking changes. Specifically: - SSL_CTX_sess_set_get_cb is now const-correct. - X509_get0_signature is now const-correct. For C++ consumers only, this change temporarily includes an overload hack for SSL_CTX_sess_set_get_cb that keeps the old callback working. This is a workaround for Node not yet supporting OpenSSL 1.1.0. The version number is set at (the as yet unreleased) 1.1.0g to denote that this change includes https://github.com/openssl/openssl/pull/4384. Bug: 91 Change-Id: I5eeb27448a6db4c25c244afac37f9604d9608a76 Reviewed-on: https://boringssl-review.googlesource.com/10340 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: Adam Langley <agl@google.com>
8 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /* crypto/asn1/x_x509.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.] */
  57. #include <assert.h>
  58. #include <limits.h>
  59. #include <stdio.h>
  60. #include <openssl/asn1t.h>
  61. #include <openssl/evp.h>
  62. #include <openssl/mem.h>
  63. #include <openssl/obj.h>
  64. #include <openssl/pool.h>
  65. #include <openssl/thread.h>
  66. #include <openssl/x509.h>
  67. #include <openssl/x509v3.h>
  68. #include "../internal.h"
  69. static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
  70. ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
  71. ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
  72. ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
  73. ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
  74. ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
  75. ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
  76. ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
  77. ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
  78. ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
  79. ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
  80. ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
  81. } ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
  82. IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
  83. /* X509 top level structure needs a bit of customisation */
  84. extern void policy_cache_free(X509_POLICY_CACHE *cache);
  85. static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
  86. void *exarg)
  87. {
  88. X509 *ret = (X509 *)*pval;
  89. switch (operation) {
  90. case ASN1_OP_NEW_POST:
  91. ret->name = NULL;
  92. ret->ex_flags = 0;
  93. ret->ex_pathlen = -1;
  94. ret->skid = NULL;
  95. ret->akid = NULL;
  96. ret->aux = NULL;
  97. ret->crldp = NULL;
  98. ret->buf = NULL;
  99. CRYPTO_new_ex_data(&ret->ex_data);
  100. CRYPTO_MUTEX_init(&ret->lock);
  101. break;
  102. case ASN1_OP_D2I_PRE:
  103. CRYPTO_BUFFER_free(ret->buf);
  104. ret->buf = NULL;
  105. break;
  106. case ASN1_OP_D2I_POST:
  107. if (ret->name != NULL)
  108. OPENSSL_free(ret->name);
  109. ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
  110. break;
  111. case ASN1_OP_FREE_POST:
  112. CRYPTO_MUTEX_cleanup(&ret->lock);
  113. CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
  114. X509_CERT_AUX_free(ret->aux);
  115. ASN1_OCTET_STRING_free(ret->skid);
  116. AUTHORITY_KEYID_free(ret->akid);
  117. CRL_DIST_POINTS_free(ret->crldp);
  118. policy_cache_free(ret->policy_cache);
  119. GENERAL_NAMES_free(ret->altname);
  120. NAME_CONSTRAINTS_free(ret->nc);
  121. CRYPTO_BUFFER_free(ret->buf);
  122. OPENSSL_free(ret->name);
  123. break;
  124. }
  125. return 1;
  126. }
  127. ASN1_SEQUENCE_ref(X509, x509_cb) = {
  128. ASN1_SIMPLE(X509, cert_info, X509_CINF),
  129. ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
  130. ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
  131. } ASN1_SEQUENCE_END_ref(X509, X509)
  132. IMPLEMENT_ASN1_FUNCTIONS(X509)
  133. IMPLEMENT_ASN1_DUP_FUNCTION(X509)
  134. X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) {
  135. if (CRYPTO_BUFFER_len(buf) > LONG_MAX) {
  136. OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
  137. return 0;
  138. }
  139. X509 *x509 = X509_new();
  140. if (x509 == NULL) {
  141. return NULL;
  142. }
  143. x509->cert_info->enc.alias_only_on_next_parse = 1;
  144. const uint8_t *inp = CRYPTO_BUFFER_data(buf);
  145. X509 *x509p = x509;
  146. X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf));
  147. if (ret == NULL ||
  148. inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) {
  149. X509_free(x509p);
  150. return NULL;
  151. }
  152. assert(x509p == x509);
  153. assert(ret == x509);
  154. CRYPTO_BUFFER_up_ref(buf);
  155. ret->buf = buf;
  156. return ret;
  157. }
  158. int X509_up_ref(X509 *x)
  159. {
  160. CRYPTO_refcount_inc(&x->references);
  161. return 1;
  162. }
  163. int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused,
  164. CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func)
  165. {
  166. int index;
  167. if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
  168. free_func)) {
  169. return -1;
  170. }
  171. return index;
  172. }
  173. int X509_set_ex_data(X509 *r, int idx, void *arg)
  174. {
  175. return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
  176. }
  177. void *X509_get_ex_data(X509 *r, int idx)
  178. {
  179. return (CRYPTO_get_ex_data(&r->ex_data, idx));
  180. }
  181. /*
  182. * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
  183. * extra info tagged on the end. Since these functions set how a certificate
  184. * is trusted they should only be used when the certificate comes from a
  185. * reliable source such as local storage.
  186. */
  187. X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
  188. {
  189. const unsigned char *q = *pp;
  190. X509 *ret;
  191. int freeret = 0;
  192. if (!a || *a == NULL)
  193. freeret = 1;
  194. ret = d2i_X509(a, &q, length);
  195. /* If certificate unreadable then forget it */
  196. if (!ret)
  197. return NULL;
  198. /* update length */
  199. length -= q - *pp;
  200. /* Parse auxiliary information if there is any. */
  201. if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
  202. goto err;
  203. *pp = q;
  204. return ret;
  205. err:
  206. if (freeret) {
  207. X509_free(ret);
  208. if (a)
  209. *a = NULL;
  210. }
  211. return NULL;
  212. }
  213. /*
  214. * Serialize trusted certificate to *pp or just return the required buffer
  215. * length if pp == NULL. We ultimately want to avoid modifying *pp in the
  216. * error path, but that depends on similar hygiene in lower-level functions.
  217. * Here we avoid compounding the problem.
  218. */
  219. static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
  220. {
  221. int length, tmplen;
  222. unsigned char *start = pp != NULL ? *pp : NULL;
  223. assert(pp == NULL || *pp != NULL);
  224. /*
  225. * This might perturb *pp on error, but fixing that belongs in i2d_X509()
  226. * not here. It should be that if a == NULL length is zero, but we check
  227. * both just in case.
  228. */
  229. length = i2d_X509(a, pp);
  230. if (length <= 0 || a == NULL) {
  231. return length;
  232. }
  233. tmplen = i2d_X509_CERT_AUX(a->aux, pp);
  234. if (tmplen < 0) {
  235. if (start != NULL)
  236. *pp = start;
  237. return tmplen;
  238. }
  239. length += tmplen;
  240. return length;
  241. }
  242. /*
  243. * Serialize trusted certificate to *pp, or just return the required buffer
  244. * length if pp == NULL.
  245. *
  246. * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since
  247. * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do
  248. * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
  249. * allocated buffer.
  250. */
  251. int i2d_X509_AUX(X509 *a, unsigned char **pp)
  252. {
  253. int length;
  254. unsigned char *tmp;
  255. /* Buffer provided by caller */
  256. if (pp == NULL || *pp != NULL)
  257. return i2d_x509_aux_internal(a, pp);
  258. /* Obtain the combined length */
  259. if ((length = i2d_x509_aux_internal(a, NULL)) <= 0)
  260. return length;
  261. /* Allocate requisite combined storage */
  262. *pp = tmp = OPENSSL_malloc(length);
  263. if (tmp == NULL)
  264. return -1; /* Push error onto error stack? */
  265. /* Encode, but keep *pp at the originally malloced pointer */
  266. length = i2d_x509_aux_internal(a, &tmp);
  267. if (length <= 0) {
  268. OPENSSL_free(*pp);
  269. *pp = NULL;
  270. }
  271. return length;
  272. }
  273. int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
  274. {
  275. x->cert_info->enc.modified = 1;
  276. return i2d_X509_CINF(x->cert_info, pp);
  277. }
  278. void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg,
  279. const X509 *x)
  280. {
  281. if (psig)
  282. *psig = x->signature;
  283. if (palg)
  284. *palg = x->sig_alg;
  285. }
  286. int X509_get_signature_nid(const X509 *x)
  287. {
  288. return OBJ_obj2nid(x->sig_alg->algorithm);
  289. }