Diff

Differences From Artifact [2e09ba053f]:

To Artifact [af3233ef21]:


    20     20   	}
    21     21   }
    22     22   
    23     23   namespace eval ::appfs {
    24     24   	variable cachedir "/tmp/appfs-cache"
    25     25   	variable ttl 3600
    26     26   	variable nttl 60
    27         -
           27  +	variable trusted_cas [list]
    28     28   
    29     29   	proc _hash_sep {hash {seps 4}} {
    30     30   		for {set idx 0} {$idx < $seps} {incr idx} {
    31     31   			append retval "[string range $hash [expr {$idx * 2}] [expr {($idx * 2) + 1}]]/"
    32     32   		}
    33     33   		append retval "[string range $hash [expr {$idx * 2}] end]"
    34     34   
................................................................................
    93     93   		if {![regexp {^[0-9a-f]*$} $value]} {
    94     94   			return false
    95     95   		}
    96     96   
    97     97   		return true
    98     98   	}
    99     99   
   100         -	proc _verifySignatureAndCertificate {certificate signature} {
          100  +	proc _verifySignatureAndCertificate {hostname certificate signature hash} {
          101  +		set certificate [binary format "H*" $certificate]
          102  +		set signature   [binary format "H*" $signature]
          103  +
          104  +		set certificate [::pki::x509::parse_cert $certificate]
          105  +
          106  +		array set certificate_arr $certificate
          107  +		set certificate_cn [::pki::x509::_dn_to_cn $certificate_arr(subject)]
          108  +
          109  +		if {![::pki::verify $signature "$hash,sha1" $certificate]} {
          110  +			return false
          111  +		}
          112  +
          113  +		if {[string tolower $certificate_cn] != [string tolower $hostname]} {
          114  +			return false
          115  +		}
          116  +
          117  +		if {![::pki::x509::verify_cert $certificate $::appfs::trusted_cas]} {
          118  +			return false
          119  +		}
          120  +
   101    121   		return true
   102    122   	}
   103    123   
   104    124   	proc _normalizeOS {os} {
   105    125   		set os [string tolower [string trim $os]]
   106    126   
   107    127   		switch -- $os {
................................................................................
   148    168   	}
   149    169   
   150    170   	proc init {} {
   151    171   		if {[info exists ::appfs::init_called]} {
   152    172   			return
   153    173   		}
   154    174   
   155         -		# Force [parray] to be loaded
          175  +		# Force [parray] and [clock] to be loaded
   156    176   		catch {
   157    177   			parray does_not_exist
   158    178   		}
          179  +		catch {
          180  +			clock seconds
          181  +		}
          182  +		catch {
          183  +			clock add [clock seconds] 3 seconds
          184  +		}
   159    185   
   160    186   		set ::appfs::init_called 1
          187  +
          188  +		# Add a default CA to list of trusted CAs
          189  +		lappend ::appfs::trusted_cas [::pki::x509::parse_cert {
          190  +-----BEGIN CERTIFICATE-----
          191  +MIIC7DCCAdSgAwIBAgIBATANBgkqhkiG9w0BAQUFADAvMRIwEAYDVQQKEwlSb3kg
          192  +S2VlbmUxGTAXBgNVBAMTEEFwcEZTIEtleSBNYXN0ZXIwHhcNMTQxMTE3MjAxNzI4
          193  +WhcNMTkxMTE3MjAxNzI4WjAvMRIwEAYDVQQKEwlSb3kgS2VlbmUxGTAXBgNVBAMT
          194  +EEFwcEZTIEtleSBNYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
          195  +AQCq6uSK46yG5b6RJWwRlvw5glAnjsc1GiX3duXA0vG4qnKUnDtl/jcMmq2GMOB9
          196  +Iy1tjabEHA0MhW2j7Vwe/O9MLFJkJ30M1PVD7YZRRNaAsz3UWIKEjPI7BBc32KOm
          197  +BL3CTXCCdzllL1HhVbnM5iCAmgHcg1DUk/EvWXvnEDxXRy2lV9mQsmDedrffY7Wl
          198  +Or57nlczaMuPLpyRSkv75PAnjQJxT3sWlBpy+/H9ImudQdpJNf/FtxcqN7iDwH5B
          199  +vIceYEtDVxFsvo5HOVkSl9jeo5E4Gpe3wyfRhoqB2UkaW1Kq0iH5R+00S760xQMx
          200  +LL9L1duhu1dL7HsmEw7IeYURAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
          201  +KoZIhvcNAQEFBQADggEBAKhO4ZSzYP37BqixNHKK9+gSeC6Fga85iLWhwpPW0kSl
          202  +z03hal80KZ+kPMzb8C52N283tQNAqJ9Q8akDPZxSzzMUVOGpGw2pJ7ZswKDz0ZTa
          203  +0edq/gdT/HrdegvNtDPc2jona5FVOYqwdcz5kbl1UWBaBp3VXUgcYjXSRaBK43Wd
          204  +cveiDUeZw7gHqRSN/AyYUCtJzWmvGsJuIFhMBonuz8jylhyMJCYJFT4iMUC8MNIw
          205  +niX1xx+Nu6fPV5ZZHj9rbhiBaLjm+tkDwtPgA3j2pxvHKYptuWxeYO+9DDNa9sCb
          206  +E5AnJIlOnd/tGe0Chf0sFQg+l9nNiNrWGgzdd9ZPJK4=
          207  +-----END CERTIFICATE-----
          208  +}]
   161    209   
   162    210   		# Load configuration file
   163    211   		set config_file [file join $::appfs::cachedir config]
   164    212   		if {[file exists $config_file]} {
   165    213   			source $config_file
   166    214   		}
   167    215   
................................................................................
   239    287   		set indexhashcert   [lindex $indexhash_data 2]
   240    288   		set indexhashsig    [lindex $indexhash_data 3]
   241    289   
   242    290   		if {![_isHash $indexhash]} {
   243    291   			return -code error "Invalid hash: $indexhash"
   244    292   		}
   245    293   
   246         -		if {![_verifySignatureAndCertificate $indexhashcert $indexhashsig]} {
          294  +		if {![_verifySignatureAndCertificate $hostname $indexhashcert $indexhashsig $indexhash]} {
   247    295   			return -code error "Invalid signature or certificate from $hostname"
   248    296   		}
   249    297   
   250    298   		set file [download $hostname $indexhash]
   251    299   		set fd [open $file]
   252    300   		set data [read $fd]
   253    301   		close $fd