Index: tests/badssl.test ================================================================== --- tests/badssl.test +++ tests/badssl.test @@ -7,14 +7,17 @@ } set auto_path [concat [list [file dirname [file dirname [info script]]]] $auto_path] package require tls + # Constraints source [file join [file dirname [info script]] common.tcl] + # Helper functions proc badssl {url} {set port 443;lassign [split $url ":"] url port;if {$port eq ""} {set port 443};set cmd [list tls::socket -autoservername 1 -require 1];if {[info exists ::env(SSL_CERT_FILE)]} {lappend cmd -cafile $::env(SSL_CERT_FILE)};lappend cmd $url $port;set ch [eval $cmd];if {[catch {tls::handshake $ch} err]} {close $ch;return -code error $err} else {close $ch}} + # BadSSL.com Tests test BadSSL-1.1 {1000-sans} -body { badssl 1000-sans.badssl.com Index: tests/ciphers.test ================================================================== --- tests/ciphers.test +++ tests/ciphers.test @@ -16,19 +16,22 @@ # Constraints set protocols [list ssl2 ssl3 tls1 tls1.1 tls1.2 tls1.3] foreach protocol $protocols {::tcltest::testConstraint $protocol 0} foreach protocol [::tls::protocols] {::tcltest::testConstraint $protocol 1} ::tcltest::testConstraint OpenSSL [string match "OpenSSL*" [::tls::version]] + # Helper functions proc lcompare {list1 list2} {set m "";set u "";foreach i $list1 {if {$i ni $list2} {lappend m $i}};foreach i $list2 {if {$i ni $list1} {lappend u $i}};return [list "missing" $m "unexpected" $u]} proc exec_get {delim args} {return [split [exec openssl {*}$args] $delim]} + # Test protocols test Protocols-1.1 {All} -body { lcompare $protocols [::tls::protocols] } -result {missing {ssl2 ssl3} unexpected {}} + # Test ciphers test CiphersAll-2.1 {SSL2} -constraints {ssl2} -body { lcompare [exec_get ":" ciphers -ssl2] [::tls::ciphers ssl2] @@ -51,10 +54,11 @@ } -result {missing {} unexpected {}} test CiphersAll-2.6 {TLS1.3} -constraints {tls1.3} -body { lcompare [exec_get ":" ciphers -tls1_3] [::tls::ciphers tls1.3] } -result {missing {} unexpected {}} + # Test cipher descriptions test CiphersDesc-3.1 {SSL2} -constraints {ssl2} -body { lcompare [exec_get "\r\n" ciphers -ssl2 -v] [split [string trim [::tls::ciphers ssl2 1]] \n] @@ -77,10 +81,11 @@ } -result {missing {} unexpected {}} test CiphersDesc-3.6 {TLS1.3} -constraints {tls1.3} -body { lcompare [exec_get "\r\n" ciphers -tls1_3 -v] [split [string trim [::tls::ciphers tls1.3 1]] \n] } -result {missing {} unexpected {}} + # Test protocol specific ciphers test CiphersSpecific-4.1 {SSL2} -constraints {ssl2} -body { lcompare [exec_get ":" ciphers -ssl2 -s] [::tls::ciphers ssl2 0 1] @@ -103,10 +108,11 @@ } -result {missing {} unexpected {}} test CiphersSpecific-4.6 {TLS1.3} -constraints {tls1.3} -body { lcompare [exec_get ":" ciphers -tls1_3 -s] [::tls::ciphers tls1.3 0 1] } -result {missing {} unexpected {}} + # Test version test Version-5.1 {All} -body { ::tls::version Index: tests/make_test_files.tcl ================================================================== --- tests/make_test_files.tcl +++ tests/make_test_files.tcl @@ -1,70 +1,104 @@ # # Name: Make Test Files From CSV Files -# Version: 0.2 -# Date: August 6, 2022 +# Version: 0.3 +# Date: March 9, 2024 # Author: Brian O'Hagan # Email: brian199@comcast.net # Legal Notice: (c) Copyright 2020 by Brian O'Hagan # Released under the Apache v2.0 license. I would appreciate a copy of any modifications # made to this package for possible incorporation in a future release. # +# +# Parse CSV line +# +proc parse_csv {ch data} { + set buffer "" + set result [list] + set start 0 + set end [string length $data] + + while {$start < $end} { + if {[string index $data $start] eq "\""} { + # Quoted + if {[set index [string first "\"" $data [incr start]]] > -1} { + set next [string index $data [expr {$index + 1}]] + if {$next eq "\""} { + # Quote + append buffer [string range $data $start $index] + set start [incr index] + + } else { + # End of quoted data + append buffer [string range $data $start [incr index -1]] + set start [incr index 3] + lappend result $buffer + set buffer "" + } + + } else { + # Multi-line + append buffer [string range $data $start end] "\n" + gets $ch new + set data "\"" + append data $new + set start 0 + set end [string length $data] + } + + } else { + # Not quoted, so no embedded NL, quotes, or commas + set index [string first "," $data $start] + if {$index > -1} { + lappend result [string range $data $start [incr index -1]] + set start [incr index 2] + } else { + lappend result [string range $data $start end] + set start [string length $data] + } + } + } + return $result +} + # # Convert test case file into test files # proc process_config_file {filename} { set prev "" set test 0 - # Open file with test case indo + # Open file with test case indo set in [open $filename r] array set cases [list] # Open output test file set out [open [format %s.test [file rootname $filename]] w] array set cases [list] - + # Add setup commands to test file puts $out [format "# Auto generated test cases for %s" [file tail $filename]] #puts $out [format "# Auto generated test cases for %s created on %s" [file tail $filename] [clock format [clock seconds]]] - + # Package requires puts $out "\n# Load Tcl Test package" puts $out [subst -nocommands {if {[lsearch [namespace children] ::tcltest] == -1} {\n\tpackage require tcltest\n\tnamespace import ::tcltest::*\n}\n}] puts $out {set auto_path [concat [list [file dirname [file dirname [info script]]]] $auto_path]} puts $out "" - + # Generate test cases and add to test file while {[gets $in data] > -1} { # Skip comments set data [string trim $data] if {[string match "#*" $data]} continue - # Split comma separated fields with quotes - set list [list] - while {[string length $data] > 0} { - if {[string index $data 0] eq "\""} { - # Quoted - set end [string first "\"," $data] - if {$end == -1} {set end [expr {[string length $data]+1}]} - lappend list [string map [list {""} \"] [string range $data 1 [incr end -1]]] - set data [string range $data [incr end 3] end] - - } else { - # Not quoted, so no embedded NL, quotes, or commas - set index [string first "," $data] - if {$index == -1} {set index [expr {[string length $data]+1}]} - lappend list [string range $data 0 [incr index -1]] - set data [string range $data [incr index 2] end] - } - } + set list [parse_csv $in $data] # Get command or test case foreach {group name constraints setup body cleanup match result output errorOutput returnCodes} $list { if {$group eq "command"} { - # Pass-through command puts $out $name } elseif {$group ne "" && $body ne ""} { set group [string map [list " " "_"] $group] if {$group ne $prev} { @@ -72,11 +106,16 @@ set prev $group puts $out "" } # Test case - set buffer [format "\ntest %s-%d.%d {%s}" $group $test [incr cases($group)] $name] + if {[string index $name 0] ne {$}} { + set buffer [format "\ntest %s-%d.%d {%s}" $group $test [incr cases($group)] $name] + } else { + set buffer [format "\ntest %s-%d.%d %s" $group $test [incr cases($group)] $name] + } + foreach opt [list -constraints -setup -body -cleanup -match -result -output -errorOutput -returnCodes] { set cmd [string trim [set [string trimleft $opt "-"]]] if {$cmd ne ""} { if {$opt in [list -setup -body -cleanup]} { append buffer " " $opt " \{\n" @@ -85,11 +124,11 @@ } append buffer " \}" } elseif {$opt in [list -output -errorOutput]} { append buffer " " $opt " {" $cmd \n "}" } elseif {$opt in [list -result]} { - if {[string index $cmd 0] in [list \[ \" \{]} { + if {[string index $cmd 0] in [list \[ \" \{ \$]} { append buffer " " $opt " " $cmd } elseif {[string match {*[\\$]*} $cmd]} { append buffer " " $opt " \"" [string map [list \\\\\" \\\"] [string map [list \" \\\" ] $cmd]] "\"" } else { append buffer " " $opt " {" $cmd "}" @@ -101,10 +140,11 @@ } puts $out $buffer } else { # Empty line + puts $out "" } break } } @@ -116,8 +156,9 @@ # # Call script # foreach file [glob *.csv] { +puts $file process_config_file $file } exit