Hex Artifact Content

Artifact 973f5211faa50d080b4fc668dd7bb950aa61b20f:


0000: 23 21 20 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20  #! /usr/bin/env 
0010: 74 63 6c 73 68 0a 0a 73 65 74 20 64 69 72 20 5b  tclsh..set dir [
0020: 66 69 6c 65 20 64 69 72 6e 61 6d 65 20 5b 69 6e  file dirname [in
0030: 66 6f 20 73 63 72 69 70 74 5d 5d 0a 0a 69 66 20  fo script]]..if 
0040: 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a  {[info exists ::
0050: 65 6e 76 28 53 53 48 5f 41 47 45 4e 54 5f 4c 49  env(SSH_AGENT_LI
0060: 42 5f 50 41 54 48 29 5d 7d 20 7b 0a 09 6c 61 70  B_PATH)]} {..lap
0070: 70 65 6e 64 20 61 75 74 6f 5f 70 61 74 68 20 7b  pend auto_path {
0080: 2a 7d 24 3a 3a 65 6e 76 28 53 53 48 5f 41 47 45  *}$::env(SSH_AGE
0090: 4e 54 5f 4c 49 42 5f 50 41 54 48 29 0a 7d 0a 0a  NT_LIB_PATH).}..
00a0: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
00b0: 73 20 3a 3a 65 6e 76 28 53 53 48 5f 41 55 54 48  s ::env(SSH_AUTH
00c0: 5f 53 4f 43 4b 29 5d 7d 20 7b 0a 09 65 72 72 6f  _SOCK)]} {..erro
00d0: 72 20 22 4d 75 73 74 20 73 65 74 20 53 53 48 5f  r "Must set SSH_
00e0: 41 55 54 48 5f 53 4f 43 4b 22 0a 7d 0a 0a 69 66  AUTH_SOCK".}..if
00f0: 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74 73 20 3a   {[info exists :
0100: 3a 65 6e 76 28 53 53 48 5f 41 47 45 4e 54 5f 50  :env(SSH_AGENT_P
0110: 4b 43 53 31 31 5f 4d 4f 44 55 4c 45 29 5d 7d 20  KCS11_MODULE)]} 
0120: 7b 0a 09 73 65 74 20 3a 3a 70 6b 63 73 31 31 4d  {..set ::pkcs11M
0130: 6f 64 75 6c 65 46 69 6c 65 6e 61 6d 65 20 24 3a  oduleFilename $:
0140: 3a 65 6e 76 28 53 53 48 5f 41 47 45 4e 54 5f 50  :env(SSH_AGENT_P
0150: 4b 43 53 31 31 5f 4d 4f 44 55 4c 45 29 0a 7d 20  KCS11_MODULE).} 
0160: 65 6c 73 65 20 7b 0a 09 65 72 72 6f 72 20 22 4d  else {..error "M
0170: 75 73 74 20 73 65 74 20 53 53 48 5f 41 47 45 4e  ust set SSH_AGEN
0180: 54 5f 50 4b 43 53 31 31 5f 4d 4f 44 55 4c 45 22  T_PKCS11_MODULE"
0190: 0a 7d 0a 0a 70 61 63 6b 61 67 65 20 72 65 71 75  .}..package requ
01a0: 69 72 65 20 64 75 6b 74 61 70 65 20 30 2e 37 0a  ire duktape 0.7.
01b0: 70 61 63 6b 61 67 65 20 72 65 71 75 69 72 65 20  package require 
01c0: 74 75 61 70 69 0a 70 61 63 6b 61 67 65 20 72 65  tuapi.package re
01d0: 71 75 69 72 65 20 70 6b 69 20 30 2e 36 0a 70 61  quire pki 0.6.pa
01e0: 63 6b 61 67 65 20 72 65 71 75 69 72 65 20 70 6b  ckage require pk
01f0: 69 3a 3a 70 6b 63 73 31 31 20 30 2e 39 2e 39 0a  i::pkcs11 0.9.9.
0200: 0a 23 20 46 69 6c 65 73 0a 73 65 74 20 3a 3a 66  .# Files.set ::f
0210: 69 6c 65 73 28 63 68 72 6f 6d 65 2d 65 6d 75 2e  iles(chrome-emu.
0220: 6a 73 29 20 7b 0a 40 40 43 48 52 4f 4d 45 5f 45  js) {.@@CHROME_E
0230: 4d 55 5f 4a 53 40 40 0a 7d 0a 0a 73 65 74 20 3a  MU_JS@@.}..set :
0240: 3a 66 69 6c 65 73 28 73 73 68 2d 61 67 65 6e 74  :files(ssh-agent
0250: 2d 6e 6f 61 73 79 6e 63 2e 6a 73 29 20 7b 0a 40  -noasync.js) {.@
0260: 40 53 53 48 5f 41 47 45 4e 54 5f 4e 4f 41 53 59  @SSH_AGENT_NOASY
0270: 4e 43 5f 4a 53 40 40 0a 7d 0a 0a 23 23 20 48 41  NC_JS@@.}..## HA
0280: 43 4b 3a 20 46 69 78 20 75 70 20 6f 6c 64 65 72  CK: Fix up older
0290: 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 22 70 6b   versions of "pk
02a0: 69 22 20 74 6f 20 69 6e 63 6c 75 64 65 20 74 68  i" to include th
02b0: 65 20 72 61 77 20 63 65 72 74 69 66 69 63 61 74  e raw certificat
02c0: 65 0a 23 23 20 20 20 20 20 20 20 74 68 69 73 20  e.##       this 
02d0: 69 73 20 6e 65 65 64 65 64 0a 61 70 70 6c 79 20  is needed.apply 
02e0: 7b 7b 7d 20 7b 0a 09 73 65 74 20 70 72 6f 63 54  {{} {..set procT
02f0: 6f 55 70 64 61 74 65 20 3a 3a 70 6b 69 3a 3a 78  oUpdate ::pki::x
0300: 35 30 39 3a 3a 70 61 72 73 65 5f 63 65 72 74 0a  509::parse_cert.
0310: 09 69 66 20 7b 21 5b 73 74 72 69 6e 67 20 6d 61  .if {![string ma
0320: 74 63 68 20 22 2a 73 65 74 20 72 65 74 28 72 61  tch "*set ret(ra
0330: 77 29 2a 22 20 5b 69 6e 66 6f 20 62 6f 64 79 20  w)*" [info body 
0340: 24 70 72 6f 63 54 6f 55 70 64 61 74 65 5d 5d 7d  $procToUpdate]]}
0350: 20 7b 0a 09 09 73 65 74 20 62 6f 64 79 20 5b 69   {...set body [i
0360: 6e 66 6f 20 62 6f 64 79 20 24 70 72 6f 63 54 6f  nfo body $procTo
0370: 55 70 64 61 74 65 5d 0a 09 09 73 65 74 20 62 6f  Update]...set bo
0380: 64 79 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 7b  dy [string map {
0390: 0a 09 09 09 22 3a 3a 61 73 6e 3a 3a 61 73 6e 47  ...."::asn::asnG
03a0: 65 74 53 65 71 75 65 6e 63 65 20 63 65 72 74 5f  etSequence cert_
03b0: 73 65 71 20 77 68 6f 6c 65 74 68 69 6e 67 22 0a  seq wholething".
03c0: 09 09 09 22 73 65 74 20 72 65 74 28 72 61 77 29  ..."set ret(raw)
03d0: 20 24 63 65 72 74 5f 73 65 71 3b 20 62 69 6e 61   $cert_seq; bina
03e0: 72 79 20 73 63 61 6e 20 24 72 65 74 28 72 61 77  ry scan $ret(raw
03f0: 29 20 48 2a 20 72 65 74 28 72 61 77 29 3b 20 3a  ) H* ret(raw); :
0400: 3a 61 73 6e 3a 3a 61 73 6e 47 65 74 53 65 71 75  :asn::asnGetSequ
0410: 65 6e 63 65 20 63 65 72 74 5f 73 65 71 20 77 68  ence cert_seq wh
0420: 6f 6c 65 74 68 69 6e 67 22 0a 09 09 7d 20 24 62  olething"...} $b
0430: 6f 64 79 5d 0a 09 09 70 72 6f 63 20 24 70 72 6f  ody]...proc $pro
0440: 63 54 6f 55 70 64 61 74 65 20 5b 69 6e 66 6f 20  cToUpdate [info 
0450: 61 72 67 73 20 24 70 72 6f 63 54 6f 55 70 64 61  args $procToUpda
0460: 74 65 5d 20 24 62 6f 64 79 0a 09 7d 0a 7d 7d 0a  te] $body..}.}}.
0470: 0a 70 72 6f 63 20 70 6b 63 73 31 31 4d 6f 64 75  .proc pkcs11Modu
0480: 6c 65 4c 6f 67 69 6e 20 7b 73 6c 6f 74 7d 20 7b  leLogin {slot} {
0490: 0a 09 73 65 74 20 70 69 6e 20 5b 65 78 65 63 20  ..set pin [exec 
04a0: 63 61 63 6b 65 79 2d 61 73 6b 70 61 73 73 5d 0a  cackey-askpass].
04b0: 09 69 66 20 7b 24 70 69 6e 20 65 71 20 22 22 7d  .if {$pin eq ""}
04c0: 20 7b 0a 09 09 65 72 72 6f 72 20 22 4e 6f 20 50   {...error "No P
04d0: 49 4e 20 70 72 6f 76 69 64 65 64 22 0a 09 7d 0a  IN provided"..}.
04e0: 0a 09 3a 3a 70 6b 69 3a 3a 70 6b 63 73 31 31 3a  ..::pki::pkcs11:
04f0: 3a 6c 6f 67 69 6e 20 24 3a 3a 70 6b 63 73 31 31  :login $::pkcs11
0500: 4d 6f 64 75 6c 65 48 61 6e 64 6c 65 20 24 73 6c  ModuleHandle $sl
0510: 6f 74 20 24 70 69 6e 0a 7d 0a 0a 70 72 6f 63 20  ot $pin.}..proc 
0520: 70 6b 63 73 31 31 4d 6f 64 75 6c 65 48 61 6e 64  pkcs11ModuleHand
0530: 6c 65 20 7b 7d 20 7b 0a 09 69 66 20 7b 21 5b 69  le {} {..if {![i
0540: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 70 6b 63  nfo exists ::pkc
0550: 73 31 31 4d 6f 64 75 6c 65 48 61 6e 64 6c 65 5d  s11ModuleHandle]
0560: 7d 20 7b 0a 09 09 73 65 74 20 3a 3a 70 6b 63 73  } {...set ::pkcs
0570: 31 31 4d 6f 64 75 6c 65 48 61 6e 64 6c 65 20 5b  11ModuleHandle [
0580: 3a 3a 70 6b 69 3a 3a 70 6b 63 73 31 31 3a 3a 6c  ::pki::pkcs11::l
0590: 6f 61 64 6d 6f 64 75 6c 65 20 24 3a 3a 70 6b 63  oadmodule $::pkc
05a0: 73 31 31 4d 6f 64 75 6c 65 46 69 6c 65 6e 61 6d  s11ModuleFilenam
05b0: 65 5d 0a 09 7d 0a 09 72 65 74 75 72 6e 20 24 3a  e]..}..return $:
05c0: 3a 70 6b 63 73 31 31 4d 6f 64 75 6c 65 48 61 6e  :pkcs11ModuleHan
05d0: 64 6c 65 0a 7d 0a 0a 70 72 6f 63 20 70 6b 63 73  dle.}..proc pkcs
05e0: 31 31 4d 6f 64 75 6c 65 55 6e 6c 6f 61 64 20 7b  11ModuleUnload {
05f0: 68 61 6e 64 6c 65 7d 20 7b 0a 09 69 66 20 7b 5b  handle} {..if {[
0600: 69 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 70 6b  info exists ::pk
0610: 63 73 31 31 4d 6f 64 75 6c 65 48 61 6e 64 6c 65  cs11ModuleHandle
0620: 5d 20 26 26 20 24 68 61 6e 64 6c 65 20 65 71 20  ] && $handle eq 
0630: 24 3a 3a 70 6b 63 73 31 31 4d 6f 64 75 6c 65 48  $::pkcs11ModuleH
0640: 61 6e 64 6c 65 7d 20 7b 0a 09 09 75 6e 73 65 74  andle} {...unset
0650: 20 3a 3a 70 6b 63 73 31 31 4d 6f 64 75 6c 65 48   ::pkcs11ModuleH
0660: 61 6e 64 6c 65 0a 09 7d 0a 09 3a 3a 70 6b 69 3a  andle..}..::pki:
0670: 3a 70 6b 63 73 31 31 3a 3a 75 6e 6c 6f 61 64 6d  :pkcs11::unloadm
0680: 6f 64 75 6c 65 20 24 68 61 6e 64 6c 65 0a 7d 0a  odule $handle.}.
0690: 0a 70 72 6f 63 20 61 64 64 52 53 41 54 6f 4a 53  .proc addRSAToJS
06a0: 20 7b 6a 73 48 61 6e 64 6c 65 7d 20 7b 0a 09 3a   {jsHandle} {..:
06b0: 3a 64 75 6b 74 61 70 65 3a 3a 74 63 6c 2d 66 75  :duktape::tcl-fu
06c0: 6e 63 74 69 6f 6e 20 24 6a 73 48 61 6e 64 6c 65  nction $jsHandle
06d0: 20 5f 5f 70 61 72 73 65 43 65 72 74 20 6a 73 6f   __parseCert jso
06e0: 6e 20 7b 63 65 72 74 7d 20 7b 0a 09 09 73 65 74  n {cert} {...set
06f0: 20 63 65 72 74 20 5b 62 69 6e 61 72 79 20 64 65   cert [binary de
0700: 63 6f 64 65 20 68 65 78 20 24 63 65 72 74 5d 0a  code hex $cert].
0710: 09 09 69 66 20 7b 5b 63 61 74 63 68 20 7b 0a 09  ..if {[catch {..
0720: 09 09 73 65 74 20 63 65 72 74 20 5b 3a 3a 70 6b  ..set cert [::pk
0730: 69 3a 3a 78 35 30 39 3a 3a 70 61 72 73 65 5f 63  i::x509::parse_c
0740: 65 72 74 20 24 63 65 72 74 5d 0a 09 09 7d 5d 7d  ert $cert]...}]}
0750: 20 7b 0a 09 09 09 72 65 74 75 72 6e 20 22 22 0a   {....return "".
0760: 09 09 7d 0a 0a 09 09 73 65 74 20 65 20 5b 66 6f  ..}....set e [fo
0770: 72 6d 61 74 20 25 6c 6c 78 20 5b 64 69 63 74 20  rmat %llx [dict 
0780: 67 65 74 20 24 63 65 72 74 20 65 5d 5d 0a 09 09  get $cert e]]...
0790: 73 65 74 20 6e 20 5b 66 6f 72 6d 61 74 20 25 6c  set n [format %l
07a0: 6c 78 20 5b 64 69 63 74 20 67 65 74 20 24 63 65  lx [dict get $ce
07b0: 72 74 20 6e 5d 5d 0a 0a 09 09 23 20 50 61 64 20  rt n]]....# Pad 
07c0: 74 6f 20 65 76 65 6e 20 73 69 7a 65 20 66 6f 72  to even size for
07d0: 20 68 65 78 20 77 69 64 74 68 0a 09 09 69 66 20   hex width...if 
07e0: 7b 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20  {[string length 
07f0: 24 65 5d 20 25 20 32 20 21 3d 20 30 7d 20 7b 0a  $e] % 2 != 0} {.
0800: 09 09 09 73 65 74 20 65 20 22 30 24 65 22 0a 09  ...set e "0$e"..
0810: 09 7d 0a 09 09 69 66 20 7b 5b 73 74 72 69 6e 67  .}...if {[string
0820: 20 6c 65 6e 67 74 68 20 24 6e 5d 20 25 20 32 20   length $n] % 2 
0830: 21 3d 20 30 7d 20 7b 0a 09 09 09 73 65 74 20 6e  != 0} {....set n
0840: 20 22 30 24 6e 22 0a 09 09 7d 0a 0a 09 09 23 20   "0$n"...}....# 
0850: 41 64 64 20 61 20 6c 65 61 64 69 6e 67 20 7a 65  Add a leading ze
0860: 72 6f 20 69 66 20 74 68 65 20 76 61 6c 75 65 20  ro if the value 
0870: 69 73 20 68 69 67 68 20 65 6e 6f 75 67 68 0a 09  is high enough..
0880: 09 69 66 20 7b 22 30 78 5b 73 74 72 69 6e 67 20  .if {"0x[string 
0890: 72 61 6e 67 65 20 24 6e 20 30 20 31 5d 22 20 3e  range $n 0 1]" >
08a0: 20 30 78 37 66 7d 20 7b 0a 09 09 09 73 65 74 20   0x7f} {....set 
08b0: 6e 20 22 30 30 24 6e 22 0a 09 09 7d 0a 0a 09 09  n "00$n"...}....
08c0: 73 65 74 20 72 65 74 76 61 6c 20 22 5c 7b 0a 09  set retval "\{..
08d0: 09 09 5c 22 70 75 62 6c 69 63 4b 65 79 5c 22 3a  ..\"publicKey\":
08e0: 20 5c 7b 0a 09 09 09 09 5c 22 74 79 70 65 5c 22   \{.....\"type\"
08f0: 3a 5c 22 5b 73 74 72 69 6e 67 20 74 6f 75 70 70  :\"[string toupp
0900: 65 72 20 5b 64 69 63 74 20 67 65 74 20 24 63 65  er [dict get $ce
0910: 72 74 20 74 79 70 65 5d 5d 5c 22 2c 0a 09 09 09  rt type]]\",....
0920: 09 5c 22 65 5c 22 3a 5c 22 24 65 5c 22 2c 0a 09  .\"e\":\"$e\",..
0930: 09 09 09 5c 22 6e 5c 22 3a 5c 22 24 6e 5c 22 0a  ...\"n\":\"$n\".
0940: 09 09 09 5c 7d 2c 0a 09 09 09 5c 22 73 75 62 6a  ...\},....\"subj
0950: 65 63 74 5c 22 3a 20 5c 22 5b 64 69 63 74 20 67  ect\": \"[dict g
0960: 65 74 20 24 63 65 72 74 20 73 75 62 6a 65 63 74  et $cert subject
0970: 5d 5c 22 2c 0a 09 09 09 5c 22 69 73 73 75 65 72  ]\",....\"issuer
0980: 5c 22 3a 20 5c 22 5b 64 69 63 74 20 67 65 74 20  \": \"[dict get 
0990: 24 63 65 72 74 20 69 73 73 75 65 72 5d 5c 22 2c  $cert issuer]\",
09a0: 0a 09 09 09 5c 22 73 65 72 69 61 6c 5c 22 3a 20  ....\"serial\": 
09b0: 5c 22 5b 64 69 63 74 20 67 65 74 20 24 63 65 72  \"[dict get $cer
09c0: 74 20 73 65 72 69 61 6c 5f 6e 75 6d 62 65 72 5d  t serial_number]
09d0: 5c 22 0a 09 09 5c 7d 22 0a 0a 09 09 72 65 74 75  \"...\}"....retu
09e0: 72 6e 20 24 72 65 74 76 61 6c 0a 09 7d 0a 0a 09  rn $retval..}...
09f0: 3a 3a 64 75 6b 74 61 70 65 3a 3a 74 63 6c 2d 66  ::duktape::tcl-f
0a00: 75 6e 63 74 69 6f 6e 20 24 6a 73 48 61 6e 64 6c  unction $jsHandl
0a10: 65 20 5f 5f 63 72 79 70 74 6f 5f 73 75 62 74 6c  e __crypto_subtl
0a20: 65 5f 64 69 67 65 73 74 20 62 79 74 65 61 72 72  e_digest bytearr
0a30: 61 79 20 7b 68 61 73 68 20 64 61 74 61 7d 20 7b  ay {hash data} {
0a40: 0a 09 09 73 77 69 74 63 68 20 2d 65 78 61 63 74  ...switch -exact
0a50: 20 2d 2d 20 24 68 61 73 68 20 7b 0a 09 09 09 22   -- $hash {...."
0a60: 53 48 41 2d 35 31 32 22 20 7b 0a 09 09 09 09 73  SHA-512" {.....s
0a70: 65 74 20 64 61 74 61 5f 62 36 34 20 5b 62 69 6e  et data_b64 [bin
0a80: 61 72 79 20 65 6e 63 6f 64 65 20 62 61 73 65 36  ary encode base6
0a90: 34 20 24 64 61 74 61 5d 0a 09 09 09 09 73 65 74  4 $data].....set
0aa0: 20 63 68 65 63 6b 73 75 6d 20 5b 65 78 65 63 20   checksum [exec 
0ab0: 62 61 73 65 36 34 20 2d 64 20 3c 3c 20 24 64 61  base64 -d << $da
0ac0: 74 61 5f 62 36 34 20 7c 20 73 68 61 35 31 32 73  ta_b64 | sha512s
0ad0: 75 6d 5d 0a 09 09 09 09 73 65 74 20 63 68 65 63  um].....set chec
0ae0: 6b 73 75 6d 20 5b 6c 69 6e 64 65 78 20 5b 73 70  ksum [lindex [sp
0af0: 6c 69 74 20 24 63 68 65 63 6b 73 75 6d 5d 20 30  lit $checksum] 0
0b00: 5d 0a 09 09 09 09 72 65 74 75 72 6e 20 5b 62 69  ].....return [bi
0b10: 6e 61 72 79 20 64 65 63 6f 64 65 20 68 65 78 20  nary decode hex 
0b20: 24 63 68 65 63 6b 73 75 6d 5d 0a 09 09 09 7d 0a  $checksum]....}.
0b30: 09 09 09 22 53 48 41 2d 32 35 36 22 20 7b 0a 09  ..."SHA-256" {..
0b40: 09 09 09 70 61 63 6b 61 67 65 20 72 65 71 75 69  ...package requi
0b50: 72 65 20 73 68 61 32 35 36 0a 09 09 09 09 72 65  re sha256.....re
0b60: 74 75 72 6e 20 5b 3a 3a 73 68 61 32 3a 3a 73 68  turn [::sha2::sh
0b70: 61 32 35 36 20 2d 2d 20 24 64 61 74 61 5d 0a 09  a256 -- $data]..
0b80: 09 09 7d 0a 09 09 09 22 53 48 41 2d 31 22 20 7b  ..}...."SHA-1" {
0b90: 0a 09 09 09 09 70 61 63 6b 61 67 65 20 72 65 71  .....package req
0ba0: 75 69 72 65 20 73 68 61 31 0a 09 09 09 09 72 65  uire sha1.....re
0bb0: 74 75 72 6e 20 5b 3a 3a 73 68 61 31 3a 3a 73 68  turn [::sha1::sh
0bc0: 61 31 20 2d 2d 20 24 64 61 74 61 5d 0a 09 09 09  a1 -- $data]....
0bd0: 7d 0a 09 09 09 64 65 66 61 75 6c 74 20 7b 0a 09  }....default {..
0be0: 09 09 09 65 72 72 6f 72 20 22 48 61 73 68 20 6e  ...error "Hash n
0bf0: 6f 74 20 73 75 70 70 6f 72 74 65 64 3a 20 24 68  ot supported: $h
0c00: 61 73 68 22 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d  ash"....}...}..}
0c10: 0a 0a 09 3a 3a 64 75 6b 74 61 70 65 3a 3a 65 76  ...::duktape::ev
0c20: 61 6c 20 24 6a 73 48 61 6e 64 6c 65 20 7b 0a 09  al $jsHandle {..
0c30: 09 63 72 79 70 74 6f 2e 73 75 62 74 6c 65 2e 64  .crypto.subtle.d
0c40: 69 67 65 73 74 2e 69 6e 74 65 72 6e 61 6c 20 3d  igest.internal =
0c50: 20 5f 5f 63 72 79 70 74 6f 5f 73 75 62 74 6c 65   __crypto_subtle
0c60: 5f 64 69 67 65 73 74 3b 0a 09 09 64 65 6c 65 74  _digest;...delet
0c70: 65 20 5f 5f 63 72 79 70 74 6f 5f 73 75 62 74 6c  e __crypto_subtl
0c80: 65 5f 64 69 67 65 73 74 3b 0a 09 7d 0a 0a 09 3a  e_digest;..}...:
0c90: 3a 64 75 6b 74 61 70 65 3a 3a 65 76 61 6c 20 24  :duktape::eval $
0ca0: 6a 73 48 61 6e 64 6c 65 20 7b 0a 09 09 66 75 6e  jsHandle {...fun
0cb0: 63 74 69 6f 6e 20 58 35 30 39 28 29 20 7b 0a 09  ction X509() {..
0cc0: 09 09 74 68 69 73 2e 68 65 78 20 3d 20 22 22 3b  ..this.hex = "";
0cd0: 0a 09 09 09 74 68 69 73 2e 72 65 61 64 43 65 72  ....this.readCer
0ce0: 74 48 65 78 20 3d 20 66 75 6e 63 74 69 6f 6e 28  tHex = function(
0cf0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 09 74 68  string) {.....th
0d00: 69 73 2e 68 65 78 20 3d 20 73 74 72 69 6e 67 3b  is.hex = string;
0d10: 0a 09 09 09 7d 3b 0a 09 09 09 74 68 69 73 2e 63  ....};....this.c
0d20: 6f 6d 70 75 74 65 43 65 72 74 44 61 74 61 20 3d  omputeCertData =
0d30: 20 66 75 6e 63 74 69 6f 6e 28 29 20 7b 0a 09 09   function() {...
0d40: 09 09 69 66 20 28 74 68 69 73 2e 63 65 72 74 44  ..if (this.certD
0d50: 61 74 61 29 20 7b 0a 09 09 09 09 09 72 65 74 75  ata) {......retu
0d60: 72 6e 3b 0a 09 09 09 09 7d 0a 09 09 09 09 74 68  rn;.....}.....th
0d70: 69 73 2e 63 65 72 74 44 61 74 61 20 3d 20 58 35  is.certData = X5
0d80: 30 39 2e 70 61 72 73 65 43 65 72 74 28 74 68 69  09.parseCert(thi
0d90: 73 2e 68 65 78 29 3b 0a 09 09 09 09 74 68 69 73  s.hex);.....this
0da0: 2e 63 65 72 74 44 61 74 61 2e 70 75 62 6c 69 63  .certData.public
0db0: 4b 65 79 2e 6e 20 3d 20 44 75 6b 74 61 70 65 2e  Key.n = Duktape.
0dc0: 64 65 63 28 27 68 65 78 27 2c 20 74 68 69 73 2e  dec('hex', this.
0dd0: 63 65 72 74 44 61 74 61 2e 70 75 62 6c 69 63 4b  certData.publicK
0de0: 65 79 2e 6e 29 3b 0a 09 09 09 09 74 68 69 73 2e  ey.n);.....this.
0df0: 63 65 72 74 44 61 74 61 2e 70 75 62 6c 69 63 4b  certData.publicK
0e00: 65 79 2e 65 20 3d 20 44 75 6b 74 61 70 65 2e 64  ey.e = Duktape.d
0e10: 65 63 28 27 68 65 78 27 2c 20 74 68 69 73 2e 63  ec('hex', this.c
0e20: 65 72 74 44 61 74 61 2e 70 75 62 6c 69 63 4b 65  ertData.publicKe
0e30: 79 2e 65 29 3b 0a 09 09 09 7d 0a 09 09 09 74 68  y.e);....}....th
0e40: 69 73 2e 67 65 74 50 75 62 6c 69 63 4b 65 79 20  is.getPublicKey 
0e50: 3d 20 66 75 6e 63 74 69 6f 6e 28 29 20 7b 0a 09  = function() {..
0e60: 09 09 09 74 68 69 73 2e 63 6f 6d 70 75 74 65 43  ...this.computeC
0e70: 65 72 74 44 61 74 61 28 29 3b 0a 09 09 09 09 72  ertData();.....r
0e80: 65 74 75 72 6e 28 74 68 69 73 2e 63 65 72 74 44  eturn(this.certD
0e90: 61 74 61 2e 70 75 62 6c 69 63 4b 65 79 29 3b 0a  ata.publicKey);.
0ea0: 09 09 09 7d 3b 0a 09 09 09 74 68 69 73 2e 67 65  ...};....this.ge
0eb0: 74 53 75 62 6a 65 63 74 53 74 72 69 6e 67 20 3d  tSubjectString =
0ec0: 20 66 75 6e 63 74 69 6f 6e 28 29 20 7b 0a 09 09   function() {...
0ed0: 09 09 74 68 69 73 2e 63 6f 6d 70 75 74 65 43 65  ..this.computeCe
0ee0: 72 74 44 61 74 61 28 29 3b 0a 09 09 09 09 72 65  rtData();.....re
0ef0: 74 75 72 6e 28 74 68 69 73 2e 63 65 72 74 44 61  turn(this.certDa
0f00: 74 61 2e 73 75 62 6a 65 63 74 29 3b 0a 09 09 09  ta.subject);....
0f10: 7d 3b 0a 09 09 09 74 68 69 73 2e 67 65 74 45 78  };....this.getEx
0f20: 74 53 75 62 6a 65 63 74 41 6c 74 4e 61 6d 65 32  tSubjectAltName2
0f30: 20 3d 20 66 75 6e 63 74 69 6f 6e 28 29 20 7b 0a   = function() {.
0f40: 09 09 09 09 72 65 74 75 72 6e 28 5b 5d 29 3b 0a  ....return([]);.
0f50: 09 09 09 7d 0a 09 09 7d 0a 09 09 58 35 30 39 2e  ...}...}...X509.
0f60: 70 61 72 73 65 43 65 72 74 20 3d 20 5f 5f 70 61  parseCert = __pa
0f70: 72 73 65 43 65 72 74 3b 0a 09 09 64 65 6c 65 74  rseCert;...delet
0f80: 65 20 5f 5f 70 61 72 73 65 43 65 72 74 3b 0a 09  e __parseCert;..
0f90: 7d 0a 7d 0a 0a 70 72 6f 63 20 72 65 61 64 46 69  }.}..proc readFi
0fa0: 6c 65 20 7b 66 69 6c 65 4e 61 6d 65 7d 20 7b 0a  le {fileName} {.
0fb0: 09 69 66 20 7b 5b 69 6e 66 6f 20 65 78 69 73 74  .if {[info exist
0fc0: 73 20 3a 3a 66 69 6c 65 73 28 24 66 69 6c 65 4e  s ::files($fileN
0fd0: 61 6d 65 29 5d 7d 20 7b 0a 09 09 73 65 74 20 64  ame)]} {...set d
0fe0: 61 74 61 20 24 3a 3a 66 69 6c 65 73 28 24 66 69  ata $::files($fi
0ff0: 6c 65 4e 61 6d 65 29 0a 09 09 69 66 20 7b 5b 73  leName)...if {[s
1000: 74 72 69 6e 67 20 72 61 6e 67 65 20 5b 73 74 72  tring range [str
1010: 69 6e 67 20 74 72 69 6d 20 24 64 61 74 61 5d 20  ing trim $data] 
1020: 30 20 31 5d 20 6e 65 20 22 40 40 22 7d 20 7b 0a  0 1] ne "@@"} {.
1030: 09 09 09 72 65 74 75 72 6e 20 24 64 61 74 61 0a  ...return $data.
1040: 09 09 7d 0a 09 7d 0a 0a 09 73 65 74 20 66 69 6c  ..}..}...set fil
1050: 65 4e 61 6d 65 20 5b 66 69 6c 65 20 6a 6f 69 6e  eName [file join
1060: 20 24 3a 3a 64 69 72 20 24 66 69 6c 65 4e 61 6d   $::dir $fileNam
1070: 65 5d 0a 09 69 66 20 7b 21 5b 69 6e 66 6f 20 65  e]..if {![info e
1080: 78 69 73 74 73 20 3a 3a 72 65 61 64 46 69 6c 65  xists ::readFile
1090: 28 24 66 69 6c 65 4e 61 6d 65 29 5d 7d 20 7b 0a  ($fileName)]} {.
10a0: 09 09 63 61 74 63 68 20 7b 0a 09 09 09 73 65 74  ..catch {....set
10b0: 20 66 64 20 5b 6f 70 65 6e 20 24 66 69 6c 65 4e   fd [open $fileN
10c0: 61 6d 65 5d 0a 09 09 09 73 65 74 20 3a 3a 72 65  ame]....set ::re
10d0: 61 64 46 69 6c 65 28 24 66 69 6c 65 4e 61 6d 65  adFile($fileName
10e0: 29 20 5b 72 65 61 64 20 24 66 64 5d 0a 09 09 7d  ) [read $fd]...}
10f0: 0a 09 09 63 61 74 63 68 20 7b 0a 09 09 09 63 6c  ...catch {....cl
1100: 6f 73 65 20 24 66 64 0a 09 09 7d 0a 09 7d 0a 0a  ose $fd...}..}..
1110: 09 72 65 74 75 72 6e 20 24 3a 3a 72 65 61 64 46  .return $::readF
1120: 69 6c 65 28 24 66 69 6c 65 4e 61 6d 65 29 0a 7d  ile($fileName).}
1130: 0a 0a 70 72 6f 63 20 69 6e 69 74 53 53 48 41 67  ..proc initSSHAg
1140: 65 6e 74 20 7b 7d 20 7b 0a 09 73 65 74 20 6a 73  ent {} {..set js
1150: 48 61 6e 64 6c 65 20 5b 3a 3a 64 75 6b 74 61 70  Handle [::duktap
1160: 65 3a 3a 69 6e 69 74 20 2d 73 61 66 65 20 74 72  e::init -safe tr
1170: 75 65 5d 0a 0a 09 3a 3a 64 75 6b 74 61 70 65 3a  ue]...::duktape:
1180: 3a 74 63 6c 2d 66 75 6e 63 74 69 6f 6e 20 24 6a  :tcl-function $j
1190: 73 48 61 6e 64 6c 65 20 5f 5f 70 75 74 73 20 7b  sHandle __puts {
11a0: 61 72 67 73 7d 20 7b 0a 09 09 69 66 20 7b 5b 6c  args} {...if {[l
11b0: 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 6e 69  length $args] ni
11c0: 20 7b 31 20 32 7d 7d 20 7b 0a 09 09 09 72 65 74   {1 2}} {....ret
11d0: 75 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20  urn -code error 
11e0: 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 70  "wrong # args: p
11f0: 75 74 73 20 3f 7b 73 74 64 65 72 72 7c 73 74 64  uts ?{stderr|std
1200: 6f 75 74 7d 3f 20 6d 65 73 73 61 67 65 22 0a 09  out}? message"..
1210: 09 7d 0a 09 09 69 66 20 7b 5b 6c 6c 65 6e 67 74  .}...if {[llengt
1220: 68 20 24 61 72 67 73 5d 20 3d 3d 20 32 7d 20 7b  h $args] == 2} {
1230: 0a 09 09 09 73 65 74 20 63 68 61 6e 20 5b 6c 69  ....set chan [li
1240: 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 09 09  ndex $args 0]...
1250: 09 69 66 20 7b 24 63 68 61 6e 20 6e 69 20 7b 73  .if {$chan ni {s
1260: 74 64 6f 75 74 20 73 74 64 65 72 72 7d 7d 20 7b  tdout stderr}} {
1270: 0a 09 09 09 09 72 65 74 75 72 6e 20 2d 63 6f 64  .....return -cod
1280: 65 20 65 72 72 6f 72 20 22 4f 6e 6c 79 20 73 74  e error "Only st
1290: 64 65 72 72 20 61 6e 64 20 73 74 64 6f 75 74 20  derr and stdout 
12a0: 61 6c 6c 6f 77 65 64 22 0a 09 09 09 7d 0a 09 09  allowed"....}...
12b0: 7d 0a 09 09 70 75 74 73 20 7b 2a 7d 24 61 72 67  }...puts {*}$arg
12c0: 73 0a 09 7d 0a 0a 09 3a 3a 64 75 6b 74 61 70 65  s..}...::duktape
12d0: 3a 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64 6c 65  ::eval $jsHandle
12e0: 20 7b 0a 09 09 72 75 6e 74 69 6d 65 20 3d 20 7b   {...runtime = {
12f0: 7d 3b 0a 09 09 72 75 6e 74 69 6d 65 2e 70 75 74  };...runtime.put
1300: 73 20 3d 20 5f 5f 70 75 74 73 3b 0a 09 09 72 75  s = __puts;...ru
1310: 6e 74 69 6d 65 2e 73 74 64 65 72 72 20 3d 20 22  ntime.stderr = "
1320: 73 74 64 65 72 72 22 3b 0a 09 09 64 65 6c 65 74  stderr";...delet
1330: 65 20 5f 5f 70 75 74 73 3b 0a 09 7d 0a 0a 09 3a  e __puts;..}...:
1340: 3a 64 75 6b 74 61 70 65 3a 3a 65 76 61 6c 20 24  :duktape::eval $
1350: 6a 73 48 61 6e 64 6c 65 20 7b 76 61 72 20 67 6f  jsHandle {var go
1360: 6f 67 20 3d 20 7b 44 45 42 55 47 3a 20 66 61 6c  og = {DEBUG: fal
1370: 73 65 7d 3b 7d 0a 09 3a 3a 64 75 6b 74 61 70 65  se};}..::duktape
1380: 3a 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64 6c 65  ::eval $jsHandle
1390: 20 5b 72 65 61 64 46 69 6c 65 20 63 68 72 6f 6d   [readFile chrom
13a0: 65 2d 65 6d 75 2e 6a 73 5d 0a 09 61 64 64 52 53  e-emu.js]..addRS
13b0: 41 54 6f 4a 53 20 24 6a 73 48 61 6e 64 6c 65 0a  AToJS $jsHandle.
13c0: 09 3a 3a 64 75 6b 74 61 70 65 3a 3a 65 76 61 6c  .::duktape::eval
13d0: 20 24 6a 73 48 61 6e 64 6c 65 20 5b 72 65 61 64   $jsHandle [read
13e0: 46 69 6c 65 20 73 73 68 2d 61 67 65 6e 74 2d 6e  File ssh-agent-n
13f0: 6f 61 73 79 6e 63 2e 6a 73 5d 0a 09 3a 3a 64 75  oasync.js]..::du
1400: 6b 74 61 70 65 3a 3a 65 76 61 6c 20 24 6a 73 48  ktape::eval $jsH
1410: 61 6e 64 6c 65 20 7b 63 61 63 6b 65 79 53 53 48  andle {cackeySSH
1420: 41 67 65 6e 74 46 65 61 74 75 72 65 73 2e 65 6e  AgentFeatures.en
1430: 61 62 6c 65 64 20 3d 20 74 72 75 65 3b 7d 0a 09  abled = true;}..
1440: 3a 3a 64 75 6b 74 61 70 65 3a 3a 65 76 61 6c 20  ::duktape::eval 
1450: 24 6a 73 48 61 6e 64 6c 65 20 7b 63 61 63 6b 65  $jsHandle {cacke
1460: 79 53 53 48 41 67 65 6e 74 46 65 61 74 75 72 65  ySSHAgentFeature
1470: 73 2e 69 6e 63 6c 75 64 65 43 65 72 74 73 20 3d  s.includeCerts =
1480: 20 74 72 75 65 3b 7d 0a 09 3a 3a 64 75 6b 74 61   true;}..::dukta
1490: 70 65 3a 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64  pe::eval $jsHand
14a0: 6c 65 20 7b 63 61 63 6b 65 79 53 53 48 41 67 65  le {cackeySSHAge
14b0: 6e 74 46 65 61 74 75 72 65 73 2e 6c 65 67 61 63  ntFeatures.legac
14c0: 79 20 3d 20 66 61 6c 73 65 3b 7d 0a 09 3a 3a 64  y = false;}..::d
14d0: 75 6b 74 61 70 65 3a 3a 65 76 61 6c 20 24 6a 73  uktape::eval $js
14e0: 48 61 6e 64 6c 65 20 7b 0a 09 09 66 75 6e 63 74  Handle {...funct
14f0: 69 6f 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 28 63  ion connection(c
1500: 61 6c 6c 62 61 63 6b 29 20 7b 0a 09 09 09 74 68  allback) {....th
1510: 69 73 2e 73 65 6e 64 65 72 20 3d 20 7b 0a 09 09  is.sender = {...
1520: 09 09 69 64 3a 20 22 70 6e 68 65 63 68 61 70 66  ..id: "pnhechapf
1530: 61 69 6e 64 6a 68 6f 6d 70 62 6e 66 6c 63 6c 64  aindjhompbnflcld
1540: 61 62 62 67 68 6a 6f 22 0a 09 09 09 7d 3b 0a 09  abbghjo"....};..
1550: 09 09 74 68 69 73 2e 6f 6e 4d 65 73 73 61 67 65  ..this.onMessage
1560: 20 3d 20 7b 0a 09 09 09 09 6c 69 73 74 65 6e 65   = {.....listene
1570: 72 73 3a 20 5b 5d 2c 0a 09 09 09 09 61 64 64 4c  rs: [],.....addL
1580: 69 73 74 65 6e 65 72 3a 20 66 75 6e 63 74 69 6f  istener: functio
1590: 6e 28 63 61 6c 6c 62 61 63 6b 29 20 7b 0a 09 09  n(callback) {...
15a0: 09 09 09 74 68 69 73 2e 6c 69 73 74 65 6e 65 72  ...this.listener
15b0: 73 2e 70 75 73 68 28 63 61 6c 6c 62 61 63 6b 29  s.push(callback)
15c0: 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 3b 0a 09 09  ;.....}....};...
15d0: 09 74 68 69 73 2e 70 6f 73 74 4d 65 73 73 61 67  .this.postMessag
15e0: 65 20 3d 20 66 75 6e 63 74 69 6f 6e 28 6d 65 73  e = function(mes
15f0: 73 61 67 65 29 20 7b 0a 09 09 09 09 72 65 74 75  sage) {.....retu
1600: 72 6e 28 63 61 6c 6c 62 61 63 6b 28 74 68 69 73  rn(callback(this
1610: 2c 20 6d 65 73 73 61 67 65 29 29 3b 0a 09 09 09  , message));....
1620: 7d 3b 0a 09 09 09 74 68 69 73 2e 73 65 6e 64 20  };....this.send 
1630: 3d 20 66 75 6e 63 74 69 6f 6e 28 6d 65 73 73 61  = function(messa
1640: 67 65 29 20 7b 0a 09 09 09 09 74 68 69 73 2e 6f  ge) {.....this.o
1650: 6e 4d 65 73 73 61 67 65 2e 6c 69 73 74 65 6e 65  nMessage.listene
1660: 72 73 2e 66 6f 72 45 61 63 68 28 66 75 6e 63 74  rs.forEach(funct
1670: 69 6f 6e 28 6c 69 73 74 65 6e 65 72 29 20 7b 0a  ion(listener) {.
1680: 09 09 09 09 09 6c 69 73 74 65 6e 65 72 28 6d 65  .....listener(me
1690: 73 73 61 67 65 29 3b 0a 09 09 09 09 7d 29 3b 0a  ssage);.....});.
16a0: 09 09 09 7d 3b 0a 09 09 7d 0a 0a 09 09 66 75 6e  ...};...}....fun
16b0: 63 74 69 6f 6e 20 68 61 6e 64 6c 65 44 61 74 61  ction handleData
16c0: 46 72 6f 6d 41 67 65 6e 74 28 73 6f 63 6b 65 74  FromAgent(socket
16d0: 2c 20 64 61 74 61 29 20 7b 0a 09 09 09 69 66 20  , data) {....if 
16e0: 28 21 64 61 74 61 20 7c 7c 20 21 64 61 74 61 2e  (!data || !data.
16f0: 74 79 70 65 20 7c 7c 20 21 64 61 74 61 2e 64 61  type || !data.da
1700: 74 61 29 20 7b 0a 09 09 09 09 72 65 74 75 72 6e  ta) {.....return
1710: 3b 0a 09 09 09 7d 0a 0a 09 09 09 69 66 20 28 64  ;....}.....if (d
1720: 61 74 61 2e 74 79 70 65 20 21 3d 20 22 61 75 74  ata.type != "aut
1730: 68 2d 61 67 65 6e 74 40 6f 70 65 6e 73 73 68 2e  h-agent@openssh.
1740: 63 6f 6d 22 29 20 7b 0a 09 09 09 09 72 65 74 75  com") {.....retu
1750: 72 6e 3b 0a 09 09 09 7d 0a 0a 09 09 09 77 72 69  rn;....}.....wri
1760: 74 65 46 72 61 6d 65 64 28 73 6f 63 6b 65 74 2e  teFramed(socket.
1770: 68 61 6e 64 6c 65 2c 20 64 61 74 61 2e 64 61 74  handle, data.dat
1780: 61 29 3b 0a 09 09 7d 0a 0a 09 09 66 75 6e 63 74  a);...}....funct
1790: 69 6f 6e 20 68 61 6e 64 6c 65 44 61 74 61 46 72  ion handleDataFr
17a0: 6f 6d 53 6f 63 6b 65 74 28 73 6f 63 6b 65 74 2c  omSocket(socket,
17b0: 20 64 61 74 61 29 20 7b 0a 09 09 09 73 6f 63 6b   data) {....sock
17c0: 65 74 2e 73 65 6e 64 28 7b 0a 09 09 09 09 74 79  et.send({.....ty
17d0: 70 65 3a 20 22 61 75 74 68 2d 61 67 65 6e 74 40  pe: "auth-agent@
17e0: 6f 70 65 6e 73 73 68 2e 63 6f 6d 22 2c 0a 09 09  openssh.com",...
17f0: 09 09 64 61 74 61 3a 20 41 72 72 61 79 2e 66 72  ..data: Array.fr
1800: 6f 6d 28 64 61 74 61 29 0a 09 09 09 7d 29 3b 0a  om(data)....});.
1810: 09 09 7d 0a 0a 09 09 66 75 6e 63 74 69 6f 6e 20  ..}....function 
1820: 77 72 69 74 65 46 72 61 6d 65 64 28 73 6f 63 6b  writeFramed(sock
1830: 2c 20 64 61 74 61 29 20 7b 0a 09 09 09 76 61 72  , data) {....var
1840: 20 62 75 66 66 65 72 3b 0a 09 09 09 76 61 72 20   buffer;....var 
1850: 69 64 78 3b 0a 0a 09 09 09 62 75 66 66 65 72 20  idx;.....buffer 
1860: 3d 20 6e 65 77 20 42 75 66 66 65 72 28 64 61 74  = new Buffer(dat
1870: 61 2e 6c 65 6e 67 74 68 29 3b 0a 09 09 09 66 6f  a.length);....fo
1880: 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20  r (idx = 0; idx 
1890: 3c 20 64 61 74 61 2e 6c 65 6e 67 74 68 3b 20 69  < data.length; i
18a0: 64 78 2b 2b 29 20 7b 0a 09 09 09 09 62 75 66 66  dx++) {.....buff
18b0: 65 72 5b 69 64 78 5d 20 3d 20 64 61 74 61 5b 69  er[idx] = data[i
18c0: 64 78 5d 3b 0a 09 09 09 7d 0a 09 09 09 72 65 74  dx];....}....ret
18d0: 75 72 6e 28 77 72 69 74 65 46 72 61 6d 65 64 42  urn(writeFramedB
18e0: 75 66 66 65 72 28 73 6f 63 6b 2c 20 62 75 66 66  uffer(sock, buff
18f0: 65 72 29 29 3b 0a 09 09 7d 0a 0a 09 09 66 75 6e  er));...}....fun
1900: 63 74 69 6f 6e 20 63 61 63 6b 65 79 4c 69 73 74  ction cackeyList
1910: 43 65 72 74 69 66 69 63 61 74 65 73 28 29 20 7b  Certificates() {
1920: 0a 09 09 09 76 61 72 20 63 65 72 74 73 3b 0a 09  ....var certs;..
1930: 09 09 76 61 72 20 63 65 72 74 4f 62 6a 73 3b 0a  ..var certObjs;.
1940: 0a 09 09 09 63 65 72 74 4f 62 6a 73 20 3d 20 5b  ....certObjs = [
1950: 5d 3b 0a 09 09 09 63 65 72 74 73 20 3d 20 63 61  ];....certs = ca
1960: 63 6b 65 79 4c 69 73 74 43 65 72 74 69 66 69 63  ckeyListCertific
1970: 61 74 65 73 42 61 72 65 28 29 3b 0a 09 09 09 63  atesBare();....c
1980: 65 72 74 73 2e 66 6f 72 45 61 63 68 28 66 75 6e  erts.forEach(fun
1990: 63 74 69 6f 6e 28 63 65 72 74 29 20 7b 0a 09 09  ction(cert) {...
19a0: 09 09 63 65 72 74 4f 62 6a 73 2e 70 75 73 68 28  ..certObjs.push(
19b0: 7b 0a 09 09 09 09 09 63 65 72 74 69 66 69 63 61  {......certifica
19c0: 74 65 3a 20 6e 65 77 20 55 69 6e 74 38 41 72 72  te: new Uint8Arr
19d0: 61 79 28 63 65 72 74 29 2c 0a 09 09 09 09 09 73  ay(cert),......s
19e0: 75 70 70 6f 72 74 65 64 48 61 73 68 65 73 3a 20  upportedHashes: 
19f0: 5b 27 53 48 41 31 27 2c 20 27 53 48 41 32 35 36  ['SHA1', 'SHA256
1a00: 27 2c 20 27 53 48 41 35 31 32 27 2c 20 27 4d 44  ', 'SHA512', 'MD
1a10: 35 5f 53 48 41 31 27 5d 0a 09 09 09 09 7d 29 3b  5_SHA1'].....});
1a20: 0a 09 09 09 7d 29 3b 0a 0a 09 09 09 72 65 74 75  ....});.....retu
1a30: 72 6e 28 63 65 72 74 4f 62 6a 73 29 3b 0a 09 09  rn(certObjs);...
1a40: 7d 0a 0a 09 09 66 75 6e 63 74 69 6f 6e 20 63 61  }....function ca
1a50: 63 6b 65 79 53 69 67 6e 4d 65 73 73 61 67 65 28  ckeySignMessage(
1a60: 72 65 71 75 65 73 74 29 20 7b 0a 09 09 09 76 61  request) {....va
1a70: 72 20 72 65 74 76 61 6c 3b 0a 09 09 09 76 61 72  r retval;....var
1a80: 20 64 69 67 65 73 74 2c 20 64 69 67 65 73 74 48   digest, digestH
1a90: 65 61 64 65 72 3b 0a 0a 09 09 09 2f 2a 0a 09 09  eader;...../*...
1aa0: 09 20 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 50 75  . * XXX:TODO: Pu
1ab0: 6c 6c 20 74 68 69 73 20 6f 75 74 20 6f 66 20 63  ll this out of c
1ac0: 61 63 6b 65 79 2e 6a 73 20 69 6e 74 6f 20 61 20  ackey.js into a 
1ad0: 63 6f 6d 6d 6f 6e 2e 6a 73 0a 09 09 09 20 2a 2f  common.js.... */
1ae0: 0a 09 09 09 73 77 69 74 63 68 20 28 72 65 71 75  ....switch (requ
1af0: 65 73 74 2e 68 61 73 68 29 20 7b 0a 09 09 09 09  est.hash) {.....
1b00: 63 61 73 65 20 22 53 48 41 31 22 3a 0a 09 09 09  case "SHA1":....
1b10: 09 09 64 69 67 65 73 74 48 65 61 64 65 72 20 3d  ..digestHeader =
1b20: 20 6e 65 77 20 55 69 6e 74 38 41 72 72 61 79 28   new Uint8Array(
1b30: 5b 30 78 33 30 2c 20 30 78 32 31 2c 20 30 78 33  [0x30, 0x21, 0x3
1b40: 30 2c 20 30 78 30 39 2c 20 30 78 30 36 2c 20 30  0, 0x09, 0x06, 0
1b50: 78 30 35 2c 20 30 78 32 62 2c 20 30 78 30 65 2c  x05, 0x2b, 0x0e,
1b60: 20 30 78 30 33 2c 20 30 78 30 32 2c 20 30 78 31   0x03, 0x02, 0x1
1b70: 61 2c 20 30 78 30 35 2c 20 30 78 30 30 2c 20 30  a, 0x05, 0x00, 0
1b80: 78 30 34 2c 20 30 78 31 34 5d 29 3b 0a 09 09 09  x04, 0x14]);....
1b90: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 63 61 73  ..break;.....cas
1ba0: 65 20 22 53 48 41 32 35 36 22 3a 0a 09 09 09 09  e "SHA256":.....
1bb0: 09 64 69 67 65 73 74 48 65 61 64 65 72 20 3d 20  .digestHeader = 
1bc0: 6e 65 77 20 55 69 6e 74 38 41 72 72 61 79 28 5b  new Uint8Array([
1bd0: 30 78 33 30 2c 20 30 78 33 31 2c 20 30 78 33 30  0x30, 0x31, 0x30
1be0: 2c 20 30 78 30 64 2c 20 30 78 30 36 2c 20 30 78  , 0x0d, 0x06, 0x
1bf0: 30 39 2c 20 30 78 36 30 2c 20 30 78 38 36 2c 20  09, 0x60, 0x86, 
1c00: 30 78 34 38 2c 20 30 78 30 31 2c 20 30 78 36 35  0x48, 0x01, 0x65
1c10: 2c 20 30 78 30 33 2c 20 30 78 30 34 2c 20 30 78  , 0x03, 0x04, 0x
1c20: 30 32 2c 20 30 78 30 31 2c 20 30 78 30 35 2c 20  02, 0x01, 0x05, 
1c30: 30 78 30 30 2c 20 30 78 30 34 2c 20 30 78 32 30  0x00, 0x04, 0x20
1c40: 5d 29 3b 0a 09 09 09 09 09 62 72 65 61 6b 3b 0a  ]);......break;.
1c50: 09 09 09 09 63 61 73 65 20 22 53 48 41 35 31 32  ....case "SHA512
1c60: 22 3a 0a 09 09 09 09 09 64 69 67 65 73 74 48 65  ":......digestHe
1c70: 61 64 65 72 20 3d 20 6e 65 77 20 55 69 6e 74 38  ader = new Uint8
1c80: 41 72 72 61 79 28 5b 30 78 33 30 2c 20 30 78 35  Array([0x30, 0x5
1c90: 31 2c 20 30 78 33 30 2c 20 30 78 30 64 2c 20 30  1, 0x30, 0x0d, 0
1ca0: 78 30 36 2c 20 30 78 30 39 2c 20 30 78 36 30 2c  x06, 0x09, 0x60,
1cb0: 20 30 78 38 36 2c 20 30 78 34 38 2c 20 30 78 30   0x86, 0x48, 0x0
1cc0: 31 2c 20 30 78 36 35 2c 20 30 78 30 33 2c 20 30  1, 0x65, 0x03, 0
1cd0: 78 30 34 2c 20 30 78 30 32 2c 20 30 78 30 33 2c  x04, 0x02, 0x03,
1ce0: 20 30 78 30 35 2c 20 30 78 30 30 2c 20 30 78 30   0x05, 0x00, 0x0
1cf0: 34 2c 20 30 78 34 30 5d 29 3b 0a 09 09 09 09 09  4, 0x40]);......
1d00: 62 72 65 61 6b 3b 0a 09 09 09 09 63 61 73 65 20  break;.....case 
1d10: 22 4d 44 35 5f 53 48 41 31 22 3a 0a 09 09 09 09  "MD5_SHA1":.....
1d20: 63 61 73 65 20 22 52 41 57 22 3a 0a 09 09 09 09  case "RAW":.....
1d30: 09 64 69 67 65 73 74 48 65 61 64 65 72 20 3d 20  .digestHeader = 
1d40: 6e 65 77 20 55 69 6e 74 38 41 72 72 61 79 28 29  new Uint8Array()
1d50: 3b 0a 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  ;......break;...
1d60: 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 09  ..default:......
1d70: 63 6f 6e 73 6f 6c 65 2e 65 72 72 6f 72 28 22 5b  console.error("[
1d80: 63 61 63 6b 65 79 5d 20 41 73 6b 65 64 20 74 6f  cackey] Asked to
1d90: 20 73 69 67 6e 20 61 20 6d 65 73 73 61 67 65 20   sign a message 
1da0: 77 69 74 68 20 61 20 68 61 73 68 20 77 65 20 64  with a hash we d
1db0: 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 3a 20 22  o not support: "
1dc0: 20 2b 20 72 65 71 75 65 73 74 2e 68 61 73 68 29   + request.hash)
1dd0: 3b 0a 09 09 09 09 09 72 65 74 75 72 6e 28 6e 75  ;......return(nu
1de0: 6c 6c 29 3b 0a 09 09 09 7d 0a 0a 09 09 09 64 69  ll);....}.....di
1df0: 67 65 73 74 20 3d 20 41 72 72 61 79 2e 66 72 6f  gest = Array.fro
1e00: 6d 28 64 69 67 65 73 74 48 65 61 64 65 72 29 3b  m(digestHeader);
1e10: 0a 09 09 09 64 69 67 65 73 74 20 3d 20 64 69 67  ....digest = dig
1e20: 65 73 74 2e 63 6f 6e 63 61 74 28 41 72 72 61 79  est.concat(Array
1e30: 2e 66 72 6f 6d 28 72 65 71 75 65 73 74 2e 64 69  .from(request.di
1e40: 67 65 73 74 29 29 3b 0a 09 09 09 64 69 67 65 73  gest));....diges
1e50: 74 20 3d 20 6e 65 77 20 42 75 66 66 65 72 28 64  t = new Buffer(d
1e60: 69 67 65 73 74 29 3b 0a 0a 09 09 09 72 65 74 76  igest);.....retv
1e70: 61 6c 20 3d 20 63 61 63 6b 65 79 53 69 67 6e 42  al = cackeySignB
1e80: 61 72 65 28 72 65 71 75 65 73 74 2e 63 65 72 74  are(request.cert
1e90: 69 66 69 63 61 74 65 2c 20 64 69 67 65 73 74 29  ificate, digest)
1ea0: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 72 65 74  ;.....return(ret
1eb0: 76 61 6c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 3a  val);...}..}...:
1ec0: 3a 64 75 6b 74 61 70 65 3a 3a 74 63 6c 2d 66 75  :duktape::tcl-fu
1ed0: 6e 63 74 69 6f 6e 20 24 6a 73 48 61 6e 64 6c 65  nction $jsHandle
1ee0: 20 77 72 69 74 65 46 72 61 6d 65 64 42 75 66 66   writeFramedBuff
1ef0: 65 72 20 7b 73 6f 63 6b 20 6d 65 73 73 61 67 65  er {sock message
1f00: 7d 20 7b 0a 09 09 73 65 74 20 64 61 74 61 4c 65  } {...set dataLe
1f10: 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68  n [string length
1f20: 20 24 6d 65 73 73 61 67 65 5d 0a 09 09 73 65 74   $message]...set
1f30: 20 64 61 74 61 4c 65 6e 20 5b 62 69 6e 61 72 79   dataLen [binary
1f40: 20 66 6f 72 6d 61 74 20 49 20 24 64 61 74 61 4c   format I $dataL
1f50: 65 6e 5d 0a 09 09 70 75 74 73 20 2d 6e 6f 6e 65  en]...puts -none
1f60: 77 6c 69 6e 65 20 24 73 6f 63 6b 20 22 24 7b 64  wline $sock "${d
1f70: 61 74 61 4c 65 6e 7d 24 7b 6d 65 73 73 61 67 65  ataLen}${message
1f80: 7d 22 0a 09 09 66 6c 75 73 68 20 24 73 6f 63 6b  }"...flush $sock
1f90: 0a 0a 09 09 72 65 74 75 72 6e 20 22 22 0a 09 7d  ....return ""..}
1fa0: 0a 0a 09 3a 3a 64 75 6b 74 61 70 65 3a 3a 74 63  ...::duktape::tc
1fb0: 6c 2d 66 75 6e 63 74 69 6f 6e 20 24 6a 73 48 61  l-function $jsHa
1fc0: 6e 64 6c 65 20 72 65 61 64 46 72 61 6d 65 64 20  ndle readFramed 
1fd0: 62 79 74 65 61 72 72 61 79 20 7b 73 6f 63 6b 7d  bytearray {sock}
1fe0: 20 7b 0a 09 09 63 61 74 63 68 20 7b 0a 09 09 09   {...catch {....
1ff0: 73 65 74 20 64 61 74 61 4c 65 6e 20 5b 72 65 61  set dataLen [rea
2000: 64 20 24 73 6f 63 6b 20 34 5d 0a 09 09 7d 0a 09  d $sock 4]...}..
2010: 09 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73  .if {![info exis
2020: 74 73 20 64 61 74 61 4c 65 6e 5d 20 7c 7c 20 5b  ts dataLen] || [
2030: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 64  string length $d
2040: 61 74 61 4c 65 6e 5d 20 21 3d 20 34 7d 20 7b 0a  ataLen] != 4} {.
2050: 09 09 09 63 6c 6f 73 65 20 24 73 6f 63 6b 0a 09  ...close $sock..
2060: 09 09 72 65 74 75 72 6e 0a 09 09 7d 0a 0a 09 09  ..return...}....
2070: 62 69 6e 61 72 79 20 73 63 61 6e 20 24 64 61 74  binary scan $dat
2080: 61 4c 65 6e 20 49 20 64 61 74 61 4c 65 6e 0a 0a  aLen I dataLen..
2090: 09 09 73 65 74 20 64 61 74 61 20 5b 72 65 61 64  ..set data [read
20a0: 20 24 73 6f 63 6b 20 24 64 61 74 61 4c 65 6e 5d   $sock $dataLen]
20b0: 0a 0a 09 09 72 65 74 75 72 6e 20 24 64 61 74 61  ....return $data
20c0: 0a 09 7d 0a 0a 0a 09 3a 3a 64 75 6b 74 61 70 65  ..}....::duktape
20d0: 3a 3a 74 63 6c 2d 66 75 6e 63 74 69 6f 6e 20 24  ::tcl-function $
20e0: 6a 73 48 61 6e 64 6c 65 20 63 61 63 6b 65 79 53  jsHandle cackeyS
20f0: 69 67 6e 42 61 72 65 20 62 79 74 65 61 72 72 61  ignBare bytearra
2100: 79 20 7b 63 65 72 74 20 6d 65 73 73 61 67 65 7d  y {cert message}
2110: 20 7b 0a 09 09 73 65 74 20 68 61 6e 64 6c 65 20   {...set handle 
2120: 5b 70 6b 63 73 31 31 4d 6f 64 75 6c 65 48 61 6e  [pkcs11ModuleHan
2130: 64 6c 65 5d 0a 09 09 73 65 74 20 63 65 72 74 49  dle]...set certI
2140: 6e 66 6f 20 5b 6c 69 73 74 43 65 72 74 73 20 24  nfo [listCerts $
2150: 68 61 6e 64 6c 65 20 24 63 65 72 74 5d 0a 09 09  handle $cert]...
2160: 69 66 20 7b 21 5b 64 69 63 74 20 65 78 69 73 74  if {![dict exist
2170: 73 20 24 63 65 72 74 49 6e 66 6f 20 70 6b 63 73  s $certInfo pkcs
2180: 31 31 5f 73 6c 6f 74 69 64 5d 7d 20 7b 0a 09 09  11_slotid]} {...
2190: 09 70 6b 63 73 31 31 4d 6f 64 75 6c 65 55 6e 6c  .pkcs11ModuleUnl
21a0: 6f 61 64 20 24 68 61 6e 64 6c 65 0a 09 09 09 72  oad $handle....r
21b0: 65 74 75 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f  eturn -code erro
21c0: 72 20 22 55 6e 61 62 6c 65 20 74 6f 20 66 69 6e  r "Unable to fin
21d0: 64 20 63 65 72 74 69 66 69 63 61 74 65 20 74 6f  d certificate to
21e0: 20 73 69 67 6e 20 77 69 74 68 22 0a 09 09 7d 0a   sign with"...}.
21f0: 0a 09 09 73 65 74 20 73 6c 6f 74 49 64 20 5b 64  ...set slotId [d
2200: 69 63 74 20 67 65 74 20 24 63 65 72 74 49 6e 66  ict get $certInf
2210: 6f 20 70 6b 63 73 31 31 5f 73 6c 6f 74 69 64 5d  o pkcs11_slotid]
2220: 0a 09 09 74 72 79 20 7b 0a 09 09 09 73 65 74 20  ...try {....set 
2230: 64 61 74 61 20 5b 3a 3a 70 6b 69 3a 3a 73 69 67  data [::pki::sig
2240: 6e 20 24 6d 65 73 73 61 67 65 20 24 63 65 72 74  n $message $cert
2250: 49 6e 66 6f 20 72 61 77 5d 0a 09 09 7d 20 6f 6e  Info raw]...} on
2260: 20 65 72 72 6f 72 20 7b 7d 20 7b 0a 09 09 09 70   error {} {....p
2270: 6b 63 73 31 31 4d 6f 64 75 6c 65 4c 6f 67 69 6e  kcs11ModuleLogin
2280: 20 24 73 6c 6f 74 49 64 0a 0a 09 09 09 73 65 74   $slotId.....set
2290: 20 64 61 74 61 20 5b 3a 3a 70 6b 69 3a 3a 73 69   data [::pki::si
22a0: 67 6e 20 24 6d 65 73 73 61 67 65 20 24 63 65 72  gn $message $cer
22b0: 74 49 6e 66 6f 20 72 61 77 5d 0a 09 09 7d 0a 0a  tInfo raw]...}..
22c0: 09 09 72 65 74 75 72 6e 20 24 64 61 74 61 0a 09  ..return $data..
22d0: 7d 0a 0a 09 3a 3a 64 75 6b 74 61 70 65 3a 3a 74  }...::duktape::t
22e0: 63 6c 2d 66 75 6e 63 74 69 6f 6e 20 24 6a 73 48  cl-function $jsH
22f0: 61 6e 64 6c 65 20 63 61 63 6b 65 79 4c 69 73 74  andle cackeyList
2300: 43 65 72 74 69 66 69 63 61 74 65 73 42 61 72 65  CertificatesBare
2310: 20 7b 61 72 72 61 79 20 62 79 74 65 61 72 72 61   {array bytearra
2320: 79 7d 20 7b 7d 20 7b 0a 09 09 73 65 74 20 68 61  y} {} {...set ha
2330: 6e 64 6c 65 20 5b 70 6b 63 73 31 31 4d 6f 64 75  ndle [pkcs11Modu
2340: 6c 65 48 61 6e 64 6c 65 5d 0a 09 09 73 65 74 20  leHandle]...set 
2350: 72 65 74 76 61 6c 20 5b 6c 69 73 74 43 65 72 74  retval [listCert
2360: 73 20 24 68 61 6e 64 6c 65 5d 0a 09 09 72 65 74  s $handle]...ret
2370: 75 72 6e 20 24 72 65 74 76 61 6c 0a 09 7d 0a 0a  urn $retval..}..
2380: 09 72 65 74 75 72 6e 20 24 6a 73 48 61 6e 64 6c  .return $jsHandl
2390: 65 0a 7d 0a 0a 70 72 6f 63 20 6c 69 73 74 43 65  e.}..proc listCe
23a0: 72 74 73 20 7b 68 61 6e 64 6c 65 20 7b 6d 61 74  rts {handle {mat
23b0: 63 68 20 22 22 7d 7d 20 7b 0a 09 73 65 74 20 63  ch ""}} {..set c
23c0: 65 72 74 73 20 5b 6c 69 73 74 5d 0a 0a 09 73 65  erts [list]...se
23d0: 74 20 73 6c 6f 74 73 20 5b 3a 3a 70 6b 69 3a 3a  t slots [::pki::
23e0: 70 6b 63 73 31 31 3a 3a 6c 69 73 74 73 6c 6f 74  pkcs11::listslot
23f0: 73 20 24 68 61 6e 64 6c 65 5d 0a 09 66 6f 72 65  s $handle]..fore
2400: 61 63 68 20 73 6c 6f 74 49 6e 66 6f 20 24 73 6c  ach slotInfo $sl
2410: 6f 74 73 20 7b 0a 09 09 73 65 74 20 73 6c 6f 74  ots {...set slot
2420: 49 64 20 5b 6c 69 6e 64 65 78 20 24 73 6c 6f 74  Id [lindex $slot
2430: 49 6e 66 6f 20 30 5d 0a 09 09 73 65 74 20 73 6c  Info 0]...set sl
2440: 6f 74 4c 61 62 65 6c 20 5b 6c 69 6e 64 65 78 20  otLabel [lindex 
2450: 24 73 6c 6f 74 49 6e 66 6f 20 31 5d 0a 09 09 73  $slotInfo 1]...s
2460: 65 74 20 73 6c 6f 74 46 6c 61 67 73 20 5b 6c 69  et slotFlags [li
2470: 6e 64 65 78 20 24 73 6c 6f 74 49 6e 66 6f 20 32  ndex $slotInfo 2
2480: 5d 0a 0a 09 09 23 20 53 6b 69 70 20 6d 69 73 73  ]....# Skip miss
2490: 69 6e 67 20 74 6f 6b 65 6e 73 0a 09 09 69 66 20  ing tokens...if 
24a0: 7b 22 54 4f 4b 45 4e 5f 50 52 45 53 45 4e 54 22  {"TOKEN_PRESENT"
24b0: 20 6e 69 20 24 73 6c 6f 74 46 6c 61 67 73 7d 20   ni $slotFlags} 
24c0: 7b 0a 09 09 09 63 6f 6e 74 69 6e 75 65 0a 09 09  {....continue...
24d0: 7d 0a 0a 09 09 73 65 74 20 73 6c 6f 74 43 65 72  }....set slotCer
24e0: 74 73 20 5b 3a 3a 70 6b 69 3a 3a 70 6b 63 73 31  ts [::pki::pkcs1
24f0: 31 3a 3a 6c 69 73 74 63 65 72 74 73 20 24 68 61  1::listcerts $ha
2500: 6e 64 6c 65 20 24 73 6c 6f 74 49 64 5d 0a 09 09  ndle $slotId]...
2510: 66 6f 72 65 61 63 68 20 6b 65 79 4c 69 73 74 20  foreach keyList 
2520: 24 73 6c 6f 74 43 65 72 74 73 20 7b 0a 09 09 09  $slotCerts {....
2530: 73 65 74 20 63 65 72 74 20 5b 64 69 63 74 20 67  set cert [dict g
2540: 65 74 20 24 6b 65 79 4c 69 73 74 20 72 61 77 5d  et $keyList raw]
2550: 0a 09 09 09 73 65 74 20 63 65 72 74 20 5b 62 69  ....set cert [bi
2560: 6e 61 72 79 20 64 65 63 6f 64 65 20 68 65 78 20  nary decode hex 
2570: 24 63 65 72 74 5d 0a 09 09 09 69 66 20 7b 24 6d  $cert]....if {$m
2580: 61 74 63 68 20 65 71 20 24 63 65 72 74 7d 20 7b  atch eq $cert} {
2590: 0a 09 09 09 09 72 65 74 75 72 6e 20 24 6b 65 79  .....return $key
25a0: 4c 69 73 74 0a 09 09 09 7d 0a 09 09 09 6c 61 70  List....}....lap
25b0: 70 65 6e 64 20 63 65 72 74 73 20 24 63 65 72 74  pend certs $cert
25c0: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 7b 24 6d  ...}..}...if {$m
25d0: 61 74 63 68 20 6e 65 20 22 22 7d 20 7b 0a 09 09  atch ne ""} {...
25e0: 73 65 74 20 63 65 72 74 73 20 5b 6c 69 73 74 5d  set certs [list]
25f0: 0a 09 7d 0a 0a 09 69 66 20 7b 5b 6c 6c 65 6e 67  ..}...if {[lleng
2600: 74 68 20 24 63 65 72 74 73 5d 20 3d 3d 20 30 7d  th $certs] == 0}
2610: 20 7b 0a 09 09 70 6b 63 73 31 31 4d 6f 64 75 6c   {...pkcs11Modul
2620: 65 55 6e 6c 6f 61 64 20 24 68 61 6e 64 6c 65 0a  eUnload $handle.
2630: 09 7d 0a 0a 09 72 65 74 75 72 6e 20 24 63 65 72  .}...return $cer
2640: 74 73 0a 7d 0a 0a 70 72 6f 63 20 68 61 6e 64 6c  ts.}..proc handl
2650: 65 44 61 74 61 20 7b 73 6f 63 6b 20 6a 73 48 61  eData {sock jsHa
2660: 6e 64 6c 65 7d 20 7b 0a 09 69 66 20 7b 5b 63 61  ndle} {..if {[ca
2670: 74 63 68 20 7b 0a 09 09 3a 3a 64 75 6b 74 61 70  tch {...::duktap
2680: 65 3a 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64 6c  e::eval $jsHandl
2690: 65 20 7b 68 61 6e 64 6c 65 44 61 74 61 46 72 6f  e {handleDataFro
26a0: 6d 53 6f 63 6b 65 74 28 73 6f 63 6b 65 74 2c 20  mSocket(socket, 
26b0: 72 65 61 64 46 72 61 6d 65 64 28 73 6f 63 6b 65  readFramed(socke
26c0: 74 2e 68 61 6e 64 6c 65 29 29 3b 7d 0a 09 7d 5d  t.handle));}..}]
26d0: 7d 20 7b 0a 09 09 70 75 74 73 20 73 74 64 65 72  } {...puts stder
26e0: 72 20 22 45 52 52 4f 52 3a 20 24 3a 3a 65 72 72  r "ERROR: $::err
26f0: 6f 72 49 6e 66 6f 22 0a 09 09 63 6c 6f 73 65 20  orInfo"...close 
2700: 24 73 6f 63 6b 0a 09 7d 0a 7d 0a 0a 70 72 6f 63  $sock..}.}..proc
2710: 20 69 6e 63 6f 6d 69 6e 67 43 6f 6e 6e 65 63 74   incomingConnect
2720: 69 6f 6e 20 7b 73 6f 63 6b 20 61 72 67 73 7d 20  ion {sock args} 
2730: 7b 0a 09 69 66 20 7b 5b 63 61 74 63 68 20 7b 0a  {..if {[catch {.
2740: 09 09 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69  ..if {![info exi
2750: 73 74 73 20 3a 3a 6a 73 48 61 6e 64 6c 65 5d 7d  sts ::jsHandle]}
2760: 20 7b 0a 09 09 09 73 65 74 20 3a 3a 6a 73 48 61   {....set ::jsHa
2770: 6e 64 6c 65 20 5b 69 6e 69 74 53 53 48 41 67 65  ndle [initSSHAge
2780: 6e 74 5d 0a 09 09 7d 0a 09 09 73 65 74 20 6a 73  nt]...}...set js
2790: 48 61 6e 64 6c 65 20 24 3a 3a 6a 73 48 61 6e 64  Handle $::jsHand
27a0: 6c 65 0a 0a 09 09 3a 3a 64 75 6b 74 61 70 65 3a  le....::duktape:
27b0: 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64 6c 65 20  :eval $jsHandle 
27c0: 7b 76 61 72 20 73 6f 63 6b 65 74 20 3d 20 6e 65  {var socket = ne
27d0: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 28 68 61 6e  w connection(han
27e0: 64 6c 65 44 61 74 61 46 72 6f 6d 41 67 65 6e 74  dleDataFromAgent
27f0: 29 3b 7d 0a 09 09 3a 3a 64 75 6b 74 61 70 65 3a  );}...::duktape:
2800: 3a 65 76 61 6c 20 24 6a 73 48 61 6e 64 6c 65 20  :eval $jsHandle 
2810: 22 73 6f 63 6b 65 74 2e 68 61 6e 64 6c 65 20 3d  "socket.handle =
2820: 20 5c 22 24 73 6f 63 6b 5c 22 3b 22 0a 09 09 3a   \"$sock\";"...:
2830: 3a 64 75 6b 74 61 70 65 3a 3a 65 76 61 6c 20 24  :duktape::eval $
2840: 6a 73 48 61 6e 64 6c 65 20 7b 63 68 72 6f 6d 65  jsHandle {chrome
2850: 2e 72 75 6e 74 69 6d 65 2e 65 78 74 65 72 6e 61  .runtime.externa
2860: 6c 43 6f 6e 6e 65 63 74 28 73 6f 63 6b 65 74 29  lConnect(socket)
2870: 3b 7d 0a 0a 09 09 66 63 6f 6e 66 69 67 75 72 65  ;}....fconfigure
2880: 20 24 73 6f 63 6b 20 2d 74 72 61 6e 73 6c 61 74   $sock -translat
2890: 69 6f 6e 20 62 69 6e 61 72 79 20 2d 65 6e 63 6f  ion binary -enco
28a0: 64 69 6e 67 20 62 69 6e 61 72 79 20 2d 62 6c 6f  ding binary -blo
28b0: 63 6b 69 6e 67 20 74 72 75 65 0a 09 09 66 69 6c  cking true...fil
28c0: 65 65 76 65 6e 74 20 24 73 6f 63 6b 20 72 65 61  eevent $sock rea
28d0: 64 61 62 6c 65 20 5b 6c 69 73 74 20 68 61 6e 64  dable [list hand
28e0: 6c 65 44 61 74 61 20 24 73 6f 63 6b 20 24 6a 73  leData $sock $js
28f0: 48 61 6e 64 6c 65 5d 0a 09 7d 5d 7d 20 7b 0a 09  Handle]..}]} {..
2900: 09 70 75 74 73 20 73 74 64 65 72 72 20 22 45 52  .puts stderr "ER
2910: 52 4f 52 3a 20 24 3a 3a 65 72 72 6f 72 49 6e 66  ROR: $::errorInf
2920: 6f 22 0a 09 09 63 6c 6f 73 65 20 24 73 6f 63 6b  o"...close $sock
2930: 0a 09 7d 0a 7d 0a 0a 3a 3a 74 75 61 70 69 3a 3a  ..}.}..::tuapi::
2940: 73 79 73 63 61 6c 6c 3a 3a 73 6f 63 6b 65 74 5f  syscall::socket_
2950: 75 6e 69 78 20 2d 73 65 72 76 65 72 20 69 6e 63  unix -server inc
2960: 6f 6d 69 6e 67 43 6f 6e 6e 65 63 74 69 6f 6e 20  omingConnection 
2970: 24 3a 3a 65 6e 76 28 53 53 48 5f 41 55 54 48 5f  $::env(SSH_AUTH_
2980: 53 4f 43 4b 29 0a 0a 76 77 61 69 74 20 66 6f 72  SOCK)..vwait for
2990: 65 76 65 72 0a                                   ever.