Version 1 of TLS server using TWAPI

Updated 2020-08-19 07:44:05 by oehhar

The following short example from miguel demonstrates the use of TWAPI for communicating over SSL/TLS on Windows.

#
# Create [ssocket], an ssl-enabled clone of the [socket] command
#
# The credentials should be in cert.pfx in the same folder as this script, the
# file cert.pwd should contain the password.
#
# At the bottom of the file we create an echo-server using ssocket.
#

apply [list {} {
    set base [file normalize [file dir [info script]]]
    set fbase [file join $base cert]
    set ::auto_path [linsert $::auto_path 0 [file join $base twapi-bin]]

    if {![catch {puts "twapi [package require twapi_crypto]"}] \
            && [file exists $fbase.pfx]} {
        # adapted from tls_init_echo_server_creds
        # http://sourceforge.net/p/twapi/code/ci/default/tree/twapi/tests/tlsecho.tcl
        
        set init_creds [list fbase {
            set f [open $fbase.pfx rb]
            set pfx [read $f]
            close $f
            set f [open $fbase.pwd r]
            set pwd [gets $f]
            close $f

            # Set up the store containing the certificates
            set certStore [cert_temporary_store -pfx $pfx \
                               -password [conceal $pwd]]

            # Set up the client and server credentials
            # Note: the substring should identify your certified url
            set serverCert [cert_store_find_certificate $certStore \
                                subject_substring hunter]
            set creds [sspi_schannel_credentials \
                           -certificates [list $serverCert] \
                           -protocols [list ssl3 tls1.1 tls1.2]]
            set creds [sspi_acquire_credentials \
                           -credentials $creds \
                           -package unisp -role server]
            cert_release $serverCert
            cert_store_release $certStore

            return $creds
        } ::twapi]
        
        interp alias {} ssocket {} ::twapi::tls_socket \
            -credentials [::apply $init_creds $fbase]
        
    } else {
        return -code error "NO TLS"
    }
}]

##################
## The echo server
##################

# An echo server - just to test the tls connection

proc answer {chan h p} {
    if {[set request [gets $chan]] eq {}} return
    puts $chan "Received request: '$request'"
    close $chan
}

set port 1234
ssocket -server answer $port
vwait forever

HaO 2020-08-19: Works like a charm for me. Some observations when adapting TCLTLS in Embedded TCL Web Server for TWAPI:

To convert a pair of PEM certificates, OPENSSL may be used to get the PFX file

openssl pkcs12 -inkey private.pem -in public.pem -export -out privatepublic.pfx

Find certificate

For me, the following command included in the upper example

cert_store_find_certificate $certStore subject_substring hunter

returned the empty string to say that the certificate was not found.

I don't know what a substring in this context is. I only had a common name and replacing "hunter" by my common name did not succeed. Searching any certificate did the job for me:

cert_store_find_certificate $certStore any