Class PasskeyChallenges
java.lang.Object
com.iizix.server.user.passkey.PasskeyChallenges
The challenges of the passkey ceremonies that are under way (CC-LOGIN-L8-PASSKEYS): made by the server from its secure random source, kept in the memory of this server only, bound to the client session that asked and to the kind of ceremony, valid for one answer and for a limited time. A client session has one challenge per kind: a new one replaces the one before. Nothing is stored in a database and nothing is sent twice; a server restart forgets them all, and the client starts again.
The store is bounded (MAX_PENDING): when it is full of challenges that have not expired, a new one is refused - the client sources that make them are held back by the sign-in throttle long before.
- Author:
- Christopher Mindus
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumThe kinds of ceremony.static final classA challenge under way.Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe size of a challenge, in bytes.static final intThe most challenges under way.Constructor Summary
ConstructorsConstructorDescriptionCreates the store on the system clock and the server's secure random source.PasskeyChallenges(LongSupplier clock, Supplier<byte[]> source) Creates the store on a clock and a source of challenges: for tests, which verify recorded ceremonies against the challenges they were recorded with.Method Summary
Modifier and TypeMethodDescriptioncreate(String session, PasskeyChallenges.Kind kind, long userID, String rpId, long validity) Makes the challenge of a ceremony.booleanrenew(String session, PasskeyChallenges.Kind kind, long validity) Extends the time a challenge under way is valid, keeping the same challenge bytes (CC-FIX-PASSKEY-RETRY-CHALLENGE): the arming of a passkey ceremony renews the challenge of the button that waits before it would be forgotten, so that the user's click never runs a ceremony against a challenge the server has already expired.intsize()Gets the count of challenges under way, expired ones that were not swept yet included.take(String session, PasskeyChallenges.Kind kind) Takes the challenge of a ceremony: it is removed, so that it is answered once.
Field Details
CHALLENGE_BYTES
public static final int CHALLENGE_BYTESThe size of a challenge, in bytes.- See Also:
MAX_PENDING
public static final int MAX_PENDINGThe most challenges under way.- See Also:
Constructor Details
PasskeyChallenges
public PasskeyChallenges()Creates the store on the system clock and the server's secure random source.PasskeyChallenges
Creates the store on a clock and a source of challenges: for tests, which verify recorded ceremonies against the challenges they were recorded with.- Parameters:
clock- The clock, milliseconds.source- The source of the challenges, each 16 bytes at least.- Throws:
NullPointerException- If a parameter is null.
Method Details
create
public PasskeyChallenges.Pending create(String session, PasskeyChallenges.Kind kind, long userID, String rpId, long validity) throws PasskeyException Makes the challenge of a ceremony. A challenge of the same client session and kind that is under way is replaced.- Parameters:
session- The key of the client session.kind- The kind of ceremony.userID- The user ID the ceremony is for, zero for a sign-in that names no user.rpId- The relying party ID the options are made for.validity- The time the challenge is valid, in milliseconds.- Returns:
- The pending challenge.
- Throws:
NullPointerException- Ifsession,kindorrpIdis null.IllegalArgumentException- Ifvalidityis not positive.PasskeyException- If the store is full.
take
Takes the challenge of a ceremony: it is removed, so that it is answered once.- Parameters:
session- The key of the client session.kind- The kind of ceremony.- Returns:
- The pending challenge, null when the client session has none of the kind or it has expired.
- Throws:
NullPointerException- If a parameter is null.
renew
Extends the time a challenge under way is valid, keeping the same challenge bytes (CC-FIX-PASSKEY-RETRY-CHALLENGE): the arming of a passkey ceremony renews the challenge of the button that waits before it would be forgotten, so that the user's click never runs a ceremony against a challenge the server has already expired. The challenge stays single-use - atake(String, PasskeyChallenges.Kind)still removes it - and bound to its session and kind; only the moment it would otherwise be forgotten moves.- Parameters:
session- The key of the client session.kind- The kind of ceremony.validity- The time from now the challenge is valid, in milliseconds.- Returns:
- true when a challenge of the session and kind was under way and was extended; false when the session has none of the kind, or it had already expired.
- Throws:
NullPointerException- If a parameter is null.IllegalArgumentException- Ifvalidityis not positive.
size
public int size()Gets the count of challenges under way, expired ones that were not swept yet included.- Returns:
- The count.