-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support CWT proof signer from niscy-eudiw/eudi-lib-jvm-openid4vci-kt@d…
- Loading branch information
1 parent
e33537b
commit c8bb7ca
Showing
16 changed files
with
532 additions
and
269 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 0 additions & 38 deletions
38
wallet-core/src/androidTest/java/eu/europa/ec/eudi/wallet/ExampleInstrumentedTest.kt
This file was deleted.
Oops, something went wrong.
123 changes: 123 additions & 0 deletions
123
.../androidTest/java/eu/europa/ec/eudi/wallet/document/issue/opeid4vci/CWTProofSignerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* Copyright (c) 2024 European Commission | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package eu.europa.ec.eudi.wallet.document.issue.opeid4vci | ||
|
||
import android.app.KeyguardManager | ||
import android.content.Context | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import eu.europa.ec.eudi.openid4vci.* | ||
import eu.europa.ec.eudi.wallet.document.Constants.EU_PID_DOCTYPE | ||
import eu.europa.ec.eudi.wallet.document.CreateIssuanceRequestResult | ||
import eu.europa.ec.eudi.wallet.document.DocumentManager | ||
import eu.europa.ec.eudi.wallet.issue.openid4vci.CWTProofSigner | ||
import eu.europa.ec.eudi.wallet.issue.openid4vci.ProofSigner | ||
import eu.europa.ec.eudi.wallet.issue.openid4vci.UserAuthRequiredException | ||
import org.bouncycastle.jce.provider.BouncyCastleProvider | ||
import org.junit.Assert | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertTrue | ||
import org.junit.Assume.assumeTrue | ||
import org.junit.BeforeClass | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import java.io.IOException | ||
import java.security.Security | ||
import java.security.Signature | ||
import java.util.* | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class CWTProofSignerTest { | ||
|
||
companion object { | ||
private lateinit var context: Context | ||
val BC = BouncyCastleProvider() | ||
|
||
@JvmStatic | ||
@BeforeClass | ||
@Throws(IOException::class) | ||
fun setUp() { | ||
Security.insertProviderAt(BC, 1) | ||
context = InstrumentationRegistry.getInstrumentation().targetContext | ||
} | ||
} | ||
|
||
@Test | ||
fun test_userAuthRequired_is_set_to_Yes_when_needed() { | ||
assumeTrue( | ||
"Device is not secure. So cannot run this test", | ||
context.getSystemService(KeyguardManager::class.java).isDeviceSecure | ||
) | ||
val documentManager = DocumentManager.Builder(context) | ||
.enableUserAuth(true) | ||
.build() | ||
|
||
|
||
val issuanceRequestResult = documentManager.createIssuanceRequest(EU_PID_DOCTYPE, false) | ||
assertTrue(issuanceRequestResult is CreateIssuanceRequestResult.Success) | ||
|
||
val issuanceRequest = | ||
(issuanceRequestResult as CreateIssuanceRequestResult.Success).issuanceRequest | ||
|
||
val proofSigner = CWTProofSigner(issuanceRequest, CoseAlgorithm.ES256, CoseCurve.P_256) | ||
assertEquals(CoseAlgorithm.ES256, proofSigner.popSigner.algorithm) | ||
assertEquals(CoseCurve.P_256, proofSigner.popSigner.curve) | ||
|
||
assertTrue(proofSigner.popSigner.bindingKey is CwtBindingKey.CoseKey) | ||
|
||
val payload = "some random bytes".toByteArray() | ||
try { | ||
proofSigner.sign(payload) | ||
Assert.fail("Expected UserAuthRequiredException") | ||
} catch (e: UserAuthRequiredException) { | ||
assertTrue(proofSigner.userAuthStatus is ProofSigner.UserAuthStatus.Required) | ||
} finally { | ||
documentManager.deleteDocumentById(issuanceRequest.documentId) | ||
} | ||
} | ||
|
||
@Test | ||
fun test_sign_method_creates_a_valid_signature() { | ||
val documentManager = DocumentManager.Builder(context) | ||
.enableUserAuth(false) | ||
.build() | ||
|
||
|
||
val issuanceRequestResult = documentManager.createIssuanceRequest(EU_PID_DOCTYPE, false) | ||
assertTrue(issuanceRequestResult is CreateIssuanceRequestResult.Success) | ||
|
||
val issuanceRequest = | ||
(issuanceRequestResult as CreateIssuanceRequestResult.Success).issuanceRequest | ||
|
||
val proofSigner = CWTProofSigner(issuanceRequest, CoseAlgorithm.ES256, CoseCurve.P_256) | ||
assertEquals(CoseAlgorithm.ES256, proofSigner.popSigner.algorithm) | ||
assertEquals(CoseCurve.P_256, proofSigner.popSigner.curve) | ||
|
||
assertTrue(proofSigner.popSigner.bindingKey is CwtBindingKey.CoseKey) | ||
|
||
val payload = "some random bytes".toByteArray() | ||
val proofSignature = proofSigner.sign(payload) | ||
val publicKey = (proofSigner.popSigner.bindingKey as CwtBindingKey.CoseKey).jwk.toECKey().toPublicKey() | ||
|
||
val result = Signature.getInstance("SHA256withECDSA", BC).apply { | ||
initVerify(publicKey) | ||
update(payload) | ||
}.verify(proofSignature) | ||
assertTrue(result) | ||
documentManager.deleteDocumentById(issuanceRequest.documentId) | ||
} | ||
} |
95 changes: 0 additions & 95 deletions
95
.../src/androidTest/java/eu/europa/ec/eudi/wallet/document/issue/opeid4vci/DPopSignerTest.kt
This file was deleted.
Oops, something went wrong.
82 changes: 82 additions & 0 deletions
82
...c/androidTest/java/eu/europa/ec/eudi/wallet/document/issue/opeid4vci/JWSDPoPSignerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2024 European Commission | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package eu.europa.ec.eudi.wallet.document.issue.opeid4vci | ||
|
||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.nimbusds.jose.JOSEException | ||
import com.nimbusds.jose.JWSAlgorithm | ||
import com.nimbusds.jose.JWSHeader | ||
import com.nimbusds.jose.crypto.ECDSAVerifier | ||
import eu.europa.ec.eudi.openid4vci.JwtBindingKey | ||
import eu.europa.ec.eudi.openid4vci.PopSigner | ||
import eu.europa.ec.eudi.wallet.issue.openid4vci.JWSDPoPSigner | ||
import org.junit.Assert | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class JWSDPoPSignerTest { | ||
|
||
@Test | ||
fun factoryInvokeCreatesDPoPSigner() { | ||
val signer = JWSDPoPSigner().getOrNull() | ||
Assert.assertTrue(signer is PopSigner.Jwt) | ||
} | ||
|
||
@Test | ||
fun signerSupportedJWSAlgorithmsIsES256() { | ||
val signer = JWSDPoPSigner().getOrThrow() | ||
Assert.assertEquals(JWSAlgorithm.ES256, signer.algorithm) | ||
Assert.assertEquals(1, signer.jwsSigner.supportedJWSAlgorithms().size) | ||
Assert.assertEquals(JWSAlgorithm.ES256, signer.jwsSigner.supportedJWSAlgorithms().first()) | ||
} | ||
|
||
@Test | ||
fun bindingKeyIsJwtBindingKey_Jwk() { | ||
val signer = JWSDPoPSigner().getOrThrow() | ||
Assert.assertTrue(signer.bindingKey is JwtBindingKey.Jwk) | ||
} | ||
|
||
@Test(expected = JOSEException::class) | ||
fun signThrowsWhenUnsupportedAlgorithmInHeader() { | ||
val signer = JWSDPoPSigner().getOrThrow() | ||
val header = JWSHeader(JWSAlgorithm.ES384) | ||
val signingInput = "test".toByteArray() | ||
signer.jwsSigner.sign(header, signingInput) | ||
} | ||
|
||
@Test | ||
fun signReturnsValidSignature() { | ||
val signer = JWSDPoPSigner().getOrThrow() | ||
val header = JWSHeader(JWSAlgorithm.ES256) | ||
val signingInput = "test".toByteArray() | ||
val signature = signer.jwsSigner.sign(header, signingInput) | ||
val jwk = (signer.bindingKey as JwtBindingKey.Jwk).jwk | ||
val verifier = ECDSAVerifier(jwk.toECKey()) | ||
val result = verifier.verify(header, signingInput, signature) | ||
Assert.assertTrue(result) | ||
} | ||
|
||
@Test | ||
fun instantiatingDPoPSignerUsesDifferentKeyPair() { | ||
val firstSigner = JWSDPoPSigner().getOrThrow() | ||
val firstJwk = (firstSigner.bindingKey as JwtBindingKey.Jwk).jwk | ||
val secondSigner = JWSDPoPSigner().getOrThrow() | ||
val secondJwk = (secondSigner.bindingKey as JwtBindingKey.Jwk).jwk | ||
Assert.assertNotEquals(firstJwk, secondJwk) | ||
} | ||
} |
Oops, something went wrong.