diff --git a/common/src/main/java/pro/javacard/fido2/common/MakeCredentialCommand.java b/common/src/main/java/pro/javacard/fido2/common/MakeCredentialCommand.java index e5bf4ae..04b4a1c 100644 --- a/common/src/main/java/pro/javacard/fido2/common/MakeCredentialCommand.java +++ b/common/src/main/java/pro/javacard/fido2/common/MakeCredentialCommand.java @@ -30,6 +30,8 @@ public class MakeCredentialCommand { byte[] pinAuth; int pinProtocol = -1; + int enterpriseAttestation = -1; + public MakeCredentialCommand withClientDataHash(byte[] hash) { clientDataHash = hash.clone(); return this; @@ -86,6 +88,13 @@ public MakeCredentialCommand withOption(String option, boolean value) { return this; } + public MakeCredentialCommand withEnterpriseAttestation(int variant) { + if (!(variant == 1 || variant == 2)) + throw new IllegalArgumentException("enterpriseAttestation must be 1 or 2"); + enterpriseAttestation = variant; + return this; + } + // Build the CBOR structure public byte[] build() { if (clientDataHash == null || origin == null || userId == null || algorithms.size() == 0) @@ -106,6 +115,8 @@ public byte[] build() { numElements++; if (excludeList.size() > 0) numElements++; + if (enterpriseAttestation != -1) + numElements++; generator.writeStartObject(numElements); @@ -183,6 +194,10 @@ public byte[] build() { generator.writeFieldId(MakeCredentialCommandParameter.pinProtocol.value()); generator.writeNumber(pinProtocol); } + if (enterpriseAttestation != -1) { + generator.writeFieldId(MakeCredentialCommandParameter.enterpriseAttestation.value()); + generator.writeNumber(enterpriseAttestation); + } generator.writeEndObject(); generator.close(); diff --git a/tool/src/main/java/pro/javacard/fido2/cli/CommandLineInterface.java b/tool/src/main/java/pro/javacard/fido2/cli/CommandLineInterface.java index af52bc0..9472b5c 100644 --- a/tool/src/main/java/pro/javacard/fido2/cli/CommandLineInterface.java +++ b/tool/src/main/java/pro/javacard/fido2/cli/CommandLineInterface.java @@ -49,6 +49,7 @@ abstract class CommandLineInterface { protected static OptionSpec OPT_AUTHENTICATE = parser.acceptsAll(Arrays.asList("a", "authenticate"), "Get assertion / authenticate").withRequiredArg().describedAs("[user@]domain"); // Arguments for registration/authentication + protected static OptionSpec OPT_EA = parser.acceptsAll(Arrays.asList("ea"), "Enterprise Attestation (FIDO2)").withOptionalArg().ofType(Integer.class).defaultsTo(1); protected static OptionSpec OPT_RK = parser.acceptsAll(Arrays.asList("rk", "discoverable"), "Discoverable (FIDO2)"); protected static OptionSpec OPT_HMAC_SECRET = parser.acceptsAll(Arrays.asList("hmac-secret"), "Use hmac-secret (FIDO2)").withOptionalArg().describedAs("hex"); protected static OptionSpec OPT_PROTECT = parser.acceptsAll(Arrays.asList("protect"), "Use credProtect (FIDO2)").withRequiredArg().ofType(Integer.class); diff --git a/tool/src/main/java/pro/javacard/fido2/cli/FIDOTool.java b/tool/src/main/java/pro/javacard/fido2/cli/FIDOTool.java index 6aa0e75..2016575 100644 --- a/tool/src/main/java/pro/javacard/fido2/cli/FIDOTool.java +++ b/tool/src/main/java/pro/javacard/fido2/cli/FIDOTool.java @@ -374,6 +374,8 @@ else if (filtered.size() > 1) { makeCredentialCommand.withUserID(uid); } if (!useU2F(transport, options)) { + if (options.has(OPT_EA)) + makeCredentialCommand.withEnterpriseAttestation(options.valueOf(OPT_EA)); if (options.has(OPT_RK)) makeCredentialCommand.withOption("rk"); if (options.has(OPT_NO_UP))