| 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.internal.util.BinaryUtil; | |
| 30 | import com.yubico.webauthn.data.ByteArray; | |
| 31 | import com.yubico.webauthn.data.COSEAlgorithmIdentifier; | |
| 32 | import java.io.IOException; | |
| 33 | import java.math.BigInteger; | |
| 34 | import java.security.KeyFactory; | |
| 35 | import java.security.NoSuchAlgorithmException; | |
| 36 | import java.security.PublicKey; | |
| 37 | import java.security.interfaces.ECPublicKey; | |
| 38 | import java.security.spec.InvalidKeySpecException; | |
| 39 | import java.security.spec.RSAPublicKeySpec; | |
| 40 | import java.security.spec.X509EncodedKeySpec; | |
| 41 | import java.util.Arrays; | |
| 42 | import java.util.HashMap; | |
| 43 | import java.util.Map; | |
| 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 P521_CURVE_OID = | |
| 60 | new ByteArray(new byte[] {0x2B, (byte) 0x81, 0x04, 0, 35}); // OID 1.3.132.0.35 | |
| 61 | ||
| 62 | 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 final ByteArray ED448_ALG_ID = | |
| 78 | new ByteArray( | |
| 79 | new byte[] { | |
| 80 | // SEQUENCE (5 bytes) | |
| 81 | 0x30, | |
| 82 | 5, | |
| 83 | // OID (3 bytes) | |
| 84 | 0x06, | |
| 85 | 3, | |
| 86 | // OID 1.3.101.113 | |
| 87 | 0x2B, | |
| 88 | 101, | |
| 89 | 113 | |
| 90 | }); | |
| 91 | ||
| 92 | static final ByteArray ML_DSA_44_ALG_ID = | |
| 93 | new ByteArray( | |
| 94 | new byte[] { | |
| 95 | // SEQUENCE (11 bytes) | |
| 96 | 0x30, | |
| 97 | 0x0B, | |
| 98 | // OID (9 bytes) | |
| 99 | 0x06, | |
| 100 | 0x09, | |
| 101 | // OID 2.16.840.1.101.3.4.3.17 | |
| 102 | 0x60, | |
| 103 | (byte) 0x86, | |
| 104 | 0x48, | |
| 105 | 0x01, | |
| 106 | 0x65, | |
| 107 | 0x03, | |
| 108 | 0x04, | |
| 109 | 0x03, | |
| 110 | 0x11 | |
| 111 | }); | |
| 112 | ||
| 113 | static final ByteArray ML_DSA_65_ALG_ID = | |
| 114 | new ByteArray( | |
| 115 | new byte[] { | |
| 116 | // SEQUENCE (11 bytes) | |
| 117 | 0x30, | |
| 118 | 0x0B, | |
| 119 | // OID (9 bytes) | |
| 120 | 0x06, | |
| 121 | 0x09, | |
| 122 | // OID 2.16.840.1.101.3.4.3.18 | |
| 123 | 0x60, | |
| 124 | (byte) 0x86, | |
| 125 | 0x48, | |
| 126 | 0x01, | |
| 127 | 0x65, | |
| 128 | 0x03, | |
| 129 | 0x04, | |
| 130 | 0x03, | |
| 131 | 0x12 | |
| 132 | }); | |
| 133 | ||
| 134 | static final ByteArray ML_DSA_87_ALG_ID = | |
| 135 | new ByteArray( | |
| 136 | new byte[] { | |
| 137 | // SEQUENCE (11 bytes) | |
| 138 | 0x30, | |
| 139 | 0x0B, | |
| 140 | // OID (9 bytes) | |
| 141 | 0x06, | |
| 142 | 0x09, | |
| 143 | // OID 2.16.840.1.101.3.4.3.19 | |
| 144 | 0x60, | |
| 145 | (byte) 0x86, | |
| 146 | 0x48, | |
| 147 | 0x01, | |
| 148 | 0x65, | |
| 149 | 0x03, | |
| 150 | 0x04, | |
| 151 | 0x03, | |
| 152 | 0x13 | |
| 153 | }); | |
| 154 | ||
| 155 | // See: https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves | |
| 156 | static final int COSE_CRV_P256 = 1; | |
| 157 | static final int COSE_CRV_P384 = 2; | |
| 158 | static final int COSE_CRV_P521 = 3; | |
| 159 | static final int COSE_CRV_ED25519 = 6; | |
| 160 | static final int COSE_CRV_ED448 = 7; | |
| 161 | ||
| 162 | static ByteArray ecPublicKeyToRaw(ECPublicKey key) { | |
| 163 | ||
| 164 | final int fieldSizeBytes = | |
| 165 | Math.toIntExact( | |
| 166 |
1
1. ecPublicKeyToRaw : Replaced double division with multiplication → KILLED |
Math.round(Math.ceil(key.getParams().getCurve().getField().getFieldSize() / 8.0))); |
| 167 | byte[] x = key.getW().getAffineX().toByteArray(); | |
| 168 | byte[] y = key.getW().getAffineY().toByteArray(); | |
| 169 |
1
1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED |
byte[] xPadding = new byte[Math.max(0, fieldSizeBytes - x.length)]; |
| 170 |
1
1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED |
byte[] yPadding = new byte[Math.max(0, fieldSizeBytes - y.length)]; |
| 171 | ||
| 172 |
1
1. ecPublicKeyToRaw : removed call to java/util/Arrays::fill → SURVIVED |
Arrays.fill(xPadding, (byte) 0); |
| 173 |
1
1. ecPublicKeyToRaw : removed call to java/util/Arrays::fill → SURVIVED |
Arrays.fill(yPadding, (byte) 0); |
| 174 | ||
| 175 |
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( |
| 176 | Bytes.concat( | |
| 177 | new byte[] {0x04}, | |
| 178 | xPadding, | |
| 179 |
1
1. ecPublicKeyToRaw : Replaced integer subtraction with addition → KILLED |
Arrays.copyOfRange(x, Math.max(0, x.length - fieldSizeBytes), x.length), |
| 180 | yPadding, | |
| 181 | Arrays.copyOfRange(y, Math.max(0, y.length - fieldSizeBytes), y.length))); | |
| 182 | } | |
| 183 | ||
| 184 | static ByteArray rawEcKeyToCose(ByteArray key) { | |
| 185 | final byte[] keyBytes = key.getBytes(); | |
| 186 | final int len = keyBytes.length; | |
| 187 |
1
1. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED |
final int lenSub1 = keyBytes.length - 1; |
| 188 |
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 |
| 189 | || len == 96 | |
| 190 | || len == 132 | |
| 191 | || (keyBytes[0] == 0x04 && (lenSub1 == 64 || lenSub1 == 96 || lenSub1 == 132)))) { | |
| 192 | throw new IllegalArgumentException( | |
| 193 | String.format( | |
| 194 | "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", | |
| 195 | keyBytes.length, keyBytes[0])); | |
| 196 | } | |
| 197 |
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; |
| 198 |
2
1. rawEcKeyToCose : Replaced integer division with multiplication → KILLED 2. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED |
final int coordinateLength = (len - start) / 2; |
| 199 | ||
| 200 | final Map<Long, Object> coseKey = new HashMap<>(); | |
| 201 | coseKey.put(1L, 2L); // Key type: EC | |
| 202 | ||
| 203 | final COSEAlgorithmIdentifier coseAlg; | |
| 204 | final int coseCrv; | |
| 205 |
1
1. rawEcKeyToCose : Replaced integer subtraction with addition → KILLED |
switch (len - start) { |
| 206 | case 64: | |
| 207 | coseAlg = COSEAlgorithmIdentifier.ES256; | |
| 208 | coseCrv = COSE_CRV_P256; | |
| 209 | break; | |
| 210 | case 96: | |
| 211 | coseAlg = COSEAlgorithmIdentifier.ES384; | |
| 212 | coseCrv = COSE_CRV_P384; | |
| 213 | break; | |
| 214 | case 132: | |
| 215 | coseAlg = COSEAlgorithmIdentifier.ES512; | |
| 216 | coseCrv = COSE_CRV_P521; | |
| 217 | break; | |
| 218 | default: | |
| 219 | throw new RuntimeException( | |
| 220 | "Failed to determine COSE EC algorithm. This should not be possible, please file a bug report."); | |
| 221 | } | |
| 222 | coseKey.put(3L, coseAlg.getId()); | |
| 223 | coseKey.put(-1L, coseCrv); | |
| 224 | ||
| 225 |
1
1. rawEcKeyToCose : Replaced integer addition with subtraction → KILLED |
coseKey.put(-2L, Arrays.copyOfRange(keyBytes, start, start + coordinateLength)); // x |
| 226 | coseKey.put( | |
| 227 |
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, |
| 228 | Arrays.copyOfRange(keyBytes, start + coordinateLength, start + 2 * coordinateLength)); // y | |
| 229 | ||
| 230 |
1
1. rawEcKeyToCose : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::rawEcKeyToCose → KILLED |
return new ByteArray(CBORObject.FromObject(coseKey).EncodeToBytes()); |
| 231 | } | |
| 232 | ||
| 233 | static PublicKey importCosePublicKey(ByteArray key) | |
| 234 | throws IOException, InvalidKeySpecException, NoSuchAlgorithmException { | |
| 235 | CBORObject cose = CBORObject.DecodeFromBytes(key.getBytes()); | |
| 236 | final int kty = cose.get(CBORObject.FromObject(1)).AsInt32(); | |
| 237 | switch (kty) { | |
| 238 | case 1: | |
| 239 |
1
1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED |
return importCoseEdDsaPublicKey(cose); |
| 240 | case 2: | |
| 241 |
1
1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED |
return importCoseEcdsaPublicKey(cose); |
| 242 | case 3: | |
| 243 |
1
1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED |
return importCoseRsaPublicKey(cose); |
| 244 | case 7: | |
| 245 |
1
1. importCosePublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCosePublicKey → KILLED |
return importCoseMlDsaPublicKey(cose); |
| 246 | default: | |
| 247 | throw new IllegalArgumentException("Unsupported key type: " + kty); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | private static PublicKey importCoseRsaPublicKey(CBORObject cose) | |
| 252 | throws NoSuchAlgorithmException, InvalidKeySpecException { | |
| 253 | RSAPublicKeySpec spec = | |
| 254 | new RSAPublicKeySpec( | |
| 255 | new BigInteger(1, cose.get(CBORObject.FromObject(-1)).GetByteString()), | |
| 256 | new BigInteger(1, cose.get(CBORObject.FromObject(-2)).GetByteString())); | |
| 257 |
1
1. importCoseRsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseRsaPublicKey → KILLED |
return KeyFactory.getInstance("RSA").generatePublic(spec); |
| 258 | } | |
| 259 | ||
| 260 | private static PublicKey importCoseEcdsaPublicKey(CBORObject cose) | |
| 261 | throws NoSuchAlgorithmException, InvalidKeySpecException { | |
| 262 | final int crv = cose.get(CBORObject.FromObject(-1)).AsInt32Value(); | |
| 263 | final byte[] x = cose.get(CBORObject.FromObject(-2)).GetByteString(); | |
| 264 | final byte[] y = cose.get(CBORObject.FromObject(-3)).GetByteString(); | |
| 265 | ||
| 266 | final byte[] curveOid; | |
| 267 | switch (crv) { | |
| 268 | case COSE_CRV_P256: | |
| 269 | curveOid = P256_CURVE_OID.getBytes(); | |
| 270 | break; | |
| 271 | ||
| 272 | case COSE_CRV_P384: | |
| 273 | curveOid = P384_CURVE_OID.getBytes(); | |
| 274 | break; | |
| 275 | ||
| 276 | case COSE_CRV_P521: | |
| 277 | curveOid = P521_CURVE_OID.getBytes(); | |
| 278 | break; | |
| 279 | ||
| 280 | default: | |
| 281 | throw new IllegalArgumentException("Unknown COSE EC2 curve: " + crv); | |
| 282 | } | |
| 283 | ||
| 284 | final byte[] algId = | |
| 285 | BinaryUtil.encodeDerSequence( | |
| 286 | BinaryUtil.encodeDerObjectId(EC_PUBLIC_KEY_OID.getBytes()), | |
| 287 | BinaryUtil.encodeDerObjectId(curveOid)); | |
| 288 | ||
| 289 | final byte[] rawKey = | |
| 290 | BinaryUtil.encodeDerBitStringWithZeroUnused( | |
| 291 | BinaryUtil.concat( | |
| 292 | new byte[] {0x04}, // Raw EC public key with x and y | |
| 293 | x, | |
| 294 | y)); | |
| 295 | ||
| 296 | final byte[] x509Key = BinaryUtil.encodeDerSequence(algId, rawKey); | |
| 297 | ||
| 298 | KeyFactory kFact = KeyFactory.getInstance("EC"); | |
| 299 |
1
1. importCoseEcdsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEcdsaPublicKey → KILLED |
return kFact.generatePublic(new X509EncodedKeySpec(x509Key)); |
| 300 | } | |
| 301 | ||
| 302 | private static PublicKey importCoseEdDsaPublicKey(CBORObject cose) | |
| 303 | throws InvalidKeySpecException, NoSuchAlgorithmException { | |
| 304 | final int alg = cose.get(CBORObject.FromObject(3)).AsInt32(); | |
| 305 | final int curveId = cose.get(CBORObject.FromObject(-1)).AsInt32(); | |
| 306 | final ByteArray algorithmOid = coseCurveToEddsaAlgorithmOid(curveId); | |
| 307 | final byte[] rawKey = cose.get(CBORObject.FromObject(-2)).GetByteString(); | |
| 308 | final byte[] x509Key = | |
| 309 | BinaryUtil.encodeDerSequence( | |
| 310 | algorithmOid.getBytes(), BinaryUtil.encodeDerBitStringWithZeroUnused(rawKey)); | |
| 311 | ||
| 312 | KeyFactory kFact = | |
| 313 | KeyFactory.getInstance( | |
| 314 | getJavaAlgorithmName( | |
| 315 | COSEAlgorithmIdentifier.fromId(alg) | |
| 316 |
1
1. lambda$importCoseEdDsaPublicKey$0 : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::lambda$importCoseEdDsaPublicKey$0 → NO_COVERAGE |
.orElseThrow(() -> new IllegalArgumentException("Unknown algorithm: " + alg)))); |
| 317 |
1
1. importCoseEdDsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseEdDsaPublicKey → KILLED |
return kFact.generatePublic(new X509EncodedKeySpec(x509Key)); |
| 318 | } | |
| 319 | ||
| 320 | private static ByteArray coseCurveToEddsaAlgorithmOid(int curveId) { | |
| 321 | switch (curveId) { | |
| 322 | case COSE_CRV_ED25519: | |
| 323 |
1
1. coseCurveToEddsaAlgorithmOid : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::coseCurveToEddsaAlgorithmOid → KILLED |
return ED25519_ALG_ID; |
| 324 | case COSE_CRV_ED448: | |
| 325 |
1
1. coseCurveToEddsaAlgorithmOid : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::coseCurveToEddsaAlgorithmOid → KILLED |
return ED448_ALG_ID; |
| 326 | default: | |
| 327 | throw new IllegalArgumentException("Unsupported EdDSA curve: " + curveId); | |
| 328 | } | |
| 329 | } | |
| 330 | ||
| 331 | private static PublicKey importCoseMlDsaPublicKey(CBORObject cose) | |
| 332 | throws InvalidKeySpecException, NoSuchAlgorithmException { | |
| 333 | final int alg = cose.get(CBORObject.FromObject(3)).AsInt32(); | |
| 334 | final ByteArray algorithmId = mlDsaAlgorithmId(alg); | |
| 335 | final byte[] rawKey = cose.get(CBORObject.FromObject(-1)).GetByteString(); | |
| 336 | final byte[] x509Key = | |
| 337 | BinaryUtil.encodeDerSequence( | |
| 338 | algorithmId.getBytes(), BinaryUtil.encodeDerBitStringWithZeroUnused(rawKey)); | |
| 339 | ||
| 340 | KeyFactory kFact = | |
| 341 | KeyFactory.getInstance( | |
| 342 | getJavaAlgorithmName( | |
| 343 | COSEAlgorithmIdentifier.fromId(alg) | |
| 344 |
1
1. lambda$importCoseMlDsaPublicKey$1 : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::lambda$importCoseMlDsaPublicKey$1 → NO_COVERAGE |
.orElseThrow(() -> new IllegalArgumentException("Unknown algorithm: " + alg)))); |
| 345 |
1
1. importCoseMlDsaPublicKey : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::importCoseMlDsaPublicKey → KILLED |
return kFact.generatePublic(new X509EncodedKeySpec(x509Key)); |
| 346 | } | |
| 347 | ||
| 348 | private static ByteArray mlDsaAlgorithmId(int alg) { | |
| 349 | switch (alg) { | |
| 350 | case -48: | |
| 351 |
1
1. mlDsaAlgorithmId : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::mlDsaAlgorithmId → KILLED |
return ML_DSA_44_ALG_ID; |
| 352 | case -49: | |
| 353 |
1
1. mlDsaAlgorithmId : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::mlDsaAlgorithmId → KILLED |
return ML_DSA_65_ALG_ID; |
| 354 | case -50: | |
| 355 |
1
1. mlDsaAlgorithmId : replaced return value with null for com/yubico/webauthn/WebAuthnCodecs::mlDsaAlgorithmId → KILLED |
return ML_DSA_87_ALG_ID; |
| 356 | default: | |
| 357 | throw new IllegalArgumentException("Unsupported ML-DSA algorithm: " + alg); | |
| 358 | } | |
| 359 | } | |
| 360 | ||
| 361 | static String getJavaAlgorithmName(COSEAlgorithmIdentifier alg) { | |
| 362 | switch (alg) { | |
| 363 | case EdDSA: | |
| 364 | case Ed25519: | |
| 365 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "Ed25519"; |
| 366 | case Ed448: | |
| 367 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "Ed448"; |
| 368 | case ES256: | |
| 369 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA256withECDSA"; |
| 370 | case ES384: | |
| 371 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA384withECDSA"; |
| 372 | case ES512: | |
| 373 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA512withECDSA"; |
| 374 | case RS256: | |
| 375 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA256withRSA"; |
| 376 | case RS384: | |
| 377 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA384withRSA"; |
| 378 | case RS512: | |
| 379 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA512withRSA"; |
| 380 | case RS1: | |
| 381 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "SHA1withRSA"; |
| 382 | case ML_DSA_44: | |
| 383 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "ML-DSA-44"; |
| 384 | case ML_DSA_65: | |
| 385 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "ML-DSA-65"; |
| 386 | case ML_DSA_87: | |
| 387 |
1
1. getJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::getJavaAlgorithmName → KILLED |
return "ML-DSA-87"; |
| 388 | default: | |
| 389 | throw new IllegalArgumentException("Unknown algorithm: " + alg); | |
| 390 | } | |
| 391 | } | |
| 392 | ||
| 393 | static String jwsAlgorithmNameToJavaAlgorithmName(String alg) { | |
| 394 |
1
1. jwsAlgorithmNameToJavaAlgorithmName : negated conditional → KILLED |
switch (alg) { |
| 395 | case "RS256": | |
| 396 |
1
1. jwsAlgorithmNameToJavaAlgorithmName : replaced return value with "" for com/yubico/webauthn/WebAuthnCodecs::jwsAlgorithmNameToJavaAlgorithmName → KILLED |
return "SHA256withRSA"; |
| 397 | } | |
| 398 | throw new IllegalArgumentException("Unknown algorithm: " + alg); | |
| 399 | } | |
| 400 | } | |
Mutations | ||
| 166 |
1.1 |
|
| 169 |
1.1 |
|
| 170 |
1.1 |
|
| 172 |
1.1 |
|
| 173 |
1.1 |
|
| 175 |
1.1 2.2 |
|
| 179 |
1.1 |
|
| 187 |
1.1 |
|
| 188 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 197 |
1.1 2.2 3.3 |
|
| 198 |
1.1 2.2 |
|
| 205 |
1.1 |
|
| 225 |
1.1 |
|
| 227 |
1.1 2.2 3.3 |
|
| 230 |
1.1 |
|
| 239 |
1.1 |
|
| 241 |
1.1 |
|
| 243 |
1.1 |
|
| 245 |
1.1 |
|
| 257 |
1.1 |
|
| 299 |
1.1 |
|
| 316 |
1.1 |
|
| 317 |
1.1 |
|
| 323 |
1.1 |
|
| 325 |
1.1 |
|
| 344 |
1.1 |
|
| 345 |
1.1 |
|
| 351 |
1.1 |
|
| 353 |
1.1 |
|
| 355 |
1.1 |
|
| 365 |
1.1 |
|
| 367 |
1.1 |
|
| 369 |
1.1 |
|
| 371 |
1.1 |
|
| 373 |
1.1 |
|
| 375 |
1.1 |
|
| 377 |
1.1 |
|
| 379 |
1.1 |
|
| 381 |
1.1 |
|
| 383 |
1.1 |
|
| 385 |
1.1 |
|
| 387 |
1.1 |
|
| 394 |
1.1 |
|
| 396 |
1.1 |