Diff
Not logged in

Differences From Artifact [3eb0b347ba]:

To Artifact [6f37b8a208]:


11
12
13
14
15
16
17
18

19
20

21
22
23
24
25
26
27
11
12
13
14
15
16
17

18
19

20
21
22
23
24
25
26
27







-
+

-
+







# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

proc usage { error } {
  if {[string length $error] > 0} then {puts stdout $error}
  if {[string length $error] > 0} then {emitOutput $error}

  puts stdout "usage:\
  emitOutput "usage:\
[file tail [getShellExecutableName]]\
[file tail [info script]] <fileName> \[vendor\] \[embed\]\
\[duration\] \[entityType\] \[encoding\] \[publicKeyFile\]\
\[privateKeyFile\] \[importFirst\] \[quantity\] \[id\]\
\[timeStamp\]"

  #
39
40
41
42
43
44
45





46
47
48
49
50
51
52
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57







+
+
+
+
+







      emitNotice [appendArgs $name " hook ok: " $result]
    } else {
      if {[string length $result] == 0} then {set result <none>}
      emitWarning [appendArgs $name " hook error: " $result]
    }
  }
}

proc emitOutput { message } {
  set message [string trim $message]
  catch {puts stdout $message}
}

proc emitNotice { message } {
  set message [string trim $message]
  catch {host result Ok [appendArgs $message \n]}
}

proc emitWarning { message } {
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133






134

135
136
137




138

139
140
141




142

143
144
145




146

147
148



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164




165
166
167
168
169

170




171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230








231
232
233
234
235
236
237
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134





135
136
137
138
139
140
141
142



143
144
145
146
147
148



149
150
151
152
153
154



155
156
157
158
159
160


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204








205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260







-
+













+
-
-
-
-
-
+
+
+
+
+
+

+
-
-
-
+
+
+
+

+
-
-
-
+
+
+
+

+
-
-
-
+
+
+
+

+
-
-
+
+
+















+
-
+
+
+
+





+
-
+
+
+
+











-
-
-
-
-
-
-
-




















-
+




















+
+
+
+
+
+
+
+







      [string match "keyRing*" $rootName]} then {
    return true
  }

  return false
}

proc checkAndMatchKeyFile { varName {keyFile ""} } {
proc checkAndMatchKeyFile { varName {keyFile ""} {quiet false} } {
  global env

  if {[info exists env($varName)]} then {
    set fileName $env($varName)

    if {[string length $fileName] > 0} then {
      if {[file exists $fileName]} then {
        if {[catch {keypair token $fileName} token] == 0 && \
            [string length $token] > 0} then {
          if {[string length $keyFile] == 0 || \
              [matchKeyFileTokens $fileName $keyFile]} then {
            return true
          } else {
            if {!$quiet} then {
            puts stdout [appendArgs \
                "file \"" $fileName \
                "\" mismatches public key token from file \"" \
                $keyFile \"]
          }
              emitOutput [appendArgs \
                  "file \"" $fileName \
                  "\" mismatches public key token from file \"" \
                  $keyFile \"]
            }
          }
        } else {
          if {!$quiet} then {
          puts stdout [appendArgs \
              "file \"" $fileName "\" is probably not a key file"]
        }
            emitOutput [appendArgs \
                "file \"" $fileName "\" is probably not a key file"]
          }
        }
      } else {
        if {!$quiet} then {
        puts stdout [appendArgs \
            "file \"" $fileName "\" does not exist"]
      }
          emitOutput [appendArgs \
              "file \"" $fileName "\" does not exist"]
        }
      }
    } else {
      if {!$quiet} then {
      puts stdout [appendArgs \
          "environment variable \"" $varName "\" has no value"]
    }
        emitOutput [appendArgs \
            "environment variable \"" $varName "\" has no value"]
      }
    }
  } else {
    if {!$quiet} then {
    puts stdout [appendArgs \
        "environment variable \"" $varName "\" was not found"]
      emitOutput [appendArgs \
          "environment variable \"" $varName "\" was not found"]
    }
  }

  return false
}

proc matchKeyFileTokens { keyFile1 keyFile2 } {
  if {[string length $keyFile1] == 0 || \
      [string length $keyFile2] == 0} then {
    return false
  }

  if {![file exists $keyFile1] || ![file exists $keyFile2]} then {
    return false
  }

  if {[catch {
  set token1 [keypair token $keyFile1]
    keypair token $keyFile1
  } token1] != 0 || [string length $token1] == 0} then {
    return false
  }

  if {[string length $token1] == 0} then {
    return false
  }

  if {[catch {
  set token2 [keypair token $keyFile2]
    keypair token $keyFile2
  } token2] != 0 || [string length $token2] == 0} then {
    return false
  }

  if {[string length $token2] == 0} then {
    return false
  }

  return [expr {$token1 eq $token2}]
}

proc readEntityValue { fileName } {
  return [readFile $fileName]
}

proc readCertificateFile { fileName } {
  return [readFile $fileName]
}

proc writeCertificateFile { fileName data } {
  return [writeFile $fileName $data]
}

proc removeEmbeddedCertificate { fileName } {
  set prefixWithSpacing [appendArgs $::embedSpacing $::embedPrefix]

  set data [readFile $fileName]
  set beginIndex [string first $prefixWithSpacing $data]

  if {$beginIndex == -1} then {
    set prefixWithSpacing $::embedPrefix
    set beginIndex [string last $prefixWithSpacing $data]
  }

  if {$beginIndex != -1} then {
    set endIndex [string first $::embedSuffix $data \
        [expr {$beginIndex + [string length $prefixWithSpacing]}]]

    if {$endIndex != -1} then {
      writeFile $fileName [string replace $data $beginIndex \
          [expr {$endIndex + [string length $::embedSuffix]}]]

      puts stdout [appendArgs \
      emitOutput [appendArgs \
          "removed embedded certificate from file \"" $fileName \"]
    }
  }
}

if {[llength $argv] >= 1 && [llength $argv] <= 12} then {
  #
  # NOTE: This tool requires Eagle.
  #
  package require Eagle

  #
  # NOTE: Needed for the [getTemporaryPath] script procedure.
  #
  package require Eagle.Test

  #
  # NOTE: This tool requires the enterprise license features.
  #
  package require Licensing.Enterprise

  #
  # NOTE: Should emitting of extra diagnostics be skipped?
  #
  if {![info exists quiet]} then {
    set quiet false
    set quiet_set true
  }

  #
  # NOTE: If the tool base path does not already exist, set it
  #       to the directory where this script is running from.
  #
  if {![info exists path]} then {
    set path [file normalize [file dirname [info script]]]
323
324
325
326
327
328
329
330
331


332
333


334
335


336
337


338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361


362
363
364


365
366
367


368
369
370


371
372
373
374
375
376
377
378


379
380
381
382
383
384
385
346
347
348
349
350
351
352


353
354
355

356
357
358

359
360
361

362
363
364
365
366
367
368
369


370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385


386
387
388


389
390
391


392
393
394


395
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411







-
-
+
+

-
+
+

-
+
+

-
+
+






-
-
+
+














-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+






-
-
+
+







  #
  if {[llength $argv] >= 8} then {
    #
    # NOTE: Use the private key file name supplied on the command
    #       line.
    #
    set privateKeyFile [string trim [lindex $argv 7]]
  } elseif {[isKeyRingFile $fileName] && \
      [checkAndMatchKeyFile EagleEnterpriseTrustRootPrivateKey]} then {
  } elseif {[isKeyRingFile $fileName] && [checkAndMatchKeyFile \
      EagleEnterpriseTrustRootPrivateKey "" $quiet]} then {
    set privateKeyFile $env(EagleEnterpriseTrustRootPrivateKey)
  } elseif {[checkAndMatchKeyFile EagleEnterpriseScriptPrivateKey]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterpriseScriptPrivateKey "" $quiet]} then {
    set privateKeyFile $env(EagleEnterpriseScriptPrivateKey)
  } elseif {[checkAndMatchKeyFile EagleEnterprisePersonalPrivateKey]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterprisePersonalPrivateKey "" $quiet]} then {
    set privateKeyFile $env(EagleEnterprisePersonalPrivateKey)
  } elseif {[checkAndMatchKeyFile EagleEnterprisePrivateKey]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterprisePrivateKey "" $quiet]} then {
    set privateKeyFile $env(EagleEnterprisePrivateKey)
  } elseif {[info exists env(Eagle)]} then {
    set privateKeyFile [file join \
        $env(Eagle) Keys EagleEnterprisePluginRootPrivate.snk]
  } else {
    #
    # NOTE: Default to "EagleEnterprisePluginRootPrivate.snk" in the current
    #       directory (which may not actually exist).
    # NOTE: Default to "EagleEnterprisePluginRootPrivate.snk" in the
    #       current directory (which may not actually exist).
    #
    set privateKeyFile EagleEnterprisePluginRootPrivate.snk
  }

  #
  # NOTE: Figure out the file name for the public strong name key
  #       file that will be used to verify the data file.
  #
  if {[llength $argv] >= 7} then {
    #
    # NOTE: Use the public key file name supplied on the command
    #       line.
    #
    set publicKeyFile [string trim [lindex $argv 6]]
  } elseif {[checkAndMatchKeyFile EagleEnterpriseTrustRootPublicKey \
      $privateKeyFile]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterpriseTrustRootPublicKey $privateKeyFile $quiet]} then {
    set publicKeyFile $env(EagleEnterpriseTrustRootPublicKey)
  } elseif {[checkAndMatchKeyFile EagleEnterpriseScriptPublicKey \
      $privateKeyFile]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterpriseScriptPublicKey $privateKeyFile $quiet]} then {
    set publicKeyFile $env(EagleEnterpriseScriptPublicKey)
  } elseif {[checkAndMatchKeyFile EagleEnterprisePersonalPublicKey \
      $privateKeyFile]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterprisePersonalPublicKey $privateKeyFile $quiet]} then {
    set publicKeyFile $env(EagleEnterprisePersonalPublicKey)
  } elseif {[checkAndMatchKeyFile EagleEnterprisePublicKey \
      $privateKeyFile]} then {
  } elseif {[checkAndMatchKeyFile \
      EagleEnterprisePublicKey $privateKeyFile $quiet]} then {
    set publicKeyFile $env(EagleEnterprisePublicKey)
  } elseif {[info exists env(Eagle)]} then {
    set publicKeyFile [file join \
        $env(Eagle) Keys EagleEnterprisePluginRootPublic.snk]
  } else {
    #
    # NOTE: Default to "EagleEnterprisePluginRootPublic.snk" in the current
    #       directory (which may not actually exist).
    # NOTE: Default to "EagleEnterprisePluginRootPublic.snk" in the
    #       current directory (which may not actually exist).
    #
    set publicKeyFile EagleEnterprisePluginRootPublic.snk
  }

  #
  # NOTE: Do we want to import the existing certificate first?
  #
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569







-
+







          " \"" $fileName \"]
    }

    #
    # NOTE: Attempt to re-verify the license certificate file.
    #
    if {[certificate verify -encoding $encoding $certificate \
            $privateKey] ne "VerifiedOk"} then {
            $publicKey] ne "VerifiedOk"} then {
      emitError [appendArgs \
          "failed to verify signature for " $fileType " \"" $fileName \"]
    }
  } else {
    #
    # NOTE: Set the file type for error messages.
    #
742
743
744
745
746
747
748
749

750
751
752
753
754

755
756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
768
769
770
771
772
773
774

775
776
777
778
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802







-
+




-
+














+







  #
  package require Harpy.Test; reformatCertificateSpacing $certificateFile

  #
  # NOTE: Show that we signed it.
  #
  if {$importFirst} then {
    puts stdout [appendArgs \
    emitOutput [appendArgs \
        "re-signed " $fileType " \"" $fileName "\" (as \"" $entityType \
        "\") using encoding \"" $encoding "\" with key " [keypair token \
        $privateKeyFile]]
  } else {
    puts stdout [appendArgs \
    emitOutput [appendArgs \
        "signed " $fileType " \"" $fileName "\" (as \"" $entityType \
        "\") using encoding \"" $encoding "\" with key " [keypair token \
        $privateKeyFile]]
  }

  #
  # NOTE: Do we need to embed the certificate at the end of the script
  #       file?
  #
  if {$shouldEmbed} then {
    #
    # NOTE: Make sure any carriage-returns are removed as they impact
    #       the line splitting algorithm being used.
    #
    set data [readFile $certificateFile]
    set data [string map [list [info newline] \n] $data]

    #
    # NOTE: Start out with the embedding prefix on a line by itself.
    #
    set lines [list $embedPrefix]

793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824




825
826
827
828




829
830
831
820
821
822
823
824
825
826

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847




848
849
850
851
852
853
854
855
856
857
858
859
860
861
862







-
+




















-
-
-
-
+
+
+
+




+
+
+
+



    #       platform.
    #
    appendFile $fileName [join $lines [info newline]]

    #
    # NOTE: Show that we embedded it.
    #
    puts stdout [appendArgs \
    emitOutput [appendArgs \
        "added embedded certificate to " $fileType " \"" $fileName \"]
  }

  #
  # HOOK: Script completion.
  #
  maybeInvokeHook certificate phase3

  #
  # NOTE: Cleanup the external embedded certificate file, if any.
  #
  if {$shouldEmbed} then {
    catch {file delete -force $certificateFile}
  }

  #
  # NOTE: Play nice and cleanup all the variables we created during the
  #       whole the signing process.
  #
  unset -nocomplain fileName vendor embed duration entityType encoding \
      privateKeyFile publicKeyFile importFirst configFileName embedSpacing \
      embedPrefix embedSuffix publicKey privateKey shouldEmbed fileType \
      certificate certificateFile data xmlNs xmlNsXsi xmlNsXsd spaces \
      lines line
      privateKeyFile publicKeyFile importFirst quantity id timeStamp \
      configFileName embedSpacing embedPrefix embedSuffix publicKey \
      privateKey shouldEmbed harpyIsSpecial fileType certificateFile \
      certificate data lines line

  if {[info exists path_set]} then {
    unset -nocomplain path path_set
  }

  if {[info exists quiet_set]} then {
    unset -nocomplain quiet quiet_set
  }
} else {
  usage ""
}