Skip to content

Commit c707fed

Browse files
committed
Convert FIDO enum-like classes to actual enums
1 parent 75489a1 commit c707fed

File tree

8 files changed

+248
-323
lines changed

8 files changed

+248
-323
lines changed

webauthn-server-core/src/main/java/com/yubico/fido/metadata/KeyProtectionType.java

Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,143 +2,137 @@
22

33
import com.fasterxml.jackson.annotation.JsonCreator;
44
import com.fasterxml.jackson.annotation.JsonValue;
5+
import java.security.Key;
56
import java.util.stream.Stream;
6-
import lombok.EqualsAndHashCode;
7+
import lombok.Getter;
78

89
/**
9-
* Enum-like collection of known <code>KEY_PROTECTION</code> values.
10+
* The KEY_PROTECTION constants are flags in a bit field represented as a 16 bit long integer. They
11+
* describe the method an authenticator uses to protect the private key material for FIDO
12+
* registrations. Refer to [UAFAuthnrCommands] for more details on the relevance of keys and key
13+
* protection. These constants are reported and queried through the UAF Discovery APIs and used to
14+
* form authenticator policies in UAF protocol messages. Each constant has a case-sensitive string
15+
* representation (in quotes), which is used in the authoritative metadata for FIDO authenticators.
1016
*
11-
* <p>Constants in this class behave like enum constants. Use {@link #of(short)} to parse raw <code>
12-
* int</code> values.
13-
*
14-
* @see #of(short)
17+
* @see #fromValue(short)
18+
* @see #fromName(String)
1519
* @see <a
16-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
20+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
1721
* Registry of Predefined Values §3.2 Key Protection Types</a>
1822
*/
19-
@EqualsAndHashCode
20-
public class KeyProtectionType {
23+
@Getter
24+
public enum KeyProtectionType {
2125

2226
/**
23-
* This flag must be set if the authenticator uses software-based key management. Mutually
24-
* exclusive with {@link #KEY_PROTECTION_HARDWARE}, {@link #KEY_PROTECTION_TEE}, {@link
25-
* #KEY_PROTECTION_SECURE_ELEMENT}.
27+
* This flag MUST be set if the authenticator uses software-based key management. Exclusive in
28+
* authenticator metadata with {@link #KEY_PROTECTION_HARDWARE}, {@link #KEY_PROTECTION_TEE},
29+
* {@link #KEY_PROTECTION_SECURE_ELEMENT}.
2630
*
2731
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
2832
*
2933
* @see <a
30-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
34+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
3135
* Registry of Predefined Values §3.2 Key Protection Types</a>
3236
*/
33-
public static final KeyProtectionType KEY_PROTECTION_SOFTWARE =
34-
new KeyProtectionType((short) 0x0001, "SOFTWARE");
37+
KEY_PROTECTION_SOFTWARE((short) 0x0001, "software"),
3538

3639
/**
37-
* This flag should be set if the authenticator uses hardware-based key management. Mutually
38-
* exclusive with {@link #KEY_PROTECTION_SOFTWARE}.
40+
* This flag SHOULD be set if the authenticator uses hardware-based key management. Exclusive in
41+
* authenticator metadata with {@link #KEY_PROTECTION_SOFTWARE}.
3942
*
4043
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
4144
*
4245
* @see <a
43-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
46+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
4447
* Registry of Predefined Values §3.2 Key Protection Types</a>
4548
*/
46-
public static final KeyProtectionType KEY_PROTECTION_HARDWARE =
47-
new KeyProtectionType((short) 0x0002, "HARDWARE");
49+
KEY_PROTECTION_HARDWARE((short) 0x0002, "hardware"),
4850

4951
/**
50-
* This flag should be set if the authenticator uses the Trusted Execution Environment for key
51-
* management. In authenticator metadata, this flag should be set in conjunction with {@link
52-
* #KEY_PROTECTION_HARDWARE}. Mutually exclusive with {@link #KEY_PROTECTION_SOFTWARE}, {@link
53-
* #KEY_PROTECTION_SECURE_ELEMENT}.
52+
* This flag SHOULD be set if the authenticator uses the Trusted Execution Environment [TEE] for
53+
* key management. In authenticator metadata, this flag should be set in conjunction with {@link
54+
* #KEY_PROTECTION_HARDWARE}. Mutually exclusive in authenticator metadata with {@link
55+
* #KEY_PROTECTION_SOFTWARE}, {@link #KEY_PROTECTION_SECURE_ELEMENT}.
5456
*
5557
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
5658
*
5759
* @see <a
58-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
60+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
5961
* Registry of Predefined Values §3.2 Key Protection Types</a>
6062
*/
61-
public static final KeyProtectionType KEY_PROTECTION_TEE =
62-
new KeyProtectionType((short) 0x0004, "TEE");
63+
KEY_PROTECTION_TEE((short) 0x0004, "tee"),
6364

6465
/**
65-
* This flag should be set if the authenticator uses a Secure Element for key management. In
66-
* authenticator metadata, this flag should be set in conjunction with {@link
67-
* #KEY_PROTECTION_HARDWARE}. Mutually exclusive with {@link #KEY_PROTECTION_TEE}, {@link
68-
* #KEY_PROTECTION_SOFTWARE}.
66+
* This flag SHOULD be set if the authenticator uses a Secure Element [SecureElement] for key
67+
* management. In authenticator metadata, this flag should be set in conjunction with {@link
68+
* #KEY_PROTECTION_HARDWARE}. Mutually exclusive in authenticator metadata with {@link
69+
* #KEY_PROTECTION_TEE}, {@link #KEY_PROTECTION_SOFTWARE}.
6970
*
7071
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
7172
*
7273
* @see <a
73-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
74+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
7475
* Registry of Predefined Values §3.2 Key Protection Types</a>
7576
*/
76-
public static final KeyProtectionType KEY_PROTECTION_SECURE_ELEMENT =
77-
new KeyProtectionType((short) 0x0008, "SECURE_ELEMENT");
77+
KEY_PROTECTION_SECURE_ELEMENT((short) 0x0008, "secure_element"),
7878

7979
/**
80-
* This flag must be set if the authenticator does not store (wrapped) UAuth keys at the client,
81-
* but relies on a server-provided key handle. This flag must be set in conjunction with one of
80+
* This flag MUST be set if the authenticator does not store (wrapped) UAuth keys at the client,
81+
* but relies on a server-provided key handle. This flag MUST be set in conjunction with one of
8282
* the other KEY_PROTECTION flags to indicate how the local key handle wrapping key and operations
83-
* are protected. Servers may unset this flag in authenticator policy if they are not prepared to
83+
* are protected. Servers MAY unset this flag in authenticator policy if they are not prepared to
8484
* store and return key handles, for example, if they have a requirement to respond
8585
* indistinguishably to authentication attempts against userIDs that do and do not exist. Refer to
86-
* [UAFProtocol] for more details.
86+
* [<a
87+
* href="https://fidoalliance.org/specs/fido-uaf-v1.2-rd-20171128/fido-uaf-protocol-v1.2-rd-20171128.html">UAFProtocol</a>]
88+
* for more details.
8789
*
8890
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
8991
*
9092
* @see <a
91-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#key-protection-types">FIDO
93+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#key-protection-types">FIDO
9294
* Registry of Predefined Values §3.2 Key Protection Types</a>
9395
* @see <a
9496
* href="https://fidoalliance.org/specs/fido-uaf-v1.2-rd-20171128/fido-uaf-protocol-v1.2-rd-20171128.html">FIDO
9597
* UAF Protocol Specification [UAFProtocol]</a>
9698
*/
97-
public static final KeyProtectionType KEY_PROTECTION_REMOTE_HANDLE =
98-
new KeyProtectionType((short) 0x0010, "REMOTE_HANDLE");
99+
KEY_PROTECTION_REMOTE_HANDLE((short) 0x0010, "remote_handle");
99100

100-
@JsonValue public final short value;
101+
private final short value;
101102

102-
@EqualsAndHashCode.Exclude private final transient String name;
103+
@JsonValue private final String name;
103104

104-
private KeyProtectionType(short value, String name) {
105+
KeyProtectionType(short value, String name) {
105106
this.value = value;
106107
this.name = name;
107108
}
108109

109110
/**
110-
* @return An array containing all predefined values of {@link KeyProtectionType} known by this
111-
* implementation.
111+
* @return If <code>value</code> matches any {@link KeyProtectionType} constant, returns that
112+
* constant instance. Otherwise throws {@link IllegalArgumentException}.
112113
*/
113-
public static KeyProtectionType[] values() {
114-
return new KeyProtectionType[] {
115-
KEY_PROTECTION_SOFTWARE,
116-
KEY_PROTECTION_HARDWARE,
117-
KEY_PROTECTION_TEE,
118-
KEY_PROTECTION_SECURE_ELEMENT,
119-
KEY_PROTECTION_REMOTE_HANDLE
120-
};
114+
public static KeyProtectionType fromValue(short value) {
115+
return Stream.of(values())
116+
.filter(v -> v.value == value)
117+
.findAny()
118+
.orElseThrow(
119+
() ->
120+
new IllegalArgumentException(
121+
String.format("Unknown %s value: 0x%04x", KeyProtectionType.class, value)));
121122
}
122123

123124
/**
124-
* @return If <code>value</code> is the same as that of any of the constants in {@link
125-
* KeyProtectionType}, returns that constant instance. Otherwise returns a new instance
126-
* containing <code>value</code>.
125+
* @return If <code>name</code> matches any {@link Key} constant, returns that constant instance.
126+
* Otherwise throws {@link IllegalArgumentException}.
127127
*/
128128
@JsonCreator
129-
public static KeyProtectionType of(short value) {
129+
public static KeyProtectionType fromName(String name) {
130130
return Stream.of(values())
131-
.filter(v -> v.value == value)
131+
.filter(v -> v.name.equals(name))
132132
.findAny()
133-
.orElseGet(() -> new KeyProtectionType(value, null));
134-
}
135-
136-
@Override
137-
public String toString() {
138-
if (name == null) {
139-
return String.format("%s(%04x)", KeyProtectionType.class.getSimpleName(), value);
140-
} else {
141-
return "KEY_PROTECTION_" + name;
142-
}
133+
.orElseThrow(
134+
() ->
135+
new IllegalArgumentException(
136+
String.format("Unknown %s name: %s", KeyProtectionType.class, name)));
143137
}
144138
}

webauthn-server-core/src/main/java/com/yubico/fido/metadata/MatcherProtectionType.java

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,100 +3,99 @@
33
import com.fasterxml.jackson.annotation.JsonCreator;
44
import com.fasterxml.jackson.annotation.JsonValue;
55
import java.util.stream.Stream;
6-
import lombok.EqualsAndHashCode;
6+
import lombok.Getter;
77

88
/**
9-
* Enum-like collection of known <code>MATCHER_PROTECTION</code> values.
9+
* The MATCHER_PROTECTION constants are flags in a bit field represented as a 16 bit long integer.
10+
* They describe the method an authenticator uses to protect the matcher that performs user
11+
* verification. These constants are reported and queried through the UAF Discovery APIs and used to
12+
* form authenticator policies in UAF protocol messages. Refer to [UAFAuthnrCommands] for more
13+
* details on the matcher component. Each constant has a case-sensitive string representation (in
14+
* quotes), which is used in the authoritative metadata for FIDO authenticators.
1015
*
11-
* <p>Constants in this class behave like enum constants. Use {@link #of(short)} to parse raw <code>
12-
* int</code> values.
13-
*
14-
* @see #of(short)
16+
* @see #fromValue(int)
17+
* @see #fromName(String)
1518
* @see <a
16-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#matcher-protection-types">FIDO
19+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#matcher-protection-types">FIDO
1720
* Registry of Predefined Values §3.3 Matcher Protection Types</a>
1821
*/
19-
@EqualsAndHashCode
20-
public class MatcherProtectionType {
22+
@Getter
23+
public enum MatcherProtectionType {
2124

2225
/**
23-
* This flag must be set if the authenticator's matcher is running in software. Mutually exclusive
24-
* with {@link #MATCHER_PROTECTION_TEE}, {@link #MATCHER_PROTECTION_ON_CHIP}.
26+
* This flag MUST be set if the authenticator's matcher is running in software. Exclusive in
27+
* authenticator metadata with {@link #MATCHER_PROTECTION_TEE}, {@link
28+
* #MATCHER_PROTECTION_ON_CHIP}.
2529
*
2630
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
2731
*
2832
* @see <a
29-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#matcher-protection-types">FIDO
33+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#matcher-protection-types">FIDO
3034
* Registry of Predefined Values §3.3 Matcher Protection Types</a>
3135
*/
32-
public static final MatcherProtectionType MATCHER_PROTECTION_SOFTWARE =
33-
new MatcherProtectionType((short) 0x0001, "SOFTWARE");
36+
MATCHER_PROTECTION_SOFTWARE((short) 0x0001, "software"),
3437

3538
/**
36-
* This flag should be set if the authenticator's matcher is running inside the Trusted Execution
37-
* Environment. Mutually exclusive with {@link #MATCHER_PROTECTION_SOFTWARE}, {@link
38-
* #MATCHER_PROTECTION_ON_CHIP}.
39+
* This flag SHOULD be set if the authenticator's matcher is running inside the Trusted Execution
40+
* Environment [TEE]. Mutually exclusive in authenticator metadata with {@link
41+
* #MATCHER_PROTECTION_SOFTWARE}, {@link #MATCHER_PROTECTION_ON_CHIP}.
3942
*
4043
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
4144
*
4245
* @see <a
43-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#matcher-protection-types">FIDO
46+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#matcher-protection-types">FIDO
4447
* Registry of Predefined Values §3.3 Matcher Protection Types</a>
4548
*/
46-
public static final MatcherProtectionType MATCHER_PROTECTION_TEE =
47-
new MatcherProtectionType((short) 0x0002, "TEE");
49+
MATCHER_PROTECTION_TEE((short) 0x0002, "tee"),
4850

4951
/**
50-
* This flag should be set if the authenticator's matcher is running on the chip. Mutually
51-
* exclusive with {@link #MATCHER_PROTECTION_TEE}, {@link #MATCHER_PROTECTION_SOFTWARE}.
52+
* This flag SHOULD be set if the authenticator's matcher is running on the chip. Mutually
53+
* exclusive in authenticator metadata with {@link #MATCHER_PROTECTION_TEE}, {@link
54+
* #MATCHER_PROTECTION_SOFTWARE}
5255
*
5356
* <p>NOTE: The above requirements apply to authenticators; this library DOES NOT enforce them.
5457
*
5558
* @see <a
56-
* href="https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#matcher-protection-types">FIDO
59+
* href="https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html#matcher-protection-types">FIDO
5760
* Registry of Predefined Values §3.3 Matcher Protection Types</a>
5861
*/
59-
public static final MatcherProtectionType MATCHER_PROTECTION_ON_CHIP =
60-
new MatcherProtectionType((short) 0x0004, "ON_CHIP");
62+
MATCHER_PROTECTION_ON_CHIP((short) 0x0004, "on_chip");
6163

62-
@JsonValue public final short value;
64+
private final short value;
6365

64-
@EqualsAndHashCode.Exclude private final transient String name;
66+
@JsonValue private final String name;
6567

66-
private MatcherProtectionType(short value, String name) {
68+
MatcherProtectionType(short value, String name) {
6769
this.value = value;
6870
this.name = name;
6971
}
7072

7173
/**
72-
* @return An array containing all predefined values of {@link MatcherProtectionType} known by
73-
* this implementation.
74+
* @return If <code>value</code> matches any {@link MatcherProtectionType} constant, returns that
75+
* constant instance. Otherwise throws {@link IllegalArgumentException}.
7476
*/
75-
public static MatcherProtectionType[] values() {
76-
return new MatcherProtectionType[] {
77-
MATCHER_PROTECTION_SOFTWARE, MATCHER_PROTECTION_TEE, MATCHER_PROTECTION_ON_CHIP
78-
};
77+
public static MatcherProtectionType fromValue(int value) {
78+
return Stream.of(values())
79+
.filter(v -> v.value == value)
80+
.findAny()
81+
.orElseThrow(
82+
() ->
83+
new IllegalArgumentException(
84+
String.format("Unknown %s value: 0x%04x", MatcherProtectionType.class, value)));
7985
}
8086

8187
/**
82-
* @return If <code>value</code> is the same as that of any of the constants in {@link
83-
* MatcherProtectionType}, returns that constant instance. Otherwise returns a new instance
84-
* containing <code>value</code>.
88+
* @return If <code>name</code> matches any {@link MatcherProtectionType} constant, returns that
89+
* constant instance. Otherwise throws {@link IllegalArgumentException}.
8590
*/
8691
@JsonCreator
87-
public static MatcherProtectionType of(short value) {
92+
public static MatcherProtectionType fromName(String name) {
8893
return Stream.of(values())
89-
.filter(v -> v.value == value)
94+
.filter(v -> v.name.equals(name))
9095
.findAny()
91-
.orElseGet(() -> new MatcherProtectionType(value, null));
92-
}
93-
94-
@Override
95-
public String toString() {
96-
if (name == null) {
97-
return String.format("%s(%04x)", MatcherProtectionType.class.getSimpleName(), value);
98-
} else {
99-
return "MATCHER_PROTECTION_" + name;
100-
}
96+
.orElseThrow(
97+
() ->
98+
new IllegalArgumentException(
99+
String.format("Unknown %s name: %s", MatcherProtectionType.class, name)));
101100
}
102101
}

0 commit comments

Comments
 (0)