16
16
package org.kotlincrypto.core
17
17
18
18
import kotlin.test.Test
19
+ import kotlin.test.assertEquals
19
20
import kotlin.test.assertNotEquals
20
21
import kotlin.test.fail
21
22
@@ -25,30 +26,48 @@ class MacUnitTest {
25
26
@OptIn(InternalKotlinCryptoApi ::class )
26
27
private class TestMac : Mac {
27
28
28
- constructor (key: ByteArray , algorithm: String ): super (algorithm, TestEngine (key))
29
+ constructor (
30
+ key: ByteArray ,
31
+ algorithm: String ,
32
+ reset: () -> Unit = {},
33
+ doFinal: () -> ByteArray = { ByteArray (0 ) },
34
+ ): super (algorithm, TestEngine (key, reset, doFinal))
35
+
29
36
private constructor (algorithm: String , engine: TestEngine ): super (algorithm, engine)
30
37
31
38
override fun copy (engineCopy : Engine ): Mac = TestMac (algorithm(), engineCopy as TestEngine )
32
39
33
40
private class TestEngine : Engine {
34
41
35
- constructor (key: ByteArray ): super (key)
36
- private constructor (state: State ): super (state)
42
+ private val reset: () -> Unit
43
+ private val doFinal: () -> ByteArray
44
+
45
+ constructor (
46
+ key: ByteArray ,
47
+ reset: () -> Unit ,
48
+ doFinal: () -> ByteArray ,
49
+ ): super (key) {
50
+ this .reset = reset
51
+ this .doFinal = doFinal
52
+ }
53
+
54
+ private constructor (state: State , engine: TestEngine ): super (state) {
55
+ this .reset = engine.reset
56
+ this .doFinal = engine.doFinal
57
+ }
37
58
38
59
// To ensure that Java implementation initializes javax.crypto.Mac
39
60
// on instantiation so that it does not throw IllegalStateException
40
61
// whenever updating.
41
62
override fun update (input : Byte ) { throw ConcurrentModificationException () }
42
63
43
- override fun reset () {}
64
+ override fun reset () { reset.invoke() }
44
65
override fun update (input : ByteArray ) {}
45
66
override fun update (input : ByteArray , offset : Int , len : Int ) {}
46
67
override fun macLength (): Int = 0
47
- override fun doFinal (): ByteArray = ByteArray (0 )
48
-
49
- override fun copy (): Engine = TestEngine (TestState ())
68
+ override fun doFinal (): ByteArray = doFinal.invoke()
50
69
51
- private inner class TestState : Engine . State ()
70
+ override fun copy () : Engine = TestEngine ( object : State () {}, this )
52
71
}
53
72
}
54
73
@@ -89,4 +108,26 @@ class MacUnitTest {
89
108
90
109
assertNotEquals(mac, copy)
91
110
}
111
+
112
+ @Test
113
+ fun givenMac_whenDoFinal_thenEngineResetIsCalled () {
114
+ var resetCount = 0
115
+ var doFinalCount = 0
116
+ val finalExpected = ByteArray (20 )
117
+
118
+ val mac = TestMac (
119
+ ByteArray (5 ),
120
+ " not blank" ,
121
+ reset = { resetCount++ },
122
+ doFinal = { doFinalCount++ ; finalExpected },
123
+ )
124
+ mac.update(ByteArray (20 ))
125
+ assertEquals(finalExpected, mac.doFinal())
126
+ assertEquals(1 , doFinalCount)
127
+ assertEquals(1 , resetCount)
128
+
129
+ assertEquals(finalExpected, mac.doFinal(ByteArray (20 )))
130
+ assertEquals(2 , doFinalCount)
131
+ assertEquals(2 , resetCount)
132
+ }
92
133
}
0 commit comments