Skip to content

Commit

Permalink
Refactor tls-test expect, creating library for other tests
Browse files Browse the repository at this point in the history
Push out some things that we'll doubtless want in other test cases.
  • Loading branch information
nwf committed Dec 22, 2019
1 parent 24b777b commit d2e6f7a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 63 deletions.
55 changes: 55 additions & 0 deletions lua_tests/expectnmcu/core.tcl
@@ -0,0 +1,55 @@
namespace eval expectnmcu::core {
}

# Establish a serial connection to the device via socat
proc ::expectnmcu::core::connect { dev baud } {
spawn "socat" "STDIO" "${dev},b${baud},rawer,crnl"
close -onexec 1 -i ${spawn_id}
return ${spawn_id}
}

# Use DTR/RTS signaling to reboot the device
## I'm not sure why we have to keep resetting the mode, but so it goes.
proc ::expectnmcu::core::reboot { dev baud } {
set victimfd [open "${dev}"]
fconfigure ${victimfd} -mode ${baud},n,8,1 -ttycontrol {DTR 0 RTS 1}
sleep 0.1
fconfigure ${victimfd} -mode ${baud},n,8,1 -ttycontrol {DTR 0 RTS 0}
close ${victimfd}
}

proc ::expectnmcu::core::waitboot { victim } {
expect {
-i ${victim} "Formatting file system" {
set timeout 60
exp_continue
}
-i ${victim} "powered by Lua" { }
timeout { return -code error "Timeout" }
}
# Catch nwf's system bootup, in case we're testing an existing system,
# rather than a blank firmware.
expect {
-i ${victim} "Reset delay!" { send "got:stop()\n" ; expect "> " }
-i ${victim} "> " { }
timeout { return -code error "Timeout" }
}
}

proc ::expectnmcu::core::send_exp_prompt { sid cmd } {
send -i ${sid} -- "${cmd}\n"
expect {
-i ${sid} -ex "\n> " { }
timeout { return -code error "Timeout" }
}
}

proc ::expectnmcu::core::send_exp_prompt_c { sid cmd } {
send -i ${sid} -- "${cmd}\n"
expect {
-i ${sid} -ex "\n>> " { }
timeout { return -code error "Timeout" }
}
}

package provide expectnmcu::core 1.0
11 changes: 11 additions & 0 deletions lua_tests/expectnmcu/pkgIndex.tcl
@@ -0,0 +1,11 @@
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex" command
# and sourced either when an application starts up or
# by a "package unknown" script. It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands. When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded expectnmcu::core 1.0 [list source [file join $dir core.tcl]]
88 changes: 25 additions & 63 deletions lua_tests/tls-test.expect
Expand Up @@ -8,7 +8,7 @@
# overridden with the -ip command line option.
#
# A typical invocation looks like:
# ./tls-test.expect -serial /dev/ttyUSB3 -wifi "$(cat wificmd)"
# TCLLIBPATH=./expectnmcu ./tls-test.expect -serial /dev/ttyUSB3 -wifi "$(cat wificmd)"
#
# where the file `wificmd` contains something like
# wifi.setmode(wifi.STATION); wifi.sta.config({...}); wifi.sta.connect()
Expand All @@ -18,10 +18,11 @@
# For debugging the test itself, it may be useful to invoke expect with -d,
# which will give a great deal of diagnostic information about the expect state
# machine's internals:
# expect -d ./tls-test.expect ...
# TCLLIBPATH=./expectnmcu expect -d ./tls-test.expect ...


package require struct::stack
package require expectnmcu::core

::struct::stack ulogstack
proc pushulog { new } {
Expand All @@ -30,35 +31,21 @@ proc pushulog { new } {
}
proc populog { } { log_user [ulogstack pop] }

proc send_exp_prompt { sid cmd } {
send -i ${sid} -- "${cmd}\n"
expect {
-i ${sid} -ex "\n> " { }
}
}

proc send_exp_prompt_c { sid cmd } {
send -i ${sid} -- "${cmd}\n"
expect {
-i ${sid} -ex "\n>> " { }
}
}

proc genectls { curve pfx } {
exec "openssl" "ecparam" "-genkey" "-name" ${curve} "-out" "${pfx}.key"
exec "openssl" "req" "-new" "-sha256" "-subj" "/CN=${curve}" "-key" "${pfx}.key" "-out" "${pfx}.csr"
exec "openssl" "req" "-x509" "-sha256" "-days" "365" "-key" "${pfx}.key" "-in" "${pfx}.csr" "-out" "${pfx}.crt"
}

proc preptls { victim } {
send_exp_prompt_c ${victim} "function tlsbasic(id,port,host)"
send_exp_prompt_c ${victim} " local c = tls.createConnection()"
send_exp_prompt_c ${victim} " c:on(\"receive\", function(sck, d) print(\"RECV\",id,d) end)"
send_exp_prompt_c ${victim} " c:on(\"connection\", function(sck) print(\"CONN\",id); sck:send(\"GET / HTTP/1.0\\r\\n\\r\\n\") end)"
send_exp_prompt_c ${victim} " c:on(\"disconnection\", function(sck) print(\"DISC\",id) end)"
send_exp_prompt_c ${victim} " c:connect(port,host)"
send_exp_prompt_c ${victim} " return c"
send_exp_prompt ${victim} "end"
::expectnmcu::core::send_exp_prompt_c ${victim} "function tlsbasic(id,port,host)"
::expectnmcu::core::send_exp_prompt_c ${victim} " local c = tls.createConnection()"
::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"receive\", function(sck, d) print(\"RECV\",id,d) end)"
::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"connection\", function(sck) print(\"CONN\",id); sck:send(\"GET / HTTP/1.0\\r\\n\\r\\n\") end)"
::expectnmcu::core::send_exp_prompt_c ${victim} " c:on(\"disconnection\", function(sck) print(\"DISC\",id) end)"
::expectnmcu::core::send_exp_prompt_c ${victim} " c:connect(port,host)"
::expectnmcu::core::send_exp_prompt_c ${victim} " return c"
::expectnmcu::core::send_exp_prompt ${victim} "end"
}

# Basic connectivity test, including disconnection of localsid.
Expand All @@ -81,7 +68,7 @@ proc basicconntest { id localsid victimsid victimconn } {
populog
expect {
-i ${victimsid} "RECV\t${id}\tabracadabra" {
send_exp_prompt ${victimsid} "${victimconn}:send(\"test 1 2 3 4\")"
::expectnmcu::core::send_exp_prompt ${victimsid} "${victimconn}:send(\"test 1 2 3 4\")"
}
}
pushulog 0
Expand Down Expand Up @@ -120,36 +107,11 @@ if {[catch {array set cmdopts [cmdline::getoptions ::argv $cmd_parameters $cmd_u

send_user "===> Note: Serial port is ${cmdopts(serial)}; debug is ${cmdopts(debug)} <===\n"

spawn "socat" "STDIO" "${cmdopts(serial)},rawer,crnl"
set victim ${spawn_id}
close -onexec 1 -i ${victim}

# Use DTR/RTS signaling to reboot the device
## I'm not sure why we have to keep resetting the mode, but so it goes.
set victimfd [open "${cmdopts(serial)}"]
fconfigure ${victimfd} -mode 115200,n,8,1 -ttycontrol {DTR 0 RTS 1}
sleep 0.1
fconfigure ${victimfd} -mode 115200,n,8,1 -ttycontrol {DTR 0 RTS 0}
close ${victimfd}
set victim [::expectnmcu::core::connect ${cmdopts(serial)} 115200]
::expectnmcu::core::reboot ${cmdopts(serial)} 115200

# Wait for the system to boot
expect {
-i ${victim} "Formatting file system" {
set timeout 60
exp_continue
}
-i ${victim} "powered by Lua" { }
timeout {
send_user "\n===> Did not see boot sequence; bailing out <===\n"
exit 0
}
}
# Catch nwf's system bootup, in case we're testing an existing system,
# rather than a blank firmware.
expect {
-i ${victim} "Reset delay!" { send "got:stop()\n" ; expect "> " }
-i ${victim} "> " { }
}
::expectnmcu::core::waitboot ${victim}
send_user "\n===> Machine has booted <===\n"

# Program a routine for TLS connections
Expand All @@ -158,7 +120,7 @@ preptls ${victim}
# Connect the board to the network

if {[expr 0 < [string length ${cmdopts(wifi)}]]} {
send_exp_prompt ${victim} ${cmdopts(wifi)}
::expectnmcu::core::send_exp_prompt ${victim} ${cmdopts(wifi)}
}

for {set i 0} {${i} < 10} {incr i} {
Expand Down Expand Up @@ -193,34 +155,34 @@ if {[expr 0 < [string length ${cmdopts(ip)}]]} {
close
}

send_exp_prompt ${victim} "tls.setDebug(2)"
send_exp_prompt ${victim} "tls.cert.verify(false)"
::expectnmcu::core::send_exp_prompt ${victim} "tls.setDebug(2)"
::expectnmcu::core::send_exp_prompt ${victim} "tls.cert.verify(false)"

send_user "\n===> TEST SSL 256v1, no verify <===\n"

spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls256v1}.crt,key=${fntls256v1}.key,reuseaddr"
send_exp_prompt ${victim} "c = tlsbasic(0,12345,\"${myip}\")"
::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(0,12345,\"${myip}\")"
basicconntest 0 ${spawn_id} ${victim} "c"

send_user "\n===> TEST SSL 384r1, no verify <===\n"

spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls384r1}.crt,key=${fntls384r1}.key,reuseaddr"
send_exp_prompt ${victim} "c = tlsbasic(1,12345,\"${myip}\")"
::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(1,12345,\"${myip}\")"
basicconntest 1 ${spawn_id} ${victim} "c"

send_user "\n===> TEST SSL 384r1, verify <===\n"

set cert [open "${fntls384r1}.crt"]
send_exp_prompt_c ${victim} "tls.cert.verify(\[\["
::expectnmcu::core::send_exp_prompt_c ${victim} "tls.cert.verify(\[\["
while { [gets $cert line] >= 0 } {
send_exp_prompt_c ${victim} $line
::expectnmcu::core::send_exp_prompt_c ${victim} $line
}
send_exp_prompt ${victim} "]])"
::expectnmcu::core::send_exp_prompt ${victim} "]])"
close ${cert}
send_exp_prompt ${victim} "tls.cert.verify(true)"
::expectnmcu::core::send_exp_prompt ${victim} "tls.cert.verify(true)"

spawn -noecho "socat" "STDIO,cfmakeraw" "OPENSSL-LISTEN:12345,verify=0,certificate=${fntls384r1}.crt,key=${fntls384r1}.key,reuseaddr"
send_exp_prompt ${victim} "c = tlsbasic(2,12345,\"${myip}\")"
::expectnmcu::core::send_exp_prompt ${victim} "c = tlsbasic(2,12345,\"${myip}\")"
basicconntest 2 ${spawn_id} ${victim} "c"

send_user "\n===> TESTS OK <===\n"

0 comments on commit d2e6f7a

Please sign in to comment.