| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- #ifdef USE_OPENSSL
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "squirrel.h"
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h> /* for malloc */
- #include <assert.h> /* for a few sanity tests */
- #include "ssl.h"
- static const SQChar SQ_LIBNAME[] = _SC("openssl");
- static const SQChar ssl_ctx_NAME[] = _SC("ssl_ctx");
- static const SQChar ssl_NAME[] = _SC("ssl");
- SQ_OPT_STRING_STRLEN();
- static const SQChar SSL_CTX_Tag[] = _SC("sq_openssl_ssl_ctx");
- #define GET_ssl_ctx_INSTANCE() SQ_GET_INSTANCE(v, 1, SSL_CTX, SSL_CTX_Tag) \
- if(self == NULL) return sq_throwerror(v, _SC("ssl_ctx object already closed"));
- static const SQChar SSL_Tag[] = _SC("sq_openssl_ssl");
- #define GET_ssl_INSTANCE() SQ_GET_INSTANCE(v, 1, SSL, SSL_Tag) \
- if(self == NULL) return sq_throwerror(v, _SC("ssl object already closed"));
- static SQRESULT ssl_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
- {
- SSL *self = (SSL*)p;
- if(self) ssl_free(self);
- return 0;
- }
- static SQRESULT sq_ssl_free(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- ssl_release_hook(self, 0, v);
- sq_setinstanceup(v, 1, 0);
- return 0;
- }
- static SQRESULT ssl_constructor(HSQUIRRELVM v, SSL *ssl, int free_on_gc)
- {
- if(!ssl)
- return sq_throwerror(v, _SC("Could'nt create an ssl object."));
- sq_pushstring(v, SQ_LIBNAME, -1);
- if(sq_getonroottable(v) == SQ_OK){
- sq_pushstring(v, ssl_NAME, -1);
- if(sq_get(v, -2) == SQ_OK){
- if(sq_createinstance(v, -1) == SQ_OK){
- sq_setinstanceup(v, -1, ssl);
- if(free_on_gc) sq_setreleasehook(v,-1, ssl_release_hook);
- return 1;
- }
- }
- }
- return SQ_ERROR;
- }
- static SQRESULT sq_ssl_read(HSQUIRRELVM v){
- SQ_FUNC_VARS(v);
- GET_ssl_INSTANCE();
- SQ_OPT_INTEGER(v, 2, count, 0);
- uint8_t *in_data;
- int result = ssl_read(self, &in_data, count);
- if (result > SSL_OK) sq_pushstring(v, (const SQChar*)in_data, result);
- else sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_write(HSQUIRRELVM v){
- SQ_FUNC_VARS(v);
- GET_ssl_INSTANCE();
- SQ_GET_STRING(v, 2, out_data);
- if(_top_ > 2) {
- SQ_GET_INTEGER(v, 3, size);
- if(size > out_data_size) return sq_throwerror(v, _SC("parameter 2 size bigger than data size"));
- out_data_size = size;
- }
- sq_pushinteger(v, ssl_write(self, (const uint8_t *)out_data, out_data_size));
- return 1;
- }
- static SQRESULT sq_ssl_get_session_id(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- const uint8_t * result = ssl_get_session_id(self);
- sq_pushstring(v, (char *)result, ssl_get_session_id_size(self));
- return 1;
- }
- static SQRESULT sq_ssl_get_session_id_size(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- uint8_t result = ssl_get_session_id_size(self);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_get_cipher_id(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- uint8_t result = ssl_get_cipher_id(self);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_handshake_status(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- int result = ssl_handshake_status(self);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_verify_cert(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- int result = ssl_verify_cert(self);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_get_cert_dn(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- SQ_GET_INTEGER(v, 2, component);
- const char* result = ssl_get_cert_dn(self, component);
- sq_pushstring(v, result, -1);
- return 1;
- }
- static SQRESULT sq_ssl_get_cert_subject_alt_dnsname(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- SQ_GET_INTEGER(v, 2, dnsindex);
- const char* result = ssl_get_cert_subject_alt_dnsname(self, dnsindex);
- sq_pushstring(v, result, -1);
- return 1;
- }
- static SQRESULT sq_ssl_renegotiate(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_INSTANCE();
- int result = ssl_renegotiate(self);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_ctx_server_new(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_ctx_INSTANCE();
- SQ_GET_INTEGER(v, 2, client_fd);
- SSL *ssl = ssl_server_new(self, client_fd);
- SQRESULT rc = ssl_constructor(v, ssl, 1);
- if(rc == SQ_ERROR && ssl){
- ssl_free(ssl);
- }
- return rc;
- }
- static SQRESULT sq_ssl_ctx_client_new(HSQUIRRELVM v){
- SQ_FUNC_VARS(v);
- GET_ssl_ctx_INSTANCE();
- SQ_GET_INTEGER(v, 2, client_fd);
- SQ_OPT_STRING(v, 3, session_id, NULL);
- SQ_OPT_INTEGER(v, 4, size, -1);
- SSL *ssl = ssl_client_new(self, client_fd, (const uint8_t *)session_id,
- size >= 0 ? size : session_id_size);
- SQRESULT rc = ssl_constructor(v, ssl, 1);
- if(rc == SQ_ERROR && ssl){
- ssl_free(ssl);
- }
- return rc;
- }
- static SQRESULT sq_ssl_ctx_find(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_ctx_INSTANCE();
- SQ_GET_INTEGER(v, 2, client_fd);
- SSL *ssl = ssl_find(self, client_fd);
- if(ssl) return ssl_constructor(v, ssl, 0);
- else sq_pushnull(v);
- return 1;
- }
- static SQRESULT sq_ssl_ctx_obj_load(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_ctx_INSTANCE();
- SQ_GET_INTEGER(v, 2, obj_type);
- SQ_GET_STRING(v, 3, filename);
- SQ_GET_STRING(v, 4, password);
- int result = ssl_obj_load(self, obj_type, filename, password);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_ssl_ctx_obj_memory_load(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_ctx_INSTANCE();
- SQ_GET_INTEGER(v, 2, obj_type);
- SQ_GET_STRING(v, 3, data);
- SQ_GET_STRING(v, 4, password);
- int result = ssl_obj_memory_load(self, obj_type, (const uint8_t *)data, data_size, password);
- sq_pushinteger(v, result);
- return 1;
- }
- static SQRESULT sq_openssl_version(HSQUIRRELVM v){
- sq_pushstring(v,(const char*)ssl_version(), -1);
- return 1;
- }
- static SQRESULT sq_openssl_get_config(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_INTEGER(v, 2, info);
- sq_pushinteger(v, ssl_get_config(info));
- return 1;
- }
- static SQRESULT sq_openssl_display_error(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_INTEGER(v, 2, error);
- ssl_display_error(error);
- return 0;
- }
- static SQRESULT sq_openssl_get_error(HSQUIRRELVM v){
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_INTEGER(v, 2, error);
- SQInteger buff_size = 250;
- SQChar *buff = sq_getscratchpad(v, buff_size);
- sq_pushstring(v, ssl_get_error(error, buff, buff_size), -1);
- return 1;
- }
- static SQRESULT ssl_ctx_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
- {
- SSL_CTX *self = (SSL_CTX*)p;
- if(self) ssl_ctx_free(self);
- return 0;
- }
- static SQRESULT sq_ssl_ctx_free(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_ssl_ctx_INSTANCE();
- ssl_ctx_release_hook(self, 0, v);
- sq_setinstanceup(v, 1, 0);
- return 0;
- }
- static SQRESULT sq_ssl_ctx_constructor(HSQUIRRELVM v)
- {
- SQInteger options, num_sessions;
- sq_getinteger(v, 2, &options);
- sq_getinteger(v, 3, &num_sessions);
- SSL_CTX *ssl_ctx = ssl_ctx_new(options, num_sessions);
- if(!ssl_ctx)
- return sq_throwerror(v, _SC("Could'nt create an ssl context."));
- sq_setinstanceup(v, 1, ssl_ctx);
- sq_setreleasehook(v,1, ssl_ctx_release_hook);
- return 1;
- }
- #define _DECL_OPENSSL_FUNC(name,nparams,pmask) {_SC(#name),sq_openssl_##name,nparams,pmask}
- static SQRegFunction openssl_obj_funcs[]={
- _DECL_OPENSSL_FUNC(get_config,2,_SC(".i")),
- _DECL_OPENSSL_FUNC(display_error,2,_SC(".i")),
- _DECL_OPENSSL_FUNC(get_error,2,_SC(".i")),
- _DECL_OPENSSL_FUNC(version,2,_SC(".")),
- {0,0}
- };
- #undef _DECL_OPENSSL_FUNC
- #define _DECL_SSL_CTX_FUNC(name,nparams,pmask) {_SC(#name),sq_ssl_ctx_##name,nparams,pmask}
- static SQRegFunction ssl_ctx_obj_funcs[]={
- _DECL_SSL_CTX_FUNC(constructor,3,_SC("xii")),
- _DECL_SSL_CTX_FUNC(free,1,_SC("x")),
- _DECL_SSL_CTX_FUNC(server_new,2,_SC("xi")),
- _DECL_SSL_CTX_FUNC(client_new,-2,_SC("xisi")),
- _DECL_SSL_CTX_FUNC(find,2,_SC("xs")),
- _DECL_SSL_CTX_FUNC(obj_load,2,_SC("xs")),
- _DECL_SSL_CTX_FUNC(obj_memory_load,2,_SC("xs")),
- {0,0}
- };
- #undef _DECL_SSL_CTX_FUNC
- #define _DECL_SSL_FUNC(name,nparams,pmask) {_SC(#name),sq_ssl_##name,nparams,pmask}
- static SQRegFunction ssl_obj_funcs[]={
- _DECL_SSL_FUNC(free,1,_SC("x")),
- _DECL_SSL_FUNC(read,-1,_SC("xi")),
- _DECL_SSL_FUNC(write,-2,_SC("xsi")),
- _DECL_SSL_FUNC(get_session_id,1,_SC("x")),
- _DECL_SSL_FUNC(get_session_id_size,1,_SC("x")),
- _DECL_SSL_FUNC(get_cipher_id,1,_SC("x")),
- _DECL_SSL_FUNC(handshake_status,1,_SC("x")),
- _DECL_SSL_FUNC(verify_cert,1,_SC("x")),
- _DECL_SSL_FUNC(get_cert_dn,2,_SC("xi")),
- _DECL_SSL_FUNC(get_cert_subject_alt_dnsname,2,_SC("xi")),
- _DECL_SSL_FUNC(renegotiate,1,_SC("x")),
- {0,0}
- };
- #undef _DECL_SSL_FUNC
- typedef struct {
- const SQChar *Str;
- SQInteger Val;
- } KeyIntType, * KeyIntPtrType;
- static KeyIntType openssl_constants[] = {
- #define MK_CONST(c) {_SC(#c), c}
- MK_CONST(SSL_SESSION_ID_SIZE),
- MK_CONST(SSL_CLIENT_AUTHENTICATION),
- MK_CONST(SSL_SERVER_VERIFY_LATER),
- MK_CONST(SSL_NO_DEFAULT_KEY),
- MK_CONST(SSL_DISPLAY_STATES),
- MK_CONST(SSL_DISPLAY_BYTES),
- MK_CONST(SSL_DISPLAY_CERTS),
- MK_CONST(SSL_DISPLAY_RSA),
- MK_CONST(SSL_CONNECT_IN_PARTS),
- MK_CONST(SSL_OK),
- MK_CONST(SSL_NOT_OK),
- MK_CONST(SSL_ERROR_DEAD),
- MK_CONST(SSL_CLOSE_NOTIFY),
- MK_CONST(SSL_ERROR_CONN_LOST),
- MK_CONST(SSL_ERROR_SOCK_SETUP_FAILURE),
- MK_CONST(SSL_ERROR_INVALID_HANDSHAKE),
- MK_CONST(SSL_ERROR_INVALID_PROT_MSG),
- MK_CONST(SSL_ERROR_INVALID_HMAC),
- MK_CONST(SSL_ERROR_INVALID_VERSION),
- MK_CONST(SSL_ERROR_INVALID_SESSION),
- MK_CONST(SSL_ERROR_NO_CIPHER),
- MK_CONST(SSL_ERROR_BAD_CERTIFICATE),
- MK_CONST(SSL_ERROR_INVALID_KEY),
- MK_CONST(SSL_ERROR_FINISHED_INVALID),
- MK_CONST(SSL_ERROR_NO_CERT_DEFINED),
- MK_CONST(SSL_ERROR_NO_CLIENT_RENOG),
- MK_CONST(SSL_ERROR_NOT_SUPPORTED),
- MK_CONST(SSL_X509_OFFSET),
- MK_CONST(SSL_ALERT_TYPE_WARNING),
- MK_CONST(SLL_ALERT_TYPE_FATAL),
- MK_CONST(SSL_ALERT_CLOSE_NOTIFY),
- MK_CONST(SSL_ALERT_UNEXPECTED_MESSAGE),
- MK_CONST(SSL_ALERT_BAD_RECORD_MAC),
- MK_CONST(SSL_ALERT_HANDSHAKE_FAILURE),
- MK_CONST(SSL_ALERT_BAD_CERTIFICATE),
- MK_CONST(SSL_ALERT_ILLEGAL_PARAMETER),
- MK_CONST(SSL_ALERT_DECODE_ERROR),
- MK_CONST(SSL_ALERT_DECRYPT_ERROR),
- MK_CONST(SSL_ALERT_INVALID_VERSION),
- MK_CONST(SSL_ALERT_NO_RENEGOTIATION),
- MK_CONST(SSL_AES128_SHA),
- MK_CONST(SSL_AES256_SHA),
- MK_CONST(SSL_RC4_128_SHA),
- MK_CONST(SSL_RC4_128_MD5),
- MK_CONST(SSL_BUILD_SKELETON_MODE),
- MK_CONST(SSL_BUILD_SERVER_ONLY),
- MK_CONST(SSL_BUILD_ENABLE_VERIFICATION),
- MK_CONST(SSL_BUILD_ENABLE_CLIENT),
- MK_CONST(SSL_BUILD_FULL_MODE),
- MK_CONST(SSL_BUILD_MODE),
- MK_CONST(SSL_MAX_CERT_CFG_OFFSET),
- MK_CONST(SSL_MAX_CA_CERT_CFG_OFFSET),
- MK_CONST(SSL_HAS_PEM),
- MK_CONST(SSL_DEFAULT_SVR_SESS),
- MK_CONST(SSL_DEFAULT_CLNT_SESS),
- MK_CONST(SSL_X509_CERT_COMMON_NAME),
- MK_CONST(SSL_X509_CERT_ORGANIZATION),
- MK_CONST(SSL_X509_CERT_ORGANIZATIONAL_NAME),
- MK_CONST(SSL_X509_CA_CERT_COMMON_NAME),
- MK_CONST(SSL_X509_CA_CERT_ORGANIZATION),
- MK_CONST(SSL_X509_CA_CERT_ORGANIZATIONAL_NAME),
- MK_CONST(SSL_OBJ_X509_CERT),
- MK_CONST(SSL_OBJ_X509_CACERT),
- MK_CONST(SSL_OBJ_RSA_KEY),
- MK_CONST(SSL_OBJ_PKCS8),
- MK_CONST(SSL_OBJ_PKCS12),
- {0,0}
- };
- /* This defines a function that opens up your library. */
- SQRESULT sqext_register_openssl (HSQUIRRELVM v) {
- //add a namespace openssl
- sq_pushstring(v, SQ_LIBNAME, -1);
- sq_newtable(v);
- sq_insert_reg_funcs(v, openssl_obj_funcs);
- //add constants
- KeyIntPtrType KeyIntPtr;
- for (KeyIntPtr = openssl_constants; KeyIntPtr->Str; KeyIntPtr++) {
- sq_pushstring(v, KeyIntPtr->Str, -1); //first the key
- sq_pushinteger(v, KeyIntPtr->Val); //then the value
- sq_newslot(v, -3, SQFalse); //store then
- }
- //now create the SSL Context class
- sq_pushstring(v,ssl_ctx_NAME,-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(void*)SSL_CTX_Tag);
- sq_insert_reg_funcs(v, ssl_ctx_obj_funcs);
- sq_newslot(v,-3,SQFalse);
- //now create the SSL class
- sq_pushstring(v,ssl_NAME,-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(void*)SSL_Tag);
- sq_insert_reg_funcs(v, ssl_obj_funcs);
- sq_newslot(v,-3,SQFalse);
- sq_newslot(v,-3,SQFalse); //add openssl table to the root table
- return SQ_OK;
- }
- #ifdef __cplusplus
- }
- #endif //USE_OPENSSL
- #endif
|