Check-in [61c3716d78]
Not logged in
Overview
Comment:Pickup upstream updates to the Harpy script signing tool.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA1: 61c3716d78443482b89ca74bc68b5704a6346098
User & Date: mistachkin on 2025-04-16 13:27:57
Other Links: manifest | tags
Context
2025-04-16
13:27
Pickup upstream updates to the Harpy script signing tool. Leaf check-in: 61c3716d78 user: mistachkin tags: trunk
04:46
Fix typo in the 'haveValidLoginCookie' procedure. check-in: d1f3dcdd08 user: mistachkin tags: trunk
Changes

Modified externals/Harpy/Tools/sign.eagle from [e2b78aa09a] to [835320f8bb].

17
18
19
20
21
22
23
24

25
26
27
28
29
30































31
32
33
34
35
36
37
proc usage { error } {
  if {[string length $error] > 0} then {puts stdout $error}

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


  #
  # NOTE: Indicate to the caller, if any, that we have failed.
  #
  exit 1
}
































proc maybeForceHashAlgorithm { certificate keyPair } {
  #
  # HACK: Some key pair types, e.g. DSA v1, require hard-coded
  #       hash algorithms, e.g. SHA1.  Do that now, if needed.
  #
  if {[isNonNullObjectHandle $keyPair] && \







|
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
proc usage { error } {
  if {[string length $error] > 0} then {puts stdout $error}

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

  #
  # NOTE: Indicate to the caller, if any, that we have failed.
  #
  exit 1
}

proc maybeInvokeHook { type phase } {
  set name [appendArgs $type _hook]

  if {[llength [info commands $name]] > 0} then {
    if {[catch {$name $phase} result] == 0} then {
      if {[string length $result] == 0} then {set result <none>}
      emitNotice [appendArgs $name " hook ok: " $result]
    } else {
      if {[string length $result] == 0} then {set result <none>}
      emitWarning [appendArgs $name " hook error: " $result]
    }
  }
}

proc emitNotice { message } {
  set message [string trim $message]
  catch {host result Ok [appendArgs $message \n]}
}

proc emitWarning { message } {
  emitNotice $message
  set message [string trim $message]
  catch {tclLog $message}
}

proc emitError { message } {
  emitWarning $message
  set message [string trim $message]
  error $message
}

proc maybeForceHashAlgorithm { certificate keyPair } {
  #
  # HACK: Some key pair types, e.g. DSA v1, require hard-coded
  #       hash algorithms, e.g. SHA1.  Do that now, if needed.
  #
  if {[isNonNullObjectHandle $keyPair] && \
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

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

  #
  # NOTE: Needed for the [getTemporaryPath] script procedure.







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

      puts stdout [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.
362
363
364
365
366
367
368
























369
370
371
372
373
374
375
  #
  if {[llength $argv] >= 10} then {
    set quantity [lindex $argv 9]
  } else {
    set quantity -1; # NOTE: Unlimited.
  }

























  #
  # NOTE: If the configuration file exists, load it now.
  #
  set configFileName [file join $path sign.settings.eagle]
  if {[file exists $configFileName]} then {source $configFileName}

  #







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
  #
  if {[llength $argv] >= 10} then {
    set quantity [lindex $argv 9]
  } else {
    set quantity -1; # NOTE: Unlimited.
  }

  #
  # NOTE: Do we want to manually override the unique Id?
  #
  if {[llength $argv] >= 11} then {
    set id [lindex $argv 10]
  } else {
    set id ""; # NOTE: Guid.NewGuid (?)
  }

  #
  # NOTE: Do we want to manually override the timestamp?
  #
  if {[llength $argv] >= 12} then {
    set timeStamp [object invoke \
        -create -alias DateTime ParseExact \
        [lindex $argv 11] yyyy-MM-ddTHH:mm:ss.fffffffK \
        null {AdjustToUniversal AssumeUniversal}]

    set timeStamp [object invoke \
        -create DateTime SpecifyKind $timeStamp Utc]
  } else {
    set timeStamp ""; # NOTE: DateTime.UtcNow (?)
  }

  #
  # NOTE: If the configuration file exists, load it now.
  #
  set configFileName [file join $path sign.settings.eagle]
  if {[file exists $configFileName]} then {source $configFileName}

  #
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  } else {
    set shouldEmbed false
  }

  #
  # HOOK: After all arguments have been parsed and processed.
  #
  catch {certificate_hook phase0}

  #
  # NOTE: The existing embedded certificate, if any, must be
  #       removed prior to signing the (script?) file.
  #
  if {$shouldEmbed && \
      ![info exists no(removeEmbeddedCertificate)]} then {







|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  } else {
    set shouldEmbed false
  }

  #
  # HOOK: After all arguments have been parsed and processed.
  #
  maybeInvokeHook certificate phase0

  #
  # NOTE: The existing embedded certificate, if any, must be
  #       removed prior to signing the (script?) file.
  #
  if {$shouldEmbed && \
      ![info exists no(removeEmbeddedCertificate)]} then {
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
    #
    set certificate [certificate import $fileName]
    maybeForceHashAlgorithm $certificate $privateKey

    #
    # HOOK: Post-certificate object creation (import).
    #
    catch {certificate_hook phase1}

    #
    # NOTE: Attempt to re-sign the license certificate file.  Skip
    #       setting the Id as it should already be set correctly.
    #
    if {[certificate sign -encoding $encoding -settimestamp \

            -setkey $certificate $privateKey] ne "SignedOk"} then {
      error [appendArgs \
          "failed to create updated signature for " $fileType \
          " \"" $fileName \"]
    }

    #
    # NOTE: Attempt to re-verify the license certificate file.
    #
    if {[certificate verify -encoding $encoding $certificate \
            $privateKey] ne "VerifiedOk"} then {
      error [appendArgs \
          "failed to verify signature for " $fileType " \"" $fileName \"]
    }
  } else {
    #
    # NOTE: Set the file type for error messages.
    #
    if {[isKeyRingFile $fileName]} then {







|





|
>

|









|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
    #
    set certificate [certificate import $fileName]
    maybeForceHashAlgorithm $certificate $privateKey

    #
    # HOOK: Post-certificate object creation (import).
    #
    maybeInvokeHook certificate phase1

    #
    # NOTE: Attempt to re-sign the license certificate file.  Skip
    #       setting the Id as it should already be set correctly.
    #
    if {[certificate sign -encoding $encoding \
            -settimestamp -maybesettimestamp $timeStamp \
            -setkey $certificate $privateKey] ne "SignedOk"} then {
      emitError [appendArgs \
          "failed to create updated signature for " $fileType \
          " \"" $fileName \"]
    }

    #
    # NOTE: Attempt to re-verify the license certificate file.
    #
    if {[certificate verify -encoding $encoding $certificate \
            $privateKey] ne "VerifiedOk"} then {
      emitError [appendArgs \
          "failed to verify signature for " $fileType " \"" $fileName \"]
    }
  } else {
    #
    # NOTE: Set the file type for error messages.
    #
    if {[isKeyRingFile $fileName]} then {
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
    }

    maybeForceHashAlgorithm $certificate $privateKey

    #
    # HOOK: Post-certificate object creation (create).
    #
    catch {certificate_hook phase1}

    #
    # NOTE: If the certificate vendor is available, set it.
    #
    if {[string length $vendor] > 0} then {
      $certificate Vendor $vendor
    }







|







567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
    }

    maybeForceHashAlgorithm $certificate $privateKey

    #
    # HOOK: Post-certificate object creation (create).
    #
    maybeInvokeHook certificate phase1

    #
    # NOTE: If the certificate vendor is available, set it.
    #
    if {[string length $vendor] > 0} then {
      $certificate Vendor $vendor
    }
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581


582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621


622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
      #       some point, be seen by the script policy callback.
      #
      $certificate EntityValue [readEntityValue $fileName]

      #
      # HOOK: Post-certificate property setup (embedded).
      #
      catch {certificate_hook phase2}

      #
      # NOTE: Attempt to sign the embedded file certificate and place
      #       the Id, timestamp, public key token, and signature bytes
      #       into the certificate we created above.
      #
      if {$importFirst} then {
        if {[certificate sign -encoding $encoding \
                -setkey -hashflags {+Basic Embedded} $certificate \
                $privateKey] ne "SignedOk"} then {
          error [appendArgs \
              "failed to create updated embedded signature for " \
              $fileType " \"" $fileName \"]
        }
      } else {
        if {[certificate sign -encoding $encoding -setid -settimestamp \


                -setkey -hashflags {+Basic Embedded} $certificate \
                $privateKey] ne "SignedOk"} then {
          error [appendArgs \
              "failed to create embedded signature for " $fileType \
              " \"" $fileName \"]
        }
      }

      #
      # NOTE: Sanity check that the embedded file certificate we just
      #       created validates properly.
      #
      if {[certificate verify -encoding $encoding \
              -hashflags {+Basic Embedded} $certificate \
              $publicKey] ne "VerifiedOk"} then {
        error [appendArgs \
            "failed to verify embedded signature for " $fileType \
            " \"" $fileName \"]
      }
    } else {
      #
      # HOOK: Post-certificate property setup (non-embedded).
      #
      catch {certificate_hook phase2}

      #
      # NOTE: Attempt to sign the data file and place the Id, timestamp,
      #       public key token, and signature bytes into the blank
      #       certificate we created above.
      #
      if {$importFirst} then {
        if {[certificate signfile -encoding $encoding \
                -setkey $certificate $privateKey \
                $fileName] ne "SignedOk"} then {
          error [appendArgs \
              "failed to create updated signature for " $fileType \
              " \"" $fileName \"]
        }
      } else {
        if {[certificate signfile -encoding $encoding -setid \


                -settimestamp -setkey $certificate $privateKey \
                $fileName] ne "SignedOk"} then {
          error [appendArgs \
              "failed to create signature for " $fileType \
              " \"" $fileName \"]
        }
      }

      #
      # NOTE: Sanity check that the data file certificate we just
      #       created validates properly.
      #
      if {[certificate verifyfile -encoding $encoding \
              $certificate $publicKey $fileName] ne "VerifiedOk"} then {
        error [appendArgs \
            "failed to verify signature for " $fileType \
            " \"" $fileName \"]
      }
    }
  }

  #







|










|




|
>
>
|

|












|







|










|




|
>
>
|

|











|







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
      #       some point, be seen by the script policy callback.
      #
      $certificate EntityValue [readEntityValue $fileName]

      #
      # HOOK: Post-certificate property setup (embedded).
      #
      maybeInvokeHook certificate phase2

      #
      # NOTE: Attempt to sign the embedded file certificate and place
      #       the Id, timestamp, public key token, and signature bytes
      #       into the certificate we created above.
      #
      if {$importFirst} then {
        if {[certificate sign -encoding $encoding \
                -setkey -hashflags {+Basic Embedded} $certificate \
                $privateKey] ne "SignedOk"} then {
          emitError [appendArgs \
              "failed to create updated embedded signature for " \
              $fileType " \"" $fileName \"]
        }
      } else {
        if {[certificate sign -encoding $encoding \
                -setid -maybesetid $id -settimestamp \
                -maybesettimestamp $timeStamp -setkey \
                -hashflags {+Basic Embedded} $certificate \
                $privateKey] ne "SignedOk"} then {
          emitError [appendArgs \
              "failed to create embedded signature for " $fileType \
              " \"" $fileName \"]
        }
      }

      #
      # NOTE: Sanity check that the embedded file certificate we just
      #       created validates properly.
      #
      if {[certificate verify -encoding $encoding \
              -hashflags {+Basic Embedded} $certificate \
              $publicKey] ne "VerifiedOk"} then {
        emitError [appendArgs \
            "failed to verify embedded signature for " $fileType \
            " \"" $fileName \"]
      }
    } else {
      #
      # HOOK: Post-certificate property setup (non-embedded).
      #
      maybeInvokeHook certificate phase2

      #
      # NOTE: Attempt to sign the data file and place the Id, timestamp,
      #       public key token, and signature bytes into the blank
      #       certificate we created above.
      #
      if {$importFirst} then {
        if {[certificate signfile -encoding $encoding \
                -setkey $certificate $privateKey \
                $fileName] ne "SignedOk"} then {
          emitError [appendArgs \
              "failed to create updated signature for " $fileType \
              " \"" $fileName \"]
        }
      } else {
        if {[certificate signfile -encoding $encoding \
                -setid -maybesetid $id -settimestamp \
                -maybesettimestamp $timeStamp -setkey \
                $certificate $privateKey \
                $fileName] ne "SignedOk"} then {
          emitError [appendArgs \
              "failed to create signature for " $fileType \
              " \"" $fileName \"]
        }
      }

      #
      # NOTE: Sanity check that the data file certificate we just
      #       created validates properly.
      #
      if {[certificate verifyfile -encoding $encoding \
              $certificate $publicKey $fileName] ne "VerifiedOk"} then {
        emitError [appendArgs \
            "failed to verify signature for " $fileType \
            " \"" $fileName \"]
      }
    }
  }

  #
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  catch {file delete -force $certificateFile}

  #
  # NOTE: Export the data file certificate to disk.
  #
  if {[certificate export $certificate $certificateFile] \
          ne "ExportedOk"} then {
    error [appendArgs \
        "failed to export signature for " $fileType " \"" $fileName \"]
  }

  #
  # NOTE: Add the standard XML comment to the file.
  #
  if {[certificate warning -type Script $certificateFile] \
          ne "WarningOk"} then {
    error [appendArgs \
        "failed to add warning for " $fileType " \"" $fileName \"]
  }

  #
  # HACK: Read the certificate file data into memory, fix the
  #       formatting how we want it, and then re-write the modified
  #       data back out to the same certificate file.







|








|







719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  catch {file delete -force $certificateFile}

  #
  # NOTE: Export the data file certificate to disk.
  #
  if {[certificate export $certificate $certificateFile] \
          ne "ExportedOk"} then {
    emitError [appendArgs \
        "failed to export signature for " $fileType " \"" $fileName \"]
  }

  #
  # NOTE: Add the standard XML comment to the file.
  #
  if {[certificate warning -type Script $certificateFile] \
          ne "WarningOk"} then {
    emitError [appendArgs \
        "failed to add warning for " $fileType " \"" $fileName \"]
  }

  #
  # HACK: Read the certificate file data into memory, fix the
  #       formatting how we want it, and then re-write the modified
  #       data back out to the same certificate file.
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
    puts stdout [appendArgs \
        "added embedded certificate to " $fileType " \"" $fileName \"]
  }

  #
  # HOOK: Script completion.
  #
  catch {certificate_hook phase3}

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







|







820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
    puts stdout [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}
  }

Modified externals/Harpy/Tools/sign.eagle.asc from [0c12f86a5e] to [7062713373].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-----BEGIN PGP SIGNATURE-----
Comment: Eagle Package Repository

iQIzBAABCAAdFiEEw8dROIPu3TrtH+QlUCyWr0ldwtkFAmd3juoACgkQUCyWr0ld
wtnJUBAAuM2RutdzFdJ9Kn8kPLmMEzrTN1D6Seukzob0tXktzdXkYiokRtNOeZj9
F7Rg2xh+fOkKl8wFoWmcsdRaGf2Xop+L3kFpP0vwJhcI5VVgQjan+WYBcoiPy5Pz
pqbhHoHoayX9E3rrFDN8kjgS6y5P2hhX/VZxNJuCUq6/UmnCLT/U6KdXTar0//T2
xppuJk2rbrlS8oWh4GqodLMzALY4KOmYhbTr+ltfFl17GSyxFbuoV2t1Vddrkbhw
OozF8r//0fKae7usuxKN13SKyZVcH6g62tQBYZlMy8DiQhdQraUVhQCUk+ijI+9V
Eh+N+3UMMfZhDfhANFHncGR6buyCYh5aS/BGO01fmLole21mRQFktDVHP1uFMaVk
7VdlHiSboXTb6OwzoQw6YnQe7ONvWohJnp2STttgbL3q2Ezs6FXka13R3ZkkiPZr
phDmUGpg/64ZdSupbIS8q2u6eDZOLAR02XqFU7HJvb1rku6eopuLw3SBBnn7PDsi
DMn3KusT4sox6xVUWfPitTHEAxeMpWxIbauDhDV7vICVEbsdJBMIbkWEFe1R8+PB
6AJhGnb+aKZJyb90Cz5FIr9eE5uwPYdv1Qa1S65dBYzZD76rIbdODsD1jFLSZbJ8
g5xRA53rzNl93fFAjqK3WNZnLyf0O30unWNuQk6KsNp5FfPqRwk=
=NjBw
-----END PGP SIGNATURE-----



|
|
|
|
|
|
|
|
|
|
|
|
|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-----BEGIN PGP SIGNATURE-----
Comment: Eagle Package Repository

iQIzBAABCAAdFiEEw8dROIPu3TrtH+QlUCyWr0ldwtkFAmf/sC8ACgkQUCyWr0ld
wtlc5BAAvEmJ2tHq24JdMAhXo8rG6z7LYRI5l/9Zk3Es3pfmz/hX43jN87SPkzw0
CLPLd3u9UC/+4sLZTfKVJ85rTFGWhOPgjSM2DRudzcY4slx9j9V9+W1fKX4a7MRl
mCIwQyiFJIaO63vPZCsMlXSI2x7OpnVajfcXMwIeuI13HuTMnkmij/if8bdA/qqV
GENtUQI0i4Yo0CAsyYYWU4WewuOS0YYqQUY5UqkZ60SVvavA8EO5OZ8T4BqJZ9yE
1QbtAQ8S2kjT/Or6kIWRoDkGf2jPreyo06foz3233pu4kbgUhdg7kc89F7CXUYcP
c/54P5LMYZP1GmzBtuM+6t4UEBb8WDEI10vhVH3l2jNHCkOx9q24ZosNO8T+SbiK
C/lU53Rm2nQkM6Hh+mnYiJ+HQXQVrl0tuXUyO/fvqJpDAVmvPHirpk2xH0lT0r7T
L9varp2LCHORhoj2gpNJZFODkWPK/kCm91tkjK5zrtqsudteK9j6A7urTKjVEhy3
EJwqj6XwU87xHhu83MmkhGPTolrckpbHP86AMHkh9jREyA8tYt7Zn137CBAbxnzG
asw4WZUvYCjcfUS0fYZB4uR29lwYtGmaIvDkuk7kmdL63jJlSdhECSVokylskT3W
ueNtrRZYg47ECAm4eac4Z4Z6yQniTCL5drJ56ZWbW0oiYZM0l8Q=
=v5/Q
-----END PGP SIGNATURE-----

Modified externals/Harpy/Tools/sign.eagle.harpy from [9b279cae82] to [b013b71a9b].

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    THE ASSOCIATED SOFTWARE MAY NOT WORK PROPERLY IF THIS FILE IS ALTERED.
-->
<Certificate xmlns="https://eagle.to/2011/harpy"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Protocol>None</Protocol>
  <Vendor>Mistachkin Systems</Vendor>
  <Id>3905bd6f-9d69-4378-bfb5-1b47601a845a</Id>
  <HashAlgorithm>SHA512</HashAlgorithm>
  <EntityType>Script</EntityType>
  <TimeStamp>2025-01-03T07:15:28.3044792Z</TimeStamp>
  <Duration>-1.00:00:00</Duration>
  <Key>0x9559f6017247e3e2</Key>
  <Signature>
    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
  </Signature>
</Certificate>







|


|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    THE ASSOCIATED SOFTWARE MAY NOT WORK PROPERLY IF THIS FILE IS ALTERED.
-->
<Certificate xmlns="https://eagle.to/2011/harpy"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Protocol>None</Protocol>
  <Vendor>Mistachkin Systems</Vendor>
  <Id>00a1aba9-8964-4af9-be97-f38e3bf4f8d3</Id>
  <HashAlgorithm>SHA512</HashAlgorithm>
  <EntityType>Script</EntityType>
  <TimeStamp>2025-04-16T13:26:06.7888453Z</TimeStamp>
  <Duration>-1.00:00:00</Duration>
  <Key>0x9559f6017247e3e2</Key>
  <Signature>
    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
  </Signature>
</Certificate>

Modified externals/Harpy/Tools/sign.eagle.harpy.asc from [e31aac5ff1] to [2820582464].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-----BEGIN PGP SIGNATURE-----
Comment: Eagle Package Repository

iQIzBAABCAAdFiEEw8dROIPu3TrtH+QlUCyWr0ldwtkFAmd3juwACgkQUCyWr0ld
wtmOBRAAgKuX8HluLRGWjxwepf7n8WUhRkd6K7LgpX4nozXofQgHFcKBdc0MFS5+
C9E4QBeomRz0M97ntML17y3rEiEvTXq4ka1Me9YnSPa1KlCXNDw1EI7/01hQdqNC
Rw/QMGRpPJqOrwRoc88kZ6h2QAJyAUDyf5pNFCpXpxadCW0Xk+EQU/QgbWAIbrwv
ewlJTclgQwGuvtsswf8B21b6mVtIDXhA8H4oyL4eb5X5Qp0jeYcGlCBLwn+QqR0P
7DhegF0d0qGxR80zQ19PkqiD+EUggBh/HvYhkv0jvOa/mLBHvH1U2I5GBvsnb1mL
UlR9fOp75SSpJxiaT9189FcsuTHaTSy5J9GTUBOTRZxVJ60yKrMlC8IZY+n/0cqR
2bgHhgjh1inAjCVG4jHPea7RGkJC+I41uLV0Axkl631jLJXDGm/XfWFpb3Y2XImG
nXpTtb2dC5ekXY59pXfSvP4Ywvzya27gvY+XvjWnlNl7ojQlJkAvnWRi6WE7FtVB
kmjeg0OT97vVTDo4FCy0S9xZvOeZ3KTdfatmHXUpjw4i7QN/qCvDOEdW//h43Ymp
GDSByMxU5rO2EKNg6RrW9g3rzQ4HPn1ssTnxkSEZmTShCvmRVAJzACFMAdseqssF
CCxufO28mAnIxQylk/a6z7wVRwRQgyKmFkKH+AU7cQp7Ixj7/Js=
=Sdvx
-----END PGP SIGNATURE-----



|
|
|
|
|
|
|
|
|
|
|
|
|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-----BEGIN PGP SIGNATURE-----
Comment: Eagle Package Repository

iQIzBAABCAAdFiEEw8dROIPu3TrtH+QlUCyWr0ldwtkFAmf/sDIACgkQUCyWr0ld
wtklog//XkO0gPo1I+tI8Nr+N3hJv6rwE7+c2qn9tF2hv5aSUT0uqm1Sv048VcXu
ITAIR1uwmuF24OxKN9u6/JiWycLY4BAid2JDtY2d1sKLozeE/mg18K/m7Z2jt051
b76tafbbrvuEbWrNhYt8duxM+g+3q6gssw7KiTe1ZGNEf+7pFPFNewcxeBsaYDAB
3VAS/5uz3z0FgHhfOKy8blF8zZfdjw9qxwoWfNGgkePEBA3H69S5gwqauMnjPush
UHoMbbhwkMq4rMgTm1iOLENv8r5yicm0NiSYzGefRaIsgUJPYk3hwq0mIWDHK2KE
EnHHJNf9Da6ngB97gK16jCYdEsPq+2lqacDnRRiQN4B8SadGYcGejOfKQvHyF1hP
FQi0+24zCmU3s8kf1CusCKMgZyp/vG5iGV4ruxuKjAGAzdb7e1X1MnEMgAx+D7mC
nccjQ0W8haWM2/Slt0/QncgDqbhip1UpvrTrcXWy9+Qto4+A4BzPkQxS11H0tHQ4
/DKGugrIo3kbSztMbiNCriIsbPrHdPmoDxH2owc2Vxle4r73IEs2d8TWmm0jtfgm
y4n1zZuV1yQXCm98sD0GZ3vVXWFWwDGdxgk7OaCKKZUHCKghBLnrqfRrx6P8mP7W
1FRr0aYhcJvBBU01PLMxFNKJrw5MOvLUQZg4X/aProFUnl1irrM=
=EahN
-----END PGP SIGNATURE-----