Class HubClusterKey
java.lang.Object
com.iizix.server.hub.HubClusterKey
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 ClassesModifier and TypeClassDescriptionstatic final classA refusal of the file: the message names the path and the reason, never the content.Field Summary
FieldsConstructor Summary
ConstructorsConstructorDescriptionHubClusterKey(byte[] key) Creates the key from bytes, for a test or a generator.Method Summary
Modifier and TypeMethodDescriptionbyte[]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).getFile()Gets the file.static HubClusterKeyLoads the key file, applying the permission rule: a POSIX refusal throws, a Windows ACL warning is logged and the file is loaded.toString()Answers the path only: the key is never a string.booleanVerifies a member's answer in constant time.
Field Details
LABEL
The label of the answer: "iizi-hub-register/1", followed by a zero byte.- See Also:
KEY_BYTES
public static final int KEY_BYTESThe key length in bytes: 32.- See Also:
ALGORITHM
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
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
answer
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_BYTESbytes.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
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