mock provider instead of constructor parameter
This commit is contained in:
parent
2f9c88594b
commit
3d93e4d84d
5 changed files with 60 additions and 21 deletions
|
@ -1,39 +1,36 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair
|
||||
|
||||
import com.google.crypto.tink.subtle.X25519
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.MessageIOException
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
|
||||
import info.nightscout.androidaps.utils.extensions.toHex
|
||||
import org.spongycastle.crypto.engines.AESEngine
|
||||
import org.spongycastle.crypto.macs.CMac
|
||||
import org.spongycastle.crypto.params.KeyParameter
|
||||
import java.security.SecureRandom
|
||||
import org.spongycastle.util.encoders.Hex
|
||||
|
||||
class KeyExchange(
|
||||
private val aapsLogger: AAPSLogger,
|
||||
var pdmPrivate: ByteArray = X25519.generatePrivateKey(),
|
||||
val pdmNonce: ByteArray = ByteArray(NONCE_SIZE)
|
||||
) {
|
||||
val pdmPublic = X25519.publicFromPrivate(pdmPrivate)
|
||||
private val x25519: X25519KeyGenerator,
|
||||
private val randomByteGenerator: RandomByteGenerator
|
||||
){
|
||||
|
||||
val pdmNonce: ByteArray = randomByteGenerator.nextBytes(NONCE_SIZE)
|
||||
val pdmPrivate: ByteArray = x25519.generatePrivateKey()
|
||||
val pdmPublic = x25519.publicFromPrivate(pdmPrivate)
|
||||
|
||||
var podPublic = ByteArray(PUBLIC_KEY_SIZE)
|
||||
var podNonce = ByteArray(NONCE_SIZE)
|
||||
private set
|
||||
var podNonce : ByteArray = ByteArray(NONCE_SIZE)
|
||||
|
||||
val podConf = ByteArray(CMAC_SIZE)
|
||||
val pdmConf = ByteArray(CMAC_SIZE)
|
||||
|
||||
var ltk = ByteArray(CMAC_SIZE)
|
||||
|
||||
init {
|
||||
if (pdmNonce.all { it == 0.toByte() }) {
|
||||
// pdmNonce is in the constructor for tests
|
||||
val random = SecureRandom()
|
||||
random.nextBytes(pdmNonce)
|
||||
}
|
||||
}
|
||||
|
||||
fun updatePodPublicData(payload: ByteArray) {
|
||||
if (payload.size != PUBLIC_KEY_SIZE + NONCE_SIZE) {
|
||||
throw MessageIOException("Invalid payload size")
|
||||
|
@ -54,7 +51,7 @@ class KeyExchange(
|
|||
}
|
||||
|
||||
private fun generateKeys() {
|
||||
val curveLTK = X25519.computeSharedSecret(pdmPrivate, podPublic)
|
||||
val curveLTK = x25519.computeSharedSecret(pdmPrivate, podPublic)
|
||||
|
||||
val firstKey = podPublic.copyOfRange(podPublic.size - 4, podPublic.size) +
|
||||
pdmPublic.copyOfRange(pdmPublic.size - 4, pdmPublic.size) +
|
||||
|
|
|
@ -8,6 +8,8 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
|
||||
import info.nightscout.androidaps.utils.extensions.hexStringToByteArray
|
||||
import info.nightscout.androidaps.utils.extensions.toHex
|
||||
|
||||
|
@ -19,7 +21,7 @@ internal class LTKExchanger(
|
|||
val podAddress: Id
|
||||
) {
|
||||
|
||||
private val keyExchange = KeyExchange(aapsLogger)
|
||||
private val keyExchange = KeyExchange(aapsLogger, X25519KeyGenerator(), RandomByteGenerator())
|
||||
private var seq: Byte = 1
|
||||
|
||||
fun negotiateLTK(): PairResult {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util
|
||||
|
||||
import java.security.SecureRandom
|
||||
|
||||
open class RandomByteGenerator {
|
||||
private val secureRandom = SecureRandom()
|
||||
|
||||
open fun nextBytes(length: Int): ByteArray = ByteArray(length).also(secureRandom::nextBytes)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util
|
||||
|
||||
import com.google.crypto.tink.subtle.X25519
|
||||
|
||||
open class X25519KeyGenerator {
|
||||
|
||||
open fun generatePrivateKey(): ByteArray = X25519.generatePrivateKey()
|
||||
fun publicFromPrivate(privateKey: ByteArray): ByteArray = X25519.publicFromPrivate(privateKey)
|
||||
fun computeSharedSecret(privateKey: ByteArray, publicKey: ByteArray): ByteArray =
|
||||
X25519.computeSharedSecret(privateKey, publicKey)
|
||||
}
|
|
@ -1,18 +1,38 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLoggerTest
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
|
||||
import info.nightscout.androidaps.utils.extensions.toHex
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.spy
|
||||
import org.spongycastle.util.encoders.Hex
|
||||
|
||||
class KeyExchangeTest {
|
||||
|
||||
val keyGenerator = X25519KeyGenerator()
|
||||
val keyGeneratorSpy = spy(keyGenerator)
|
||||
|
||||
var randomByteGenerator: RandomByteGenerator = mock(RandomByteGenerator::class.java)
|
||||
|
||||
@Test fun testLTK() {
|
||||
val aapsLogger = AAPSLoggerTest()
|
||||
|
||||
Mockito.doReturn(Hex.decode("27ec94b71a201c5e92698d668806ae5ba00594c307cf5566e60c1fc53a6f6bb6"))
|
||||
.`when`(keyGeneratorSpy).generatePrivateKey()
|
||||
|
||||
val pdmNonce = Hex.decode("edfdacb242c7f4e1d2bc4d93ca3c5706")
|
||||
|
||||
Mockito.`when`(randomByteGenerator.nextBytes(anyInt())).thenReturn(pdmNonce)
|
||||
|
||||
val ke = KeyExchange(
|
||||
aapsLogger,
|
||||
pdmPrivate = Hex.decode("27ec94b71a201c5e92698d668806ae5ba00594c307cf5566e60c1fc53a6f6bb6"),
|
||||
pdmNonce = Hex.decode("edfdacb242c7f4e1d2bc4d93ca3c5706")
|
||||
keyGeneratorSpy,
|
||||
randomByteGenerator
|
||||
)
|
||||
val podPublicKey = Hex.decode("2fe57da347cd62431528daac5fbb290730fff684afc4cfc2ed90995f58cb3b74")
|
||||
val podNonce = Hex.decode("00000000000000000000000000000000")
|
||||
|
@ -22,4 +42,4 @@ class KeyExchangeTest {
|
|||
ke.validatePodConf(Hex.decode("af4f10db5f96e5d9cd6cfc1f54f4a92f"))
|
||||
assertEquals(ke.ltk.toHex(), "341e16d13f1cbf73b19d1c2964fee02b")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue