TLS Networking Using LibTLS
Posted: Sat Dec 31, 2022 3:07 am
Windows:
You will need four files from the LibreSSL package: https://ftp.openbsd.org/pub/OpenBSD/Lib ... indows.zip
Note: This is an old (but only) precompiled build of LibreSSL for Windows. If you can, build a newer version!
Ubuntu:
Main.pb
LibTLS.pbi
tls_write() and tls_read() take place of SendNetworkData() and ReceiveNetworkData(). Included are macros to re-route the PB native functions to them for easier install and remove from existing apps. You just have to omit the asterisks in front of the buffers while using them for example:
becomes:
Should also work on Linux. For a server you would just replace tls_client() with tls_server() and use tls_accept_socket() to associate the tls context with the return of your CreateNetworkServer() (may not work idk).
You can display TLS error messages with something like:
There should also be some cleanup like tls_config_free(), tls_close(), tls_free() that you can tie in.
You will need four files from the LibreSSL package: https://ftp.openbsd.org/pub/OpenBSD/Lib ... indows.zip
Note: This is an old (but only) precompiled build of LibreSSL for Windows. If you can, build a newer version!
- libtls-15.lib
- libtls-15.dll
- libssl-43.dll
- libcrypto-41.dll
Ubuntu:
Code: Select all
sudo apt update
sudo apt install libtls-dev
Code: Select all
DeclareModule Gateway
XIncludeFile "LibTLS.pbi"
Global *ctx, *cfg
Macro SendNetworkData(Connection, MemoryBuffer, Length)
tls_write(*ctx, *MemoryBuffer, Length)
EndMacro
Macro ReceiveNetworkData(Connection, DataBuffer, DataBufferLength)
tls_read(*ctx, *DataBuffer, DataBufferLength)
EndMacro
Declare Main()
EndDeclareModule
Module Gateway
Procedure Main()
Protected *FrameBuffer = AllocateMemory(1024)
OpenConsole()
; ------------------------------------------------------------
; Setup LIBTLS
; ------------------------------------------------------------
If tls_init() = -1
PrintN(PeekS(tls_error(*ctx), -1, #PB_Ascii)) : Input() : End
EndIf
*cfg = tls_config_new()
If *cfg = #Null
PrintN(PeekS(tls_error(*ctx), -1, #PB_Ascii)) : Input() : End
EndIf
; We are not going to verify with the server (otherwise set your certs here)
tls_config_insecure_noverifycert(*cfg)
tls_config_insecure_noverifyname(*cfg)
; Set which protocol we're going to use (TLS v1.2)
If tls_config_set_protocols(*cfg, #TLS_PROTOCOL_TLSv1_2) = -1
PrintN(PeekS(tls_error(*ctx), -1, #PB_Ascii)) : Input() : End
EndIf
; Set context as a client
*ctx = tls_client()
If *ctx = #Null
PrintN(PeekS(tls_error(*ctx), -1, #PB_Ascii)) : Input() : End
EndIf
; Apply our configuration to the tls context
If tls_configure(*ctx, *cfg) = -1
PrintN(PeekS(tls_error(*ctx), -1, #PB_Ascii)) : Input() : End
EndIf
; ------------------------------------------------------------
; Typical Network Program
; ------------------------------------------------------------
request.s = "GET /raw HTTP/1.1" + #CRLF$ +
"Host: ws.postman-echo.com" + #CRLF$ +
"Upgrade: websocket" + #CRLF$ +
"Connection: Upgrade" + #CRLF$ +
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" + #CRLF$ +
"Sec-WebSocket-Version: 13" + #CRLF$ + #CRLF$
socket = OpenNetworkConnection("ws.postman-echo.com", 443)
If socket
If tls_connect_socket(*ctx, ConnectionID(socket), "abc") = 0 ; This Being The Exception
PokeS(*FrameBuffer, request, StringByteLength(request, #PB_UTF8), #PB_UTF8)
size = SendNetworkData(socket, FrameBuffer, StringByteLength(request))
If size
FillMemory(*FrameBuffer, 1024)
Repeat
recv = ReceiveNetworkData(socket, FrameBuffer, 1024)
answer$ = answer$ + PeekS(*FrameBuffer, recv, #PB_UTF8)
Until FindString(answer$, #CRLF$ + #CRLF$)
PrintN(answer$)
; Check Answer
If FindString(answer$, "HTTP/1.1 101", 1, #PB_String_NoCase) And
FindString(answer$, "Upgrade: websocket", 1, #PB_String_NoCase) And
FindString(answer$, "Connection: Upgrade", 1, #PB_String_NoCase)
PrintN("Connection upgraded, now do whatever...")
EndIf
Input() : End
EndIf
EndIf
EndIf
EndProcedure
EndModule
Gateway::Main()
Code: Select all
; /* $OpenBSD: tls.h,v 1.58 2020/01/22 06:44:02 beck Exp $ */
; /*
; * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
; *
; * Permission To use, copy, modify, And distribute this software For any
; * purpose With Or without fee is hereby granted, provided that the above
; * copyright notice And this permission notice appear in all copies.
; *
; * THE SOFTWARE IS PROVIDED "AS IS" And THE AUTHOR DISCLAIMS ALL WARRANTIES
; * With REGARD To THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
; * MERCHANTABILITY And FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE For
; * ANY SPECIAL, DIRECT, INDIRECT, Or CONSEQUENTIAL DAMAGES Or ANY DAMAGES
; * WHATSOEVER RESULTING FROM LOSS OF USE, Data Or PROFITS, WHETHER IN AN
; * ACTION OF CONTRACT, NEGLIGENCE Or OTHER TORTIOUS ACTION, ARISING OUT OF
; * Or IN CONNECTION With THE USE Or PERFORMANCE OF THIS SOFTWARE.
; */
Macro const : p-utf8 : EndMacro
#TLS_API = 20200120
#TLS_PROTOCOL_TLSv1_0 = (1 << 1)
#TLS_PROTOCOL_TLSv1_1 = (1 << 2)
#TLS_PROTOCOL_TLSv1_2 = (1 << 3)
#TLS_PROTOCOL_TLSv1_3 = (1 << 4)
#TLS_PROTOCOL_TLSv1 = (#TLS_PROTOCOL_TLSv1_0 | #TLS_PROTOCOL_TLSv1_1 | #TLS_PROTOCOL_TLSv1_2 | #TLS_PROTOCOL_TLSv1_3)
#TLS_PROTOCOLS_ALL = #TLS_PROTOCOL_TLSv1
#TLS_PROTOCOLS_DEFAULT = (#TLS_PROTOCOL_TLSv1_2 | #TLS_PROTOCOL_TLSv1_3)
#TLS_WANT_POLLIN = -2
#TLS_WANT_POLLOUT = -3
;/* RFC 6960 Section 2.3 */
#TLS_OCSP_RESPONSE_SUCCESSFUL = 0
#TLS_OCSP_RESPONSE_MALFORMED = 1
#TLS_OCSP_RESPONSE_INTERNALERROR = 2
#TLS_OCSP_RESPONSE_TRYLATER = 3
#TLS_OCSP_RESPONSE_SIGREQUIRED = 4
#TLS_OCSP_RESPONSE_UNAUTHORIZED = 5
;/* RFC 6960 Section 2.2 */
#TLS_OCSP_CERT_GOOD = 0
#TLS_OCSP_CERT_REVOKED = 1
#TLS_OCSP_CERT_UNKNOWN = 2
;/* RFC 5280 Section 5.3.1 */
#TLS_CRL_REASON_UNSPECIFIED = 0
#TLS_CRL_REASON_KEY_COMPROMISE = 1
#TLS_CRL_REASON_CA_COMPROMISE = 2
#TLS_CRL_REASON_AFFILIATION_CHANGED = 3
#TLS_CRL_REASON_SUPERSEDED = 4
#TLS_CRL_REASON_CESSATION_OF_OPERATION = 5
#TLS_CRL_REASON_CERTIFICATE_HOLD = 6
#TLS_CRL_REASON_REMOVE_FROM_CRL = 8
#TLS_CRL_REASON_PRIVILEGE_WITHDRAWN = 9
#TLS_CRL_REASON_AA_COMPROMISE = 10
#TLS_MAX_SESSION_ID_LENGTH = 32
#TLS_TICKET_KEY_SIZE = 48
PrototypeC tls_read_cb(*_ctx, *_buf, _buflen, *_cb_arg)
PrototypeC tls_write_cb(*_ctx, *_buf, _buflen, *_cb_arg)
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
#LIBRESSLPATH = "libtls-15.lib"
CompilerElse
#LIBRESSLPATH = "-ltls"
CompilerEndIf
ImportC #LIBRESSLPATH
tls_init()
tls_config_error(*config)
tls_error(*ctx)
tls_config_new()
tls_config_free(*config)
tls_default_ca_cert_file()
tls_config_add_keypair_file(*config, *_cert_file.const, *_key_file.const)
tls_config_add_keypair_mem(*config, *_cert.const, _cert_len.i, *_key.const, _key_len.i)
tls_config_add_keypair_ocsp_file(*config, *_cert_file.const, *_key_file.const, *_ocsp_staple_file.const)
tls_config_add_keypair_ocsp_mem(*config, *_cert.const, _cert_len.i, *_key.const, _key_len.i, *_staple.const,_staple_len.i)
tls_config_set_alpn(*config, *_alpn.const)
tls_config_set_ca_file(*config, *_ca_file.const)
tls_config_set_ca_path(*config, *_ca_path.const)
tls_config_set_ca_mem(*config, *_ca.const, _len.i)
tls_config_set_cert_file(*config, *_cert_file.const)
tls_config_set_cert_mem(*config, *_cert.const, _len.i)
tls_config_set_ciphers(*config, *_ciphers.const)
tls_config_set_crl_file(*config, *_crl_file.const)
tls_config_set_crl_mem(*config, *_crl.const,_len.i)
tls_config_set_dheparams(*config, *_params.const)
tls_config_set_ecdhecurve(*config, *_curve.const)
tls_config_set_ecdhecurves(*config, *_curves.const)
tls_config_set_key_file(*config, *_key_file.const)
tls_config_set_key_mem(*config, *_key.const, _len.i)
tls_config_set_keypair_file(*config, *_cert_file.const, *_key_file.const)
tls_config_set_keypair_mem(*config, *_cert.const,_cert_len.i, *_key.const, _key_len.i)
tls_config_set_keypair_ocsp_file(*config, *_cert_file.const, *_key_file.const, *_staple_file.const)
tls_config_set_keypair_ocsp_mem(*config, *_cert.const, _cert_len.i, *_key.const, _key_len.i, *_staple.const, staple_len.i)
tls_config_set_ocsp_staple_mem(*config, *_staple.const, _len.i)
tls_config_set_ocsp_staple_file(*config, *_staple_file.const)
tls_config_set_protocols(*config, _protocols.l)
tls_config_set_session_fd(*config, _session_fd.l)
tls_config_set_verify_depth(*config, _verify_depth.l)
tls_config_prefer_ciphers_client(*config)
tls_config_prefer_ciphers_server(*config)
tls_config_insecure_noverifycert(*config)
tls_config_insecure_noverifyname(*config)
tls_config_insecure_noverifytime(*config)
tls_config_verify(*config)
tls_config_ocsp_require_stapling(*config)
tls_config_verify_client(*config)
tls_config_verify_client_optional(*config)
tls_config_clear_keys(*config)
tls_config_parse_protocols(*_protocols, *_protostr.const)
tls_config_set_session_id(*config, *_session_id.const, _len.i)
tls_config_set_session_lifetime(*config, _lifetime.l)
tls_config_add_ticket_key(*config, _keyrev.i, *_key, _keylen.i)
tls_client()
tls_server()
tls_configure(*ctx, *config)
tls_reset(*ctx)
tls_free(*ctx)
tls_accept_fds(*ctx, *_cctx, _fd_read.l, _fd_write.l)
tls_accept_socket(*ctx, *_cctx, _socket.l)
tls_accept_cbs(*ctx, *_cctx, *_read_cb.tls_read_cb, *_write_cb.tls_write_cb, *_cb_arg)
tls_connect(*ctx, *host.const, *port.const)
tls_connect_fds(*ctx, _fd_read.l, _fd_write.l, *_servername.const)
tls_connect_servername(*ctx, *_host.const, *_port.const, *_servername.const)
tls_connect_socket(*ctx, s.l, *servername.const)
tls_connect_cbs(*ctx, *_read_cb.tls_read_cb, *_write_cb.tls_write_cb, *_cb_arg,*_servername.const)
tls_handshake(*ctx)
tls_read(*ctx, *_buf, _buflen.i)
tls_write(*ctx, *_buf.const, _buflen.i)
tls_close(*ctx)
tls_peer_cert_provided(*ctx)
tls_peer_cert_contains_name(*ctx, *_name.const)
tls_peer_cert_hash(*ctx)
tls_peer_cert_issuer(*ctx)
tls_peer_cert_subject(*ctx)
tls_peer_cert_notbefore(*ctx)
tls_peer_cert_notafter(*ctx)
tls_peer_cert_chain_pem(*ctx, *_len)
tls_conn_alpn_selected(*ctx)
tls_conn_cipher(*ctx)
tls_conn_cipher_strength(*ctx)
tls_conn_servername(*ctx)
tls_conn_session_resumed(*ctx)
tls_conn_version(*ctx)
tls_load_file(*_file.const, *_len,*_password)
tls_unload_file(*_buf, len.i)
tls_ocsp_process_response(*ctx, *_response.const, _size.i)
tls_peer_ocsp_cert_status(*ctx)
tls_peer_ocsp_crl_reason(*ctx)
tls_peer_ocsp_next_update(*ctx)
tls_peer_ocsp_response_status(*ctx)
tls_peer_ocsp_result(*ctx)
tls_peer_ocsp_revocation_time(*ctx)
tls_peer_ocsp_this_update(*ctx)
tls_peer_ocsp_url(*ctx)
EndImport
Code: Select all
SendNetworkData(connection_id, *buffer, len)
Code: Select all
SendNetworkData(connection_id, buffer, len)
You can display TLS error messages with something like:
Code: Select all
Debug PeekS(tls_error(*ctx), -1, #PB_Ascii)