Check-in [a1b40a439c]
Overview
Comment:Add SHA-512 support (hacked) and a bit of cleanup
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a1b40a439c8fc9effc2cd08a622d0a9145316d91
User & Date: rkeene on 2022-03-13 20:23:23
Other Links: manifest | tags
Context
2022-03-13
20:46
Make Tcl SSH Agent more standalone Leaf check-in: 2d57dd9864 user: rkeene tags: trunk
20:23
Add SHA-512 support (hacked) and a bit of cleanup check-in: a1b40a439c user: rkeene tags: trunk
20:15
Better error logging in Tcl/JS emulation check-in: f69d4ccb30 user: rkeene tags: trunk
Changes

Modified build/tcl/ssh-agent.tcl from [183583332c] to [bf92e80fb2].

     1      1   #! /usr/bin/env tclsh
            2  +
            3  +set dir [file dirname [info script]]
     2      4   
     3      5   if {[info exists ::env(SSH_AGENT_LIB_PATH)]} {
     4      6   	lappend auto_path {*}$::env(SSH_AGENT_LIB_PATH)
     5      7   }
            8  +
            9  +if {![info exists ::env(SSH_AUTH_SOCK)]} {
           10  +	error "Must set SSH_AUTH_SOCK"
           11  +}
     6     12   
     7     13   if {[info exists ::env(SSH_AGENT_PKCS11_MODULE)]} {
     8     14   	set ::pkcs11ModuleFilename $::env(SSH_AGENT_PKCS11_MODULE)
     9     15   } else {
    10         -	set ::pkcs11ModuleFilename /home/rkeene/tmp/cackey/build/tcl/softokn3-pkcs11.so
           16  +	error "Must set SSH_AGENT_PKCS11_MODULE"
    11     17   }
    12     18   
    13     19   package require duktape 0.7
    14     20   package require tuapi
    15     21   package require pki 0.6
    16     22   package require pki::pkcs11 0.9.9
    17     23   
................................................................................
    24     30   		set body [string map {
    25     31   			"::asn::asnGetSequence cert_seq wholething"
    26     32   			"set ret(raw) $cert_seq; binary scan $ret(raw) H* ret(raw); ::asn::asnGetSequence cert_seq wholething"
    27     33   		} $body]
    28     34   		proc $procToUpdate [info args $procToUpdate] $body
    29     35   	}
    30     36   }}
           37  +
           38  +proc pkcs11ModuleLogin {slot} {
           39  +	set pin [exec cackey-askpass]
           40  +	if {$pin eq ""} {
           41  +		error "No PIN provided"
           42  +	}
           43  +
           44  +	::pki::pkcs11::login $::pkcs11ModuleHandle $slot $pin
           45  +}
    31     46   
    32     47   proc pkcs11ModuleHandle {} {
    33     48   	if {![info exists ::pkcs11ModuleHandle]} {
    34     49   		set ::pkcs11ModuleHandle [::pki::pkcs11::loadmodule $::pkcs11ModuleFilename]
    35     50   	}
    36     51   	return $::pkcs11ModuleHandle
    37     52   }
................................................................................
    80     95   		\}"
    81     96   
    82     97   		return $retval
    83     98   	}
    84     99   
    85    100   	::duktape::tcl-function $jsHandle __crypto_subtle_digest bytearray {hash data} {
    86    101   		switch -exact -- $hash {
          102  +			"SHA-512" {
          103  +				set data_b64 [binary encode base64 $data]
          104  +				set checksum [exec base64 -d << $data_b64 | sha512sum]
          105  +				set checksum [lindex [split $checksum] 0]
          106  +				return [binary decode hex $checksum]
          107  +			}
    87    108   			"SHA-256" {
    88    109   				package require sha256
    89    110   				return [::sha2::sha256 -- $data]
    90    111   			}
    91    112   			"SHA-1" {
    92    113   				package require sha1
    93    114   				return [::sha1::sha1 -- $data]
................................................................................
   131    152   		}
   132    153   		X509.parseCert = __parseCert;
   133    154   		delete __parseCert;
   134    155   	}
   135    156   }
   136    157   
   137    158   proc readFile {fileName} {
          159  +	set fileName [file join $::dir $fileName]
   138    160   	if {![info exists ::readFile($fileName)]} {
   139    161   		catch {
   140    162   			set fd [open $fileName]
   141    163   			set ::readFile($fileName) [read $fd]
   142    164   		}
   143    165   		catch {
   144    166   			close $fd
................................................................................
   172    194   	}
   173    195   
   174    196   	::duktape::eval $jsHandle {var goog = {DEBUG: false};}
   175    197   	::duktape::eval $jsHandle [readFile chrome-emu.js]
   176    198   	addRSAToJS $jsHandle
   177    199   	::duktape::eval $jsHandle [readFile ssh-agent-noasync.js]
   178    200   	::duktape::eval $jsHandle {cackeySSHAgentFeatures.enabled = true;}
   179         -	::duktape::eval $jsHandle {cackeySSHAgentFeatures.includeCerts = false;}
          201  +	::duktape::eval $jsHandle {cackeySSHAgentFeatures.includeCerts = true;}
   180    202   	::duktape::eval $jsHandle {cackeySSHAgentFeatures.legacy = false;}
   181    203   	::duktape::eval $jsHandle {
   182    204   		function connection(callback) {
   183    205   			this.sender = {
   184    206   				id: "pnhechapfaindjhompbnflcldabbghjo"
   185    207   			};
   186    208   			this.onMessage = {
................................................................................
   312    334   		set certInfo [listCerts $handle $cert]
   313    335   		if {![dict exists $certInfo pkcs11_slotid]} {
   314    336   			pkcs11ModuleUnload $handle
   315    337   			return -code error "Unable to find certificate to sign with"
   316    338   		}
   317    339   
   318    340   		set slotId [dict get $certInfo pkcs11_slotid]
   319         -		set data [::pki::sign $message $certInfo raw]
          341  +		try {
          342  +			set data [::pki::sign $message $certInfo raw]
          343  +		} on error {} {
          344  +			pkcs11ModuleLogin $slotId
          345  +
          346  +			set data [::pki::sign $message $certInfo raw]
          347  +		}
   320    348   
   321    349   		return $data
   322    350   	}
   323    351   
   324         -	::duktape::tcl-function $jsHandle cackeyListCertificatesBare {arraylist bytearray} {} {
          352  +	::duktape::tcl-function $jsHandle cackeyListCertificatesBare {array bytearray} {} {
   325    353   		set handle [pkcs11ModuleHandle]
   326         -		return [listCerts $handle]
          354  +		set retval [listCerts $handle]
          355  +		return $retval
   327    356   	}
   328    357   
   329    358   	return $jsHandle
   330    359   }
   331    360   
   332    361   proc listCerts {handle {match ""}} {
   333    362   	set certs [list]
   334    363   
   335    364   	set slots [::pki::pkcs11::listslots $handle]
   336    365   	foreach slotInfo $slots {
   337    366   		set slotId [lindex $slotInfo 0]
   338    367   		set slotLabel [lindex $slotInfo 1]
   339    368   		set slotFlags [lindex $slotInfo 2]
          369  +
          370  +		# Skip missing tokens
          371  +		if {"TOKEN_PRESENT" ni $slotFlags} {
          372  +			continue
          373  +		}
   340    374   
   341    375   		set slotCerts [::pki::pkcs11::listcerts $handle $slotId]
   342    376   		foreach keyList $slotCerts {
   343    377   			set cert [dict get $keyList raw]
   344    378   			set cert [binary decode hex $cert]
   345    379   			if {$match eq $cert} {
   346    380   				return $keyList
   347    381   			}
   348    382   			lappend certs $cert
   349    383   		}
   350    384   	}
   351    385   
   352    386   	if {$match ne ""} {
   353         -		return [list]
          387  +		set certs [list]
          388  +	}
          389  +
          390  +	if {[llength $certs] == 0} {
          391  +		pkcs11ModuleUnload $handle
   354    392   	}
   355    393   
   356    394   	return $certs
   357    395   }
   358    396   
   359    397   proc handleData {sock jsHandle} {
   360    398   	if {[catch {
................................................................................
   380    418   		fileevent $sock readable [list handleData $sock $jsHandle]
   381    419   	}]} {
   382    420   		puts stderr "ERROR: $::errorInfo"
   383    421   		close $sock
   384    422   	}
   385    423   }
   386    424   
   387         -::tuapi::syscall::socket_unix -server incomingConnection "./agent"
          425  +::tuapi::syscall::socket_unix -server incomingConnection $::env(SSH_AUTH_SOCK)
   388    426   
   389    427   vwait forever