quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit c447c4302e87d1d85933b959f744ac77333996cb
parent b3357f13126bae0ac61f7d27e989296dd52d9d5c
Author: Florian Dold <florian@dold.me>
Date:   Wed, 21 Dec 2022 11:13:32 +0100

wallet-core header

Diffstat:
Mmeson.build | 32++++++++++++++++++++++++--------
Mquickjs-libc.c | 1+
Asubprojects/curl/meson.build | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msubprojects/mbedtls/meson.build | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ataler_wallet_core_lib.h | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 476 insertions(+), 8 deletions(-)

diff --git a/meson.build b/meson.build @@ -3,16 +3,24 @@ project('quickjs-tart', 'c', add_project_arguments('-D_GNU_SOURCE', language : 'c') add_project_arguments('-DCONFIG_VERSION="0.0.1"', language : 'c') +add_project_arguments('-DCONFIG_BIGNUM', language : 'c') cc = meson.get_compiler('c') -m_dep = cc.find_library('m', required : true) -mbedcrypto_dep = cc.find_library('mbedcrypto', required : true) -curl_dep = cc.find_library('curl', required : true) -sodium_proj = subproject('libsodium', required : true) +m_dep = cc.find_library('m', required : false) -#sodium_dep = cc.find_library('sodium', required : true) +mbedtls_proj = subproject('mbedtls', required : true) +#mbedcrypto_dep = cc.find_library('mbedcrypto', required : true) +mbedcrypto_dep = mbedtls_proj.get_variable('mbedcrypto_dep') +mbedtls_dep = mbedtls_proj.get_variable('mbedtls_dep') +mbedx509_dep = mbedtls_proj.get_variable('mbedx509_dep') + +curl_proj = subproject('curl', required : true) +# curl_dep = cc.find_library('curl', required : true) +curl_dep = curl_proj.get_variable('curl_dep') +sodium_proj = subproject('libsodium', required : true) +#sodium_dep = cc.find_library('sodium', required : true) sodium_dep = sodium_proj.get_variable('sodium_dep') qjsc_exe = executable('qjsc', [ @@ -24,15 +32,22 @@ qjsc_exe = executable('qjsc', [ 'quickjs-libc.c', 'quickjs.c', ], - dependencies: [m_dep, mbedcrypto_dep, curl_dep, sodium_dep]) + dependencies: [m_dep, mbedcrypto_dep, mbedtls_dep, mbedx509_dep, curl_dep, sodium_dep]) -repl_c = custom_target('gen-output', +repl_c = custom_target('repl', input : ['repl.js'], output : ['repl.c'], command : [qjsc_exe, '-c', '-m', '-o', '@OUTPUT@', '@INPUT@']) +qjscalc_c = custom_target('qjscalc', + input : ['qjscalc.js'], + output : ['qjscalc.c'], + command : [qjsc_exe, '-c', '-m', + '-o', '@OUTPUT@', + '@INPUT@']) + qjs_exe = executable('qjs', [ 'qjs.c', 'libbf.c', @@ -42,5 +57,6 @@ qjs_exe = executable('qjs', [ 'quickjs-libc.c', 'quickjs.c', repl_c, + qjscalc_c, ], - dependencies: [m_dep, mbedcrypto_dep, curl_dep, sodium_dep]) + dependencies: [m_dep, mbedcrypto_dep, mbedtls_dep, mbedx509_dep, curl_dep, sodium_dep]) diff --git a/quickjs-libc.c b/quickjs-libc.c @@ -2170,6 +2170,7 @@ static JSValue js_os_fetchHttp(JSContext *ctx, JSValueConst this_val, goto exception; } curl_easy_setopt(curl, CURLOPT_URL, req_url); + curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/ssl/certs/ca-certificates.crt"); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_header_callback); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &req_context); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb); diff --git a/subprojects/curl/meson.build b/subprojects/curl/meson.build @@ -0,0 +1,264 @@ +project('curl', 'c') + +c_compiler = meson.get_compiler('c') + +add_project_arguments('-DCURL_DISABLE_LDAP', language : 'c') +add_project_arguments('-DCURL_DISABLE_IMAP', language : 'c') +add_project_arguments('-DCURL_DISABLE_SMTP', language : 'c') +add_project_arguments('-DCURL_DISABLE_POP3', language : 'c') +add_project_arguments('-D_GNU_SOURCE', language : 'c') + +if c_compiler.check_header('unistd.h') + add_project_arguments('-DHAVE_UNISTD_H', language : 'c') +endif + +if c_compiler.check_header('signal.h') + add_project_arguments('-DHAVE_SIGNAL_H', language : 'c') +endif + +if c_compiler.check_header('time.h') + add_project_arguments('-DHAVE_TIME_H', language : 'c') +endif + +if c_compiler.check_header('netinet/in.h') + add_project_arguments('-DHAVE_NETINET_IN_H', language : 'c') +endif + +if c_compiler.check_header('netdb.h') + add_project_arguments('-DHAVE_NETDB_H', language : 'c') +endif + +if c_compiler.check_header('fcntl.h') + add_project_arguments('-DHAVE_FCNTL_H', language : 'c') +endif + +if c_compiler.check_header('arpa/inet.h') + add_project_arguments('-DHAVE_ARPA_INET_H', language : 'c') +endif + +if c_compiler.check_header('sys/socket.h') + add_project_arguments('-DHAVE_SYS_SOCKET_H', language : 'c') +endif + +if c_compiler.check_header('sys/types.h') + add_project_arguments('-DHAVE_SYS_TYPES_H', language : 'c') +endif + +if c_compiler.check_header('sys/select.h') + add_project_arguments('-DHAVE_SYS_SELECT_H', language : 'c') +endif + +if c_compiler.check_header('sys/stat.h') + add_project_arguments('-DHAVE_SYS_STAT_H', language : 'c') +endif + +if c_compiler.check_header('sys/poll.h') + add_project_arguments('-DHAVE_SYS_POLL_H', language : 'c') +endif + +sizeof_curl_off_t = c_compiler.sizeof('curl_off_t', prefix : '#include <curl/system.h>') +add_project_arguments(f'-DSIZEOF_CURL_OFF_T=@sizeof_curl_off_t@', language : 'c') +sizeof_long = c_compiler.sizeof('long') +add_project_arguments(f'-DSIZEOF_LONG=@sizeof_long@', language : 'c') +sizeof_int = c_compiler.sizeof('int') +add_project_arguments(f'-DSIZEOF_INT=@sizeof_int@', language : 'c') +sizeof_time_t = c_compiler.sizeof('time_t', prefix : '#include <time.h>') +add_project_arguments(f'-DSIZEOF_TIME_T=@sizeof_time_t@', language : 'c') +sizeof_off_t = c_compiler.sizeof('off_t') +add_project_arguments(f'-DSIZEOF_OFF_T=@sizeof_off_t@', language : 'c') + +add_project_arguments('-DHAVE_ERRNO_H', language : 'c') +add_project_arguments('-DHAVE_STDBOOL_H', language : 'c') +add_project_arguments('-DHAVE_BOOL_T', language : 'c') +add_project_arguments('-DHAVE_STRUCT_TIMEVAL', language : 'c') +add_project_arguments('-DHAVE_RECV', language : 'c') +add_project_arguments('-DHAVE_SEND', language : 'c') +add_project_arguments('-DHAVE_LONGLONG', language : 'c') +add_project_arguments('-DHAVE_LONGLONG', language : 'c') + +# FIXME: test for this! +add_project_arguments('-DHAVE_FCNTL_O_NONBLOCK', language : 'c') +add_project_arguments('-DHAVE_SELECT', language : 'c') +add_project_arguments('-DHAVE_SOCKET', language : 'c') +os = host_machine.system() +add_project_arguments('-DOS="@os@"', language : 'c') + +# SSL config +add_project_arguments('-DUSE_MBEDTLS', language : 'c') +add_project_arguments('-DCURL_DEFAULT_SSL_BACKEND="mbedtls"', language : 'c') + +lib_c_src = [ + 'lib/altsvc.c', + 'lib/amigaos.c', + 'lib/asyn-ares.c', + 'lib/asyn-thread.c', + 'lib/base64.c', + 'lib/bufref.c', + 'lib/c-hyper.c', + 'lib/conncache.c', + 'lib/connect.c', + 'lib/content_encoding.c', + 'lib/cookie.c', + 'lib/curl_addrinfo.c', + 'lib/curl_des.c', + 'lib/curl_endian.c', + 'lib/curl_fnmatch.c', + 'lib/curl_get_line.c', + 'lib/curl_gethostname.c', + 'lib/curl_gssapi.c', + 'lib/curl_memrchr.c', + 'lib/curl_multibyte.c', + 'lib/curl_ntlm_core.c', + 'lib/curl_ntlm_wb.c', + 'lib/curl_path.c', + 'lib/curl_range.c', + 'lib/curl_rtmp.c', + 'lib/curl_sasl.c', + 'lib/curl_sspi.c', + 'lib/curl_threads.c', + 'lib/dict.c', + 'lib/doh.c', + 'lib/dynbuf.c', + 'lib/easy.c', + 'lib/easygetopt.c', + 'lib/easyoptions.c', + 'lib/escape.c', + 'lib/file.c', + 'lib/fileinfo.c', + 'lib/fopen.c', + 'lib/formdata.c', + 'lib/ftp.c', + 'lib/ftplistparser.c', + 'lib/getenv.c', + 'lib/getinfo.c', + 'lib/gopher.c', + 'lib/h2h3.c', + 'lib/hash.c', + 'lib/headers.c', + 'lib/hmac.c', + 'lib/hostasyn.c', + 'lib/hostip.c', + 'lib/hostip4.c', + 'lib/hostip6.c', + 'lib/hostsyn.c', + 'lib/hsts.c', + 'lib/http.c', + 'lib/http2.c', + 'lib/http_chunks.c', + 'lib/http_digest.c', + 'lib/http_negotiate.c', + 'lib/http_ntlm.c', + 'lib/http_proxy.c', + 'lib/http_aws_sigv4.c', + 'lib/idn_win32.c', + 'lib/if2ip.c', + 'lib/imap.c', + 'lib/inet_ntop.c', + 'lib/inet_pton.c', + 'lib/krb5.c', + 'lib/ldap.c', + 'lib/llist.c', + 'lib/md4.c', + 'lib/md5.c', + 'lib/memdebug.c', + 'lib/mime.c', + 'lib/mprintf.c', + 'lib/mqtt.c', + 'lib/multi.c', + 'lib/netrc.c', + 'lib/nonblock.c', + 'lib/noproxy.c', + 'lib/openldap.c', + 'lib/parsedate.c', + 'lib/pingpong.c', + 'lib/pop3.c', + 'lib/progress.c', + 'lib/psl.c', + 'lib/rand.c', + 'lib/rename.c', + 'lib/rtsp.c', + 'lib/select.c', + 'lib/sendf.c', + 'lib/setopt.c', + 'lib/sha256.c', + 'lib/share.c', + 'lib/slist.c', + 'lib/smb.c', + 'lib/smtp.c', + 'lib/socketpair.c', + 'lib/socks.c', + 'lib/socks_gssapi.c', + 'lib/socks_sspi.c', + 'lib/speedcheck.c', + 'lib/splay.c', + 'lib/strcase.c', + 'lib/strdup.c', + 'lib/strerror.c', + 'lib/strtok.c', + 'lib/strtoofft.c', + 'lib/system_win32.c', + 'lib/telnet.c', + 'lib/tftp.c', + 'lib/timediff.c', + 'lib/timeval.c', + 'lib/transfer.c', + 'lib/url.c', + 'lib/urlapi.c', + 'lib/version.c', + 'lib/version_win32.c', + 'lib/warnless.c', + 'lib/wildcard.c', + 'lib/ws.c', +] + +lib_vtls_src = [ + 'lib/vtls/bearssl.c', + 'lib/vtls/gskit.c', + 'lib/vtls/gtls.c', + 'lib/vtls/hostcheck.c', + 'lib/vtls/keylog.c', + 'lib/vtls/mbedtls.c', + 'lib/vtls/mbedtls_threadlock.c', + 'lib/vtls/nss.c', + 'lib/vtls/openssl.c', + 'lib/vtls/rustls.c', + 'lib/vtls/schannel.c', + 'lib/vtls/schannel_verify.c', + 'lib/vtls/sectransp.c', + 'lib/vtls/vtls.c', + 'lib/vtls/wolfssl.c', + 'lib/vtls/x509asn1.c', +] + +lib_vauth_src = [ + 'lib/vauth/cleartext.c', + 'lib/vauth/cram.c', + 'lib/vauth/digest.c', + 'lib/vauth/digest_sspi.c', + 'lib/vauth/gsasl.c', + 'lib/vauth/krb5_gssapi.c', + 'lib/vauth/krb5_sspi.c', + 'lib/vauth/ntlm.c', + 'lib/vauth/ntlm_sspi.c', + 'lib/vauth/oauth2.c', + 'lib/vauth/spnego_gssapi.c', + 'lib/vauth/spnego_sspi.c', + 'lib/vauth/vauth.c', +] + +mbedtls_proj = subproject('mbedtls', required : true) +#mbedcrypto_dep = cc.find_library('mbedcrypto', required : true) +mbedcrypto_dep = mbedtls_proj.get_variable('mbedcrypto_dep') +mbedtls_dep = mbedtls_proj.get_variable('mbedtls_dep') +mbedx509_dep = mbedtls_proj.get_variable('mbedx509_dep') + +libcurl = static_library('curl', [lib_c_src, lib_vtls_src, lib_vauth_src], + include_directories : ['include', 'lib'], + c_args : ['-DBUILDING_LIBCURL'], + dependencies : [mbedtls_dep, mbedcrypto_dep, mbedx509_dep]) + + +curl_dep = declare_dependency( + include_directories : ['include/'], + link_with : [libcurl], +) diff --git a/subprojects/mbedtls/meson.build b/subprojects/mbedtls/meson.build @@ -1,5 +1,11 @@ project('mbedtls', 'c') +if meson.is_subproject() + message('mbedtls is subproject') +else + message('mbedtls is NOT subproject') +endif + src_crypto = [ 'library/aes.c', 'library/aesni.c', @@ -78,6 +84,57 @@ src_crypto = [ 'library/version_features.c', ] +src_x509 = [ + 'library/pkcs7.c', + 'library/x509.c', + 'library/x509_create.c', + 'library/x509_crl.c', + 'library/x509_crt.c', + 'library/x509_csr.c', + 'library/x509write_crt.c', + 'library/x509write_csr.c', +] + +src_tls = [ + 'library/debug.c', + 'library/mps_reader.c', + 'library/mps_trace.c', + 'library/net_sockets.c', + 'library/ssl_cache.c', + 'library/ssl_ciphersuites.c', + 'library/ssl_client.c', + 'library/ssl_cookie.c', + 'library/ssl_debug_helpers_generated.c', + 'library/ssl_msg.c', + 'library/ssl_ticket.c', + 'library/ssl_tls.c', + 'library/ssl_tls12_client.c', + 'library/ssl_tls12_server.c', + 'library/ssl_tls13_keys.c', + 'library/ssl_tls13_server.c', + 'library/ssl_tls13_client.c', + 'library/ssl_tls13_generic.c', +] mbedcrypto = static_library('mbedcrypto', src_crypto, include_directories : ['include']) + +mbedtls = static_library('mbedtls', src_tls, + include_directories : ['include']) + +mbedx509 = static_library('mbedx509', src_x509, + include_directories : ['include']) + + +mbedcrypto_dep = declare_dependency( + include_directories : ['include'], + link_with : [mbedcrypto], +) +mbedtls_dep = declare_dependency( + include_directories : ['include'], + link_with : [mbedtls], +) +mbedx509_dep = declare_dependency( + include_directories : ['include'], + link_with : [mbedx509], +) diff --git a/taler_wallet_core_lib.h b/taler_wallet_core_lib.h @@ -0,0 +1,130 @@ +/* + This file is part of GNU Taler + Copyright (C) 2014-2022 Taler Systems SA + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * C interface to the functionality of wallet-core. + * + * Currently, the underlying implementation uses the JS implementation of + * wallet-core, but this may (or may not) change in the future. + * + * @author Florian Dold + */ +#ifndef _TALER_WALLET_LIB_H +#define _TALER_WALLET_LIB_H + +/** + * Opaque handle to a Taler wallet-core. + */ +struct TALER_WALLET_Handle; + +/** + * Handler for messages from the wallet. + */ +typedef void TALER_WALLET_MessageHandlerFn(void *handler_p, char *message); + +/** + * Create a new wallet-core handle. + */ +struct TALER_WALLET_Handle * +TALER_WALLET_create(); + +/** + * Set a handler for notification and response messages. + * Must be called before the wallet runs. + * + * Caution: The handler will be called from a different thread. + */ +void +TALER_WALLET_set_handler(struct TALER_WALLET_Handle *h, + TALER_WALLET_MessageHandlerFn *handler_f, + void *handler_p); + + +/** + * Enable or disable message queueing mode of the wallet. + * + * Queueing is disabled by default. + */ +void +TALER_WALLET_set_queueing (struct TALER_WALLET_Handle *h, + int yesno); + +/** + * Get a pipe file descriptor that signals the availability + * of new messages in the message queue. + * + * One byte of data will be written to the pipe for every available message. + * The client is responsible for ensuring that every call + * to #TALER_WALLET_discard_message is paired with a 1-byte + * read from the pipe. + * + * Returns -1 if on error, for example when the platform + * doesn't support pipes. + */ +int +TALER_WALLET_get_eventpipe (struct TALER_WALLET_Handle *h); + +/** + * Look at the message at the head of the message queue. + * + * Only works when queueing is enabled. + */ +const char * +TALER_WALLET_peek_message (struct TALER_WALLET_Handle *h); + +/** + * Discard the message at the head of the message queue. + */ +void +TALER_WALLET_discard_message (struct TALER_WALLET_Handle *h); + +/** + * Set/override the JS file with the wallet-core implementation. + * Must be called before the wallet runs. + */ +void +TALER_WALLET_set_jsfile(struct TALER_WALLET_Handle *h, + char *filename); + +/** + * Send a message to wallet-core. + * + * Responses will be sent asynchronously to the message handler + * set with #TALER_WALLET_set_handler. + */ +void +TALER_WALLET_send_message (struct TALER_WALLET_Handle *h); + +/** + * Run wallet-core in a thread. + * + * This function creates a new thread and returns immediately. + */ +void +TALER_WALLET_run (); + +/** + * Destroy the wallet handle and free resources associated with it. + * + * Note that for a graceful shutdown of the wallet, + * an appropriate shutdown message should be sent first, + * and destroy() should only be called after the wallet has + * sent a response to the shutdown message. + */ +void +TALER_WALLET_destroy(struct TALER_WALLET_Handle *h); + +#endif /*_TALER_WALLET_LIB_H */