mbedtls-x509.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #include "private-lib-core.h"
  25. #include "private-lib-tls-mbedtls.h"
  26. #include <mbedtls/oid.h>
  27. #if defined(LWS_PLAT_OPTEE) || defined(OPTEE_DEV_KIT)
  28. struct tm {
  29. int tm_sec; // seconds [0,61]
  30. int tm_min; // minutes [0,59]
  31. int tm_hour; // hour [0,23]
  32. int tm_mday; // day of month [1,31]
  33. int tm_mon; // month of year [0,11]
  34. int tm_year; // years since 1900
  35. int tm_wday; // day of week [0,6] (Sunday = 0)
  36. int tm_yday; // day of year [0,365]
  37. int tm_isdst; // daylight savings flag
  38. };
  39. time_t mktime(struct tm *t)
  40. {
  41. return (time_t)0;
  42. }
  43. #endif
  44. static time_t
  45. lws_tls_mbedtls_time_to_unix(mbedtls_x509_time *xtime)
  46. {
  47. struct tm t;
  48. if (!xtime || !xtime->year || xtime->year < 0)
  49. return (time_t)(long long)-1;
  50. memset(&t, 0, sizeof(t));
  51. t.tm_year = xtime->year - 1900;
  52. t.tm_mon = xtime->mon - 1; /* mbedtls months are 1+, tm are 0+ */
  53. t.tm_mday = xtime->day - 1; /* mbedtls days are 1+, tm are 0+ */
  54. t.tm_hour = xtime->hour;
  55. t.tm_min = xtime->min;
  56. t.tm_sec = xtime->sec;
  57. t.tm_isdst = -1;
  58. return mktime(&t);
  59. }
  60. static int
  61. lws_tls_mbedtls_get_x509_name(mbedtls_x509_name *name,
  62. union lws_tls_cert_info_results *buf, size_t len)
  63. {
  64. while (name) {
  65. if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid)) {
  66. name = name->next;
  67. continue;
  68. }
  69. if (len - 1 < name->val.len)
  70. return -1;
  71. memcpy(&buf->ns.name[0], name->val.p, name->val.len);
  72. buf->ns.name[name->val.len] = '\0';
  73. buf->ns.len = name->val.len;
  74. return 0;
  75. }
  76. return -1;
  77. }
  78. static int
  79. lws_tls_mbedtls_cert_info(mbedtls_x509_crt *x509, enum lws_tls_cert_info type,
  80. union lws_tls_cert_info_results *buf, size_t len)
  81. {
  82. if (!x509)
  83. return -1;
  84. switch (type) {
  85. case LWS_TLS_CERT_INFO_VALIDITY_FROM:
  86. buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_from);
  87. if (buf->time == (time_t)(long long)-1)
  88. return -1;
  89. break;
  90. case LWS_TLS_CERT_INFO_VALIDITY_TO:
  91. buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_to);
  92. if (buf->time == (time_t)(long long)-1)
  93. return -1;
  94. break;
  95. case LWS_TLS_CERT_INFO_COMMON_NAME:
  96. return lws_tls_mbedtls_get_x509_name(&x509->subject, buf, len);
  97. case LWS_TLS_CERT_INFO_ISSUER_NAME:
  98. return lws_tls_mbedtls_get_x509_name(&x509->issuer, buf, len);
  99. case LWS_TLS_CERT_INFO_USAGE:
  100. buf->usage = x509->key_usage;
  101. break;
  102. case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
  103. {
  104. char *p = buf->ns.name;
  105. size_t r = len, u;
  106. switch (mbedtls_pk_get_type(&x509->pk)) {
  107. case MBEDTLS_PK_RSA:
  108. {
  109. mbedtls_rsa_context *rsa = mbedtls_pk_rsa(x509->pk);
  110. if (mbedtls_mpi_write_string(&rsa->N, 16, p, r, &u))
  111. return -1;
  112. r -= u;
  113. p += u;
  114. if (mbedtls_mpi_write_string(&rsa->E, 16, p, r, &u))
  115. return -1;
  116. p += u;
  117. buf->ns.len = lws_ptr_diff(p, buf->ns.name);
  118. break;
  119. }
  120. case MBEDTLS_PK_ECKEY:
  121. {
  122. mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(x509->pk);
  123. if (mbedtls_mpi_write_string(&ecp->Q.X, 16, p, r, &u))
  124. return -1;
  125. r -= u;
  126. p += u;
  127. if (mbedtls_mpi_write_string(&ecp->Q.Y, 16, p, r, &u))
  128. return -1;
  129. r -= u;
  130. p += u;
  131. if (mbedtls_mpi_write_string(&ecp->Q.Z, 16, p, r, &u))
  132. return -1;
  133. p += u;
  134. buf->ns.len = lws_ptr_diff(p, buf->ns.name);
  135. break;
  136. }
  137. default:
  138. lwsl_notice("%s: x509 has unsupported pubkey type %d\n",
  139. __func__,
  140. mbedtls_pk_get_type(&x509->pk));
  141. return -1;
  142. }
  143. break;
  144. }
  145. default:
  146. return -1;
  147. }
  148. return 0;
  149. }
  150. #if defined(LWS_WITH_NETWORK)
  151. int
  152. lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
  153. union lws_tls_cert_info_results *buf, size_t len)
  154. {
  155. mbedtls_x509_crt *x509;
  156. x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->tls.ssl_ctx);
  157. return lws_tls_mbedtls_cert_info(x509, type, buf, len);
  158. }
  159. int
  160. lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
  161. union lws_tls_cert_info_results *buf, size_t len)
  162. {
  163. mbedtls_x509_crt *x509;
  164. wsi = lws_get_network_wsi(wsi);
  165. x509 = ssl_get_peer_mbedtls_x509_crt(wsi->tls.ssl);
  166. if (!x509)
  167. return -1;
  168. switch (type) {
  169. case LWS_TLS_CERT_INFO_VERIFIED:
  170. buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK;
  171. return 0;
  172. default:
  173. return lws_tls_mbedtls_cert_info(x509, type, buf, len);
  174. }
  175. return -1;
  176. }
  177. #endif
  178. int
  179. lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
  180. union lws_tls_cert_info_results *buf, size_t len)
  181. {
  182. return lws_tls_mbedtls_cert_info(&x509->cert, type, buf, len);
  183. }
  184. int
  185. lws_x509_create(struct lws_x509_cert **x509)
  186. {
  187. *x509 = lws_malloc(sizeof(**x509), __func__);
  188. return !(*x509);
  189. }
  190. /*
  191. * Parse one DER-encoded or one or more concatenated PEM-encoded certificates
  192. * and add them to the chained list.
  193. */
  194. int
  195. lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
  196. {
  197. int ret;
  198. mbedtls_x509_crt_init(&x509->cert);
  199. ret = mbedtls_x509_crt_parse(&x509->cert, pem, len);
  200. if (ret) {
  201. if (ret > 0)
  202. mbedtls_x509_crt_free(&x509->cert);
  203. lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
  204. __func__, -ret);
  205. return -1;
  206. }
  207. return 0;
  208. }
  209. int
  210. lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
  211. const char *common_name)
  212. {
  213. uint32_t flags = 0;
  214. int ret;
  215. ret = mbedtls_x509_crt_verify_with_profile(&x509->cert, &trusted->cert,
  216. NULL,
  217. &mbedtls_x509_crt_profile_next,
  218. common_name, &flags, NULL,
  219. NULL);
  220. if (ret) {
  221. lwsl_err("%s: unable to parse PEM cert: -0x%x\n",
  222. __func__, -ret);
  223. return -1;
  224. }
  225. return 0;
  226. }
  227. #if defined(LWS_WITH_JOSE)
  228. int
  229. lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
  230. const char *curves, int rsa_min_bits)
  231. {
  232. int kt = mbedtls_pk_get_type(&x509->cert.pk), n, count = 0, ret = -1;
  233. mbedtls_rsa_context *rsactx;
  234. mbedtls_ecp_keypair *ecpctx;
  235. mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
  236. memset(jwk, 0, sizeof(*jwk));
  237. switch (kt) {
  238. case MBEDTLS_PK_RSA:
  239. lwsl_notice("%s: RSA key\n", __func__);
  240. jwk->kty = LWS_GENCRYPTO_KTY_RSA;
  241. rsactx = mbedtls_pk_rsa(x509->cert.pk);
  242. mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = &rsactx->E;
  243. mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = &rsactx->N;
  244. mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->D;
  245. mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->P;
  246. mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->Q;
  247. mpi[LWS_GENCRYPTO_RSA_KEYEL_DP] = &rsactx->DP;
  248. mpi[LWS_GENCRYPTO_RSA_KEYEL_DQ] = &rsactx->DQ;
  249. mpi[LWS_GENCRYPTO_RSA_KEYEL_QI] = &rsactx->QP;
  250. count = LWS_GENCRYPTO_RSA_KEYEL_COUNT;
  251. n = LWS_GENCRYPTO_RSA_KEYEL_E;
  252. break;
  253. case MBEDTLS_PK_ECKEY:
  254. lwsl_notice("%s: EC key\n", __func__);
  255. jwk->kty = LWS_GENCRYPTO_KTY_EC;
  256. ecpctx = mbedtls_pk_ec(x509->cert.pk);
  257. mpi[LWS_GENCRYPTO_EC_KEYEL_X] = &ecpctx->Q.X;
  258. mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->d;
  259. mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = &ecpctx->Q.Y;
  260. if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
  261. ecpctx->grp.id, jwk))
  262. /* already logged */
  263. goto bail;
  264. count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
  265. n = LWS_GENCRYPTO_EC_KEYEL_X;
  266. break;
  267. default:
  268. lwsl_err("%s: key type %d not supported\n", __func__, kt);
  269. return -1;
  270. }
  271. for (; n < count; n++) {
  272. if (!mbedtls_mpi_size(mpi[n]))
  273. continue;
  274. jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
  275. if (!jwk->e[n].buf)
  276. goto bail;
  277. jwk->e[n].len = mbedtls_mpi_size(mpi[n]);
  278. mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
  279. }
  280. ret = 0;
  281. bail:
  282. /* jwk destroy will clean up partials */
  283. if (ret)
  284. lws_jwk_destroy(jwk);
  285. return ret;
  286. }
  287. int
  288. lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len,
  289. const char *passphrase)
  290. {
  291. mbedtls_rsa_context *rsactx;
  292. mbedtls_ecp_keypair *ecpctx;
  293. mbedtls_pk_context pk;
  294. mbedtls_mpi *mpi[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
  295. int n, ret = -1, count = 0;
  296. mbedtls_pk_init(&pk);
  297. n = 0;
  298. if (passphrase)
  299. n = strlen(passphrase);
  300. n = mbedtls_pk_parse_key(&pk, pem, len, (uint8_t *)passphrase, n);
  301. if (n) {
  302. lwsl_err("%s: parse PEM key failed: -0x%x\n", __func__, -n);
  303. return -1;
  304. }
  305. /* the incoming private key type */
  306. switch (mbedtls_pk_get_type(&pk)) {
  307. case MBEDTLS_PK_RSA:
  308. if (jwk->kty != LWS_GENCRYPTO_KTY_RSA) {
  309. lwsl_err("%s: RSA privkey, non-RSA jwk\n", __func__);
  310. goto bail;
  311. }
  312. rsactx = mbedtls_pk_rsa(pk);
  313. mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = &rsactx->D;
  314. mpi[LWS_GENCRYPTO_RSA_KEYEL_P] = &rsactx->P;
  315. mpi[LWS_GENCRYPTO_RSA_KEYEL_Q] = &rsactx->Q;
  316. n = LWS_GENCRYPTO_RSA_KEYEL_D;
  317. count = LWS_GENCRYPTO_RSA_KEYEL_Q + 1;
  318. break;
  319. case MBEDTLS_PK_ECKEY:
  320. if (jwk->kty != LWS_GENCRYPTO_KTY_EC) {
  321. lwsl_err("%s: EC privkey, non-EC jwk\n", __func__);
  322. goto bail;
  323. }
  324. ecpctx = mbedtls_pk_ec(pk);
  325. mpi[LWS_GENCRYPTO_EC_KEYEL_D] = &ecpctx->d;
  326. n = LWS_GENCRYPTO_EC_KEYEL_D;
  327. count = n + 1;
  328. break;
  329. default:
  330. lwsl_err("%s: unusable key type %d\n", __func__,
  331. mbedtls_pk_get_type(&pk));
  332. goto bail;
  333. }
  334. for (; n < count; n++) {
  335. if (!mbedtls_mpi_size(mpi[n])) {
  336. lwsl_err("%s: empty privkey\n", __func__);
  337. goto bail;
  338. }
  339. jwk->e[n].buf = lws_malloc(mbedtls_mpi_size(mpi[n]), "certjwk");
  340. if (!jwk->e[n].buf)
  341. goto bail;
  342. jwk->e[n].len = mbedtls_mpi_size(mpi[n]);
  343. mbedtls_mpi_write_binary(mpi[n], jwk->e[n].buf, jwk->e[n].len);
  344. }
  345. ret = 0;
  346. bail:
  347. mbedtls_pk_free(&pk);
  348. return ret;
  349. }
  350. #endif
  351. void
  352. lws_x509_destroy(struct lws_x509_cert **x509)
  353. {
  354. if (!*x509)
  355. return;
  356. mbedtls_x509_crt_free(&(*x509)->cert);
  357. lws_free_set_NULL(*x509);
  358. }