COSEAlgorithmIdentifier.java

1
// Copyright (c) 2018, 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.data;
26
27
import com.fasterxml.jackson.annotation.JsonCreator;
28
import com.fasterxml.jackson.annotation.JsonValue;
29
import com.upokecenter.cbor.CBORException;
30
import com.upokecenter.cbor.CBORObject;
31
import java.util.Optional;
32
import java.util.stream.Stream;
33
import lombok.Getter;
34
import lombok.NonNull;
35
36
/**
37
 * A number identifying a cryptographic algorithm. The algorithm identifiers SHOULD be values
38
 * registered in the IANA COSE Algorithms registry, for instance, -7 for "ES256" and -257 for
39
 * "RS256".
40
 *
41
 * @see <a
42
 *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#typedefdef-cosealgorithmidentifier">§5.10.5.
43
 *     Cryptographic Algorithm Identifier (typedef COSEAlgorithmIdentifier)</a>
44
 */
45
public enum COSEAlgorithmIdentifier {
46
  EdDSA(-8),
47
  ES256(-7),
48
  ES384(-35),
49
  ES512(-36),
50
  RS256(-257),
51
  RS384(-258),
52
  RS512(-259),
53
  RS1(-65535);
54
55
  @JsonValue @Getter private final long id;
56
57
  COSEAlgorithmIdentifier(long id) {
58
    this.id = id;
59
  }
60
61
  /**
62
   * Attempt to parse an integer as a {@link COSEAlgorithmIdentifier}.
63
   *
64
   * @param id an integer equal to the {@link #getId() id} of a constant in {@link
65
   *     COSEAlgorithmIdentifier}
66
   * @return The {@link COSEAlgorithmIdentifier} instance whose {@link #getId() id} equals <code>id
67
   *     </code>, if any.
68
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">§5.8.5.
69
   *     Cryptographic Algorithm Identifier (typedef COSEAlgorithmIdentifier)</a>
70
   */
71
  public static Optional<COSEAlgorithmIdentifier> fromId(long id) {
72 3 1. lambda$fromId$0 : replaced boolean return with true for com/yubico/webauthn/data/COSEAlgorithmIdentifier::lambda$fromId$0 → KILLED
2. lambda$fromId$0 : negated conditional → KILLED
3. fromId : replaced return value with Optional.empty for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromId → KILLED
    return Stream.of(values()).filter(v -> v.id == id).findAny();
73
  }
74
75
  /**
76
   * Read the {@link COSEAlgorithmIdentifier} from a public key in COSE_Key format.
77
   *
78
   * @param publicKeyCose a public key in COSE_Key format.
79
   * @return The <code>alg</code> of the <code>publicKeyCose</code> parsed as a {@link
80
   *     COSEAlgorithmIdentifier}, if possible. Returns empty if the {@link COSEAlgorithmIdentifier}
81
   *     enum has no constant matching the <code>alg</code> value.
82
   * @throws IllegalArgumentException if <code>publicKeyCose</code> is not a well-formed COSE_Key.
83
   */
84 1 1. fromPublicKey : negated conditional → KILLED
  public static Optional<COSEAlgorithmIdentifier> fromPublicKey(@NonNull ByteArray publicKeyCose) {
85
    final CBORObject ALG = CBORObject.FromObject(3);
86
    final int alg;
87
    try {
88
      CBORObject cose = CBORObject.DecodeFromBytes(publicKeyCose.getBytes());
89 1 1. fromPublicKey : negated conditional → KILLED
      if (!cose.ContainsKey(ALG)) {
90
        throw new IllegalArgumentException(
91
            "Public key does not contain an \"alg\"(3) value: " + publicKeyCose);
92
      }
93
      CBORObject algCbor = cose.get(ALG);
94 2 1. fromPublicKey : negated conditional → KILLED
2. fromPublicKey : negated conditional → KILLED
      if (!(algCbor.isNumber() && algCbor.AsNumber().IsInteger())) {
95
        throw new IllegalArgumentException(
96
            "Public key has non-integer \"alg\"(3) value: " + publicKeyCose);
97
      }
98
      alg = algCbor.AsInt32();
99
    } catch (CBORException e) {
100
      throw new IllegalArgumentException("Failed to parse public key", e);
101
    }
102 1 1. fromPublicKey : replaced return value with Optional.empty for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromPublicKey → KILLED
    return fromId(alg);
103
  }
104
105
  @JsonCreator
106
  private static COSEAlgorithmIdentifier fromJson(long id) {
107 1 1. fromJson : replaced return value with null for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromJson → KILLED
    return fromId(id)
108
        .orElseThrow(
109 1 1. lambda$fromJson$1 : replaced return value with null for com/yubico/webauthn/data/COSEAlgorithmIdentifier::lambda$fromJson$1 → KILLED
            () -> new IllegalArgumentException("Unknown COSE algorithm identifier: " + id));
110
  }
111
}

Mutations

72

1.1
Location : lambda$fromId$0
Killed by : com.yubico.webauthn.data.EnumsSpec
replaced boolean return with true for com/yubico/webauthn/data/COSEAlgorithmIdentifier::lambda$fromId$0 → KILLED

2.2
Location : lambda$fromId$0
Killed by : com.yubico.webauthn.data.EnumsSpec
negated conditional → KILLED

3.3
Location : fromId
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromId → KILLED

84

1.1
Location : fromPublicKey
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

89

1.1
Location : fromPublicKey
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

94

1.1
Location : fromPublicKey
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

2.2
Location : fromPublicKey
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

102

1.1
Location : fromPublicKey
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with Optional.empty for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromPublicKey → KILLED

107

1.1
Location : fromJson
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with null for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromJson → KILLED

109

1.1
Location : lambda$fromJson$1
Killed by : com.yubico.webauthn.data.EnumsSpec
replaced return value with null for com/yubico/webauthn/data/COSEAlgorithmIdentifier::lambda$fromJson$1 → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0