Crypto.java

1
// Copyright (c) 2014-2018, Yubico AB
2
// Copyright (c) 2014, Google Inc.
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are met:
7
//
8
// 1. Redistributions of source code must retain the above copyright notice, this
9
//    list of conditions and the following disclaimer.
10
//
11
// 2. Redistributions in binary form must reproduce the above copyright notice,
12
//    this list of conditions and the following disclaimer in the documentation
13
//    and/or other materials provided with the distribution.
14
//
15
// 3. Neither the name of Google Inc. nor the names of its contributors may be
16
//    used to endorse or promote products derived from this software without
17
//    specific prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
package com.yubico.webauthn;
31
32
import com.google.common.hash.Hashing;
33
import com.yubico.webauthn.data.ByteArray;
34
import com.yubico.webauthn.data.COSEAlgorithmIdentifier;
35
import java.math.BigInteger;
36
import java.nio.charset.StandardCharsets;
37
import java.security.GeneralSecurityException;
38
import java.security.MessageDigest;
39
import java.security.NoSuchAlgorithmException;
40
import java.security.PublicKey;
41
import java.security.Signature;
42
import java.security.cert.X509Certificate;
43
import java.security.spec.ECFieldFp;
44
import java.security.spec.ECParameterSpec;
45
import java.security.spec.EllipticCurve;
46
import lombok.experimental.UtilityClass;
47
import lombok.extern.slf4j.Slf4j;
48
49
@UtilityClass
50
@Slf4j
51
final class Crypto {
52
  // Values from
53
  // https://apps.nsa.gov/iaarchive/library/ia-guidance/ia-solutions-for-classified/algorithm-guidance/mathematical-routines-for-the-nist-prime-elliptic-curves.cfm
54
  // cross-referenced with "secp256r1" in https://www.secg.org/sec2-v2.pdf
55
  private static final EllipticCurve P256 =
56
      new EllipticCurve(
57
          new ECFieldFp(
58
              new BigInteger(
59
                  "115792089210356248762697446949407573530086143415290314195533631308867097853951",
60
                  10)),
61
          new BigInteger(
62
              "115792089210356248762697446949407573530086143415290314195533631308867097853948", 10),
63
          new BigInteger(
64
              "41058363725152142129326129780047268409114441015993725554835256314039467401291", 10));
65
66
  static boolean isP256(ECParameterSpec params) {
67 2 1. isP256 : replaced boolean return with true for com/yubico/webauthn/Crypto::isP256 → KILLED
2. isP256 : replaced boolean return with false for com/yubico/webauthn/Crypto::isP256 → KILLED
    return P256.equals(params.getCurve());
68
  }
69
70
  public static boolean verifySignature(
71
      X509Certificate attestationCertificate,
72
      ByteArray signedBytes,
73
      ByteArray signature,
74
      COSEAlgorithmIdentifier alg) {
75 2 1. verifySignature : replaced boolean return with true for com/yubico/webauthn/Crypto::verifySignature → KILLED
2. verifySignature : replaced boolean return with false for com/yubico/webauthn/Crypto::verifySignature → KILLED
    return verifySignature(attestationCertificate.getPublicKey(), signedBytes, signature, alg);
76
  }
77
78
  public static boolean verifySignature(
79
      PublicKey publicKey,
80
      ByteArray signedBytes,
81
      ByteArray signatureBytes,
82
      COSEAlgorithmIdentifier alg) {
83
    try {
84
      Signature signature = Signature.getInstance(WebAuthnCodecs.getJavaAlgorithmName(alg));
85 1 1. verifySignature : removed call to java/security/Signature::initVerify → KILLED
      signature.initVerify(publicKey);
86 1 1. verifySignature : removed call to java/security/Signature::update → KILLED
      signature.update(signedBytes.getBytes());
87 2 1. verifySignature : replaced boolean return with true for com/yubico/webauthn/Crypto::verifySignature → KILLED
2. verifySignature : replaced boolean return with false for com/yubico/webauthn/Crypto::verifySignature → KILLED
      return signature.verify(signatureBytes.getBytes());
88
    } catch (GeneralSecurityException | IllegalArgumentException e) {
89
      throw new RuntimeException(
90
          String.format(
91
              "Failed to verify signature. This could be a problem with your JVM environment, or a bug in webauthn-server-core. Public key: %s, signed data: %s , signature: %s",
92
              publicKey, signedBytes.getBase64Url(), signatureBytes.getBase64Url()),
93
          e);
94
    }
95
  }
96
97
  public static ByteArray sha256(ByteArray bytes) {
98 1 1. sha256 : replaced return value with null for com/yubico/webauthn/Crypto::sha256 → KILLED
    return new ByteArray(Hashing.sha256().hashBytes(bytes.getBytes()).asBytes());
99
  }
100
101
  public static ByteArray sha384(ByteArray bytes) {
102 1 1. sha384 : replaced return value with null for com/yubico/webauthn/Crypto::sha384 → KILLED
    return new ByteArray(Hashing.sha384().hashBytes(bytes.getBytes()).asBytes());
103
  }
104
105
  public static ByteArray sha512(ByteArray bytes) {
106 1 1. sha512 : replaced return value with null for com/yubico/webauthn/Crypto::sha512 → KILLED
    return new ByteArray(Hashing.sha512().hashBytes(bytes.getBytes()).asBytes());
107
  }
108
109
  public static ByteArray sha256(String str) {
110 1 1. sha256 : replaced return value with null for com/yubico/webauthn/Crypto::sha256 → KILLED
    return sha256(new ByteArray(str.getBytes(StandardCharsets.UTF_8)));
111
  }
112
113
  public static ByteArray sha1(ByteArray bytes) throws NoSuchAlgorithmException {
114 1 1. sha1 : replaced return value with null for com/yubico/webauthn/Crypto::sha1 → KILLED
    return new ByteArray(MessageDigest.getInstance("SHA-1").digest(bytes.getBytes()));
115
  }
116
}

Mutations

67

1.1
Location : isP256
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/Crypto::isP256 → KILLED

2.2
Location : isP256
Killed by : com.yubico.webauthn.PackedAttestationStatementVerifierSpec
replaced boolean return with false for com/yubico/webauthn/Crypto::isP256 → KILLED

75

1.1
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyV2RegistrationSpec
replaced boolean return with true for com/yubico/webauthn/Crypto::verifySignature → KILLED

2.2
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyCeremoniesSpec
replaced boolean return with false for com/yubico/webauthn/Crypto::verifySignature → KILLED

85

1.1
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
removed call to java/security/Signature::initVerify → KILLED

86

1.1
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
removed call to java/security/Signature::update → KILLED

87

1.1
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced boolean return with true for com/yubico/webauthn/Crypto::verifySignature → KILLED

2.2
Location : verifySignature
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced boolean return with false for com/yubico/webauthn/Crypto::verifySignature → KILLED

98

1.1
Location : sha256
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/Crypto::sha256 → KILLED

102

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

106

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

110

1.1
Location : sha256
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/Crypto::sha256 → KILLED

114

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

Active mutators

Tests examined


Report generated by PIT 1.15.0