ssl.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. #define HL_NAME(n) ssl_##n
  2. #define _WINSOCKAPI_
  3. #include <hl.h>
  4. #ifdef HL_WIN
  5. #include <winsock2.h>
  6. #include <wincrypt.h>
  7. #else
  8. #include <sys/socket.h>
  9. #include <strings.h>
  10. #include <errno.h>
  11. typedef int SOCKET;
  12. #endif
  13. #include <stdio.h>
  14. #include <string.h>
  15. #ifdef HL_MAC
  16. #include <Security/Security.h>
  17. #endif
  18. #define SOCKET_ERROR (-1)
  19. #define NRETRYS 20
  20. #include "mbedtls/platform.h"
  21. #include "mbedtls/error.h"
  22. #include "mbedtls/entropy.h"
  23. #include "mbedtls/ctr_drbg.h"
  24. #include "mbedtls/md.h"
  25. #include "mbedtls/pk.h"
  26. #include "mbedtls/oid.h"
  27. #include "mbedtls/x509_crt.h"
  28. #include "mbedtls/ssl.h"
  29. // Duplicate from socket.c
  30. typedef struct _hl_socket {
  31. SOCKET sock;
  32. } hl_socket;
  33. typedef struct _hl_ssl_cert hl_ssl_cert;
  34. struct _hl_ssl_cert {
  35. void(*finalize)(hl_ssl_cert *);
  36. mbedtls_x509_crt *c;
  37. };
  38. typedef struct _hl_ssl_pkey hl_ssl_pkey;
  39. struct _hl_ssl_pkey {
  40. void(*finalize)(hl_ssl_pkey *);
  41. mbedtls_pk_context *k;
  42. };
  43. #define _SOCK _ABSTRACT(hl_socket)
  44. #define TSSL _ABSTRACT(mbedtls_ssl_context)
  45. #define TCONF _ABSTRACT(mbedtls_ssl_config)
  46. #define TCERT _ABSTRACT(hl_ssl_cert)
  47. #define TPKEY _ABSTRACT(hl_ssl_pkey)
  48. static bool ssl_init_done = false;
  49. static mbedtls_entropy_context entropy;
  50. static mbedtls_ctr_drbg_context ctr_drbg;
  51. static void cert_finalize(hl_ssl_cert *c) {
  52. mbedtls_x509_crt_free(c->c);
  53. free(c->c);
  54. c->c = NULL;
  55. }
  56. static void pkey_finalize(hl_ssl_pkey *k) {
  57. mbedtls_pk_free(k->k);
  58. free(k->k);
  59. k->k = NULL;
  60. }
  61. static int block_error() {
  62. #ifdef HL_WIN
  63. int err = WSAGetLastError();
  64. if (err == WSAEWOULDBLOCK || err == WSAEALREADY || err == WSAETIMEDOUT)
  65. #else
  66. if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS || errno == EALREADY)
  67. #endif
  68. return -1;
  69. return -2;
  70. }
  71. static int ssl_error(int ret) {
  72. char buf[128];
  73. uchar buf16[128];
  74. mbedtls_strerror(ret, buf, sizeof(buf));
  75. hl_from_utf8(buf16, (int)strlen(buf), buf);
  76. hl_error("%s",buf16);
  77. return ret;
  78. }
  79. HL_PRIM mbedtls_ssl_context *HL_NAME(ssl_new)(mbedtls_ssl_config *config) {
  80. int ret;
  81. mbedtls_ssl_context *ssl;
  82. ssl = (mbedtls_ssl_context *)hl_gc_alloc_noptr(sizeof(mbedtls_ssl_context));
  83. mbedtls_ssl_init(ssl);
  84. if ((ret = mbedtls_ssl_setup(ssl, config)) != 0) {
  85. mbedtls_ssl_free(ssl);
  86. ssl_error(ret);
  87. return NULL;
  88. }
  89. return ssl;
  90. }
  91. HL_PRIM void HL_NAME(ssl_close)(mbedtls_ssl_context *ssl) {
  92. mbedtls_ssl_free(ssl);
  93. }
  94. HL_PRIM int HL_NAME(ssl_handshake)(mbedtls_ssl_context *ssl) {
  95. int r;
  96. r = mbedtls_ssl_handshake(ssl);
  97. if (r == SOCKET_ERROR)
  98. return block_error();
  99. else if (r != 0)
  100. return ssl_error(r);
  101. return 0;
  102. }
  103. int net_read(void *fd, unsigned char *buf, size_t len) {
  104. return recv((SOCKET)(int_val)fd, (char *)buf, (int)len, 0);
  105. }
  106. int net_write(void *fd, const unsigned char *buf, size_t len) {
  107. return send((SOCKET)(int_val)fd, (char *)buf, (int)len, 0);
  108. }
  109. HL_PRIM void HL_NAME(ssl_set_socket)(mbedtls_ssl_context *ssl, hl_socket *socket) {
  110. mbedtls_ssl_set_bio(ssl, (void*)(int_val)socket->sock, net_write, net_read, NULL);
  111. }
  112. HL_PRIM void HL_NAME(ssl_set_hostname)(mbedtls_ssl_context *ssl, vbyte *hostname) {
  113. int ret;
  114. if ((ret = mbedtls_ssl_set_hostname(ssl, (char*)hostname)) != 0)
  115. ssl_error(ret);
  116. }
  117. HL_PRIM hl_ssl_cert *HL_NAME(ssl_get_peer_certificate)(mbedtls_ssl_context *ssl) {
  118. hl_ssl_cert *cert = (hl_ssl_cert*)hl_gc_alloc_noptr(sizeof(hl_ssl_cert));
  119. cert->c = (mbedtls_x509_crt*)mbedtls_ssl_get_peer_cert(ssl);
  120. return cert;
  121. }
  122. DEFINE_PRIM(TSSL, ssl_new, TCONF);
  123. DEFINE_PRIM(_VOID, ssl_close, TSSL);
  124. DEFINE_PRIM(_I32, ssl_handshake, TSSL);
  125. DEFINE_PRIM(_VOID, ssl_set_socket, TSSL _SOCK);
  126. DEFINE_PRIM(_VOID, ssl_set_hostname, TSSL _BYTES);
  127. DEFINE_PRIM(TCERT, ssl_get_peer_certificate, TSSL);
  128. HL_PRIM int HL_NAME(ssl_send_char)(mbedtls_ssl_context *ssl, int c) {
  129. unsigned char cc;
  130. cc = (unsigned char)c;
  131. if (mbedtls_ssl_write(ssl, &cc, 1) == SOCKET_ERROR)
  132. return block_error();
  133. return 1;
  134. }
  135. HL_PRIM int HL_NAME(ssl_send)(mbedtls_ssl_context *ssl, vbyte *buf, int pos, int len) {
  136. int r = mbedtls_ssl_write(ssl, (const unsigned char *)buf + pos, len);
  137. if (r == SOCKET_ERROR)
  138. return block_error();
  139. return r;
  140. }
  141. HL_PRIM int HL_NAME(ssl_recv_char)(mbedtls_ssl_context *ssl) {
  142. unsigned char c;
  143. int ret = mbedtls_ssl_read(ssl, &c, 1);
  144. if (ret == SOCKET_ERROR || ret == 0 || ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
  145. return block_error();
  146. return c;
  147. }
  148. HL_PRIM int HL_NAME(ssl_recv)(mbedtls_ssl_context *ssl, vbyte *buf, int pos, int len) {
  149. int ret = mbedtls_ssl_read(ssl, (unsigned char*)buf+pos, len);
  150. if (ret == SOCKET_ERROR)
  151. return block_error();
  152. else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
  153. return 0;
  154. return ret;
  155. }
  156. DEFINE_PRIM(_I32, ssl_send_char, TSSL _I32);
  157. DEFINE_PRIM(_I32, ssl_send, TSSL _BYTES _I32 _I32);
  158. DEFINE_PRIM(_I32, ssl_recv_char, TSSL);
  159. DEFINE_PRIM(_I32, ssl_recv, TSSL _BYTES _I32 _I32);
  160. HL_PRIM mbedtls_ssl_config *HL_NAME(conf_new)(bool server) {
  161. int ret;
  162. mbedtls_ssl_config *conf;
  163. conf = (mbedtls_ssl_config *)hl_gc_alloc_noptr(sizeof(mbedtls_ssl_config));
  164. mbedtls_ssl_config_init(conf);
  165. if ((ret = mbedtls_ssl_config_defaults(conf, server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
  166. MBEDTLS_SSL_TRANSPORT_STREAM, 0)) != 0) {
  167. mbedtls_ssl_config_free(conf);
  168. ssl_error(ret);
  169. return NULL;
  170. }
  171. mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &ctr_drbg);
  172. return conf;
  173. }
  174. HL_PRIM void HL_NAME(conf_close)(mbedtls_ssl_config *conf) {
  175. mbedtls_ssl_config_free(conf);
  176. }
  177. HL_PRIM void HL_NAME(conf_set_ca)(mbedtls_ssl_config *conf, hl_ssl_cert *cert) {
  178. mbedtls_ssl_conf_ca_chain(conf, cert->c, NULL);
  179. }
  180. HL_PRIM void HL_NAME(conf_set_verify)(mbedtls_ssl_config *conf, int mode) {
  181. if (mode == 2)
  182. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
  183. else if (mode == 1)
  184. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  185. else
  186. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
  187. }
  188. HL_PRIM void HL_NAME(conf_set_cert)(mbedtls_ssl_config *conf, hl_ssl_cert *cert, hl_ssl_pkey *key) {
  189. int r;
  190. if ((r = mbedtls_ssl_conf_own_cert(conf, cert->c, key->k)) != 0)
  191. ssl_error(r);
  192. }
  193. typedef struct {
  194. hl_type *t;
  195. hl_ssl_cert *cert;
  196. hl_ssl_pkey *key;
  197. } sni_callb_ret;
  198. static int sni_callback(void *arg, mbedtls_ssl_context *ctx, const unsigned char *name, size_t len) {
  199. if (name && arg) {
  200. vclosure *c = (vclosure*)arg;
  201. sni_callb_ret *ret;
  202. if( c->hasValue )
  203. ret = ((sni_callb_ret*(*)(void*, vbyte*))c->fun)(c->value, (vbyte*)name);
  204. else
  205. ret = ((sni_callb_ret*(*)(vbyte*))c->fun)((vbyte*)name);
  206. if (ret && ret->cert && ret->key) {
  207. return mbedtls_ssl_set_hs_own_cert(ctx, ret->cert->c, ret->key->k);
  208. }
  209. }
  210. return -1;
  211. }
  212. HL_PRIM void HL_NAME(conf_set_servername_callback)(mbedtls_ssl_config *conf, vclosure *cb) {
  213. mbedtls_ssl_conf_sni(conf, sni_callback, (void *)cb);
  214. }
  215. DEFINE_PRIM(TCONF, conf_new, _BOOL);
  216. DEFINE_PRIM(_VOID, conf_close, TCONF);
  217. DEFINE_PRIM(_VOID, conf_set_ca, TCONF TCERT);
  218. DEFINE_PRIM(_VOID, conf_set_verify, TCONF _I32);
  219. DEFINE_PRIM(_VOID, conf_set_cert, TCONF TCERT TPKEY);
  220. DEFINE_PRIM(_VOID, conf_set_servername_callback, TCONF _FUN(_OBJ(TCERT TPKEY), _BYTES));
  221. HL_PRIM hl_ssl_cert *HL_NAME(cert_load_file)(vbyte *file) {
  222. int r;
  223. hl_ssl_cert *cert;
  224. mbedtls_x509_crt *x = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  225. mbedtls_x509_crt_init(x);
  226. if ((r = mbedtls_x509_crt_parse_file(x, (char*)file)) != 0) {
  227. mbedtls_x509_crt_free(x);
  228. free(x);
  229. ssl_error(r);
  230. return NULL;
  231. }
  232. cert = (hl_ssl_cert*)hl_gc_alloc_finalizer(sizeof(hl_ssl_cert));
  233. cert->c = x;
  234. cert->finalize = cert_finalize;
  235. return cert;
  236. }
  237. HL_PRIM hl_ssl_cert *HL_NAME(cert_load_path)(vbyte *path) {
  238. int r;
  239. hl_ssl_cert *cert;
  240. mbedtls_x509_crt *x = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  241. mbedtls_x509_crt_init(x);
  242. if ((r = mbedtls_x509_crt_parse_path(x, (char*)path)) != 0) {
  243. mbedtls_x509_crt_free(x);
  244. free(x);
  245. ssl_error(r);
  246. return NULL;
  247. }
  248. cert = (hl_ssl_cert*)hl_gc_alloc_finalizer(sizeof(hl_ssl_cert));
  249. cert->c = x;
  250. cert->finalize = cert_finalize;
  251. return cert;
  252. }
  253. HL_PRIM hl_ssl_cert *HL_NAME(cert_load_defaults)() {
  254. hl_ssl_cert *v = NULL;
  255. mbedtls_x509_crt *chain = NULL;
  256. #if defined(HL_WIN)
  257. HCERTSTORE store;
  258. PCCERT_CONTEXT cert;
  259. if (store = CertOpenSystemStore(0, (LPCWSTR)L"Root")) {
  260. cert = NULL;
  261. while (cert = CertEnumCertificatesInStore(store, cert)) {
  262. if (chain == NULL) {
  263. chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  264. mbedtls_x509_crt_init(chain);
  265. }
  266. mbedtls_x509_crt_parse_der(chain, (unsigned char *)cert->pbCertEncoded, cert->cbCertEncoded);
  267. }
  268. CertCloseStore(store, 0);
  269. }
  270. #elif defined(HL_MAC)
  271. CFMutableDictionaryRef search;
  272. CFArrayRef result;
  273. SecKeychainRef keychain;
  274. SecCertificateRef item;
  275. CFDataRef dat;
  276. // Load keychain
  277. if (SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain", &keychain) != errSecSuccess)
  278. return NULL;
  279. // Search for certificates
  280. search = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
  281. CFDictionarySetValue(search, kSecClass, kSecClassCertificate);
  282. CFDictionarySetValue(search, kSecMatchLimit, kSecMatchLimitAll);
  283. CFDictionarySetValue(search, kSecReturnRef, kCFBooleanTrue);
  284. CFDictionarySetValue(search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL));
  285. if (SecItemCopyMatching(search, (CFTypeRef *)&result) == errSecSuccess) {
  286. CFIndex n = CFArrayGetCount(result);
  287. for (CFIndex i = 0; i < n; i++) {
  288. item = (SecCertificateRef)CFArrayGetValueAtIndex(result, i);
  289. // Get certificate in DER format
  290. dat = SecCertificateCopyData(item);
  291. if (dat) {
  292. if (chain == NULL) {
  293. chain = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  294. mbedtls_x509_crt_init(chain);
  295. }
  296. mbedtls_x509_crt_parse_der(chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat));
  297. CFRelease(dat);
  298. }
  299. }
  300. }
  301. CFRelease(keychain);
  302. #endif
  303. if (chain != NULL) {
  304. v = (hl_ssl_cert*)hl_gc_alloc_finalizer(sizeof(hl_ssl_cert));
  305. v->c = chain;
  306. v->finalize = cert_finalize;
  307. }
  308. return v;
  309. }
  310. static vbyte *asn1_buf_to_string(mbedtls_asn1_buf *dat) {
  311. unsigned int i, c;
  312. hl_buffer *buf = hl_alloc_buffer();
  313. for (i = 0; i < dat->len; i++) {
  314. c = dat->p[i];
  315. if (c < 32 || c == 127 || (c > 128 && c < 160))
  316. hl_buffer_char(buf, '?');
  317. else
  318. hl_buffer_char(buf, c);
  319. }
  320. return (vbyte*)hl_buffer_content(buf,NULL);
  321. }
  322. HL_PRIM vbyte *HL_NAME(cert_get_subject)(hl_ssl_cert *cert, vbyte *objname) {
  323. mbedtls_x509_name *obj;
  324. int r;
  325. const char *oname, *rname;
  326. obj = &cert->c->subject;
  327. if (obj == NULL)
  328. hl_error("Invalid subject");
  329. rname = (char*)objname;
  330. while (obj != NULL) {
  331. r = mbedtls_oid_get_attr_short_name(&obj->oid, &oname);
  332. if (r == 0 && strcmp(oname, rname) == 0)
  333. return asn1_buf_to_string(&obj->val);
  334. obj = obj->next;
  335. }
  336. return NULL;
  337. }
  338. HL_PRIM vbyte *HL_NAME(cert_get_issuer)(hl_ssl_cert *cert, vbyte *objname) {
  339. mbedtls_x509_name *obj;
  340. int r;
  341. const char *oname, *rname;
  342. obj = &cert->c->issuer;
  343. if (obj == NULL)
  344. hl_error("Invalid issuer");
  345. rname = (char*)objname;
  346. while (obj != NULL) {
  347. r = mbedtls_oid_get_attr_short_name(&obj->oid, &oname);
  348. if (r == 0 && strcmp(oname, rname) == 0)
  349. return asn1_buf_to_string(&obj->val);
  350. obj = obj->next;
  351. }
  352. return NULL;
  353. }
  354. HL_PRIM varray *HL_NAME(cert_get_altnames)(hl_ssl_cert *cert) {
  355. mbedtls_asn1_sequence *cur;
  356. int count = 0;
  357. int pos = 0;
  358. varray *a = NULL;
  359. vbyte **current = NULL;
  360. mbedtls_x509_crt *crt = cert->c;
  361. if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
  362. cur = &crt->subject_alt_names;
  363. while (cur != NULL) {
  364. if (pos == count) {
  365. int ncount = count == 0 ? 16 : count * 2;
  366. varray *narr = hl_alloc_array(&hlt_bytes, ncount);
  367. vbyte **ncur = hl_aptr(narr, vbyte*);
  368. memcpy(ncur, current, count * sizeof(void*));
  369. current = ncur;
  370. a = narr;
  371. count = ncount;
  372. }
  373. current[pos++] = asn1_buf_to_string(&cur->buf);
  374. cur = cur->next;
  375. }
  376. }
  377. if (a == NULL) a = hl_alloc_array(&hlt_bytes, 0);
  378. a->size = pos;
  379. return a;
  380. }
  381. static varray *x509_time_to_array(mbedtls_x509_time *t) {
  382. varray *a = NULL;
  383. int *p;
  384. if (!t)
  385. hl_error("Invalid x509 time");
  386. a = hl_alloc_array(&hlt_i32, 6);
  387. p = hl_aptr(a, int);
  388. p[0] = t->year;
  389. p[1] = t->mon;
  390. p[2] = t->day;
  391. p[3] = t->hour;
  392. p[4] = t->min;
  393. p[5] = t->sec;
  394. return a;
  395. }
  396. HL_PRIM varray *HL_NAME(cert_get_notbefore)(hl_ssl_cert *cert) {
  397. return x509_time_to_array(&cert->c->valid_from);
  398. }
  399. HL_PRIM varray *HL_NAME(cert_get_notafter)(hl_ssl_cert *cert) {
  400. return x509_time_to_array(&cert->c->valid_to);
  401. }
  402. HL_PRIM hl_ssl_cert *HL_NAME(cert_get_next)(hl_ssl_cert *cert) {
  403. hl_ssl_cert *ncert;
  404. if (cert->c->next == NULL)
  405. return NULL;
  406. ncert = (hl_ssl_cert*)hl_gc_alloc_noptr(sizeof(hl_ssl_cert));
  407. ncert->c = cert->c->next;
  408. return ncert;
  409. }
  410. HL_PRIM hl_ssl_cert *HL_NAME(cert_add_pem)(hl_ssl_cert *cert, vbyte *data) {
  411. mbedtls_x509_crt *crt;
  412. int r, len;
  413. unsigned char *buf;
  414. if (cert != NULL)
  415. crt = cert->c;
  416. else{
  417. crt = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  418. mbedtls_x509_crt_init(crt);
  419. }
  420. len = (int)strlen((char*)data) + 1;
  421. buf = (unsigned char *)malloc(len);
  422. memcpy(buf, (char*)data, len - 1);
  423. buf[len - 1] = '\0';
  424. r = mbedtls_x509_crt_parse(crt, buf, len);
  425. free(buf);
  426. if (r < 0) {
  427. if (cert == NULL) {
  428. mbedtls_x509_crt_free(crt);
  429. free(crt);
  430. }
  431. ssl_error(r);
  432. return NULL;
  433. }
  434. if (cert == NULL) {
  435. cert = (hl_ssl_cert*)hl_gc_alloc_finalizer(sizeof(hl_ssl_cert));
  436. cert->c = crt;
  437. cert->finalize = cert_finalize;
  438. }
  439. return cert;
  440. }
  441. HL_PRIM hl_ssl_cert *HL_NAME(cert_add_der)(hl_ssl_cert *cert, vbyte *data, int len) {
  442. mbedtls_x509_crt *crt;
  443. int r;
  444. if (cert != NULL)
  445. crt = cert->c;
  446. else {
  447. crt = (mbedtls_x509_crt*)malloc(sizeof(mbedtls_x509_crt));
  448. mbedtls_x509_crt_init(crt);
  449. }
  450. if ((r = mbedtls_x509_crt_parse_der(crt, (const unsigned char*)data, len)) < 0) {
  451. if (cert == NULL) {
  452. mbedtls_x509_crt_free(crt);
  453. free(crt);
  454. }
  455. ssl_error(r);
  456. return NULL;
  457. }
  458. if (cert == NULL) {
  459. cert = (hl_ssl_cert*)hl_gc_alloc_finalizer(sizeof(hl_ssl_cert));
  460. cert->c = crt;
  461. cert->finalize = cert_finalize;
  462. }
  463. return cert;
  464. }
  465. DEFINE_PRIM(TCERT, cert_load_defaults, _NO_ARG);
  466. DEFINE_PRIM(TCERT, cert_load_file, _BYTES);
  467. DEFINE_PRIM(TCERT, cert_load_path, _BYTES);
  468. DEFINE_PRIM(_BYTES, cert_get_subject, TCERT _BYTES);
  469. DEFINE_PRIM(_BYTES, cert_get_issuer, TCERT _BYTES);
  470. DEFINE_PRIM(_ARR, cert_get_altnames, TCERT);
  471. DEFINE_PRIM(_ARR, cert_get_notbefore, TCERT);
  472. DEFINE_PRIM(_ARR, cert_get_notafter, TCERT);
  473. DEFINE_PRIM(TCERT, cert_get_next, TCERT);
  474. DEFINE_PRIM(TCERT, cert_add_pem, TCERT _BYTES);
  475. DEFINE_PRIM(TCERT, cert_add_der, TCERT _BYTES _I32);
  476. HL_PRIM hl_ssl_pkey *HL_NAME(key_from_der)(vbyte *data, int len, bool pub) {
  477. int r;
  478. hl_ssl_pkey *key;
  479. mbedtls_pk_context *pk = (mbedtls_pk_context *)malloc(sizeof(mbedtls_pk_context));
  480. mbedtls_pk_init(pk);
  481. if (pub)
  482. r = mbedtls_pk_parse_public_key(pk, (const unsigned char*)data, len);
  483. else
  484. r = mbedtls_pk_parse_key(pk, (const unsigned char*)data, len, NULL, 0);
  485. if (r != 0) {
  486. mbedtls_pk_free(pk);
  487. free(pk);
  488. ssl_error(r);
  489. return NULL;
  490. }
  491. key = (hl_ssl_pkey*)hl_gc_alloc_finalizer(sizeof(hl_ssl_pkey));
  492. key->k = pk;
  493. key->finalize = pkey_finalize;
  494. return key;
  495. }
  496. HL_PRIM hl_ssl_pkey *HL_NAME(key_from_pem)(vbyte *data, bool pub, vbyte *pass) {
  497. int r, len;
  498. hl_ssl_pkey *key;
  499. unsigned char *buf;
  500. mbedtls_pk_context *pk = (mbedtls_pk_context *)malloc(sizeof(mbedtls_pk_context));
  501. mbedtls_pk_init(pk);
  502. len = (int)strlen((char*)data) + 1;
  503. buf = (unsigned char *)malloc(len);
  504. memcpy(buf, (char*)data, len - 1);
  505. buf[len - 1] = '\0';
  506. if (pub)
  507. r = mbedtls_pk_parse_public_key(pk, buf, len);
  508. else if (pass == NULL)
  509. r = mbedtls_pk_parse_key(pk, buf, len, NULL, 0);
  510. else
  511. r = mbedtls_pk_parse_key(pk, buf, len, (const unsigned char*)pass, strlen((char*)pass));
  512. free(buf);
  513. if (r != 0) {
  514. mbedtls_pk_free(pk);
  515. free(pk);
  516. ssl_error(r);
  517. return NULL;
  518. }
  519. key = (hl_ssl_pkey*)hl_gc_alloc_finalizer(sizeof(hl_ssl_pkey));
  520. key->k = pk;
  521. key->finalize = pkey_finalize;
  522. return key;
  523. }
  524. DEFINE_PRIM(TPKEY, key_from_der, _BYTES _I32 _BOOL);
  525. DEFINE_PRIM(TPKEY, key_from_pem, _BYTES _BOOL _BYTES);
  526. HL_PRIM vbyte *HL_NAME(dgst_make)(vbyte *data, int len, vbyte *alg, int *size) {
  527. const mbedtls_md_info_t *md;
  528. int mdlen, r = -1;
  529. vbyte *out;
  530. md = mbedtls_md_info_from_string((char*)alg);
  531. if (md == NULL) {
  532. hl_error("Invalid hash algorithm");
  533. return NULL;
  534. }
  535. mdlen = mbedtls_md_get_size(md);
  536. *size = mdlen;
  537. out = hl_gc_alloc_noptr(mdlen);
  538. if ((r = mbedtls_md(md, (const unsigned char *)data, len, out)) != 0){
  539. ssl_error(r);
  540. return NULL;
  541. }
  542. return out;
  543. }
  544. HL_PRIM vbyte *HL_NAME(dgst_sign)(vbyte *data, int len, hl_ssl_pkey *key, vbyte *alg, int *size) {
  545. const mbedtls_md_info_t *md;
  546. int r = -1;
  547. vbyte *out;
  548. unsigned char hash[MBEDTLS_MD_MAX_SIZE];
  549. size_t ssize = size ? *size : 0;
  550. md = mbedtls_md_info_from_string((char*)alg);
  551. if (md == NULL) {
  552. hl_error("Invalid hash algorithm");
  553. return NULL;
  554. }
  555. if ((r = mbedtls_md(md, (unsigned char *)data, len, hash)) != 0){
  556. ssl_error(r);
  557. return NULL;
  558. }
  559. out = hl_gc_alloc_noptr(MBEDTLS_MPI_MAX_SIZE);
  560. if ((r = mbedtls_pk_sign(key->k, mbedtls_md_get_type(md), hash, 0, out, (size ? &ssize : NULL), mbedtls_ctr_drbg_random, &ctr_drbg)) != 0){
  561. ssl_error(r);
  562. return NULL;
  563. }
  564. if( size ) *size = (int)ssize;
  565. return out;
  566. }
  567. HL_PRIM bool HL_NAME(dgst_verify)(vbyte *data, int dlen, vbyte *sign, int slen, hl_ssl_pkey *key, vbyte *alg) {
  568. const mbedtls_md_info_t *md;
  569. int r = -1;
  570. unsigned char hash[MBEDTLS_MD_MAX_SIZE];
  571. md = mbedtls_md_info_from_string((char*)alg);
  572. if (md == NULL) {
  573. hl_error("Invalid hash algorithm");
  574. return false;
  575. }
  576. if ((r = mbedtls_md(md, (const unsigned char *)data, dlen, hash)) != 0)
  577. return ssl_error(r);
  578. if ((r = mbedtls_pk_verify(key->k, mbedtls_md_get_type(md), hash, 0, (unsigned char *)sign, slen)) != 0)
  579. return false;
  580. return true;
  581. }
  582. DEFINE_PRIM(_BYTES, dgst_make, _BYTES _I32 _BYTES _REF(_I32));
  583. DEFINE_PRIM(_BYTES, dgst_sign, _BYTES _I32 TPKEY _BYTES _REF(_I32));
  584. DEFINE_PRIM(_BOOL, dgst_verify, _BYTES _I32 _BYTES _I32 TPKEY _BYTES);
  585. #if _MSC_VER
  586. static void threading_mutex_init_alt(mbedtls_threading_mutex_t *mutex) {
  587. if (mutex == NULL)
  588. return;
  589. InitializeCriticalSection(&mutex->cs);
  590. mutex->is_valid = 1;
  591. }
  592. static void threading_mutex_free_alt(mbedtls_threading_mutex_t *mutex) {
  593. if (mutex == NULL || !mutex->is_valid)
  594. return;
  595. DeleteCriticalSection(&mutex->cs);
  596. mutex->is_valid = 0;
  597. }
  598. static int threading_mutex_lock_alt(mbedtls_threading_mutex_t *mutex) {
  599. if (mutex == NULL || !mutex->is_valid)
  600. return(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA);
  601. EnterCriticalSection(&mutex->cs);
  602. return(0);
  603. }
  604. static int threading_mutex_unlock_alt(mbedtls_threading_mutex_t *mutex) {
  605. if (mutex == NULL || !mutex->is_valid)
  606. return(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA);
  607. LeaveCriticalSection(&mutex->cs);
  608. return(0);
  609. }
  610. #endif
  611. HL_PRIM void HL_NAME(ssl_init)() {
  612. if (ssl_init_done)
  613. return;
  614. ssl_init_done = true;
  615. #if _MSC_VER
  616. mbedtls_threading_set_alt(threading_mutex_init_alt, threading_mutex_free_alt,
  617. threading_mutex_lock_alt, threading_mutex_unlock_alt);
  618. #endif
  619. // Init RNG
  620. mbedtls_entropy_init(&entropy);
  621. mbedtls_ctr_drbg_init(&ctr_drbg);
  622. mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
  623. }
  624. DEFINE_PRIM(_VOID, ssl_init, _NO_ARG);