Skip to content

Commit 4cb64e3

Browse files
committed
Add JavaDoc and README docs parseFidoSernumExtension
1 parent 482f4a2 commit 4cb64e3

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

webauthn-server-attestation/README.adoc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ An optional module which extends link:../[`webauthn-server-core`]
99
with a trust root source for verifying
1010
https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-attestation[attestation statements],
1111
by interfacing with the https://fidoalliance.org/metadata/[FIDO Metadata Service].
12+
The module also provides helper functions for inspecting properties of attestation certificates.
1213

1314

1415
*Table of contents*
@@ -17,7 +18,7 @@ toc::[]
1718

1819
== Features
1920

20-
This module does four things:
21+
The FIDO MDS integration does four things:
2122

2223
- Download, verify and cache metadata BLOBs from the FIDO Metadata Service.
2324
- Re-download the metadata BLOB when out of date or invalid.
@@ -414,3 +415,28 @@ link:https://developers.yubico.com/java-webauthn-server/JavaDoc/webauthn-server-
414415
class uses `CertPathValidator.getInstance("PKIX")` to retrieve a `CertPathValidator` instance.
415416
If you need to override any aspect of certificate path validation,
416417
such as CRL retrieval or OCSP, you may provide a custom `CertPathValidator` provider for the `"PKIX"` algorithm.
418+
419+
420+
== Using enterprise attestation
421+
422+
link:https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#dom-attestationconveyancepreference-enterprise[Enterprise attestation]
423+
is the idea of having attestation statements contain a unique identifier such as a device serial number.
424+
For example, this identifier could be used by an employer provisioning security keys for their employees.
425+
By recording which employee has which security key serial numbers,
426+
the employer can automatically trust the employee upon successful WebAuthn registration
427+
without having to first authenticate the employee by other means.
428+
429+
Because enterprise attestation by design introduces powerful user tracking,
430+
it is only allowed in certain contexts and is otherwise blocked by the client.
431+
See the
432+
link:https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html#sctn-feature-descriptions-enterp-attstn[CTAP2 section on Enterprise Attestation]
433+
for guidance on how to enable enterprise attestation -
434+
this typically involves a special agreement with an authenticator or client vendor.
435+
436+
At time of writing, there is only one standardized way to convey an enterprise attestation identifer:
437+
438+
- An X.509 certificate extension with OID `1.3.6.1.4.1.45724.1.1.2 (id-fido-gen-ce-sernum)`
439+
MAY indicate a unique octet string such as a serial number
440+
see
441+
https://w3c.github.io/webauthn/#sctn-enterprise-packed-attestation-cert-requirements[Web Authentication Level 3 §8.2.2. Certificate Requirements for Enterprise Packed Attestation Statements].
442+
The `CertificateUtil` class provides `parseFidoSernumExtension` helper function for parsing this extension if present.

webauthn-server-attestation/src/main/java/com/yubico/webauthn/attestation/CertificateUtil.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
package com.yubico.webauthn.attestation;
2626

2727
import com.yubico.internal.util.BinaryUtil;
28+
import com.yubico.webauthn.RegistrationResult;
29+
import com.yubico.webauthn.RelyingParty;
2830
import com.yubico.webauthn.data.ByteArray;
31+
import java.nio.ByteBuffer;
2932
import java.security.cert.X509Certificate;
3033
import java.util.Optional;
3134
import lombok.experimental.UtilityClass;
@@ -45,6 +48,37 @@ private static byte[] parseSerNum(byte[] bytes) {
4548
}
4649
}
4750

51+
/**
52+
* Attempt to parse the FIDO enterprise attestation serial number extension from the given
53+
* certificate.
54+
*
55+
* <p>NOTE: This function does NOT verify that the returned serial number is authentic and
56+
* trustworthy. See:
57+
*
58+
* <ul>
59+
* <li>{@link RelyingParty.RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource)}
60+
* <li>{@link RegistrationResult#isAttestationTrusted()}
61+
* <li>{@link RelyingParty.RelyingPartyBuilder#allowUntrustedAttestation(boolean)}
62+
* </ul>
63+
*
64+
* <p>Note that the serial number is an opaque byte array with no defined structure in general.
65+
* For example, the byte array may or may not represent a big-endian integer depending on the
66+
* authenticator vendor.
67+
*
68+
* <p>The extension has OID <code>1.3.6.1.4.1.45724.1.1.2 (id-fido-gen-ce-sernum)</code>.
69+
*
70+
* @param cert the attestation certificate to parse the serial number from.
71+
* @return The serial number, if present and validly encoded. Empty if the extension is not
72+
* present in the certificate.
73+
* @throws IllegalArgumentException if the extension is present but not validly encoded.
74+
* @see RelyingParty.RelyingPartyBuilder#attestationTrustSource(AttestationTrustSource)
75+
* @see RegistrationResult#isAttestationTrusted()
76+
* @see RelyingParty.RelyingPartyBuilder#allowUntrustedAttestation(boolean)
77+
* @see <a
78+
* href="https://w3c.github.io/webauthn/#sctn-enterprise-packed-attestation-cert-requirements">WebAuthn
79+
* Level 3 §8.2.2. Certificate Requirements for Enterprise Packed Attestation Statements</a>
80+
* @see ByteBuffer#getLong()
81+
*/
4882
public static Optional<ByteArray> parseFidoSernumExtension(X509Certificate cert) {
4983
return Optional.ofNullable(cert.getExtensionValue(ID_FIDO_GEN_CE_SERNUM))
5084
.map(CertificateUtil::parseSerNum)

0 commit comments

Comments
 (0)