Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 17 additions & 18 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@
buildscript {

ext {
kotlin_version = "1.3.70"
kotlin_serialization_version = "0.20.0"
coroutines_version = "1.3.5"
kotlin_version = "1.5.20"
kotlin_serialization_version = "1.2.1"
coroutines_version = "1.5.0"

junit_version = "4.12"
mockk_version = "1.9.3"
assertk_version = "0.22"
detekt_version = "1.6.0"
jacoco_version = "0.8.4"

bivrost_version = "v0.7.1"
kethereum_version = "0.81.4"
khex_version = "1.0.0-RC6"
khash_version = "1.0.0-RC5"
kbase58_version = "0.1"
mockk_version = "1.11.0"
assertk_version = "0.24"
detekt_version = "1.17.1"
jacoco_version = "0.8.7"

bivrost_version = "v0.8.1"
spongycastle_version = "1.58.0.0"
uport_kotlin_common_version = "0.4.3"
kethereum_version = "0.83.4"
khex_version = "1.0.0"
khash_version = "1.0.0-RC5"
kbase58_version = "0.2"
uport_kotlin_common_version = "0.4.4"

current_release_version = "0.4.0"
}

repositories {
google()
jcenter()
mavenCentral()
gradlePluginPortal()
maven { url "https://jitpack.io" }
maven { url "https://kotlin.bintray.com/kotlinx" }
}

dependencies {
Expand Down Expand Up @@ -78,9 +78,8 @@ allprojects {

repositories {
google()
jcenter()
mavenCentral()
maven { url "https://jitpack.io" }
maven { url "https://kotlin.bintray.com/kotlinx" }
// mavenLocal()
}

Expand Down
3 changes: 2 additions & 1 deletion ethr-did/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ project.ext.description = "DID resolver for the ethr-did (ERC 1056) lightweight
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlin_serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialization_version"

api "com.github.gnosis.bivrost-kotlin:bivrost-solidity-types:$bivrost_version"

Expand Down
10 changes: 6 additions & 4 deletions ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDDocument.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package me.uport.sdk.ethrdid
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import me.uport.sdk.universaldid.AuthenticationEntry
import me.uport.sdk.universaldid.DIDDocument
import me.uport.sdk.universaldid.PublicKeyEntry
Expand Down Expand Up @@ -35,7 +34,7 @@ data class EthrDIDDocument(
/**
* serialize this [EthrDIDDocument] to a JSON string
*/
fun toJson() = jsonParser.stringify(serializer(), this)
fun toJson() = jsonParser.encodeToString(serializer(), this)

companion object {
/**
Expand All @@ -46,10 +45,13 @@ data class EthrDIDDocument(
/**
* Parse a json serialized [EthrDIDDocument] into an object
*/
fun fromJson(json: String) = jsonParser.parse(serializer(), json)
fun fromJson(json: String) = jsonParser.decodeFromString(serializer(), json)

private val jsonParser =
Json(JsonConfiguration.Stable.copy(isLenient = true, ignoreUnknownKeys = true))
Json {
isLenient = true
ignoreUnknownKeys = true
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ class EthrDIDResolverTest {

validDids.forEach {
val normalizedDid = EthrDIDResolver.normalizeDid(it)
assertThat(normalizedDid.toLowerCase()).isEqualTo("did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a")
assertThat(normalizedDid.lowercase()).isEqualTo("did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a")
}

invalidDids.forEach {
Expand Down Expand Up @@ -509,7 +509,7 @@ class EthrDIDResolverTest {
"did:ethr:0x04:0xB9C5714089478a327F09197987f16f9E5d936E8a#owner"
)
validNetworkedDIDs.forEach {
val normalizedDid = EthrDIDResolver.normalizeDid(it).toLowerCase()
val normalizedDid = EthrDIDResolver.normalizeDid(it).lowercase()
println("normalizing `$it` got `$normalizedDid`")
assertThat(normalizedDid).isNotEmpty()
assertThat(normalizedDid).doesNotContain("#owner")
Expand All @@ -536,7 +536,7 @@ class EthrDIDResolverTest {
"did:ethr:0x04:0xB9C5714089478a327F09197987f16f9E5d936E8a#owner"
)
validNetworkedDIDs.forEach {
val address = EthrDIDResolver.extractAddress(it).toLowerCase()
val address = EthrDIDResolver.extractAddress(it).lowercase()
println("extracting address from `$it` got `$address`")
assertThat(address).isEqualTo("0xb9c5714089478a327f09197987f16f9e5d936e8a")
}
Expand All @@ -562,7 +562,7 @@ class EthrDIDResolverTest {
"did:ethr:0x04:0xB9C5714089478a327F09197987f16f9E5d936E8a#owner" to "0x04"
)
validNetworkedDIDs.forEach { (did, expectedNetwork) ->
val extractedNetwork = EthrDIDResolver.extractNetwork(did).toLowerCase()
val extractedNetwork = EthrDIDResolver.extractNetwork(did).lowercase()
println("extracting network from `$did` got `$extractedNetwork`")
assertThat(extractedNetwork).isEqualTo(expectedNetwork)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class EthrStatusResolver : StatusResolver {
result.hexToBigInteger()
}
.filter { it != BigInteger.ZERO }
.min()
.minOrNull()
?: BigInteger.ZERO

return EthrStatus(minRevocationBlock)
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
2 changes: 1 addition & 1 deletion jwt-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ project.ext.description = "tools to enable testing of the did-jwt library"

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialization_version"

implementation project(":ethr-did")
api "com.github.uport-project.kotlin-common:test-helpers:$uport_kotlin_common_version"
Expand Down
2 changes: 1 addition & 1 deletion jwt/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ project.ext.description = "tools for creating and verifying JWTs that use uPort
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialization_version"

api "com.github.komputing.khex:extensions:$khex_version"
api "com.github.komputing.kethereum:extensions_kotlin:$kethereum_version"
Expand Down
35 changes: 13 additions & 22 deletions jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,15 @@
package me.uport.sdk.jwt

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.JsonException
import me.uport.sdk.core.EthNetwork
import me.uport.sdk.core.ITimeProvider
import me.uport.sdk.core.SystemTimeProvider
import me.uport.sdk.core.clean0xPrefix
import me.uport.sdk.core.decodeBase64
import me.uport.sdk.core.hexToByteArray
import me.uport.sdk.core.toBase64UrlSafe
import me.uport.sdk.core.*
import me.uport.sdk.jwt.JWTUtils.normalizeKnownDID
import me.uport.sdk.jwt.JWTUtils.splitToken
import me.uport.sdk.jwt.model.ArbitraryMapSerializer
import me.uport.sdk.jwt.model.JwtHeader
import me.uport.sdk.jwt.model.JwtHeader.Companion.ES256K
import me.uport.sdk.jwt.model.JwtHeader.Companion.ES256K_R
import me.uport.sdk.jwt.model.JwtPayload
import me.uport.sdk.signer.SIG_RECOVERABLE_SIZE
import me.uport.sdk.signer.Signer
import me.uport.sdk.signer.decodeJose
import me.uport.sdk.signer.normalize
import me.uport.sdk.signer.utf8
import me.uport.sdk.signer.*
import me.uport.sdk.universaldid.DIDDocument
import me.uport.sdk.universaldid.DIDResolver
import me.uport.sdk.universaldid.PublicKeyEntry
Expand Down Expand Up @@ -134,8 +122,8 @@ class JWTTools(
mutablePayload["iss"] = issuerDID
}

val serializedPayload = Json(JsonConfiguration.Stable)
.stringify(ArbitraryMapSerializer, mutablePayload)
val serializedPayload = Json
.encodeToString(ArbitraryMapSerializer, mutablePayload)

@Suppress("SimplifiableCallChain", "ConvertCallChainIntoSequence")
val signingInput = listOf(header.toJson(), serializedPayload)
Expand Down Expand Up @@ -170,7 +158,7 @@ class JWTTools(
val header = JwtHeader.fromJson(headerString)
val payload = JwtPayload.fromJson(payloadString)
return Triple(header, payload, signatureBytes)
} catch (ex: JsonException) {
} catch (ex: Exception) {
throw JWTEncodingException("cannot parse the JWT($token)", ex)
}
}
Expand All @@ -196,10 +184,10 @@ class JWTTools(
//Parse Json
val header = JwtHeader.fromJson(headerString)

val payload = jsonParser.parse(ArbitraryMapSerializer, payloadString)
val payload = jsonParser.decodeFromString(ArbitraryMapSerializer, payloadString)

return Triple(header, payload, signatureBytes)
} catch (ex: JsonException) {
} catch (ex: Exception) {
throw JWTEncodingException("cannot parse the JWT($token)", ex)
}
}
Expand Down Expand Up @@ -283,7 +271,10 @@ class JWTTools(
}

private val jsonParser =
Json(JsonConfiguration.Stable.copy(isLenient = true, ignoreUnknownKeys = true))
Json {
isLenient = true
ignoreUnknownKeys = true
}

/**
* maps known algorithms to the corresponding verification method
Expand Down Expand Up @@ -353,7 +344,7 @@ class JWTTools(
}
}.map { pubKey ->
val pubKeyNoPrefix = PublicKey(pubKey).normalize()
pubKeyNoPrefix.toAddress().cleanHex.toLowerCase()
pubKeyNoPrefix.toAddress().cleanHex.lowercase()
}

val matches = publicKeys.map { pubKeyEntry ->
Expand All @@ -367,7 +358,7 @@ class JWTTools(
(pubKeyEntry.ethereumAddress?.clean0xPrefix() ?: pubKey.toAddress().cleanHex)

}.filter { ethereumAddress ->
ethereumAddress.toLowerCase() in recoveredAddresses
ethereumAddress.lowercase() in recoveredAddresses
}

return matches.isNotEmpty()
Expand Down
45 changes: 18 additions & 27 deletions jwt/src/main/java/me/uport/sdk/jwt/model/ArbitraryMapSerializer.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package me.uport.sdk.jwt.model

import kotlinx.serialization.Decoder
import kotlinx.serialization.Encoder
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.PolymorphicKind
import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.encode
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonLiteral
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonObjectSerializer
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.modules.getContextualOrDefault
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import kotlinx.serialization.json.Json.Default.encodeToJsonElement
import kotlin.reflect.typeOf

/**
* This handles serialization and deserialization of arbitrary JSON trees represented as
Expand All @@ -33,12 +24,10 @@ object ArbitraryMapSerializer : KSerializer<Map<String, Any?>> {
////////////////////////
// converting to Json //
////////////////////////
@ImplicitReflectionSerializer
private fun Map<*, *>.toJsonObject(): JsonObject = JsonObject(map {
it.key.toString() to it.value.toJsonElement()
}.toMap())

@ImplicitReflectionSerializer
private fun Any?.toJsonElement(): JsonElement = when (this) {
null -> JsonNull
is Number -> JsonPrimitive(this)
Expand All @@ -49,25 +38,24 @@ object ArbitraryMapSerializer : KSerializer<Map<String, Any?>> {
is Array<*> -> JsonArray(this.map { it.toJsonElement() })
else -> {
//supporting classes that declare serializers
val jsonParser = Json(JsonConfiguration.Stable)
val serializer = jsonParser.context.getContextualOrDefault(this)
jsonParser.toJson(serializer, this)
val jsonParser = Json
jsonParser.encodeToJsonElement(this)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I am missing a serializer here. Any ideas what is required? @mirceanis

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really :(
I am not familiar with the latest kotlinx.serialization requirements, unfortunately.

}
}

//////////////////////////////////////////////////
// converting back to primitives (no type info) //
//////////////////////////////////////////////////
private fun JsonObject.toPrimitiveMap(): Map<String, Any?> =
this.content.map {
this.map {
it.key to it.value.toPrimitive()
}.toMap()

private fun JsonElement.toPrimitive(): Any? = when (this) {
is JsonNull -> null
is JsonObject -> this.toPrimitiveMap()
is JsonArray -> this.map { it.toPrimitive() }
is JsonLiteral -> {
is JsonPrimitive -> {
if (isString) {
contentOrNull
} else {
Expand All @@ -78,16 +66,19 @@ object ArbitraryMapSerializer : KSerializer<Map<String, Any?>> {
}

override fun deserialize(decoder: Decoder): Map<String, Any?> {
val asJsonObject: JsonObject = decoder.decodeSerializableValue(JsonObjectSerializer)
assert(decoder is JsonDecoder) {"Only JsonDecoder supported, found " + decoder::class.java}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this safe to assert?

val asJsonObject: JsonObject = (decoder as JsonDecoder).decodeJsonElement().jsonObject
return asJsonObject.toPrimitiveMap()
}

@ExperimentalSerializationApi
override val descriptor: SerialDescriptor
get() = SerialDescriptor("arbitrary map", PolymorphicKind.OPEN)
get() = mapSerialDescriptor(PrimitiveSerialDescriptor("key", PrimitiveKind.STRING),
PrimitiveSerialDescriptor("value", PrimitiveKind.STRING))

@ImplicitReflectionSerializer
override fun serialize(encoder: Encoder, value: Map<String, Any?>) {
assert(encoder is JsonEncoder) {"Only JsonEncoder support, found " + encoder::class.java}
val asJsonObj: JsonObject = value.toJsonObject()
encoder.encode(JsonObjectSerializer, asJsonObj)
(encoder as JsonEncoder).encodeJsonElement(asJsonObj)
}
}
7 changes: 3 additions & 4 deletions jwt/src/main/java/me/uport/sdk/jwt/model/JwtHeader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package me.uport.sdk.jwt.model

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration

/**
* Standard JWT header
Expand All @@ -14,16 +13,16 @@ class JwtHeader(
val alg: String = ES256K
) {

fun toJson(): String = jsonAdapter.stringify(serializer(), this)
fun toJson(): String = jsonAdapter.encodeToString(serializer(), this)

companion object {
const val ES256K = "ES256K"
const val ES256K_R = "ES256K-R"

fun fromJson(headerString: String): JwtHeader =
jsonAdapter.parse(serializer(), headerString)
jsonAdapter.decodeFromString(serializer(), headerString)

private val jsonAdapter =
Json(JsonConfiguration.Stable.copy(isLenient = true, ignoreUnknownKeys = true))
Json { isLenient = true; ignoreUnknownKeys = true; }
}
}
Loading