CertificateUtil.java

1
// Copyright (c) 2024, Yubico AB
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// 1. Redistributions of source code must retain the above copyright notice, this
8
//    list of conditions and the following disclaimer.
9
//
10
// 2. Redistributions in binary form must reproduce the above copyright notice,
11
//    this list of conditions and the following disclaimer in the documentation
12
//    and/or other materials provided with the distribution.
13
//
14
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25
package com.yubico.webauthn.attestation;
26
27
import com.yubico.internal.util.BinaryUtil;
28
import com.yubico.webauthn.RegistrationResult;
29
import com.yubico.webauthn.RelyingParty;
30
import com.yubico.webauthn.data.ByteArray;
31
import java.nio.ByteBuffer;
32
import java.security.cert.X509Certificate;
33
import java.util.Optional;
34
import lombok.experimental.UtilityClass;
35
36
@UtilityClass
37
public class CertificateUtil {
38
  public static final String ID_FIDO_GEN_CE_SERNUM = "1.3.6.1.4.1.45724.1.1.2";
39
40
  private static byte[] parseSerNum(byte[] bytes) {
41
    try {
42
      byte[] extensionValueContents = BinaryUtil.parseDerOctetString(bytes, 0).result;
43
      byte[] sernumContents = BinaryUtil.parseDerOctetString(extensionValueContents, 0).result;
44 1 1. parseSerNum : replaced return value with null for com/yubico/webauthn/attestation/CertificateUtil::parseSerNum → KILLED
      return sernumContents;
45
    } catch (Exception e) {
46
      throw new IllegalArgumentException(
47
          "X.509 extension 1.3.6.1.4.1.45724.1.1.2 (id-fido-gen-ce-sernum) is not valid.", e);
48
    }
49
  }
50
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
   */
82
  public static Optional<ByteArray> parseFidoSernumExtension(X509Certificate cert) {
83 1 1. parseFidoSernumExtension : replaced return value with Optional.empty for com/yubico/webauthn/attestation/CertificateUtil::parseFidoSernumExtension → KILLED
    return Optional.ofNullable(cert.getExtensionValue(ID_FIDO_GEN_CE_SERNUM))
84
        .map(CertificateUtil::parseSerNum)
85
        .map(ByteArray::new);
86
  }
87
}

Mutations

44

1.1
Location : parseSerNum
Killed by : com.yubico.webauthn.attestation.CertificateUtilSpec
replaced return value with null for com/yubico/webauthn/attestation/CertificateUtil::parseSerNum → KILLED

83

1.1
Location : parseFidoSernumExtension
Killed by : com.yubico.webauthn.attestation.CertificateUtilSpec
replaced return value with Optional.empty for com/yubico/webauthn/attestation/CertificateUtil::parseFidoSernumExtension → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0