Skip to content

Commit ee47a56

Browse files
authored
Merge pull request #1867 from walt-id/fix/replace-base64
refactor: use crypto base64 utils in openid4vci
2 parents 90ef684 + 2a24fe4 commit ee47a56

7 files changed

Lines changed: 24 additions & 24 deletions

File tree

waltid-libraries/protocols/waltid-openid4vci-wallet/src/commonTest/kotlin/id/waltid/openid4vci/wallet/attestation/ClientAttestationAssemblerTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package id.waltid.openid4vci.wallet.attestation
33
import id.walt.crypto.keys.Key
44
import id.walt.crypto.keys.KeyMeta
55
import id.walt.crypto.keys.KeyType
6+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
67
import kotlinx.coroutines.test.runTest
78
import kotlinx.serialization.json.JsonElement
89
import kotlinx.serialization.json.JsonObject
9-
import kotlin.io.encoding.Base64
1010
import kotlin.test.Test
1111
import kotlin.test.assertEquals
1212

@@ -28,8 +28,8 @@ private class AssemblerTestP256Key : Key() {
2828

2929
override suspend fun signJws(plaintext: ByteArray, headers: Map<String, JsonElement>): String {
3030
val headerJson = JsonObject(headers).toString()
31-
val headerB64 = Base64.UrlSafe.encode(headerJson.encodeToByteArray()).trimEnd('=')
32-
val payloadB64 = Base64.UrlSafe.encode(plaintext).trimEnd('=')
31+
val headerB64 = headerJson.encodeToByteArray().encodeToBase64Url()
32+
val payloadB64 = plaintext.encodeToBase64Url()
3333
return "$headerB64.$payloadB64.mock-sig"
3434
}
3535
}

waltid-libraries/protocols/waltid-openid4vci-wallet/src/commonTest/kotlin/id/waltid/openid4vci/wallet/attestation/WalletAttestationPopBuilderTest.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ package id.waltid.openid4vci.wallet.attestation
33
import id.walt.crypto.keys.Key
44
import id.walt.crypto.keys.KeyMeta
55
import id.walt.crypto.keys.KeyType
6+
import id.walt.crypto.utils.Base64Utils.decodeFromBase64Url
7+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
68
import kotlinx.coroutines.test.runTest
79
import kotlinx.serialization.json.Json
810
import kotlinx.serialization.json.JsonElement
911
import kotlinx.serialization.json.JsonObject
1012
import kotlinx.serialization.json.jsonObject
1113
import kotlinx.serialization.json.jsonPrimitive
12-
import kotlin.io.encoding.Base64
1314
import kotlin.test.Test
1415
import kotlin.test.assertEquals
1516
import kotlin.test.assertFailsWith
@@ -34,8 +35,8 @@ private class PopTestP256Key : Key() {
3435

3536
override suspend fun signJws(plaintext: ByteArray, headers: Map<String, JsonElement>): String {
3637
val headerJson = JsonObject(headers).toString()
37-
val headerB64 = Base64.UrlSafe.encode(headerJson.encodeToByteArray()).trimEnd('=')
38-
val payloadB64 = Base64.UrlSafe.encode(plaintext).trimEnd('=')
38+
val headerB64 = headerJson.encodeToByteArray().encodeToBase64Url()
39+
val payloadB64 = plaintext.encodeToBase64Url()
3940
return "$headerB64.$payloadB64.mock-sig"
4041
}
4142
}
@@ -70,16 +71,14 @@ class WalletAttestationPopBuilderTest {
7071
val parts = jwt.split(".")
7172
assertEquals(3, parts.size, "JWT should have 3 parts")
7273

73-
val b64 = Base64.UrlSafe.withPadding(Base64.PaddingOption.ABSENT_OPTIONAL)
74-
7574
val header = Json.parseToJsonElement(
76-
b64.decode(parts[0]).decodeToString()
75+
parts[0].decodeFromBase64Url().decodeToString()
7776
).jsonObject
7877
assertEquals("oauth-client-attestation-pop+jwt", header["typ"]?.jsonPrimitive?.content)
7978
assertEquals("ES256", header["alg"]?.jsonPrimitive?.content)
8079

8180
val payload = Json.parseToJsonElement(
82-
b64.decode(parts[1]).decodeToString()
81+
parts[1].decodeFromBase64Url().decodeToString()
8382
).jsonObject
8483
assertEquals("wallet-client", payload["iss"]?.jsonPrimitive?.content)
8584
assertEquals("https://issuer.example.com/token", payload["aud"]?.jsonPrimitive?.content)

waltid-libraries/protocols/waltid-openid4vci/src/commonMain/kotlin/id/walt/openid4vci/handlers/granttypes/authorizationcode/AuthorizationCodeAuthorizationEndpoint.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
package id.walt.openid4vci.handlers.granttypes.authorizationcode
33

4+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
45
import id.walt.openid4vci.handlers.endpoints.authorization.AuthorizationEndpointHandler
56
import id.walt.openid4vci.DEFAULT_AUTHORIZATION_CODE_LIFETIME_SECONDS
67
import id.walt.openid4vci.Session
@@ -14,7 +15,6 @@ import id.walt.openid4vci.requests.authorization.AuthorizationRequest
1415
import id.walt.openid4vci.responses.authorization.AuthorizationResponse
1516
import id.walt.openid4vci.responses.authorization.AuthorizationResponseResult
1617
import org.kotlincrypto.random.CryptoRand
17-
import kotlin.io.encoding.Base64
1818
import kotlin.time.Duration.Companion.seconds
1919

2020
/**
@@ -115,7 +115,7 @@ class AuthorizationCodeAuthorizationEndpoint(
115115
}
116116

117117
private fun generateCode(): String {
118-
val bytes = ByteArray(33) //prevent padding
119-
return Base64.UrlSafe.encode(CryptoRand.nextBytes(bytes))
118+
val bytes = ByteArray(33)
119+
return CryptoRand.nextBytes(bytes).encodeToBase64Url()
120120
}
121121
}

waltid-libraries/protocols/waltid-openid4vci/src/commonMain/kotlin/id/walt/openid4vci/preauthorized/PreAuthorizedCodeIssuer.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package id.walt.openid4vci.preauthorized
22

3+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
34
import id.walt.openid4vci.Session
45
import id.walt.openid4vci.TokenType
56
import id.walt.openid4vci.offers.TxCode
@@ -8,7 +9,6 @@ import id.walt.openid4vci.repository.preauthorized.DefaultPreAuthorizedCodeRecor
89
import id.walt.openid4vci.repository.preauthorized.PreAuthorizedCodeRepository
910
import org.kotlincrypto.hash.sha2.SHA256
1011
import org.kotlincrypto.random.CryptoRand
11-
import kotlin.io.encoding.Base64
1212
import kotlin.time.Duration.Companion.seconds
1313
import kotlin.time.Instant
1414

@@ -108,7 +108,7 @@ class DefaultPreAuthorizedCodeIssuer(
108108
buildRecord: (String) -> DefaultPreAuthorizedCodeRecord,
109109
): Pair<String, DefaultPreAuthorizedCodeRecord> {
110110
repeat(maxGenerateAttempts) { attempt ->
111-
val code = Base64.UrlSafe.encode(secureRandomBytes(33))
111+
val code = secureRandomBytes(33).encodeToBase64Url()
112112
try {
113113
val record = buildRecord(code)
114114
repository.save(record)
@@ -178,7 +178,7 @@ private fun generateRandomString(alphabet: String, length: Int): String =
178178
}
179179

180180
internal fun hashTxCode(txCode: String): String =
181-
Base64.UrlSafe.encode(SHA256().digest(txCode.encodeToByteArray()))
181+
SHA256().digest(txCode.encodeToByteArray()).encodeToBase64Url()
182182

183183
internal fun secureRandomBytes(size: Int): ByteArray {
184184
val bytes = ByteArray(size)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package id.walt.openid4vci.requests
22

3+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
34
import org.kotlincrypto.random.CryptoRand
4-
import kotlin.io.encoding.Base64
55

66
internal fun generateRequestId(): String {
77
val bytes = ByteArray(16)
88
CryptoRand.nextBytes(bytes)
9-
return Base64.UrlSafe.encode(bytes)
9+
return bytes.encodeToBase64Url()
1010
}

waltid-libraries/protocols/waltid-openid4vci/src/commonMain/kotlin/id/walt/openid4vci/tokens/jwt/refresh/JwtRefreshTokenIssuer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package id.walt.openid4vci.tokens.jwt.refresh
22

3+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
34
import id.walt.openid4vci.tokens.jwt.JwtPayloadClaims
45
import id.walt.openid4vci.tokens.jwt.JwtSigningKeyResolver
56
import id.walt.openid4vci.tokens.jwt.JwtTokenSigner
67
import id.walt.openid4vci.tokens.jwt.compactJwsSignature
78
import id.walt.openid4vci.tokens.refresh.RefreshTokenGenerationRequest
89
import id.walt.openid4vci.tokens.refresh.RefreshTokenIssuer
910
import org.kotlincrypto.random.CryptoRand
10-
import kotlin.io.encoding.Base64
1111

1212
const val KEYCLOAK_REFRESH_TOKEN_TYPE = "Refresh"
1313

@@ -47,7 +47,7 @@ class JwtRefreshTokenIssuer internal constructor(
4747
compactJwsSignature(token, "Refresh token")
4848

4949
private fun generateTokenId(): String =
50-
Base64.UrlSafe.encode(CryptoRand.nextBytes(ByteArray(TOKEN_ID_BYTES)))
50+
CryptoRand.nextBytes(ByteArray(TOKEN_ID_BYTES)).encodeToBase64Url()
5151

5252
private companion object {
5353
const val TOKEN_ID_BYTES = 32

waltid-libraries/protocols/waltid-openid4vci/src/commonTest/kotlin/id/walt/openid4vci/TestConfigFactory.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package id.walt.openid4vci
22

3+
import id.walt.crypto.utils.Base64Utils.decodeFromBase64Url
4+
import id.walt.crypto.utils.Base64Utils.encodeToBase64Url
35
import id.walt.openid4vci.core.OAuth2ProviderConfig
46
import id.walt.openid4vci.preauthorized.DefaultPreAuthorizedCodeIssuer
57
import id.walt.openid4vci.repository.authorization.InMemoryAuthorizationCodeRepository
@@ -23,7 +25,6 @@ import id.walt.openid4vci.validation.DefaultAuthorizationRequestValidator
2325
import id.walt.openid4vci.validation.CredentialRequestValidator
2426
import id.walt.openid4vci.validation.DefaultCredentialRequestValidator
2527
import id.walt.openid4vci.validation.IssuerStateValidator
26-
import kotlin.io.encoding.Base64
2728
import kotlin.random.Random
2829
import kotlin.time.Clock
2930

@@ -79,8 +80,8 @@ internal class TestRefreshTokenIssuer : RefreshTokenIssuer, RefreshTokenVerifier
7980
request.sessionId.orEmpty(),
8081
request.scopes.joinToString(" "),
8182
).joinToString("|")
82-
val encodedPayload = Base64.UrlSafe.encode(payload.encodeToByteArray())
83-
val signature = Base64.UrlSafe.encode(Random.nextBytes(32))
83+
val encodedPayload = payload.encodeToByteArray().encodeToBase64Url()
84+
val signature = Random.nextBytes(32).encodeToBase64Url()
8485
return "test-refresh.$encodedPayload.$signature"
8586
}
8687

@@ -113,7 +114,7 @@ internal class TestRefreshTokenIssuer : RefreshTokenIssuer, RefreshTokenVerifier
113114
private fun decodeClaims(token: String): RefreshTokenClaims {
114115
val parts = token.split('.')
115116
require(parts.size == 3) { "Invalid refresh token" }
116-
val values = Base64.UrlSafe.decode(parts[1]).decodeToString().split('|')
117+
val values = parts[1].decodeFromBase64Url().decodeToString().split('|')
117118
require(values.size == 7) { "Invalid refresh token payload" }
118119
val scopes = values[6].splitToSequence(' ')
119120
.filter { it.isNotBlank() }

0 commit comments

Comments
 (0)