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
 * @since 0.3.0
42
 * @see <a
43
 *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#typedefdef-cosealgorithmidentifier">§5.10.5.
44
 *     Cryptographic Algorithm Identifier (typedef COSEAlgorithmIdentifier)</a>
45
 */
46
public enum COSEAlgorithmIdentifier {
47
48
  /**
49
   * The signature scheme Ed25519 as defined in <a href="https://www.rfc-editor.org/rfc/rfc8032">RFC
50
   * 8032</a>.
51
   *
52
   * <p>Note: This COSE identifier does not in general identify the full Ed25519 parameter suite,
53
   * but is specialized to that meaning within the WebAuthn API.
54
   *
55
   * @since 1.4.0
56
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
57
   *     registry</a>
58
   * @see <a href="https://www.rfc-editor.org/rfc/rfc8032">RFC 8032</a>
59
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
60
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
61
   *     )</a>
62
   */
63
  EdDSA(-8),
64
65
  /**
66
   * The signature scheme Ed25519 as defined in <a href="https://www.rfc-editor.org/rfc/rfc8032">RFC
67
   * 8032</a>.
68
   *
69
   * <p>This value is NOT RECOMMENDED, see the <a
70
   * href="https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-pubkeycredparams">documentation
71
   * of <code>pubKeyCredParams</code></a>. Use {@link #EdDSA} instead or in addition.
72
   *
73
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
74
   *     registry</a>
75
   * @see <a
76
   *     href="https://www.ietf.org/archive/id/draft-ietf-jose-fully-specified-algorithms-13.html#name-edwards-curve-digital-signa">Fully-Specified
77
   *     Algorithms for JOSE and COSE</a>
78
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
79
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
80
   *     )</a>
81
   */
82
  Ed25519(-19),
83
84
  /**
85
   * The signature scheme Ed448 as defined in <a href="https://www.rfc-editor.org/rfc/rfc8032">RFC
86
   * 8032</a>.
87
   *
88
   * @since 2.8.0
89
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
90
   *     registry</a>
91
   * @see <a
92
   *     href="https://www.ietf.org/archive/id/draft-ietf-jose-fully-specified-algorithms-13.html#name-edwards-curve-digital-signa">Fully-Specified
93
   *     Algorithms for JOSE and COSE</a>
94
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
95
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
96
   *     )</a>
97
   */
98
  Ed448(-53),
99
100
  /**
101
   * ECDSA with SHA-256 on the NIST P-256 curve.
102
   *
103
   * <p>Note: This COSE identifier does not in general restrict the curve to P-256, but is
104
   * specialized to that meaning within the WebAuthn API.
105
   *
106
   * @since 0.3.0
107
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
108
   *     registry</a>
109
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
110
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
111
   *     )</a>
112
   */
113
  ES256(-7),
114
115
  /**
116
   * ECDSA with SHA-384 on the NIST P-384 curve.
117
   *
118
   * <p>Note: This COSE identifier does not in general restrict the curve to P-384, but is
119
   * specialized to that meaning within the WebAuthn API.
120
   *
121
   * @since 2.1.0
122
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
123
   *     registry</a>
124
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
125
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
126
   *     )</a>
127
   */
128
  ES384(-35),
129
130
  /**
131
   * ECDSA with SHA-512 on the NIST P-521 curve.
132
   *
133
   * <p>Note: This COSE identifier does not in general restrict the curve to P-521, but is
134
   * specialized to that meaning within the WebAuthn API.
135
   *
136
   * @since 2.1.0
137
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
138
   *     registry</a>
139
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">WebAuthn
140
   *     §5.8.5. Cryptographic Algorithm Identifier (typedef <code>COSEAlgorithmIdentifier</code>
141
   *     )</a>
142
   */
143
  ES512(-36),
144
145
  /**
146
   * RSASSA-PKCS1-v1_5 using SHA-256.
147
   *
148
   * @since 0.3.0
149
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
150
   *     registry</a>
151
   */
152
  RS256(-257),
153
154
  /**
155
   * RSASSA-PKCS1-v1_5 using SHA-384.
156
   *
157
   * @since 2.4.0
158
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
159
   *     registry</a>
160
   */
161
  RS384(-258),
162
163
  /**
164
   * RSASSA-PKCS1-v1_5 using SHA-512.
165
   *
166
   * @since 2.4.0
167
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
168
   *     registry</a>
169
   */
170
  RS512(-259),
171
172
  /**
173
   * RSASSA-PKCS1-v1_5 using SHA-1.
174
   *
175
   * @since 1.5.0
176
   * @see <a href="https://www.iana.org/assignments/cose/cose.xhtml#algorithms">COSE Algorithms
177
   *     registry</a>
178
   */
179
  RS1(-65535);
180
181
  @JsonValue @Getter private final long id;
182
183
  COSEAlgorithmIdentifier(long id) {
184
    this.id = id;
185
  }
186
187
  /**
188
   * Attempt to parse an integer as a {@link COSEAlgorithmIdentifier}.
189
   *
190
   * @param id an integer equal to the {@link #getId() id} of a constant in {@link
191
   *     COSEAlgorithmIdentifier}
192
   * @return The {@link COSEAlgorithmIdentifier} instance whose {@link #getId() id} equals <code>id
193
   *     </code>, if any.
194
   * @since 0.3.0
195
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#sctn-alg-identifier">§5.8.5.
196
   *     Cryptographic Algorithm Identifier (typedef COSEAlgorithmIdentifier)</a>
197
   */
198
  public static Optional<COSEAlgorithmIdentifier> fromId(long id) {
199 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();
200
  }
201
202
  /**
203
   * Read the {@link COSEAlgorithmIdentifier} from a public key in COSE_Key format.
204
   *
205
   * @param publicKeyCose a public key in COSE_Key format.
206
   * @return The <code>alg</code> of the <code>publicKeyCose</code> parsed as a {@link
207
   *     COSEAlgorithmIdentifier}, if possible. Returns empty if the {@link COSEAlgorithmIdentifier}
208
   *     enum has no constant matching the <code>alg</code> value.
209
   * @throws IllegalArgumentException if <code>publicKeyCose</code> is not a well-formed COSE_Key.
210
   * @since 2.1.0
211
   */
212 1 1. fromPublicKey : negated conditional → KILLED
  public static Optional<COSEAlgorithmIdentifier> fromPublicKey(@NonNull ByteArray publicKeyCose) {
213
    final CBORObject ALG = CBORObject.FromObject(3);
214
    final int alg;
215
    try {
216
      CBORObject cose = CBORObject.DecodeFromBytes(publicKeyCose.getBytes());
217 1 1. fromPublicKey : negated conditional → KILLED
      if (!cose.ContainsKey(ALG)) {
218
        throw new IllegalArgumentException(
219
            "Public key does not contain an \"alg\"(3) value: " + publicKeyCose);
220
      }
221
      CBORObject algCbor = cose.get(ALG);
222 2 1. fromPublicKey : negated conditional → KILLED
2. fromPublicKey : negated conditional → KILLED
      if (!(algCbor.isNumber() && algCbor.AsNumber().IsInteger())) {
223
        throw new IllegalArgumentException(
224
            "Public key has non-integer \"alg\"(3) value: " + publicKeyCose);
225
      }
226
      alg = algCbor.AsInt32();
227
    } catch (CBORException e) {
228
      throw new IllegalArgumentException("Failed to parse public key", e);
229
    }
230 1 1. fromPublicKey : replaced return value with Optional.empty for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromPublicKey → KILLED
    return fromId(alg);
231
  }
232
233
  @JsonCreator
234
  private static COSEAlgorithmIdentifier fromJson(long id) {
235 1 1. fromJson : replaced return value with null for com/yubico/webauthn/data/COSEAlgorithmIdentifier::fromJson → KILLED
    return fromId(id)
236
        .orElseThrow(
237 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));
238
  }
239
}

Mutations

199

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

212

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

217

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

222

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

230

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

235

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

237

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