sq_openssl.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. #ifdef USE_OPENSSL
  2. #ifdef __cplusplus
  3. extern "C" {
  4. #endif
  5. #include "squirrel.h"
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <stdlib.h> /* for malloc */
  9. #include <assert.h> /* for a few sanity tests */
  10. #include "ssl.h"
  11. static const SQChar SQ_LIBNAME[] = _SC("openssl");
  12. static const SQChar ssl_ctx_NAME[] = _SC("ssl_ctx");
  13. static const SQChar ssl_NAME[] = _SC("ssl");
  14. SQ_OPT_STRING_STRLEN();
  15. static const SQChar SSL_CTX_Tag[] = _SC("sq_openssl_ssl_ctx");
  16. #define GET_ssl_ctx_INSTANCE() SQ_GET_INSTANCE(v, 1, SSL_CTX, SSL_CTX_Tag) \
  17. if(self == NULL) return sq_throwerror(v, _SC("ssl_ctx object already closed"));
  18. static const SQChar SSL_Tag[] = _SC("sq_openssl_ssl");
  19. #define GET_ssl_INSTANCE() SQ_GET_INSTANCE(v, 1, SSL, SSL_Tag) \
  20. if(self == NULL) return sq_throwerror(v, _SC("ssl object already closed"));
  21. static SQRESULT ssl_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
  22. {
  23. SSL *self = (SSL*)p;
  24. if(self) ssl_free(self);
  25. return 0;
  26. }
  27. static SQRESULT sq_ssl_free(HSQUIRRELVM v)
  28. {
  29. SQ_FUNC_VARS_NO_TOP(v);
  30. GET_ssl_INSTANCE();
  31. ssl_release_hook(self, 0, v);
  32. sq_setinstanceup(v, 1, 0);
  33. return 0;
  34. }
  35. static SQRESULT ssl_constructor(HSQUIRRELVM v, SSL *ssl, int free_on_gc)
  36. {
  37. if(!ssl)
  38. return sq_throwerror(v, _SC("Could'nt create an ssl object."));
  39. sq_pushstring(v, SQ_LIBNAME, -1);
  40. if(sq_getonroottable(v) == SQ_OK){
  41. sq_pushstring(v, ssl_NAME, -1);
  42. if(sq_get(v, -2) == SQ_OK){
  43. if(sq_createinstance(v, -1) == SQ_OK){
  44. sq_setinstanceup(v, -1, ssl);
  45. if(free_on_gc) sq_setreleasehook(v,-1, ssl_release_hook);
  46. return 1;
  47. }
  48. }
  49. }
  50. return SQ_ERROR;
  51. }
  52. static SQRESULT sq_ssl_read(HSQUIRRELVM v){
  53. SQ_FUNC_VARS(v);
  54. GET_ssl_INSTANCE();
  55. SQ_OPT_INTEGER(v, 2, count, 0);
  56. uint8_t *in_data;
  57. int result = ssl_read(self, &in_data, count);
  58. if (result > SSL_OK) sq_pushstring(v, (const SQChar*)in_data, result);
  59. else sq_pushinteger(v, result);
  60. return 1;
  61. }
  62. static SQRESULT sq_ssl_write(HSQUIRRELVM v){
  63. SQ_FUNC_VARS(v);
  64. GET_ssl_INSTANCE();
  65. SQ_GET_STRING(v, 2, out_data);
  66. if(_top_ > 2) {
  67. SQ_GET_INTEGER(v, 3, size);
  68. if(size > out_data_size) return sq_throwerror(v, _SC("parameter 2 size bigger than data size"));
  69. out_data_size = size;
  70. }
  71. sq_pushinteger(v, ssl_write(self, (const uint8_t *)out_data, out_data_size));
  72. return 1;
  73. }
  74. static SQRESULT sq_ssl_get_session_id(HSQUIRRELVM v){
  75. SQ_FUNC_VARS_NO_TOP(v);
  76. GET_ssl_INSTANCE();
  77. const uint8_t * result = ssl_get_session_id(self);
  78. sq_pushstring(v, (char *)result, ssl_get_session_id_size(self));
  79. return 1;
  80. }
  81. static SQRESULT sq_ssl_get_session_id_size(HSQUIRRELVM v){
  82. SQ_FUNC_VARS_NO_TOP(v);
  83. GET_ssl_INSTANCE();
  84. uint8_t result = ssl_get_session_id_size(self);
  85. sq_pushinteger(v, result);
  86. return 1;
  87. }
  88. static SQRESULT sq_ssl_get_cipher_id(HSQUIRRELVM v){
  89. SQ_FUNC_VARS_NO_TOP(v);
  90. GET_ssl_INSTANCE();
  91. uint8_t result = ssl_get_cipher_id(self);
  92. sq_pushinteger(v, result);
  93. return 1;
  94. }
  95. static SQRESULT sq_ssl_handshake_status(HSQUIRRELVM v){
  96. SQ_FUNC_VARS_NO_TOP(v);
  97. GET_ssl_INSTANCE();
  98. int result = ssl_handshake_status(self);
  99. sq_pushinteger(v, result);
  100. return 1;
  101. }
  102. static SQRESULT sq_ssl_verify_cert(HSQUIRRELVM v){
  103. SQ_FUNC_VARS_NO_TOP(v);
  104. GET_ssl_INSTANCE();
  105. int result = ssl_verify_cert(self);
  106. sq_pushinteger(v, result);
  107. return 1;
  108. }
  109. static SQRESULT sq_ssl_get_cert_dn(HSQUIRRELVM v){
  110. SQ_FUNC_VARS_NO_TOP(v);
  111. GET_ssl_INSTANCE();
  112. SQ_GET_INTEGER(v, 2, component);
  113. const char* result = ssl_get_cert_dn(self, component);
  114. sq_pushstring(v, result, -1);
  115. return 1;
  116. }
  117. static SQRESULT sq_ssl_get_cert_subject_alt_dnsname(HSQUIRRELVM v){
  118. SQ_FUNC_VARS_NO_TOP(v);
  119. GET_ssl_INSTANCE();
  120. SQ_GET_INTEGER(v, 2, dnsindex);
  121. const char* result = ssl_get_cert_subject_alt_dnsname(self, dnsindex);
  122. sq_pushstring(v, result, -1);
  123. return 1;
  124. }
  125. static SQRESULT sq_ssl_renegotiate(HSQUIRRELVM v){
  126. SQ_FUNC_VARS_NO_TOP(v);
  127. GET_ssl_INSTANCE();
  128. int result = ssl_renegotiate(self);
  129. sq_pushinteger(v, result);
  130. return 1;
  131. }
  132. static SQRESULT sq_ssl_ctx_server_new(HSQUIRRELVM v){
  133. SQ_FUNC_VARS_NO_TOP(v);
  134. GET_ssl_ctx_INSTANCE();
  135. SQ_GET_INTEGER(v, 2, client_fd);
  136. SSL *ssl = ssl_server_new(self, client_fd);
  137. SQRESULT rc = ssl_constructor(v, ssl, 1);
  138. if(rc == SQ_ERROR && ssl){
  139. ssl_free(ssl);
  140. }
  141. return rc;
  142. }
  143. static SQRESULT sq_ssl_ctx_client_new(HSQUIRRELVM v){
  144. SQ_FUNC_VARS(v);
  145. GET_ssl_ctx_INSTANCE();
  146. SQ_GET_INTEGER(v, 2, client_fd);
  147. SQ_OPT_STRING(v, 3, session_id, NULL);
  148. SQ_OPT_INTEGER(v, 4, size, -1);
  149. SSL *ssl = ssl_client_new(self, client_fd, (const uint8_t *)session_id,
  150. size >= 0 ? size : session_id_size);
  151. SQRESULT rc = ssl_constructor(v, ssl, 1);
  152. if(rc == SQ_ERROR && ssl){
  153. ssl_free(ssl);
  154. }
  155. return rc;
  156. }
  157. static SQRESULT sq_ssl_ctx_find(HSQUIRRELVM v){
  158. SQ_FUNC_VARS_NO_TOP(v);
  159. GET_ssl_ctx_INSTANCE();
  160. SQ_GET_INTEGER(v, 2, client_fd);
  161. SSL *ssl = ssl_find(self, client_fd);
  162. if(ssl) return ssl_constructor(v, ssl, 0);
  163. else sq_pushnull(v);
  164. return 1;
  165. }
  166. static SQRESULT sq_ssl_ctx_obj_load(HSQUIRRELVM v){
  167. SQ_FUNC_VARS_NO_TOP(v);
  168. GET_ssl_ctx_INSTANCE();
  169. SQ_GET_INTEGER(v, 2, obj_type);
  170. SQ_GET_STRING(v, 3, filename);
  171. SQ_GET_STRING(v, 4, password);
  172. int result = ssl_obj_load(self, obj_type, filename, password);
  173. sq_pushinteger(v, result);
  174. return 1;
  175. }
  176. static SQRESULT sq_ssl_ctx_obj_memory_load(HSQUIRRELVM v){
  177. SQ_FUNC_VARS_NO_TOP(v);
  178. GET_ssl_ctx_INSTANCE();
  179. SQ_GET_INTEGER(v, 2, obj_type);
  180. SQ_GET_STRING(v, 3, data);
  181. SQ_GET_STRING(v, 4, password);
  182. int result = ssl_obj_memory_load(self, obj_type, (const uint8_t *)data, data_size, password);
  183. sq_pushinteger(v, result);
  184. return 1;
  185. }
  186. static SQRESULT sq_openssl_version(HSQUIRRELVM v){
  187. sq_pushstring(v,(const char*)ssl_version(), -1);
  188. return 1;
  189. }
  190. static SQRESULT sq_openssl_get_config(HSQUIRRELVM v){
  191. SQ_FUNC_VARS_NO_TOP(v);
  192. SQ_GET_INTEGER(v, 2, info);
  193. sq_pushinteger(v, ssl_get_config(info));
  194. return 1;
  195. }
  196. static SQRESULT sq_openssl_display_error(HSQUIRRELVM v){
  197. SQ_FUNC_VARS_NO_TOP(v);
  198. SQ_GET_INTEGER(v, 2, error);
  199. ssl_display_error(error);
  200. return 0;
  201. }
  202. static SQRESULT sq_openssl_get_error(HSQUIRRELVM v){
  203. SQ_FUNC_VARS_NO_TOP(v);
  204. SQ_GET_INTEGER(v, 2, error);
  205. SQInteger buff_size = 250;
  206. SQChar *buff = sq_getscratchpad(v, buff_size);
  207. sq_pushstring(v, ssl_get_error(error, buff, buff_size), -1);
  208. return 1;
  209. }
  210. static SQRESULT ssl_ctx_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
  211. {
  212. SSL_CTX *self = (SSL_CTX*)p;
  213. if(self) ssl_ctx_free(self);
  214. return 0;
  215. }
  216. static SQRESULT sq_ssl_ctx_free(HSQUIRRELVM v)
  217. {
  218. SQ_FUNC_VARS_NO_TOP(v);
  219. GET_ssl_ctx_INSTANCE();
  220. ssl_ctx_release_hook(self, 0, v);
  221. sq_setinstanceup(v, 1, 0);
  222. return 0;
  223. }
  224. static SQRESULT sq_ssl_ctx_constructor(HSQUIRRELVM v)
  225. {
  226. SQInteger options, num_sessions;
  227. sq_getinteger(v, 2, &options);
  228. sq_getinteger(v, 3, &num_sessions);
  229. SSL_CTX *ssl_ctx = ssl_ctx_new(options, num_sessions);
  230. if(!ssl_ctx)
  231. return sq_throwerror(v, _SC("Could'nt create an ssl context."));
  232. sq_setinstanceup(v, 1, ssl_ctx);
  233. sq_setreleasehook(v,1, ssl_ctx_release_hook);
  234. return 1;
  235. }
  236. #define _DECL_OPENSSL_FUNC(name,nparams,pmask) {_SC(#name),sq_openssl_##name,nparams,pmask}
  237. static SQRegFunction openssl_obj_funcs[]={
  238. _DECL_OPENSSL_FUNC(get_config,2,_SC(".i")),
  239. _DECL_OPENSSL_FUNC(display_error,2,_SC(".i")),
  240. _DECL_OPENSSL_FUNC(get_error,2,_SC(".i")),
  241. _DECL_OPENSSL_FUNC(version,2,_SC(".")),
  242. {0,0}
  243. };
  244. #undef _DECL_OPENSSL_FUNC
  245. #define _DECL_SSL_CTX_FUNC(name,nparams,pmask) {_SC(#name),sq_ssl_ctx_##name,nparams,pmask}
  246. static SQRegFunction ssl_ctx_obj_funcs[]={
  247. _DECL_SSL_CTX_FUNC(constructor,3,_SC("xii")),
  248. _DECL_SSL_CTX_FUNC(free,1,_SC("x")),
  249. _DECL_SSL_CTX_FUNC(server_new,2,_SC("xi")),
  250. _DECL_SSL_CTX_FUNC(client_new,-2,_SC("xisi")),
  251. _DECL_SSL_CTX_FUNC(find,2,_SC("xs")),
  252. _DECL_SSL_CTX_FUNC(obj_load,2,_SC("xs")),
  253. _DECL_SSL_CTX_FUNC(obj_memory_load,2,_SC("xs")),
  254. {0,0}
  255. };
  256. #undef _DECL_SSL_CTX_FUNC
  257. #define _DECL_SSL_FUNC(name,nparams,pmask) {_SC(#name),sq_ssl_##name,nparams,pmask}
  258. static SQRegFunction ssl_obj_funcs[]={
  259. _DECL_SSL_FUNC(free,1,_SC("x")),
  260. _DECL_SSL_FUNC(read,-1,_SC("xi")),
  261. _DECL_SSL_FUNC(write,-2,_SC("xsi")),
  262. _DECL_SSL_FUNC(get_session_id,1,_SC("x")),
  263. _DECL_SSL_FUNC(get_session_id_size,1,_SC("x")),
  264. _DECL_SSL_FUNC(get_cipher_id,1,_SC("x")),
  265. _DECL_SSL_FUNC(handshake_status,1,_SC("x")),
  266. _DECL_SSL_FUNC(verify_cert,1,_SC("x")),
  267. _DECL_SSL_FUNC(get_cert_dn,2,_SC("xi")),
  268. _DECL_SSL_FUNC(get_cert_subject_alt_dnsname,2,_SC("xi")),
  269. _DECL_SSL_FUNC(renegotiate,1,_SC("x")),
  270. {0,0}
  271. };
  272. #undef _DECL_SSL_FUNC
  273. typedef struct {
  274. const SQChar *Str;
  275. SQInteger Val;
  276. } KeyIntType, * KeyIntPtrType;
  277. static KeyIntType openssl_constants[] = {
  278. #define MK_CONST(c) {_SC(#c), c}
  279. MK_CONST(SSL_SESSION_ID_SIZE),
  280. MK_CONST(SSL_CLIENT_AUTHENTICATION),
  281. MK_CONST(SSL_SERVER_VERIFY_LATER),
  282. MK_CONST(SSL_NO_DEFAULT_KEY),
  283. MK_CONST(SSL_DISPLAY_STATES),
  284. MK_CONST(SSL_DISPLAY_BYTES),
  285. MK_CONST(SSL_DISPLAY_CERTS),
  286. MK_CONST(SSL_DISPLAY_RSA),
  287. MK_CONST(SSL_CONNECT_IN_PARTS),
  288. MK_CONST(SSL_OK),
  289. MK_CONST(SSL_NOT_OK),
  290. MK_CONST(SSL_ERROR_DEAD),
  291. MK_CONST(SSL_CLOSE_NOTIFY),
  292. MK_CONST(SSL_ERROR_CONN_LOST),
  293. MK_CONST(SSL_ERROR_SOCK_SETUP_FAILURE),
  294. MK_CONST(SSL_ERROR_INVALID_HANDSHAKE),
  295. MK_CONST(SSL_ERROR_INVALID_PROT_MSG),
  296. MK_CONST(SSL_ERROR_INVALID_HMAC),
  297. MK_CONST(SSL_ERROR_INVALID_VERSION),
  298. MK_CONST(SSL_ERROR_INVALID_SESSION),
  299. MK_CONST(SSL_ERROR_NO_CIPHER),
  300. MK_CONST(SSL_ERROR_BAD_CERTIFICATE),
  301. MK_CONST(SSL_ERROR_INVALID_KEY),
  302. MK_CONST(SSL_ERROR_FINISHED_INVALID),
  303. MK_CONST(SSL_ERROR_NO_CERT_DEFINED),
  304. MK_CONST(SSL_ERROR_NO_CLIENT_RENOG),
  305. MK_CONST(SSL_ERROR_NOT_SUPPORTED),
  306. MK_CONST(SSL_X509_OFFSET),
  307. MK_CONST(SSL_ALERT_TYPE_WARNING),
  308. MK_CONST(SLL_ALERT_TYPE_FATAL),
  309. MK_CONST(SSL_ALERT_CLOSE_NOTIFY),
  310. MK_CONST(SSL_ALERT_UNEXPECTED_MESSAGE),
  311. MK_CONST(SSL_ALERT_BAD_RECORD_MAC),
  312. MK_CONST(SSL_ALERT_HANDSHAKE_FAILURE),
  313. MK_CONST(SSL_ALERT_BAD_CERTIFICATE),
  314. MK_CONST(SSL_ALERT_ILLEGAL_PARAMETER),
  315. MK_CONST(SSL_ALERT_DECODE_ERROR),
  316. MK_CONST(SSL_ALERT_DECRYPT_ERROR),
  317. MK_CONST(SSL_ALERT_INVALID_VERSION),
  318. MK_CONST(SSL_ALERT_NO_RENEGOTIATION),
  319. MK_CONST(SSL_AES128_SHA),
  320. MK_CONST(SSL_AES256_SHA),
  321. MK_CONST(SSL_RC4_128_SHA),
  322. MK_CONST(SSL_RC4_128_MD5),
  323. MK_CONST(SSL_BUILD_SKELETON_MODE),
  324. MK_CONST(SSL_BUILD_SERVER_ONLY),
  325. MK_CONST(SSL_BUILD_ENABLE_VERIFICATION),
  326. MK_CONST(SSL_BUILD_ENABLE_CLIENT),
  327. MK_CONST(SSL_BUILD_FULL_MODE),
  328. MK_CONST(SSL_BUILD_MODE),
  329. MK_CONST(SSL_MAX_CERT_CFG_OFFSET),
  330. MK_CONST(SSL_MAX_CA_CERT_CFG_OFFSET),
  331. MK_CONST(SSL_HAS_PEM),
  332. MK_CONST(SSL_DEFAULT_SVR_SESS),
  333. MK_CONST(SSL_DEFAULT_CLNT_SESS),
  334. MK_CONST(SSL_X509_CERT_COMMON_NAME),
  335. MK_CONST(SSL_X509_CERT_ORGANIZATION),
  336. MK_CONST(SSL_X509_CERT_ORGANIZATIONAL_NAME),
  337. MK_CONST(SSL_X509_CA_CERT_COMMON_NAME),
  338. MK_CONST(SSL_X509_CA_CERT_ORGANIZATION),
  339. MK_CONST(SSL_X509_CA_CERT_ORGANIZATIONAL_NAME),
  340. MK_CONST(SSL_OBJ_X509_CERT),
  341. MK_CONST(SSL_OBJ_X509_CACERT),
  342. MK_CONST(SSL_OBJ_RSA_KEY),
  343. MK_CONST(SSL_OBJ_PKCS8),
  344. MK_CONST(SSL_OBJ_PKCS12),
  345. {0,0}
  346. };
  347. /* This defines a function that opens up your library. */
  348. SQRESULT sqext_register_openssl (HSQUIRRELVM v) {
  349. //add a namespace openssl
  350. sq_pushstring(v, SQ_LIBNAME, -1);
  351. sq_newtable(v);
  352. sq_insert_reg_funcs(v, openssl_obj_funcs);
  353. //add constants
  354. KeyIntPtrType KeyIntPtr;
  355. for (KeyIntPtr = openssl_constants; KeyIntPtr->Str; KeyIntPtr++) {
  356. sq_pushstring(v, KeyIntPtr->Str, -1); //first the key
  357. sq_pushinteger(v, KeyIntPtr->Val); //then the value
  358. sq_newslot(v, -3, SQFalse); //store then
  359. }
  360. //now create the SSL Context class
  361. sq_pushstring(v,ssl_ctx_NAME,-1);
  362. sq_newclass(v,SQFalse);
  363. sq_settypetag(v,-1,(void*)SSL_CTX_Tag);
  364. sq_insert_reg_funcs(v, ssl_ctx_obj_funcs);
  365. sq_newslot(v,-3,SQFalse);
  366. //now create the SSL class
  367. sq_pushstring(v,ssl_NAME,-1);
  368. sq_newclass(v,SQFalse);
  369. sq_settypetag(v,-1,(void*)SSL_Tag);
  370. sq_insert_reg_funcs(v, ssl_obj_funcs);
  371. sq_newslot(v,-3,SQFalse);
  372. sq_newslot(v,-3,SQFalse); //add openssl table to the root table
  373. return SQ_OK;
  374. }
  375. #ifdef __cplusplus
  376. }
  377. #endif //USE_OPENSSL
  378. #endif