Class UpdateVerifier

java.lang.Object
com.iizix.server.tools.UpdateVerifier

public final class UpdateVerifier extends Object
Verifies an update package - the signed iiziServer-distribution-V.B.jar - right before the updater writes anything (CC-SERVER-RESTART-UPDATE-V5, survey section 6, the owner's ruling of 2026-10-11 18:41 point 5):
  1. every entry is signed, and by ONE chain (an entry altered after the signing fails to read, an entry added after it has no signer);
  2. the leaf's public key equals one of the AT MOST TWO keys the running build pins (old and current, current and new, or only current): a package signed by a key the build does not know is refused, and the administrator must download a newer build of the server, which knows the new certificate - no override;
  3. the chain validates (PKIX) to the trust store - the JDK's cacerts - at the date of the signature's timestamp (TSA), so that a package signed while the certificate was valid still verifies after its expiry;
  4. the package's build is newer than the installed one (a downgrade only with the explicit offline flag);
  5. the expected top-level directories are there and exactly one lib/com.iizix.standardserver-*.jar;
  6. no entry with .., an absolute path or a drive letter (zip slip);
  7. the package's flavour, read from its server jar (DistributionFlavour: customer, mindus or mls), is the installation's - a customer package never updates a Mindus installation, nor the reverse (CC-FIX-DIST-NO-ICU, the owner's ruling DN-1 of 2026-10-23);
  8. the installation's disk has room for the stage and the rollback copy.
A server built without a signature (SIGN=false, a test reactor) pins no key and refuses every package, unless the updater was started with -allowUnsigned (the server's -allowUnsignedUpdate true, refused in a production run mode).

Nothing here depends on another IIZI class: the updater runs from its own jar.

Author:
Christopher Mindus
  • Field Details

    • TOP_LEVEL

      public static final String[] TOP_LEVEL
      The top-level directories a package carries (build-iiziServer-distribution.ps1).
    • SERVER_JAR

      public static final Pattern SERVER_JAR
      The server jar inside a package or an installation: lib/com.iizix.standardserver-5.0.0.20657.jar.
  • Constructor Details

    • UpdateVerifier

      public UpdateVerifier(Collection<PublicKey> pinned, Collection<TrustAnchor> anchors, String currentBuild, boolean allowDowngrade, boolean allowUnsigned)
      Constructor without a flavour check (the tests of the other checks).
      Parameters:
      pinned - The public keys the running build pins, at most two; empty for an unsigned build.
      anchors - The trust anchors (the JDK's cacerts for a real server).
      currentBuild - The installed build, null when unknown (then no version check).
      allowDowngrade - true to accept an older or the same build.
      allowUnsigned - true to accept a package that is not signed.
      Throws:
      IllegalArgumentException - For more than two pinned keys.
    • UpdateVerifier

      public UpdateVerifier(Collection<PublicKey> pinned, Collection<TrustAnchor> anchors, String currentBuild, String installedFlavour, boolean allowDowngrade, boolean allowUnsigned)
      Constructor.
      Parameters:
      pinned - The public keys the running build pins, at most two; empty for an unsigned build.
      anchors - The trust anchors (the JDK's cacerts for a real server).
      currentBuild - The installed build, null when unknown (then no version check).
      installedFlavour - The installation's flavour (DistributionFlavour.ofInstallation(File)): a package of another flavour is refused; null for no flavour check.
      allowDowngrade - true to accept an older or the same build.
      allowUnsigned - true to accept a package that is not signed.
      Throws:
      IllegalArgumentException - For more than two pinned keys.
  • Method Details

    • jdkTrustAnchors

      public static Set<TrustAnchor> jdkTrustAnchors() throws IOException
      Loads the trust anchors of the JDK this JVM runs on: <java.home>/lib/security/cacerts.
      Returns:
      The anchors.
      Throws:
      IOException - If the store cannot be read.
    • trustAnchors

      public static Set<TrustAnchor> trustAnchors(File file, char[] password) throws IOException
      Loads the trust anchors of a key store (every certificate entry).
      Parameters:
      file - The key store file (JKS or PKCS12).
      password - Its password.
      Returns:
      The anchors.
      Throws:
      IOException - If the store cannot be read.
    • pinnedKeys

      public static List<PublicKey> pinnedKeys(String pem) throws IOException
      Reads the public keys of the certificates of a PEM text (the pinned signers of a build).
      Parameters:
      pem - The text: one or two -----BEGIN CERTIFICATE----- blocks.
      Returns:
      The keys, in order.
      Throws:
      IOException - If a certificate cannot be parsed.
    • installedBuild

      public static String installedBuild(File install)
      Finds the build of an installation: the version string of its single server jar.
      Parameters:
      install - The installation directory.
      Returns:
      The build, e.g. 5.0.0.20657, or null when there is not exactly one server jar.
    • compareBuilds

      public static int compareBuilds(String a, String b)
      Compares two builds: the last numeric component is the build number, the ones before are the version.
      Parameters:
      a - A build, e.g. 5.0.0.20657.
      b - Another.
      Returns:
      negative, zero or positive as a is older, the same or newer than b.
    • unsafeEntry

      public static String unsafeEntry(String name)
      Checks an entry name for zip slip: .. as a segment, an absolute path, a drive letter, a backslash.
      Parameters:
      name - The entry name.
      Returns:
      null when the name is safe, otherwise why not.
    • verify

      public UpdateVerifier.Result verify(File pkg, File install)
      Verifies a package.
      Parameters:
      pkg - The package file.
      install - The installation directory, for the free-space check; null to skip it.
      Returns:
      The result: ok or the reason of the refusal.