WebAuthnCodecs.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;
26
27
import com.google.common.primitives.Bytes;
28
import com.upokecenter.cbor.CBORObject;
29
import com.yubico.webauthn.data.ByteArray;
30
import com.yubico.webauthn.data.COSEAlgorithmIdentifier;
31
import java.io.IOException;
32
import java.math.BigInteger;
33
import java.security.KeyFactory;
34
import java.security.NoSuchAlgorithmException;
35
import java.security.PublicKey;
36
import java.security.interfaces.ECPublicKey;
37
import java.security.spec.InvalidKeySpecException;
38
import java.security.spec.RSAPublicKeySpec;
39
import java.security.spec.X509EncodedKeySpec;
40
import java.util.Arrays;
41
import java.util.HashMap;
42
import java.util.Map;
43
import java.util.stream.Stream;
44
45
final class WebAuthnCodecs {
46
47
  private static final ByteArray EC_PUBLIC_KEY_OID =
48
      new ByteArray(
49
          new byte[] {
50
            0x2A, (byte) 0x86, 0x48, (byte) 0xCE, 0x3D, 2, 1
51
          }); // OID 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
52
  private static final ByteArray P256_CURVE_OID =
53
      new ByteArray(
54
          new byte[] {
55
            0x2A, (byte) 0x86, 0x48, (byte) 0xCE, 0x3D, 3, 1, 7 // OID 1.2.840.10045.3.1.7
56
          });
57
  private static final ByteArray P384_CURVE_OID =
58
      new ByteArray(new byte[] {0x2B, (byte) 0x81, 0x04, 0, 34}); // OID 1.3.132.0.34
59
  private static final ByteArray P512_CURVE_OID =
60
      new ByteArray(new byte[] {0x2B, (byte) 0x81, 0x04, 0, 35}); // OID 1.3.132.0.35
61
62
  private static final ByteArray ED25519_ALG_ID =
63
      new ByteArray(
64
          new byte[] {
65
            // SEQUENCE (5 bytes)
66
            0x30,
67
            5,
68
            // OID (3 bytes)
69
            0x06,
70
            3,
71
            // OID 1.3.101.112
72
            0x2B,
73
            101,
74
            112
75
          });
76
77
  static ByteArray ecPublicKeyToRaw(ECPublicKey key) {
78
79
    final int fieldSizeBytes =
80
        Math.toIntExact(
81 1 1. ecPublicKeyToRaw : Replaced double division with multiplication → KILLED
            Math.round(Math.ceil(key.getParams().getCurve().getField().getFieldSize() / 8.0)));
82
    byte[] x = key.getW().getAffineX().toByteArray();
83
    byte[] y = key.getW().getAffineY().toByteArray();
84 1 1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED
    byte[] xPadding = new byte[Math.max(0, fieldSizeBytes - x.length)];
85 1 1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED
    byte[] yPadding = new byte[Math.max(0, fieldSizeBytes - y.length)];
86
87 1 1. ecPublicKeyToRaw : removed call to java/util/Arrays::fill → SURVIVED
    Arrays.fill(xPadding, (byte) 0);
88 1 1. ecPublicKeyToRaw : removed call to java/util/Arrays::fill → SURVIVED
    Arrays.fill(yPadding, (byte) 0);
89
90 2 1. ecPublicKeyToRaw : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::ecPublicKeyToRaw → KILLED
2. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED
    return new ByteArray(
91
        Bytes.concat(
92
            new byte[] {0x04},
93
            xPadding,
94 1 1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED
            Arrays.copyOfRange(x, Math.max(0, x.length - fieldSizeBytes), x.length),
95
            yPadding,
96
            Arrays.copyOfRange(y, Math.max(0, y.length - fieldSizeBytes), y.length)));
97
  }
98
99
  static ByteArray rawEcKeyToCose(ByteArray key) {
100
    final byte[] keyBytes = key.getBytes();
101
    final int len = keyBytes.length;
102 1 1. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED
    final int lenSub1 = keyBytes.length - 1;
103 7 1. rawEcKeyToCose : negated conditional → SURVIVED
2. rawEcKeyToCose : negated conditional → SURVIVED
3. rawEcKeyToCose : negated conditional → NO_COVERAGE
4. rawEcKeyToCose : negated conditional → SURVIVED
5. rawEcKeyToCose : negated conditional → KILLED
6. rawEcKeyToCose : negated conditional → KILLED
7. rawEcKeyToCose : negated conditional → KILLED
    if (!(len == 64
104
        || len == 96
105
        || len == 132
106
        || (keyBytes[0] == 0x04 && (lenSub1 == 64 || lenSub1 == 96 || lenSub1 == 132)))) {
107
      throw new IllegalArgumentException(
108
          String.format(
109
              "Raw key must be 64, 96 or 132 bytes long, or start with 0x04 and be 65, 97 or 133 bytes long; was %d bytes starting with %02x",
110
              keyBytes.length, keyBytes[0]));
111
    }
112 3 1. rawEcKeyToCose : negated conditional → KILLED
2. rawEcKeyToCose : negated conditional → KILLED
3. rawEcKeyToCose : negated conditional → KILLED
    final int start = (len == 64 || len == 96 || len == 132) ? 0 : 1;
113 2 1. rawEcKeyToCose : Replaced integer division with multiplication → KILLED
2. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED
    final int coordinateLength = (len - start) / 2;
114
115
    final Map<Long, Object> coseKey = new HashMap<>();
116
    coseKey.put(1L, 2L); // Key type: EC
117
118
    final COSEAlgorithmIdentifier coseAlg;
119
    final int coseCrv;
120 1 1. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED
    switch (len - start) {
121
      case 64:
122
        coseAlg = COSEAlgorithmIdentifier.ES256;
123
        coseCrv = 1;
124
        break;
125
      case 96:
126
        coseAlg = COSEAlgorithmIdentifier.ES384;
127
        coseCrv = 2;
128
        break;
129
      case 132:
130
        coseAlg = COSEAlgorithmIdentifier.ES512;
131
        coseCrv = 3;
132
        break;
133
      default:
134
        throw new RuntimeException(
135
            "Failed to determine COSE EC algorithm. This should not be possible, please file a bug report.");
136
    }
137
    coseKey.put(3L, coseAlg.getId());
138
    coseKey.put(-1L, coseCrv);
139
140 1 1. rawEcKeyToCose : Replaced integer addition with subtraction → KILLED
    coseKey.put(-2L, Arrays.copyOfRange(keyBytes, start, start + coordinateLength)); // x
141
    coseKey.put(
142 3 1. rawEcKeyToCose : Replaced integer addition with subtraction → KILLED
2. rawEcKeyToCose : Replaced integer addition with subtraction → KILLED
3. rawEcKeyToCose : Replaced integer multiplication with division → KILLED
        -3L,
143
        Arrays.copyOfRange(keyBytes, start + coordinateLength, start + 2 * coordinateLength)); // y
144
145 1 1. rawEcKeyToCose : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::rawEcKeyToCose → KILLED
    return new ByteArray(CBORObject.FromObject(coseKey).EncodeToBytes());
146
  }
147
148
  static PublicKey importCosePublicKey(ByteArray key)
149
      throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
150
    CBORObject cose = CBORObject.DecodeFromBytes(key.getBytes());
151
    final int kty = cose.get(CBORObject.FromObject(1)).AsInt32();
152
    switch (kty) {
153
      case 1:
154 1 1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED
        return importCoseEdDsaPublicKey(cose);
155
      case 2:
156 1 1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED
        return importCoseEcdsaPublicKey(cose);
157
      case 3:
158 1 1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED
        return importCoseRsaPublicKey(cose);
159
      default:
160
        throw new IllegalArgumentException("Unsupported key type: " + kty);
161
    }
162
  }
163
164
  private static PublicKey importCoseRsaPublicKey(CBORObject cose)
165
      throws NoSuchAlgorithmException, InvalidKeySpecException {
166
    RSAPublicKeySpec spec =
167
        new RSAPublicKeySpec(
168
            new BigInteger(1, cose.get(CBORObject.FromObject(-1)).GetByteString()),
169
            new BigInteger(1, cose.get(CBORObject.FromObject(-2)).GetByteString()));
170 1 1. importCoseRsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseRsaPublicKey → KILLED
    return KeyFactory.getInstance("RSA").generatePublic(spec);
171
  }
172
173
  private static PublicKey importCoseEcdsaPublicKey(CBORObject cose)
174
      throws NoSuchAlgorithmException, InvalidKeySpecException {
175
    final int crv = cose.get(CBORObject.FromObject(-1)).AsInt32Value();
176
    final ByteArray x = new ByteArray(cose.get(CBORObject.FromObject(-2)).GetByteString());
177
    final ByteArray y = new ByteArray(cose.get(CBORObject.FromObject(-3)).GetByteString());
178
179
    final ByteArray curveOid;
180
    switch (crv) {
181
      case 1:
182
        curveOid = P256_CURVE_OID;
183
        break;
184
185
      case 2:
186
        curveOid = P384_CURVE_OID;
187
        break;
188
189
      case 3:
190
        curveOid = P512_CURVE_OID;
191
        break;
192
193
      default:
194
        throw new IllegalArgumentException("Unknown COSE EC2 curve: " + crv);
195
    }
196
197
    final ByteArray algId =
198
        encodeDerSequence(encodeDerObjectId(EC_PUBLIC_KEY_OID), encodeDerObjectId(curveOid));
199
200
    final ByteArray rawKey =
201
        encodeDerBitStringWithZeroUnused(
202
            new ByteArray(new byte[] {0x04}) // Raw EC public key with x and y
203
                .concat(x)
204
                .concat(y));
205
206
    final ByteArray x509Key = encodeDerSequence(algId, rawKey);
207
208
    KeyFactory kFact = KeyFactory.getInstance("EC");
209 1 1. importCoseEcdsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEcdsaPublicKey → KILLED
    return kFact.generatePublic(new X509EncodedKeySpec(x509Key.getBytes()));
210
  }
211
212
  private static ByteArray encodeDerLength(final int length) {
213 2 1. encodeDerLength : changed conditional boundary → SURVIVED
2. encodeDerLength : negated conditional → KILLED
    if (length <= 127) {
214 1 1. encodeDerLength : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → KILLED
      return new ByteArray(new byte[] {(byte) length});
215 2 1. encodeDerLength : changed conditional boundary → SURVIVED
2. encodeDerLength : negated conditional → KILLED
    } else if (length <= 0xffff) {
216 2 1. encodeDerLength : negated conditional → SURVIVED
2. encodeDerLength : changed conditional boundary → SURVIVED
      if (length <= 255) {
217 1 1. encodeDerLength : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → KILLED
        return new ByteArray(new byte[] {-127, (byte) length});
218
      } else {
219 3 1. encodeDerLength : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → NO_COVERAGE
2. encodeDerLength : Replaced Shift Right with Shift Left → NO_COVERAGE
3. encodeDerLength : Replaced bitwise AND with OR → NO_COVERAGE
        return new ByteArray(new byte[] {-126, (byte) (length >> 8), (byte) (length & 0x00ff)});
220
      }
221
    } else {
222
      throw new UnsupportedOperationException("Too long: " + length);
223
    }
224
  }
225
226
  private static ByteArray encodeDerObjectId(final ByteArray oid) {
227 1 1. encodeDerObjectId : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerObjectId → KILLED
    return new ByteArray(new byte[] {0x06, (byte) oid.size()}).concat(oid);
228
  }
229
230
  private static ByteArray encodeDerBitStringWithZeroUnused(final ByteArray content) {
231 1 1. encodeDerBitStringWithZeroUnused : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerBitStringWithZeroUnused → KILLED
    return new ByteArray(new byte[] {0x03})
232 1 1. encodeDerBitStringWithZeroUnused : Replaced integer addition with subtraction → KILLED
        .concat(encodeDerLength(1 + content.size()))
233
        .concat(new ByteArray(new byte[] {0}))
234
        .concat(content);
235
  }
236
237
  private static ByteArray encodeDerSequence(final ByteArray... items) {
238
    final ByteArray content =
239 1 1. lambda$encodeDerSequence$0 : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::lambda$encodeDerSequence$0 → NO_COVERAGE
        Stream.of(items).reduce(ByteArray::concat).orElseGet(() -> new ByteArray(new byte[0]));
240 1 1. encodeDerSequence : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerSequence → KILLED
    return new ByteArray(new byte[] {0x30}).concat(encodeDerLength(content.size())).concat(content);
241
  }
242
243
  private static PublicKey importCoseEdDsaPublicKey(CBORObject cose)
244
      throws InvalidKeySpecException, NoSuchAlgorithmException {
245
    final int curveId = cose.get(CBORObject.FromObject(-1)).AsInt32();
246
    switch (curveId) {
247
      case 6:
248 1 1. importCoseEdDsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEdDsaPublicKey → KILLED
        return importCoseEd25519PublicKey(cose);
249
      default:
250
        throw new IllegalArgumentException("Unsupported EdDSA curve: " + curveId);
251
    }
252
  }
253
254
  private static PublicKey importCoseEd25519PublicKey(CBORObject cose)
255
      throws InvalidKeySpecException, NoSuchAlgorithmException {
256
    final ByteArray rawKey = new ByteArray(cose.get(CBORObject.FromObject(-2)).GetByteString());
257
    final ByteArray x509Key =
258
        encodeDerSequence(ED25519_ALG_ID, encodeDerBitStringWithZeroUnused(rawKey));
259
260
    KeyFactory kFact = KeyFactory.getInstance("EdDSA");
261 1 1. importCoseEd25519PublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEd25519PublicKey → KILLED
    return kFact.generatePublic(new X509EncodedKeySpec(x509Key.getBytes()));
262
  }
263
264
  static String getJavaAlgorithmName(COSEAlgorithmIdentifier alg) {
265
    switch (alg) {
266
      case EdDSA:
267 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "EDDSA";
268
      case ES256:
269 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA256withECDSA";
270
      case ES384:
271 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA384withECDSA";
272
      case ES512:
273 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA512withECDSA";
274
      case RS256:
275 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA256withRSA";
276
      case RS384:
277 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA384withRSA";
278
      case RS512:
279 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA512withRSA";
280
      case RS1:
281 1 1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED
        return "SHA1withRSA";
282
      default:
283
        throw new IllegalArgumentException("Unknown algorithm: " + alg);
284
    }
285
  }
286
287
  static String jwsAlgorithmNameToJavaAlgorithmName(String alg) {
288 1 1. jwsAlgorithmNameToJavaAlgorithmName : negated conditional → KILLED
    switch (alg) {
289
      case "RS256":
290 1 1. jwsAlgorithmNameToJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::jwsAlgorithmNameToJavaAlgorithmName → KILLED
        return "SHA256withRSA";
291
    }
292
    throw new IllegalArgumentException("Unknown algorithm: " + alg);
293
  }
294
}

Mutations

81

1.1
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced double division with multiplication → KILLED

84

1.1
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

85

1.1
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

87

1.1
Location : ecPublicKeyToRaw
Killed by : none
removed call to java/util/Arrays::fill → SURVIVED

88

1.1
Location : ecPublicKeyToRaw
Killed by : none
removed call to java/util/Arrays::fill → SURVIVED

90

1.1
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::ecPublicKeyToRaw → KILLED

2.2
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

94

1.1
Location : ecPublicKeyToRaw
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

102

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

103

1.1
Location : rawEcKeyToCose
Killed by : none
negated conditional → SURVIVED

2.2
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

3.3
Location : rawEcKeyToCose
Killed by : none
negated conditional → SURVIVED

4.4
Location : rawEcKeyToCose
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

6.6
Location : rawEcKeyToCose
Killed by : none
negated conditional → SURVIVED

7.7
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

112

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

2.2
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

3.3
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
negated conditional → KILLED

113

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer division with multiplication → KILLED

2.2
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
Replaced integer subtraction with addition → KILLED

120

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer subtraction with addition → KILLED

140

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer addition with subtraction → KILLED

142

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer addition with subtraction → KILLED

2.2
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer addition with subtraction → KILLED

3.3
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer multiplication with division → KILLED

145

1.1
Location : rawEcKeyToCose
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::rawEcKeyToCose → KILLED

154

1.1
Location : importCosePublicKey
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED

156

1.1
Location : importCosePublicKey
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED

158

1.1
Location : importCosePublicKey
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED

170

1.1
Location : importCoseRsaPublicKey
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseRsaPublicKey → KILLED

209

1.1
Location : importCoseEcdsaPublicKey
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEcdsaPublicKey → KILLED

213

1.1
Location : encodeDerLength
Killed by : none
changed conditional boundary → SURVIVED

2.2
Location : encodeDerLength
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

214

1.1
Location : encodeDerLength
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → KILLED

215

1.1
Location : encodeDerLength
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

2.2
Location : encodeDerLength
Killed by : none
changed conditional boundary → SURVIVED

216

1.1
Location : encodeDerLength
Killed by : none
negated conditional → SURVIVED

2.2
Location : encodeDerLength
Killed by : none
changed conditional boundary → SURVIVED

217

1.1
Location : encodeDerLength
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → KILLED

219

1.1
Location : encodeDerLength
Killed by : none
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerLength → NO_COVERAGE

2.2
Location : encodeDerLength
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

3.3
Location : encodeDerLength
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

227

1.1
Location : encodeDerObjectId
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerObjectId → KILLED

231

1.1
Location : encodeDerBitStringWithZeroUnused
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerBitStringWithZeroUnused → KILLED

232

1.1
Location : encodeDerBitStringWithZeroUnused
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
Replaced integer addition with subtraction → KILLED

239

1.1
Location : lambda$encodeDerSequence$0
Killed by : none
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::lambda$encodeDerSequence$0 → NO_COVERAGE

240

1.1
Location : encodeDerSequence
Killed by : com.yubico.webauthn.data.AuthenticatorDataSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::encodeDerSequence → KILLED

248

1.1
Location : importCoseEdDsaPublicKey
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEdDsaPublicKey → KILLED

261

1.1
Location : importCoseEd25519PublicKey
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEd25519PublicKey → KILLED

267

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

269

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

271

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

273

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

275

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyTest.doesNotLogWarningIfAllAlgorithmsAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

277

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyTest.defaultSettingsLogWarningIfSomeAlgorithmNotAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

279

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyTest.defaultSettingsLogWarningIfSomeAlgorithmNotAvailable(com.yubico.webauthn.RelyingPartyTest)
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

281

1.1
Location : getJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED

288

1.1
Location : jwsAlgorithmNameToJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
negated conditional → KILLED

290

1.1
Location : jwsAlgorithmNameToJavaAlgorithmName
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::jwsAlgorithmNameToJavaAlgorithmName → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0