Class HubClusterKey

java.lang.Object
com.iizix.server.hub.HubClusterKey

public final class HubClusterKey extends Object
The interim cluster key of HUB-DESIGN.md section 2.2 (ruled H-8): a random 256-bit key in the file the definition's [hub] key names, identical on every member, distributed by the operator as the Push key files are, and used as an HMAC challenge-response at registration until B-9 replaces it with the member's licence document. The principal opens every connection with CHALLENGE {pn} (ruled LV-12 (a)) and the member answers with answer(byte[],String,String): HMAC-SHA256 under the key over "iizi-hub-register/1" 0x00 pn member run, so that a credential copied from one connection is worthless on another and a credential of one member is worthless for another member or run.

The file: text, the key as 64 hexadecimal digits, whitespace and line breaks ignored, # or ; comment lines ignored; an operator creates it with openssl rand -hex 32 > hub.key. Protected as PUSH-CREDENTIALS.md section 8 protects its file, by the same code: on a POSIX file system a file that grants anything to group or others is REFUSED (PushKeyFiles.posixRefusal(Path)); on Windows an ACL that grants read to a broad principal is a WARNING (PushKeyFiles.windowsAclWarning(Path)).

Never logged: the key, the answer, any line of the file; a refusal names the path and what is wrong with it. toString() answers the path only.

Author:
Christopher Mindus
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    A refusal of the file: the message names the path and the reason, never the content.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The MAC algorithm: "HmacSHA256".
    static final int
    The key length in bytes: 32.
    static final String
    The label of the answer: "iizi-hub-register/1", followed by a zero byte.
  • Constructor Summary

    Constructors
    Constructor
    Description
    HubClusterKey(byte[] key)
    Creates the key from bytes, for a test or a generator.
  • Method Summary

    Modifier and Type
    Method
    Description
    byte[]
    answer(byte[] pn, String member, String run)
    Computes the answer to a challenge: HMAC-SHA256 under the key over "iizi-hub-register/1", a zero byte, the challenge, the member ID and the run UUID (UTF-8).
    Gets the file.
    load(Path file)
    Loads the key file, applying the permission rule: a POSIX refusal throws, a Windows ACL warning is logged and the file is loaded.
    Answers the path only: the key is never a string.
    boolean
    verify(byte[] pn, String member, String run, byte[] cred)
    Verifies a member's answer in constant time.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

  • Constructor Details

    • HubClusterKey

      public HubClusterKey(byte[] key)
      Creates the key from bytes, for a test or a generator.
      Parameters:
      key - The 32 bytes, copied.
      Throws:
      IllegalArgumentException - If the key is not 32 bytes.
  • Method Details

    • load

      public static HubClusterKey load(Path file) throws HubClusterKey.Refusal
      Loads the key file, applying the permission rule: a POSIX refusal throws, a Windows ACL warning is logged and the file is loaded.
      Parameters:
      file - The file, as the definition names it, resolved against the working directory when relative.
      Returns:
      The key.
      Throws:
      HubClusterKey.Refusal - If the file does not exist, is not a file, grants permissions to group or others, cannot be read, or does not hold 64 hexadecimal digits.
    • getFile

      public Path getFile()
      Gets the file.
      Returns:
      The file, or null for a key given as bytes.
    • answer

      public byte[] answer(byte[] pn, String member, String run)
      Computes the answer to a challenge: HMAC-SHA256 under the key over "iizi-hub-register/1", a zero byte, the challenge, the member ID and the run UUID (UTF-8).
      Parameters:
      pn - The challenge, HubServerProp.CHALLENGE_BYTES bytes.
      member - The member ID.
      run - The run UUID, in its canonical 36-character form.
      Returns:
      The 32-byte answer.
      Throws:
      IllegalArgumentException - If the challenge is null or of another length.
    • verify

      public boolean verify(byte[] pn, String member, String run, byte[] cred)
      Verifies a member's answer in constant time.
      Parameters:
      pn - The challenge this connection was opened with.
      member - The member ID the member claims.
      run - The run UUID the member claims.
      cred - The credential the member sent, may be null.
      Returns:
      true when the credential is the answer to this challenge for that member and run.
    • toString

      public String toString()
      Answers the path only: the key is never a string.
      Overrides:
      toString in class Object
      Returns:
      The path, or (bytes).