ssl_x509.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "ssl_x509.h"
  7. #include "ssl_methods.h"
  8. #include "ssl_dbg.h"
  9. #include "ssl_port.h"
  10. #include "bio.h"
  11. /**
  12. * @brief show X509 certification information
  13. */
  14. int __X509_show_info(X509 *x)
  15. {
  16. return X509_METHOD_CALL(show_info, x);
  17. }
  18. /**
  19. * @brief create a X509 certification object according to input X509 certification
  20. */
  21. X509* __X509_new(X509 *ix)
  22. {
  23. int ret;
  24. X509 *x;
  25. x = ssl_mem_zalloc(sizeof(X509));
  26. if (!x) {
  27. SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)");
  28. goto no_mem;
  29. }
  30. x->ref_counter = 1;
  31. if (ix && ix->method)
  32. x->method = ix->method;
  33. else
  34. x->method = X509_method();
  35. ret = X509_METHOD_CALL(new, x, ix);
  36. if (ret) {
  37. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(new) return %d", ret);
  38. goto failed;
  39. }
  40. return x;
  41. failed:
  42. ssl_mem_free(x);
  43. no_mem:
  44. return NULL;
  45. }
  46. /**
  47. * @brief create a X509 certification object
  48. */
  49. X509* X509_new(void)
  50. {
  51. return __X509_new(NULL);
  52. }
  53. /**
  54. * @brief free a X509 certification object
  55. */
  56. void X509_free(X509 *x)
  57. {
  58. SSL_ASSERT3(x);
  59. if (--x->ref_counter > 0) {
  60. return;
  61. }
  62. X509_METHOD_CALL(free, x);
  63. ssl_mem_free(x);
  64. };
  65. /**
  66. * @brief load a character certification context into system context. If '*cert' is pointed to the
  67. * certification, then load certification into it. Or create a new X509 certification object
  68. */
  69. X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len)
  70. {
  71. int m = 0;
  72. int ret;
  73. X509 *x;
  74. SSL_ASSERT2(buffer);
  75. SSL_ASSERT2(len);
  76. if (cert && *cert) {
  77. x = *cert;
  78. } else {
  79. x = X509_new();
  80. if (!x) {
  81. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL");
  82. goto failed1;
  83. }
  84. m = 1;
  85. }
  86. ret = X509_METHOD_CALL(load, x, buffer, len);
  87. if (ret) {
  88. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret);
  89. goto failed2;
  90. }
  91. return x;
  92. failed2:
  93. if (m)
  94. X509_free(x);
  95. failed1:
  96. return NULL;
  97. }
  98. /**
  99. * @brief return SSL X509 verify parameters
  100. */
  101. X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl)
  102. {
  103. return &ssl->param;
  104. }
  105. /**
  106. * @brief set X509 host verification flags
  107. */
  108. int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
  109. unsigned long flags)
  110. {
  111. /* flags not supported yet */
  112. return 0;
  113. }
  114. /**
  115. * @brief clear X509 host verification flags
  116. */
  117. int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param,
  118. unsigned long flags)
  119. {
  120. /* flags not supported yet */
  121. return 0;
  122. }
  123. /**
  124. * @brief set SSL context client CA certification
  125. */
  126. int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
  127. {
  128. SSL_ASSERT1(ctx);
  129. SSL_ASSERT1(x);
  130. if (ctx->client_CA == x)
  131. return 1;
  132. X509_free(ctx->client_CA);
  133. ctx->client_CA = x;
  134. return 1;
  135. }
  136. /**
  137. * @brief add CA client certification into the SSL
  138. */
  139. int SSL_add_client_CA(SSL *ssl, X509 *x)
  140. {
  141. SSL_ASSERT1(ssl);
  142. SSL_ASSERT1(x);
  143. if (ssl->client_CA == x)
  144. return 1;
  145. X509_free(ssl->client_CA);
  146. ssl->client_CA = x;
  147. return 1;
  148. }
  149. /**
  150. * @brief set the SSL context certification
  151. */
  152. int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
  153. {
  154. SSL_ASSERT1(ctx);
  155. SSL_ASSERT1(x);
  156. if (ctx->cert->x509 == x)
  157. return 1;
  158. X509_free(ctx->cert->x509);
  159. ctx->cert->x509 = x;
  160. x->ref_counter++;
  161. return 1;
  162. }
  163. /**
  164. * @brief set the SSL certification
  165. */
  166. int SSL_use_certificate(SSL *ssl, X509 *x)
  167. {
  168. SSL_ASSERT1(ssl);
  169. SSL_ASSERT1(x);
  170. if (ssl->cert->x509 == x)
  171. return 1;
  172. X509_free(ssl->cert->x509);
  173. ssl->cert->x509 = x;
  174. return 1;
  175. }
  176. long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x)
  177. {
  178. return SSL_CTX_use_certificate(ctx, x);
  179. }
  180. /**
  181. * @brief get the SSL certification point
  182. */
  183. X509 *SSL_get_certificate(const SSL *ssl)
  184. {
  185. SSL_ASSERT2(ssl);
  186. return ssl->cert->x509;
  187. }
  188. /**
  189. * @brief load certification into the SSL context
  190. */
  191. int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
  192. const unsigned char *d)
  193. {
  194. int ret;
  195. X509 *x;
  196. x = d2i_X509(NULL, d, len);
  197. if (!x) {
  198. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
  199. goto failed1;
  200. }
  201. ret = SSL_CTX_use_certificate(ctx, x); // This uses the "x" so increments ref_count
  202. if (!ret) {
  203. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_certificate() return %d", ret);
  204. goto failed2;
  205. }
  206. X509_free(x); // decrements ref_count, so in case of happy flow doesn't free the "x"
  207. return 1;
  208. failed2:
  209. X509_free(x);
  210. failed1:
  211. return 0;
  212. }
  213. /**
  214. * @brief load certification into the SSL
  215. */
  216. int SSL_use_certificate_ASN1(SSL *ssl, int len,
  217. const unsigned char *d)
  218. {
  219. int ret;
  220. X509 *x;
  221. x = d2i_X509(NULL, d, len);
  222. if (!x) {
  223. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL");
  224. goto failed1;
  225. }
  226. ret = SSL_use_certificate(ssl, x);
  227. if (!ret) {
  228. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_certificate() return %d", ret);
  229. goto failed2;
  230. }
  231. return 1;
  232. failed2:
  233. X509_free(x);
  234. failed1:
  235. return 0;
  236. }
  237. /**
  238. * @brief load the certification file into SSL context
  239. */
  240. int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
  241. {
  242. return 0;
  243. }
  244. /**
  245. * @brief load the certification file into SSL
  246. */
  247. int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
  248. {
  249. return 0;
  250. }
  251. /**
  252. * @brief get peer certification
  253. */
  254. X509 *SSL_get_peer_certificate(const SSL *ssl)
  255. {
  256. SSL_ASSERT2(ssl);
  257. return ssl->session->peer;
  258. }
  259. /**
  260. * @brief set SSL context client CA certification
  261. */
  262. int X509_STORE_add_cert(X509_STORE *store, X509 *x) {
  263. x->ref_counter++;
  264. SSL_CTX *ctx = (SSL_CTX *)store;
  265. SSL_ASSERT1(ctx);
  266. SSL_ASSERT1(x);
  267. if (ctx->client_CA == x) {
  268. return 1;
  269. }
  270. if (ctx->client_CA!=NULL) {
  271. X509_free(ctx->client_CA);
  272. }
  273. ctx->client_CA = x;
  274. return 1;
  275. }
  276. /**
  277. * @brief load a character certification context into system context.
  278. *
  279. * If '*cert' is pointed to the certification, then load certification
  280. * into it, or create a new X509 certification object.
  281. */
  282. X509 * PEM_read_bio_X509(BIO *bp, X509 **cert, pem_password_cb cb, void *u) {
  283. int m = 0;
  284. int ret;
  285. X509 *x;
  286. SSL_ASSERT2(BIO_method_type(bp) & BIO_TYPE_MEM);
  287. if (bp->data == NULL || bp->dlen == 0) {
  288. return NULL;
  289. }
  290. if (cert && *cert) {
  291. x = *cert;
  292. } else {
  293. x = X509_new();
  294. if (!x) {
  295. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL");
  296. goto failed;
  297. }
  298. m = 1;
  299. }
  300. ret = X509_METHOD_CALL(load, x, bp->data, bp->dlen);
  301. if (ret) {
  302. SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret);
  303. goto failed;
  304. }
  305. // If buffer successfully created a X509 from the bio, mark the buffer as consumed
  306. bp->data = NULL;
  307. bp->dlen = 0;
  308. return x;
  309. failed:
  310. if (m) {
  311. X509_free(x);
  312. }
  313. return NULL;
  314. }
  315. X509 *PEM_read_bio_X509_AUX(BIO *bp, X509 **cert, pem_password_cb *cb, void *u)
  316. {
  317. return PEM_read_bio_X509(bp, cert, cb, u);
  318. }
  319. /**
  320. * @brief get the SSL context object X509 certification storage
  321. */
  322. X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
  323. return (X509_STORE *)ctx;
  324. }