Key.java

1
/**
2
   Copyright 2017 Carlos Macasaet
3
4
   Licensed under the Apache License, Version 2.0 (the "License");
5
   you may not use this file except in compliance with the License.
6
   You may obtain a copy of the License at
7
8
       https://www.apache.org/licenses/LICENSE-2.0
9
10
   Unless required by applicable law or agreed to in writing, software
11
   distributed under the License is distributed on an "AS IS" BASIS,
12
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
   See the License for the specific language governing permissions and
14
   limitations under the License.
15
 */
16
package com.macasaet.fernet;
17
18
import static com.macasaet.fernet.Constants.cipherTransformation;
19
import static com.macasaet.fernet.Constants.decoder;
20
import static com.macasaet.fernet.Constants.encoder;
21
import static com.macasaet.fernet.Constants.encryptionAlgorithm;
22
import static com.macasaet.fernet.Constants.encryptionKeyBytes;
23
import static com.macasaet.fernet.Constants.fernetKeyBytes;
24
import static com.macasaet.fernet.Constants.signingAlgorithm;
25
import static com.macasaet.fernet.Constants.signingKeyBytes;
26
import static com.macasaet.fernet.Constants.tokenPrefixBytes;
27
import static java.util.Arrays.copyOf;
28
import static java.util.Arrays.copyOfRange;
29
import static javax.crypto.Cipher.DECRYPT_MODE;
30
import static javax.crypto.Cipher.ENCRYPT_MODE;
31
32
import java.io.ByteArrayOutputStream;
33
import java.io.DataOutputStream;
34
import java.io.IOException;
35
import java.io.OutputStream;
36
import java.security.InvalidAlgorithmParameterException;
37
import java.security.InvalidKeyException;
38
import java.security.MessageDigest;
39
import java.security.NoSuchAlgorithmException;
40
import java.security.SecureRandom;
41
import java.time.Instant;
42
import java.util.Arrays;
43
import java.util.Base64.Encoder;
44
45
import javax.crypto.BadPaddingException;
46
import javax.crypto.Cipher;
47
import javax.crypto.IllegalBlockSizeException;
48
import javax.crypto.Mac;
49
import javax.crypto.NoSuchPaddingException;
50
import javax.crypto.spec.IvParameterSpec;
51
import javax.crypto.spec.SecretKeySpec;
52
53
/**
54
 * A Fernet shared secret key.
55
 *
56
 * <p>Copyright &copy; 2017 Carlos Macasaet.</p>
57
 *
58
 * @author Carlos Macasaet
59
 */
60
@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"})
61
public class Key {
62
63
    private final byte[] signingKey;
64
    private final byte[] encryptionKey;
65
66
    /**
67
     * Create a Key from individual components.
68
     *
69
     * @param signingKey
70
     *            a 128-bit (16 byte) key for signing tokens.
71
     * @param encryptionKey
72
     *            a 128-bit (16 byte) key for encrypting and decrypting token contents.
73
     */
74
    public Key(final byte[] signingKey, final byte[] encryptionKey) {
75 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
        if (signingKey == null || signingKey.length != signingKeyBytes) {
76
            throw new IllegalArgumentException("Signing key must be 128 bits");
77
        }
78 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
        if (encryptionKey == null || encryptionKey.length != encryptionKeyBytes) {
79
            throw new IllegalArgumentException("Encryption key must be 128 bits");
80
        }
81
        this.signingKey = copyOf(signingKey, signingKeyBytes);
82
        this.encryptionKey = copyOf(encryptionKey, encryptionKeyBytes);
83
    }
84
85
    /**
86
     * Create a Key from a payload containing the signing and encryption
87
     * key.
88
     *
89
     * @param concatenatedKeys an array of 32 bytes of which the first 16 is
90
     *                         the signing key and the last 16 is the
91
     *                         encryption/decryption key
92
     */
93
    public Key(final byte[] concatenatedKeys) {
94
        this(copyOfRange(concatenatedKeys, 0, signingKeyBytes),
95
                copyOfRange(concatenatedKeys, signingKeyBytes, fernetKeyBytes));
96
    }
97
98
    /**
99
     * @param string
100
     *            a Base 64 URL string in the format Signing-key (128 bits) || Encryption-key (128 bits)
101
     */
102
    public Key(final String string) {
103
        this(decoder.decode(string));
104
    }
105
106
    /**
107
     * Generate a random key
108
     *
109
     * @return a new shared secret key
110
     */
111
    public static Key generateKey() {
112
        return generateKey(new SecureRandom());
113
    }
114
115
    /**
116
     * Generate a random key
117
     *
118
     * @param random
119
     *            source of entropy
120
     * @return a new shared secret key
121
     */
122
    public static Key generateKey(final SecureRandom random) {
123
        final byte[] signingKey = new byte[signingKeyBytes];
124
        random.nextBytes(signingKey);
125
        final byte[] encryptionKey = new byte[encryptionKeyBytes];
126
        random.nextBytes(encryptionKey);
127 1 1. generateKey : mutated return of Object value for com/macasaet/fernet/Key::generateKey to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new Key(signingKey, encryptionKey);
128
    }
129
130
    /**
131
     * Generate an HMAC SHA-256 signature from the components of a Fernet token.
132
     *
133
     * @param version
134
     *            the Fernet version number
135
     * @param timestamp
136
     *            the seconds after the epoch that the token was generated
137
     * @param initializationVector
138
     *            the encryption and decryption initialization vector
139
     * @param cipherText
140
     *            the encrypted content of the token
141
     * @return the HMAC signature
142
     */
143
    public byte[] sign(final byte version, final Instant timestamp, final IvParameterSpec initializationVector,
144
            final byte[] cipherText) {
145 2 1. sign : removed call to java/io/ByteArrayOutputStream::close → NO_COVERAGE
2. sign : removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE
        try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream(
146 1 1. sign : Replaced integer addition with subtraction → KILLED
                getTokenPrefixBytes() + cipherText.length)) {
147 1 1. sign : mutated return of Object value for com/macasaet/fernet/Key::sign to ( if (x != null) null else throw new RuntimeException ) → KILLED
            return sign(version, timestamp, initializationVector, cipherText, byteStream);
148 1 1. sign : removed call to java/io/ByteArrayOutputStream::close → SURVIVED
        } catch (final IOException e) {
149
            // this should not happen as I/O is to memory only
150
            throw new IllegalStateException(e.getMessage(), e);
151
        }
152
    }
153
154
    /**
155
     * Encrypt a payload to embed in a Fernet token
156
     *
157
     * @param payload the raw bytes of the data to store in a token
158
     * @param initializationVector random bytes from a high-entropy source to initialise the AES cipher
159
     * @return the AES-encrypted payload. The length will always be a multiple of 16 (128 bits).
160
     * @see #decrypt(byte[], IvParameterSpec)
161
     */
162
    @SuppressWarnings("PMD.LawOfDemeter")
163
    public byte[] encrypt(final byte[] payload, final IvParameterSpec initializationVector) {
164
        final SecretKeySpec encryptionKeySpec = getEncryptionKeySpec();
165
        try {
166
            final Cipher cipher = Cipher.getInstance(cipherTransformation);
167 1 1. encrypt : removed call to javax/crypto/Cipher::init → KILLED
            cipher.init(ENCRYPT_MODE, encryptionKeySpec, initializationVector);
168 1 1. encrypt : mutated return of Object value for com/macasaet/fernet/Key::encrypt to ( if (x != null) null else throw new RuntimeException ) → KILLED
            return cipher.doFinal(payload);
169
        } catch (final NoSuchAlgorithmException | NoSuchPaddingException e) {
170
            // these should not happen as we use an algorithm (AES) and padding (PKCS5) that are guaranteed to exist
171
            throw new IllegalStateException("Unable to access cipher " + cipherTransformation + ": " + e.getMessage(), e);
172
        } catch (final InvalidKeyException | InvalidAlgorithmParameterException e) {
173
            // this should not happen as the key is validated ahead of time and
174
            // we use an algorithm guaranteed to exist
175
            throw new IllegalStateException(
176
                    "Unable to initialise encryption cipher with algorithm " + encryptionKeySpec.getAlgorithm()
177
                            + " and format " + encryptionKeySpec.getFormat() + ": " + e.getMessage(),
178
                    e);
179
        } catch (final IllegalBlockSizeException | BadPaddingException e) {
180
            // these should not happen as we control the block size and padding
181
            throw new IllegalStateException("Unable to encrypt data: " + e.getMessage(), e);
182
        }
183
    }
184
185
    /**
186
     * <p>Decrypt the payload of a Fernet token.</p>
187
     *
188
     * <p>Warning: Do not call this unless the cipher text has first been verified. Attempting to decrypt a cipher text
189
     * that has been tampered with will leak whether or not the padding is correct and this can be used to decrypt
190
     * stolen cipher text.</p>
191
     *
192
     * @param cipherText
193
     *            the verified padded encrypted payload of a token. The length <em>must</em> be a multiple of 16 (128
194
     *            bits).
195
     * @param initializationVector
196
     *            the random bytes used in the AES encryption of the token
197
     * @return the decrypted payload
198
     * @see Key#encrypt(byte[], IvParameterSpec)
199
     */
200
    @SuppressWarnings("PMD.LawOfDemeter")
201
    protected byte[] decrypt(final byte[] cipherText, final IvParameterSpec initializationVector) {
202
        try {
203
            final Cipher cipher = Cipher.getInstance(getCipherTransformation());
204 1 1. decrypt : removed call to javax/crypto/Cipher::init → KILLED
            cipher.init(DECRYPT_MODE, getEncryptionKeySpec(), initializationVector);
205 1 1. decrypt : mutated return of Object value for com/macasaet/fernet/Key::decrypt to ( if (x != null) null else throw new RuntimeException ) → KILLED
            return cipher.doFinal(cipherText);
206
        } catch (final NoSuchAlgorithmException | NoSuchPaddingException
207
                | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException e) {
208
            // this should not happen as we use an algorithm (AES) and padding
209
            // (PKCS5) that are guaranteed to exist.
210
            // in addition, we validate the encryption key and initialization vector up front
211
            throw new IllegalStateException(e.getMessage(), e);
212
        } catch (final BadPaddingException bpe) {
213
            throw new TokenValidationException("Invalid padding in token: " + bpe.getMessage(), bpe);
214
        }
215
    }
216
217
    /**
218
     * @return the Base 64 URL representation of this Fernet key
219
     */
220
    @SuppressWarnings("PMD.LawOfDemeter")
221
    public String serialise() {
222 2 1. serialise : removed call to java/io/ByteArrayOutputStream::close → NO_COVERAGE
2. serialise : removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE
        try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream(fernetKeyBytes)) {
223 1 1. serialise : removed call to com/macasaet/fernet/Key::writeTo → KILLED
            writeTo(byteStream);
224 1 1. serialise : mutated return of Object value for com/macasaet/fernet/Key::serialise to ( if (x != null) null else throw new RuntimeException ) → KILLED
            return getEncoder().encodeToString(byteStream.toByteArray());
225 1 1. serialise : removed call to java/io/ByteArrayOutputStream::close → SURVIVED
        } catch (final IOException ioe) {
226
            // this should not happen as I/O is to memory
227
            throw new IllegalStateException(ioe.getMessage(), ioe);
228
        }
229
    }
230
231
    /**
232
     * Write the raw bytes of this key to the specified output stream.
233
     *
234
     * @param outputStream
235
     *            the target
236
     * @throws IOException
237
     *             if the underlying I/O device cannot be written to
238
     */
239
    public void writeTo(final OutputStream outputStream) throws IOException {
240 1 1. writeTo : removed call to java/io/OutputStream::write → KILLED
        outputStream.write(getSigningKey());
241 1 1. writeTo : removed call to java/io/OutputStream::write → KILLED
        outputStream.write(getEncryptionKey());
242
    }
243
244
    public int hashCode() {
245
        final int prime = 31;
246
        int result = 1;
247 2 1. hashCode : Replaced integer multiplication with division → SURVIVED
2. hashCode : Replaced integer addition with subtraction → SURVIVED
        result = prime * result + Arrays.hashCode(getSigningKey());
248 2 1. hashCode : Replaced integer addition with subtraction → SURVIVED
2. hashCode : Replaced integer multiplication with division → KILLED
        result = prime * result + Arrays.hashCode(getEncryptionKey());
249 1 1. hashCode : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return result;
250
    }
251
252
    @SuppressWarnings("PMD.LawOfDemeter")
253
    public boolean equals(final Object obj) {
254 1 1. equals : negated conditional → KILLED
        if (this == obj) {
255 1 1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
            return true;
256
        }
257 1 1. equals : negated conditional → KILLED
        if (!(obj instanceof Key)) {
258 1 1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
            return false;
259
        }
260
        final Key other = (Key) obj;
261
262 2 1. equals : negated conditional → KILLED
2. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED
        return MessageDigest.isEqual(getSigningKey(), other.getSigningKey())
263 1 1. equals : negated conditional → KILLED
                && MessageDigest.isEqual(getEncryptionKey(), other.getEncryptionKey());
264
    }
265
266
    @SuppressWarnings("PMD.LawOfDemeter")
267
    protected byte[] sign(final byte version, final Instant timestamp, final IvParameterSpec initializationVector,
268
            final byte[] cipherText, final ByteArrayOutputStream byteStream)
269
        throws IOException {
270 2 1. sign : removed call to java/io/DataOutputStream::close → NO_COVERAGE
2. sign : removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE
        try (DataOutputStream dataStream = new DataOutputStream(byteStream)) {
271 1 1. sign : removed call to java/io/DataOutputStream::writeByte → KILLED
            dataStream.writeByte(version);
272 1 1. sign : removed call to java/io/DataOutputStream::writeLong → KILLED
            dataStream.writeLong(timestamp.getEpochSecond());
273 1 1. sign : removed call to java/io/DataOutputStream::write → KILLED
            dataStream.write(initializationVector.getIV());
274 1 1. sign : removed call to java/io/DataOutputStream::write → KILLED
            dataStream.write(cipherText);
275
276
            try {
277
                final Mac mac = Mac.getInstance(getSigningAlgorithm());
278 1 1. sign : removed call to javax/crypto/Mac::init → KILLED
                mac.init(getSigningKeySpec());
279 1 1. sign : mutated return of Object value for com/macasaet/fernet/Key::sign to ( if (x != null) null else throw new RuntimeException ) → KILLED
                return mac.doFinal(byteStream.toByteArray());
280
            } catch (final InvalidKeyException ike) {
281
                // this should not happen because we control the signing key
282
                // algorithm and pre-validate the length
283
                throw new IllegalStateException("Unable to initialise HMAC with shared secret: " + ike.getMessage(),
284
                        ike);
285
            } catch (final NoSuchAlgorithmException nsae) {
286
                // this should not happen as implementors are required to
287
                // provide the HmacSHA256 algorithm.
288
                throw new IllegalStateException(nsae.getMessage(), nsae);
289
            }
290 1 1. sign : removed call to java/io/DataOutputStream::close → SURVIVED
        }
291
    }
292
293
    /**
294
     * @return an HMAC SHA-256 key for signing the token
295
     */
296
    protected java.security.Key getSigningKeySpec() {
297 1 1. getSigningKeySpec : mutated return of Object value for com/macasaet/fernet/Key::getSigningKeySpec to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new SecretKeySpec(getSigningKey(), getSigningAlgorithm());
298
    }
299
300
    /**
301
     * @return the AES key for encrypting and decrypting the token payload
302
     */
303
    protected SecretKeySpec getEncryptionKeySpec() {
304 1 1. getEncryptionKeySpec : mutated return of Object value for com/macasaet/fernet/Key::getEncryptionKeySpec to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return new SecretKeySpec(getEncryptionKey(), getEncryptionAlgorithm());
305
    }
306
307
    /**
308
     * Warning: Modifying the returned byte array will write through to this object.
309
     *
310
     * @return the raw underlying signing key bytes
311
     */
312
    @SuppressWarnings("PMD.MethodReturnsInternalArray")
313
    protected byte[] getSigningKey() {
314 1 1. getSigningKey : mutated return of Object value for com/macasaet/fernet/Key::getSigningKey to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return signingKey;
315
    }
316
317
    /**
318
     * Warning: Modifying the returned byte array will write through to this object.
319
     *
320
     * @return the raw underlying encryption key bytes
321
     */
322
    @SuppressWarnings("PMD.MethodReturnsInternalArray")
323
    protected byte[] getEncryptionKey() {
324 1 1. getEncryptionKey : mutated return of Object value for com/macasaet/fernet/Key::getEncryptionKey to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return encryptionKey;
325
    }
326
327
    protected int getTokenPrefixBytes() {
328 1 1. getTokenPrefixBytes : replaced return of integer sized value with (x == 0 ? 1 : 0) → SURVIVED
        return tokenPrefixBytes;
329
    }
330
331
    protected String getSigningAlgorithm() {
332 1 1. getSigningAlgorithm : mutated return of Object value for com/macasaet/fernet/Key::getSigningAlgorithm to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return signingAlgorithm;
333
    }
334
335
    protected String getEncryptionAlgorithm() {
336 1 1. getEncryptionAlgorithm : mutated return of Object value for com/macasaet/fernet/Key::getEncryptionAlgorithm to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return encryptionAlgorithm;
337
    }
338
339
    protected Encoder getEncoder() {
340 1 1. getEncoder : mutated return of Object value for com/macasaet/fernet/Key::getEncoder to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return encoder;
341
    }
342
343
    protected String getCipherTransformation() {
344 1 1. getCipherTransformation : mutated return of Object value for com/macasaet/fernet/Key::getCipherTransformation to ( if (x != null) null else throw new RuntimeException ) → KILLED
        return cipherTransformation;
345
    }
346
347
}

Mutations

75

1.1
Location : <init>
Killed by : com.macasaet.fernet.KeyTest.testGetEncryptionKeySpec(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.macasaet.fernet.KeyTest.testConstructorValidatesSigningKey(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

78

1.1
Location : <init>
Killed by : com.macasaet.fernet.KeyTest.testGetEncryptionKeySpec(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.macasaet.fernet.KeyTest.testConstructorValidatesEncryptionKey(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

127

1.1
Location : generateKey
Killed by : com.macasaet.fernet.KeyTest.testGenerateKey(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::generateKey to ( if (x != null) null else throw new RuntimeException ) → KILLED

145

1.1
Location : sign
Killed by : none
removed call to java/io/ByteArrayOutputStream::close → NO_COVERAGE

2.2
Location : sign
Killed by : none
removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE

146

1.1
Location : sign
Killed by : com.macasaet.fernet.StringObjectValidatorTest.testValidateAndDecryptKeyToken(com.macasaet.fernet.StringObjectValidatorTest)
Replaced integer addition with subtraction → KILLED

147

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::sign to ( if (x != null) null else throw new RuntimeException ) → KILLED

148

1.1
Location : sign
Killed by : none
removed call to java/io/ByteArrayOutputStream::close → SURVIVED

167

1.1
Location : encrypt
Killed by : com.macasaet.fernet.TokenTest.verifyTokenGenerationWithDefaultEntropySource(com.macasaet.fernet.TokenTest)
removed call to javax/crypto/Cipher::init → KILLED

168

1.1
Location : encrypt
Killed by : com.macasaet.fernet.TokenTest.verifyTokenGenerationWithDefaultEntropySource(com.macasaet.fernet.TokenTest)
mutated return of Object value for com/macasaet/fernet/Key::encrypt to ( if (x != null) null else throw new RuntimeException ) → KILLED

204

1.1
Location : decrypt
Killed by : com.macasaet.fernet.TokenTest.testGenerate(com.macasaet.fernet.TokenTest)
removed call to javax/crypto/Cipher::init → KILLED

205

1.1
Location : decrypt
Killed by : com.macasaet.fernet.TokenTest.testGenerate(com.macasaet.fernet.TokenTest)
mutated return of Object value for com/macasaet/fernet/Key::decrypt to ( if (x != null) null else throw new RuntimeException ) → KILLED

222

1.1
Location : serialise
Killed by : none
removed call to java/io/ByteArrayOutputStream::close → NO_COVERAGE

2.2
Location : serialise
Killed by : none
removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE

223

1.1
Location : serialise
Killed by : com.macasaet.fernet.KeyTest.testSerialise(com.macasaet.fernet.KeyTest)
removed call to com/macasaet/fernet/Key::writeTo → KILLED

224

1.1
Location : serialise
Killed by : com.macasaet.fernet.KeyTest.testSerialise(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::serialise to ( if (x != null) null else throw new RuntimeException ) → KILLED

225

1.1
Location : serialise
Killed by : none
removed call to java/io/ByteArrayOutputStream::close → SURVIVED

240

1.1
Location : writeTo
Killed by : com.macasaet.fernet.KeyTest.testSerialise(com.macasaet.fernet.KeyTest)
removed call to java/io/OutputStream::write → KILLED

241

1.1
Location : writeTo
Killed by : com.macasaet.fernet.KeyTest.testSerialise(com.macasaet.fernet.KeyTest)
removed call to java/io/OutputStream::write → KILLED

247

1.1
Location : hashCode
Killed by : none
Replaced integer multiplication with division → SURVIVED

2.2
Location : hashCode
Killed by : none
Replaced integer addition with subtraction → SURVIVED

248

1.1
Location : hashCode
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
Replaced integer multiplication with division → KILLED

2.2
Location : hashCode
Killed by : none
Replaced integer addition with subtraction → SURVIVED

249

1.1
Location : hashCode
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

254

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

255

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

257

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

258

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

262

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

2.2
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED

263

1.1
Location : equals
Killed by : com.macasaet.fernet.KeyTest.verifyEqualityContract(com.macasaet.fernet.KeyTest)
negated conditional → KILLED

270

1.1
Location : sign
Killed by : none
removed call to java/io/DataOutputStream::close → NO_COVERAGE

2.2
Location : sign
Killed by : none
removed call to java/lang/Throwable::addSuppressed → NO_COVERAGE

271

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
removed call to java/io/DataOutputStream::writeByte → KILLED

272

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
removed call to java/io/DataOutputStream::writeLong → KILLED

273

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
removed call to java/io/DataOutputStream::write → KILLED

274

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
removed call to java/io/DataOutputStream::write → KILLED

278

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
removed call to javax/crypto/Mac::init → KILLED

279

1.1
Location : sign
Killed by : com.macasaet.fernet.KeyTest.testGetHmac(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::sign to ( if (x != null) null else throw new RuntimeException ) → KILLED

290

1.1
Location : sign
Killed by : none
removed call to java/io/DataOutputStream::close → SURVIVED

297

1.1
Location : getSigningKeySpec
Killed by : com.macasaet.fernet.KeyTest.testGetSigningKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getSigningKeySpec to ( if (x != null) null else throw new RuntimeException ) → KILLED

304

1.1
Location : getEncryptionKeySpec
Killed by : com.macasaet.fernet.KeyTest.testGetEncryptionKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getEncryptionKeySpec to ( if (x != null) null else throw new RuntimeException ) → KILLED

314

1.1
Location : getSigningKey
Killed by : com.macasaet.fernet.KeyTest.testGetSigningKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getSigningKey to ( if (x != null) null else throw new RuntimeException ) → KILLED

324

1.1
Location : getEncryptionKey
Killed by : com.macasaet.fernet.KeyTest.testGetEncryptionKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getEncryptionKey to ( if (x != null) null else throw new RuntimeException ) → KILLED

328

1.1
Location : getTokenPrefixBytes
Killed by : none
replaced return of integer sized value with (x == 0 ? 1 : 0) → SURVIVED

332

1.1
Location : getSigningAlgorithm
Killed by : com.macasaet.fernet.KeyTest.testGetSigningKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getSigningAlgorithm to ( if (x != null) null else throw new RuntimeException ) → KILLED

336

1.1
Location : getEncryptionAlgorithm
Killed by : com.macasaet.fernet.KeyTest.testGetEncryptionKeySpec(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getEncryptionAlgorithm to ( if (x != null) null else throw new RuntimeException ) → KILLED

340

1.1
Location : getEncoder
Killed by : com.macasaet.fernet.KeyTest.testSerialise(com.macasaet.fernet.KeyTest)
mutated return of Object value for com/macasaet/fernet/Key::getEncoder to ( if (x != null) null else throw new RuntimeException ) → KILLED

344

1.1
Location : getCipherTransformation
Killed by : com.macasaet.fernet.TokenTest.testGenerate(com.macasaet.fernet.TokenTest)
mutated return of Object value for com/macasaet/fernet/Key::getCipherTransformation to ( if (x != null) null else throw new RuntimeException ) → KILLED

Active mutators

Tests examined


Report generated by PIT 1.4.10