Skip to content

Commit 816bb91

Browse files
authored
Throw InvalidKeyException and InvalidParameterException instead of IllegalArgumentException (#124)
1 parent 7620a40 commit 816bb91

File tree

12 files changed

+84
-68
lines changed

12 files changed

+84
-68
lines changed

library/digest/src/commonMain/kotlin/org/kotlincrypto/core/digest/Digest.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.kotlincrypto.core.digest
1919

2020
import org.kotlincrypto.core.*
21+
import org.kotlincrypto.error.InvalidParameterException
2122
import org.kotlincrypto.error.ShortBufferException
2223

2324
/**
@@ -39,13 +40,13 @@ public expect abstract class Digest: Algorithm, Copyable<Digest>, Resettable, Up
3940
* @param [algorithm] See [Algorithm.algorithm]
4041
* @param [blockSize] See [Digest.blockSize]
4142
* @param [digestLength] See [Digest.digestLength]
42-
* @throws [IllegalArgumentException] when:
43+
* @throws [InvalidParameterException] when:
4344
* - [algorithm] is blank
4445
* - [blockSize] is less than or equal to 0
4546
* - [blockSize] is not a factor of 8
4647
* - [digestLength] is negative
4748
* */
48-
@Throws(IllegalArgumentException::class)
49+
@Throws(InvalidParameterException::class)
4950
protected constructor(algorithm: String, blockSize: Int, digestLength: Int)
5051

5152
/**

library/digest/src/commonMain/kotlin/org/kotlincrypto/core/digest/internal/-Buffer.kt

+7-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
package org.kotlincrypto.core.digest.internal
1919

2020
import org.kotlincrypto.core.digest.Digest
21+
import org.kotlincrypto.error.InvalidParameterException
2122
import org.kotlincrypto.error.ShortBufferException
23+
import org.kotlincrypto.error.requireParam
2224
import kotlin.contracts.ExperimentalContracts
2325
import kotlin.contracts.InvocationKind
2426
import kotlin.contracts.contract
@@ -27,17 +29,17 @@ import kotlin.jvm.JvmInline
2729
@JvmInline
2830
internal value class Buffer internal constructor(internal val value: ByteArray)
2931

30-
@Throws(IllegalArgumentException::class)
32+
@Throws(InvalidParameterException::class)
3133
@Suppress("UnusedReceiverParameter")
3234
internal inline fun Digest.initializeBuffer(
3335
algorithm: String,
3436
blockSize: Int,
3537
digestLength: Int,
3638
): Buffer {
37-
require(algorithm.isNotBlank()) { "algorithm cannot be blank" }
38-
require(blockSize > 0) { "blockSize must be greater than 0" }
39-
require(blockSize % 8 == 0) { "blockSize must be a factor of 8" }
40-
require(digestLength >= 0) { "digestLength cannot be negative" }
39+
requireParam(algorithm.isNotBlank()) { "algorithm cannot be blank" }
40+
requireParam(blockSize > 0) { "blockSize must be greater than 0" }
41+
requireParam(blockSize % 8 == 0) { "blockSize must be a factor of 8" }
42+
requireParam(digestLength >= 0) { "digestLength cannot be negative" }
4143
return Buffer(ByteArray(blockSize))
4244
}
4345

library/digest/src/commonTest/kotlin/org/kotlincrypto/core/digest/DigestUnitTest.kt

+2-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
**/
1616
package org.kotlincrypto.core.digest
1717

18+
import org.kotlincrypto.error.InvalidParameterException
1819
import org.kotlincrypto.error.ShortBufferException
1920
import kotlin.random.Random
2021
import kotlin.test.*
@@ -39,13 +40,7 @@ class DigestUnitTest: AbstractTestUpdateExceptions() {
3940
fun givenDigest_whenLengthNegative_thenThrowsException() {
4041
// accepts 0 length
4142
TestDigest(digestLength = 0)
42-
43-
try {
44-
TestDigest(digestLength = -1)
45-
fail()
46-
} catch (_: IllegalArgumentException) {
47-
// pass
48-
}
43+
assertFailsWith<InvalidParameterException> { TestDigest(digestLength = -1) }
4944
}
5045

5146
@Test

library/digest/src/jvmMain/kotlin/org/kotlincrypto/core/digest/Digest.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.kotlincrypto.core.digest
1919

2020
import org.kotlincrypto.core.*
2121
import org.kotlincrypto.core.digest.internal.*
22+
import org.kotlincrypto.error.InvalidParameterException
2223
import org.kotlincrypto.error.ShortBufferException
2324
import java.nio.ByteBuffer
2425
import java.security.DigestException
@@ -48,13 +49,13 @@ public actual abstract class Digest: MessageDigest, Algorithm, Cloneable, Copyab
4849
* @param [algorithm] See [Algorithm.algorithm]
4950
* @param [blockSize] See [Digest.blockSize]
5051
* @param [digestLength] See [Digest.digestLength]
51-
* @throws [IllegalArgumentException] when:
52+
* @throws [InvalidParameterException] when:
5253
* - [algorithm] is blank
5354
* - [blockSize] is less than or equal to 0
5455
* - [blockSize] is not a factor of 8
5556
* - [digestLength] is negative
5657
* */
57-
@Throws(IllegalArgumentException::class)
58+
@Throws(InvalidParameterException::class)
5859
protected actual constructor(algorithm: String, blockSize: Int, digestLength: Int): super(algorithm) {
5960
this.buf = initializeBuffer(algorithm, blockSize, digestLength)
6061
this.digestLength = digestLength

library/digest/src/nonJvmMain/kotlin/org/kotlincrypto/core/digest/Digest.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.kotlincrypto.core.digest
1919

2020
import org.kotlincrypto.core.*
2121
import org.kotlincrypto.core.digest.internal.*
22+
import org.kotlincrypto.error.InvalidParameterException
2223
import org.kotlincrypto.error.ShortBufferException
2324

2425
/**
@@ -45,13 +46,13 @@ public actual abstract class Digest: Algorithm, Copyable<Digest>, Resettable, Up
4546
* @param [algorithm] See [Algorithm.algorithm]
4647
* @param [blockSize] See [Digest.blockSize]
4748
* @param [digestLength] See [Digest.digestLength]
48-
* @throws [IllegalArgumentException] when:
49+
* @throws [InvalidParameterException] when:
4950
* - [algorithm] is blank
5051
* - [blockSize] is less than or equal to 0
5152
* - [blockSize] is not a factor of 8
5253
* - [digestLength] is negative
5354
* */
54-
@Throws(IllegalArgumentException::class)
55+
@Throws(InvalidParameterException::class)
5556
protected actual constructor(algorithm: String, blockSize: Int, digestLength: Int) {
5657
this.buf = initializeBuffer(algorithm, blockSize, digestLength)
5758
this.algorithm = algorithm

library/mac/src/commonMain/kotlin/org/kotlincrypto/core/mac/Mac.kt

+12-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package org.kotlincrypto.core.mac
1919

2020
import org.kotlincrypto.core.*
21+
import org.kotlincrypto.error.InvalidKeyException
22+
import org.kotlincrypto.error.InvalidParameterException
2123
import org.kotlincrypto.error.ShortBufferException
2224

2325
/**
@@ -43,10 +45,10 @@ public expect abstract class Mac: Algorithm, Copyable<Mac>, Resettable, Updatabl
4345
*
4446
* @param [algorithm] See [Algorithm.algorithm]
4547
* @param [engine] See [Engine]
46-
* @throws [IllegalArgumentException] when:
48+
* @throws [InvalidParameterException] when:
4749
* - [algorithm] is blank
4850
* */
49-
@Throws(IllegalArgumentException::class)
51+
@Throws(InvalidParameterException::class)
5052
protected constructor(algorithm: String, engine: Engine)
5153

5254
/**
@@ -122,7 +124,7 @@ public expect abstract class Mac: Algorithm, Copyable<Mac>, Resettable, Updatabl
122124
* This is useful if wanting to zero out the key before de-referencing.
123125
*
124126
* @see [clearKey]
125-
* @throws [IllegalArgumentException] if [newKey] is empty, or of a length
127+
* @throws [InvalidKeyException] if [newKey] is empty, or of a length
126128
* inappropriate for the [Mac] implementation.
127129
* */
128130
public fun reset(newKey: ByteArray)
@@ -160,19 +162,19 @@ public expect abstract class Mac: Algorithm, Copyable<Mac>, Resettable, Updatabl
160162
* or [Engine.doFinalInto] have been invoked).
161163
*
162164
* @param [key] The key that this [Engine] instance will use to apply its function to
163-
* @throws [IllegalArgumentException] if [key] is empty
165+
* @throws [InvalidKeyException] if [key] is empty
164166
* */
165-
@Throws(IllegalArgumentException::class)
167+
@Throws(InvalidKeyException::class)
166168
public constructor(key: ByteArray)
167169

168170
/**
169171
* Initializes a new [Engine] with the provided [key] and [resetOnDoFinal] configuration.
170172
*
171173
* @param [key] the key that this [Engine] instance will use to apply its function to
172174
* @param [resetOnDoFinal] See [Engine.resetOnDoFinal] documentation
173-
* @throws [IllegalArgumentException] if [key] is empty
175+
* @throws [InvalidKeyException] if [key] is empty
174176
* */
175-
@Throws(IllegalArgumentException::class)
177+
@Throws(InvalidKeyException::class)
176178
public constructor(key: ByteArray, resetOnDoFinal: Boolean)
177179

178180
/**
@@ -217,10 +219,10 @@ public expect abstract class Mac: Algorithm, Copyable<Mac>, Resettable, Updatabl
217219
* before passing it here. Implementations should ensure any old key material
218220
* is zeroed out.
219221
*
220-
* @throws [IllegalArgumentException] if [newKey] is a length inappropriate
221-
* for the [Mac] implementation.
222+
* @throws [InvalidKeyException] if [newKey] is a length inappropriate
223+
* for the [Engine] implementation.
222224
* */
223-
@Throws(IllegalArgumentException::class)
225+
@Throws(InvalidKeyException::class)
224226
public abstract fun reset(newKey: ByteArray)
225227

226228
/** @suppress */

library/mac/src/commonMain/kotlin/org/kotlincrypto/core/mac/internal/-CommonPlatform.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@
1818
package org.kotlincrypto.core.mac.internal
1919

2020
import org.kotlincrypto.core.mac.Mac
21+
import org.kotlincrypto.error.InvalidParameterException
2122
import org.kotlincrypto.error.ShortBufferException
23+
import org.kotlincrypto.error.requireParam
2224
import kotlin.contracts.ExperimentalContracts
2325
import kotlin.contracts.InvocationKind
2426
import kotlin.contracts.contract
2527

2628
private val SINGLE_0BYTE_KEY = ByteArray(1) { 0 }
2729

2830
@Suppress("UnusedReceiverParameter")
29-
@Throws(IllegalArgumentException::class)
31+
@Throws(InvalidParameterException::class)
3032
internal inline fun Mac.commonInit(algorithm: String) {
31-
require(algorithm.isNotBlank()) { "algorithm cannot be blank" }
33+
requireParam(algorithm.isNotBlank()) { "algorithm cannot be blank" }
3234
}
3335

3436
internal inline fun Mac.commonToString(): String {
@@ -62,10 +64,10 @@ internal inline fun Mac.commonClearKey(engineReset: (ByteArray) -> Unit) {
6264

6365
try {
6466
engineReset(SINGLE_0BYTE_KEY)
65-
} catch (e1: IllegalArgumentException) {
67+
} catch (e1: Throwable) {
6668
try {
6769
engineReset(ByteArray(macLength()))
68-
} catch (e2: IllegalArgumentException) {
70+
} catch (e2: Throwable) {
6971
e2.addSuppressed(e1)
7072
throw e2
7173
}

library/mac/src/commonTest/kotlin/org/kotlincrypto/core/mac/MacUnitTest.kt

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,31 @@
1515
**/
1616
package org.kotlincrypto.core.mac
1717

18+
import org.kotlincrypto.error.InvalidKeyException
19+
import org.kotlincrypto.error.InvalidParameterException
1820
import org.kotlincrypto.error.ShortBufferException
1921
import kotlin.test.*
2022

2123
class MacUnitTest {
2224

2325
@Test
2426
fun givenMac_whenEmptyKey_thenThrowsException() {
25-
assertFailsWith<IllegalArgumentException> {
27+
assertFailsWith<InvalidKeyException> {
2628
TestMac(ByteArray(0), "not empty")
2729
}
2830
}
2931

3032
@Test
3133
fun givenMac_whenBlankAlgorithm_thenThrowsException() {
32-
assertFailsWith<IllegalArgumentException> {
34+
assertFailsWith<InvalidParameterException> {
3335
TestMac(ByteArray(5), " ")
3436
}
3537
}
3638

3739
@Test
3840
fun givenMac_whenResetWithEmptyKey_thenThrowsException() {
3941
val mac = TestMac(ByteArray(5), "my algorithm")
40-
assertFailsWith<IllegalArgumentException> {
42+
assertFailsWith<InvalidKeyException> {
4143
mac.reset(ByteArray(0))
4244
}
4345
}

library/mac/src/jvmMain/kotlin/org/kotlincrypto/core/mac/Mac.kt

+20-17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package org.kotlincrypto.core.mac
2020
import org.kotlincrypto.core.*
2121
import org.kotlincrypto.core.mac.internal.*
2222
import org.kotlincrypto.error.InvalidKeyException
23+
import org.kotlincrypto.error.InvalidParameterException
2324
import org.kotlincrypto.error.ShortBufferException
2425
import java.nio.ByteBuffer
2526
import java.security.Key
@@ -44,7 +45,6 @@ import javax.crypto.SecretKey
4445
* https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#mac-algorithms
4546
*
4647
* @see [Engine]
47-
* @throws [IllegalArgumentException] if [algorithm] is blank
4848
* */
4949
public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Resettable, Updatable {
5050

@@ -55,10 +55,10 @@ public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Re
5555
*
5656
* @param [algorithm] See [Algorithm.algorithm]
5757
* @param [engine] See [Engine]
58-
* @throws [IllegalArgumentException] when:
58+
* @throws [InvalidParameterException] when:
5959
* - [algorithm] is blank
6060
* */
61-
@Throws(IllegalArgumentException::class)
61+
@Throws(InvalidParameterException::class)
6262
protected actual constructor(algorithm: String, engine: Engine): super(
6363
/* macSpi */ engine,
6464
/* provider */ AndroidApi21to23MacSpiProvider.createOrNull(engine, algorithm),
@@ -67,9 +67,8 @@ public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Re
6767
commonInit(algorithm)
6868
this.engine = engine
6969

70-
// Engine.engineInit is overridden as no-op, so this does
71-
// nothing other than set `javax.crypto.Mac.initialized`
72-
// to true
70+
// Engine.engineInit is overridden to ignore EmptyKey, so this does
71+
// nothing other than set `javax.crypto.Mac.initialized` to true.
7372
super.init(EmptyKey)
7473
}
7574

@@ -129,12 +128,16 @@ public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Re
129128
* This is useful if wanting to zero out the key before de-referencing.
130129
*
131130
* @see [clearKey]
132-
* @throws [IllegalArgumentException] if [newKey] is empty, or of a length
131+
* @throws [InvalidKeyException] if [newKey] is empty, or of a length
133132
* inappropriate for the [Mac] implementation.
134133
* */
135134
public actual fun reset(newKey: ByteArray) {
136-
require(newKey.isNotEmpty()) { "newKey cannot be empty" }
137-
engine.reset(newKey)
135+
if (newKey.isEmpty()) throw InvalidKeyException("newKey cannot be empty")
136+
try {
137+
engine.reset(newKey)
138+
} catch (e: IllegalArgumentException) {
139+
throw InvalidKeyException(e)
140+
}
138141
}
139142

140143
/**
@@ -172,21 +175,21 @@ public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Re
172175
* or [Engine.doFinalInto] have been invoked).
173176
*
174177
* @param [key] The key that this [Engine] instance will use to apply its function to
175-
* @throws [IllegalArgumentException] if [key] is empty
178+
* @throws [InvalidKeyException] if [key] is empty
176179
* */
177-
@Throws(IllegalArgumentException::class)
180+
@Throws(InvalidKeyException::class)
178181
public actual constructor(key: ByteArray): this(key, resetOnDoFinal = true)
179182

180183
/**
181184
* Initializes a new [Engine] with the provided [key] and [resetOnDoFinal] configuration.
182185
*
183186
* @param [key] the key that this [Engine] instance will use to apply its function to
184187
* @param [resetOnDoFinal] See [Engine.resetOnDoFinal] documentation
185-
* @throws [IllegalArgumentException] if [key] is empty
188+
* @throws [InvalidKeyException] if [key] is empty
186189
* */
187-
@Throws(IllegalArgumentException::class)
190+
@Throws(InvalidKeyException::class)
188191
public actual constructor(key: ByteArray, resetOnDoFinal: Boolean) {
189-
require(key.isNotEmpty()) { "key cannot be empty" }
192+
if (key.isEmpty()) throw InvalidKeyException("key cannot be empty")
190193
this.resetOnDoFinal = resetOnDoFinal
191194
}
192195

@@ -239,10 +242,10 @@ public actual abstract class Mac: javax.crypto.Mac, Algorithm, Copyable<Mac>, Re
239242
* before passing it here. Implementations should ensure any old key material
240243
* is zeroed out.
241244
*
242-
* @throws [IllegalArgumentException] if [newKey] is a length inappropriate
243-
* for the [Mac] implementation.
245+
* @throws [InvalidKeyException] if [newKey] is a length inappropriate
246+
* for the [Engine] implementation.
244247
* */
245-
@Throws(IllegalArgumentException::class)
248+
@Throws(InvalidKeyException::class)
246249
public actual abstract fun reset(newKey: ByteArray)
247250

248251
// Gets set in engineDoFinal if resetOnDoFinal is set to false. Subsequent

0 commit comments

Comments
 (0)