@@ -10,6 +10,7 @@ import io.iohk.atala.prism.didcomm.didpeer.PeerDID
1010import io.iohk.atala.prism.didcomm.didpeer.SERVICE_ACCEPT
1111import io.iohk.atala.prism.didcomm.didpeer.SERVICE_DIDCOMM_MESSAGING
1212import io.iohk.atala.prism.didcomm.didpeer.SERVICE_ENDPOINT
13+ import io.iohk.atala.prism.didcomm.didpeer.SERVICE_ID
1314import io.iohk.atala.prism.didcomm.didpeer.SERVICE_ROUTING_KEYS
1415import io.iohk.atala.prism.didcomm.didpeer.SERVICE_TYPE
1516import io.iohk.atala.prism.didcomm.didpeer.SERVICE_URI
@@ -24,7 +25,10 @@ import io.iohk.atala.prism.didcomm.didpeer.VerificationMethodTypeAuthentication
2425import io.iohk.atala.prism.didcomm.didpeer.VerificationMethodTypePeerDID
2526import kotlinx.serialization.SerializationException
2627import kotlinx.serialization.json.Json
28+ import kotlinx.serialization.json.JsonArray
2729import kotlinx.serialization.json.JsonObject
30+ import kotlinx.serialization.json.buildJsonArray
31+ import kotlinx.serialization.json.buildJsonObject
2832import kotlinx.serialization.json.jsonArray
2933import kotlinx.serialization.json.jsonObject
3034import kotlin.jvm.JvmName
@@ -36,24 +40,21 @@ import kotlin.jvm.JvmName
3640 * @property prefix The character value of the prefix
3741 */
3842internal enum class Numalgo2Prefix (val prefix : Char ) {
39- AUTHENTICATION (' V' ),
40- KEY_AGREEMENT (' E' ),
41- SERVICE (' S' )
43+ AUTHENTICATION (' V' ), KEY_AGREEMENT (' E' ), SERVICE (' S' )
4244}
4345
4446/* *
4547 * Prefix values used for encoding and decoding services.
4648 * Each prefix corresponds to a specific service type.
4749 */
48- private val ServicePrefix =
49- mapOf (
50- SERVICE_TYPE to " t" ,
51- SERVICE_ENDPOINT to " s" ,
52- SERVICE_DIDCOMM_MESSAGING to " dm" ,
53- SERVICE_ROUTING_KEYS to " r" ,
54- SERVICE_ACCEPT to " a" ,
55- SERVICE_URI to " uri"
56- )
50+ private val ServicePrefix = mapOf (
51+ SERVICE_TYPE to " t" ,
52+ SERVICE_ENDPOINT to " s" ,
53+ SERVICE_DIDCOMM_MESSAGING to " dm" ,
54+ SERVICE_ROUTING_KEYS to " r" ,
55+ SERVICE_ACCEPT to " a" ,
56+ SERVICE_URI to " uri"
57+ )
5758
5859/* *
5960 * Encodes a service based on the provided JSON string.
@@ -87,9 +88,11 @@ internal fun encodeService(service: JSON): String {
8788 encodeIndividualService(trimmedService)
8889 }
8990 }
91+
9092 trimmedService.startsWith(" {" ) -> {
9193 encodeIndividualService(trimmedService)
9294 }
95+
9396 else -> throw IllegalArgumentException (" Invalid JSON format" )
9497 }
9598}
@@ -101,16 +104,45 @@ internal fun encodeService(service: JSON): String {
101104 * @return The encoded service string
102105 */
103106fun encodeIndividualService (service : JSON ): String {
104- val serviceToEncode = service.replace(Regex (" [\n\t\\ s]*" ), " " )
105- .replace(SERVICE_TYPE , ServicePrefix .getValue(SERVICE_TYPE ))
106- .replace(SERVICE_ENDPOINT , ServicePrefix .getValue(SERVICE_ENDPOINT ))
107- .replace(SERVICE_DIDCOMM_MESSAGING , ServicePrefix .getValue(SERVICE_DIDCOMM_MESSAGING ))
108- .replace(SERVICE_ROUTING_KEYS , ServicePrefix .getValue(SERVICE_ROUTING_KEYS ))
109- .replace(SERVICE_ACCEPT , ServicePrefix .getValue(SERVICE_ACCEPT ))
107+ val newService = removeIdFromService(service)
108+ val serviceToEncode =
109+ newService.replace(Regex (" [\n\t\\ s]*" ), " " ).replace(SERVICE_TYPE , ServicePrefix .getValue(SERVICE_TYPE ))
110+ .replace(SERVICE_ENDPOINT , ServicePrefix .getValue(SERVICE_ENDPOINT ))
111+ .replace(SERVICE_DIDCOMM_MESSAGING , ServicePrefix .getValue(SERVICE_DIDCOMM_MESSAGING ))
112+ .replace(SERVICE_ROUTING_KEYS , ServicePrefix .getValue(SERVICE_ROUTING_KEYS ))
113+ .replace(SERVICE_ACCEPT , ServicePrefix .getValue(SERVICE_ACCEPT ))
110114 val encodedService = serviceToEncode.encodeToByteArray().base64UrlEncoded
111115 return " .${Numalgo2Prefix .SERVICE .prefix}$encodedService "
112116}
113117
118+ private fun removeIdFromService (service : JSON ): String {
119+ val jsonElement = Json .parseToJsonElement(service)
120+ if (jsonElement is JsonArray ) {
121+ val array = buildJsonArray {
122+ jsonElement.forEach { element ->
123+ add(buildJsonObject {
124+ element.jsonObject.forEach { (key, value) ->
125+ if (key != SERVICE_ID ) {
126+ put(key, value)
127+ }
128+
129+ }
130+ })
131+ }
132+ }
133+ return array.toString()
134+ } else {
135+ val newElement = buildJsonObject {
136+ jsonElement.jsonObject.forEach { (key, value) ->
137+ if (key != SERVICE_ID ) {
138+ put(key, value)
139+ }
140+ }
141+ }
142+ return newElement.toString()
143+ }
144+ }
145+
114146/* *
115147 * Decodes [encodedServices] according to PeerDID spec
116148 * @see
@@ -135,25 +167,23 @@ internal fun decodeService(encodedServices: List<JSON>, peerDID: PeerDID): List<
135167 decodedServices.joinToString(separator = " ," , prefix = " [" , postfix = " ]" )
136168 }
137169
138- val serviceMapList =
170+ val serviceMapList = try {
171+ fromJsonToList(decodedServicesJson)
172+ } catch (e: SerializationException ) {
139173 try {
140- fromJsonToList( decodedServicesJson)
174+ listOf (fromJsonToMap( decodedServicesJson) )
141175 } catch (e: SerializationException ) {
142- try {
143- listOf (fromJsonToMap(decodedServicesJson))
144- } catch (e: SerializationException ) {
145- throw IllegalArgumentException (" Invalid JSON $decodedServices " )
146- }
176+ throw IllegalArgumentException (" Invalid JSON $decodedServices " )
147177 }
178+ }
148179
149180 return serviceMapList.mapIndexed { serviceNumber, serviceMap ->
150181 if (! serviceMap.containsKey(ServicePrefix .getValue(SERVICE_TYPE ))) {
151182 throw IllegalArgumentException (" service doesn't contain a type" )
152183 }
153184
154- val serviceType =
155- serviceMap.getValue(ServicePrefix .getValue(SERVICE_TYPE )).toString()
156- .replace(ServicePrefix .getValue(SERVICE_DIDCOMM_MESSAGING ), SERVICE_DIDCOMM_MESSAGING )
185+ val serviceType = serviceMap.getValue(ServicePrefix .getValue(SERVICE_TYPE )).toString()
186+ .replace(ServicePrefix .getValue(SERVICE_DIDCOMM_MESSAGING ), SERVICE_DIDCOMM_MESSAGING )
157187 val serviceId = if (serviceMapList.size > 1 ) {
158188 if (serviceNumber == 0 ) {
159189 " #service"
@@ -167,26 +197,49 @@ internal fun decodeService(encodedServices: List<JSON>, peerDID: PeerDID): List<
167197 val serviceEndpointMap = mutableMapOf<String , Any >()
168198 when (val serviceEndpointValue = serviceMap[ServicePrefix .getValue(SERVICE_ENDPOINT )]) {
169199 is String -> {
170- serviceMap[ServicePrefix .getValue(SERVICE_ENDPOINT )]?.let { serviceEndpointMap.put(SERVICE_URI , it) }
171- serviceMap[ServicePrefix .getValue(SERVICE_ROUTING_KEYS )]?.let { serviceEndpointMap.put(SERVICE_ROUTING_KEYS , it) }
172- serviceMap[ServicePrefix .getValue(SERVICE_ACCEPT )]?.let { serviceEndpointMap.put(SERVICE_ACCEPT , it) }
200+ serviceMap[ServicePrefix .getValue(SERVICE_ENDPOINT )]?.let {
201+ serviceEndpointMap.put(
202+ SERVICE_URI , it
203+ )
204+ }
205+ serviceMap[ServicePrefix .getValue(SERVICE_ROUTING_KEYS )]?.let {
206+ serviceEndpointMap.put(
207+ SERVICE_ROUTING_KEYS , it
208+ )
209+ }
210+ serviceMap[ServicePrefix .getValue(SERVICE_ACCEPT )]?.let {
211+ serviceEndpointMap.put(
212+ SERVICE_ACCEPT , it
213+ )
214+ }
173215 }
216+
174217 is Map <* , * > -> {
175- serviceEndpointValue[ServicePrefix .getValue(SERVICE_URI )]?.let { serviceEndpointMap.put(SERVICE_URI , it) }
176- serviceEndpointValue[ServicePrefix .getValue(SERVICE_ROUTING_KEYS )]?.let { serviceEndpointMap.put(SERVICE_ROUTING_KEYS , it) }
177- serviceEndpointValue[ServicePrefix .getValue(SERVICE_ACCEPT )]?.let { serviceEndpointMap.put(SERVICE_ACCEPT , it) }
218+ serviceEndpointValue[ServicePrefix .getValue(SERVICE_URI )]?.let {
219+ serviceEndpointMap.put(
220+ SERVICE_URI , it
221+ )
222+ }
223+ serviceEndpointValue[ServicePrefix .getValue(SERVICE_ROUTING_KEYS )]?.let {
224+ serviceEndpointMap.put(
225+ SERVICE_ROUTING_KEYS , it
226+ )
227+ }
228+ serviceEndpointValue[ServicePrefix .getValue(SERVICE_ACCEPT )]?.let {
229+ serviceEndpointMap.put(
230+ SERVICE_ACCEPT , it
231+ )
232+ }
178233 }
234+
179235 else -> {
180236 throw IllegalArgumentException (" Service doesn't contain a valid Endpoint" )
181237 }
182238 }
183239
184- val service =
185- mutableMapOf<String , Any >(
186- " id" to serviceId,
187- " type" to serviceType,
188- " serviceEndpoint" to serviceEndpointMap
189- )
240+ val service = mutableMapOf<String , Any >(
241+ " id" to serviceId, " type" to serviceType, " serviceEndpoint" to serviceEndpointMap
242+ )
190243
191244 OtherService (service)
192245 }.toList()
@@ -201,12 +254,11 @@ internal fun decodeService(encodedServices: List<JSON>, peerDID: PeerDID): List<
201254 * @return transform+encnumbasis
202255 */
203256internal fun createMultibaseEncnumbasis (key : VerificationMaterialPeerDID <out VerificationMethodTypePeerDID >): String {
204- val decodedKey =
205- when (key.format) {
206- VerificationMaterialFormatPeerDID .BASE58 -> fromBase58(key.value.toString())
207- VerificationMaterialFormatPeerDID .MULTIBASE -> fromMulticodec(fromBase58Multibase(key.value.toString()).second).second
208- VerificationMaterialFormatPeerDID .JWK -> fromJwk(key)
209- }
257+ val decodedKey = when (key.format) {
258+ VerificationMaterialFormatPeerDID .BASE58 -> fromBase58(key.value.toString())
259+ VerificationMaterialFormatPeerDID .MULTIBASE -> fromMulticodec(fromBase58Multibase(key.value.toString()).second).second
260+ VerificationMaterialFormatPeerDID .JWK -> fromJwk(key)
261+ }
210262 validateRawKeyLength(decodedKey)
211263 return toBase58Multibase(toMulticodec(decodedKey, key.type))
212264}
@@ -218,8 +270,7 @@ internal fun createMultibaseEncnumbasis(key: VerificationMaterialPeerDID<out Ver
218270 * @property verMaterial The verification material.
219271 */
220272internal data class DecodedEncumbasis (
221- val encnumbasis : String ,
222- val verMaterial : VerificationMaterialPeerDID <out VerificationMethodTypePeerDID >
273+ val encnumbasis : String , val verMaterial : VerificationMaterialPeerDID <out VerificationMethodTypePeerDID >
223274)
224275
225276/* *
@@ -230,78 +281,64 @@ internal data class DecodedEncumbasis(
230281 * @return decoded encnumbasis as verification material for DID DOC
231282 */
232283internal fun decodeMultibaseEncnumbasis (
233- multibase : String ,
234- format : VerificationMaterialFormatPeerDID
284+ multibase : String , format : VerificationMaterialFormatPeerDID
235285): DecodedEncumbasis {
236286 val (encnumbasis, decodedEncnumbasis) = fromBase58Multibase(multibase)
237287 val (codec, decodedEncnumbasisWithoutPrefix) = fromMulticodec(decodedEncnumbasis)
238288 validateRawKeyLength(decodedEncnumbasisWithoutPrefix)
239289
240- val verMaterial =
241- when (format) {
242- VerificationMaterialFormatPeerDID .BASE58 ->
243- when (codec) {
244- Codec .X25519 ->
245- VerificationMaterialAgreement (
246- format = format,
247- type = VerificationMethodTypeAgreement .X25519KeyAgreementKey2019 ,
248- value = toBase58(decodedEncnumbasisWithoutPrefix)
249- )
250- Codec .ED25519 ->
251- VerificationMaterialAuthentication (
252- format = format,
253- type = VerificationMethodTypeAuthentication .ED25519VerificationKey2018 ,
254- value = toBase58(decodedEncnumbasisWithoutPrefix)
255- )
256- }
257- VerificationMaterialFormatPeerDID .MULTIBASE ->
258- when (codec) {
259- Codec .X25519 ->
260- VerificationMaterialAgreement (
261- format = format,
262- type = VerificationMethodTypeAgreement .X25519KeyAgreementKey2020 ,
263- value =
264- toBase58Multibase(
265- toMulticodec(
266- decodedEncnumbasisWithoutPrefix,
267- VerificationMethodTypeAgreement .X25519KeyAgreementKey2020
268- )
269- )
270- )
271- Codec .ED25519 ->
272- VerificationMaterialAuthentication (
273- format = format,
274- type = VerificationMethodTypeAuthentication .ED25519VerificationKey2020 ,
275- value =
276- toBase58Multibase(
277- toMulticodec(
278- decodedEncnumbasisWithoutPrefix,
279- VerificationMethodTypeAuthentication .ED25519VerificationKey2020
280- )
281- )
282- )
283- }
284- VerificationMaterialFormatPeerDID .JWK ->
285- when (codec) {
286- Codec .X25519 ->
287- VerificationMaterialAgreement (
288- format = format,
289- type = VerificationMethodTypeAgreement .JsonWebKey2020 ,
290- value = toJwk(decodedEncnumbasisWithoutPrefix, VerificationMethodTypeAgreement .JsonWebKey2020 )
291- )
292- Codec .ED25519 ->
293- VerificationMaterialAuthentication (
294- format = format,
295- type = VerificationMethodTypeAuthentication .JsonWebKey2020 ,
296- value =
297- toJwk(
298- decodedEncnumbasisWithoutPrefix,
299- VerificationMethodTypeAuthentication .JsonWebKey2020
300- )
301- )
302- }
290+ val verMaterial = when (format) {
291+ VerificationMaterialFormatPeerDID .BASE58 -> when (codec) {
292+ Codec .X25519 -> VerificationMaterialAgreement (
293+ format = format,
294+ type = VerificationMethodTypeAgreement .X25519KeyAgreementKey2019 ,
295+ value = toBase58(decodedEncnumbasisWithoutPrefix)
296+ )
297+
298+ Codec .ED25519 -> VerificationMaterialAuthentication (
299+ format = format,
300+ type = VerificationMethodTypeAuthentication .ED25519VerificationKey2018 ,
301+ value = toBase58(decodedEncnumbasisWithoutPrefix)
302+ )
303303 }
304304
305+ VerificationMaterialFormatPeerDID .MULTIBASE -> when (codec) {
306+ Codec .X25519 -> VerificationMaterialAgreement (
307+ format = format,
308+ type = VerificationMethodTypeAgreement .X25519KeyAgreementKey2020 ,
309+ value = toBase58Multibase(
310+ toMulticodec(
311+ decodedEncnumbasisWithoutPrefix, VerificationMethodTypeAgreement .X25519KeyAgreementKey2020
312+ )
313+ )
314+ )
315+
316+ Codec .ED25519 -> VerificationMaterialAuthentication (
317+ format = format,
318+ type = VerificationMethodTypeAuthentication .ED25519VerificationKey2020 ,
319+ value = toBase58Multibase(
320+ toMulticodec(
321+ decodedEncnumbasisWithoutPrefix, VerificationMethodTypeAuthentication .ED25519VerificationKey2020
322+ )
323+ )
324+ )
325+ }
326+
327+ VerificationMaterialFormatPeerDID .JWK -> when (codec) {
328+ Codec .X25519 -> VerificationMaterialAgreement (
329+ format = format, type = VerificationMethodTypeAgreement .JsonWebKey2020 , value = toJwk(
330+ decodedEncnumbasisWithoutPrefix, VerificationMethodTypeAgreement .JsonWebKey2020
331+ )
332+ )
333+
334+ Codec .ED25519 -> VerificationMaterialAuthentication (
335+ format = format, type = VerificationMethodTypeAuthentication .JsonWebKey2020 , value = toJwk(
336+ decodedEncnumbasisWithoutPrefix, VerificationMethodTypeAuthentication .JsonWebKey2020
337+ )
338+ )
339+ }
340+ }
341+
305342 return DecodedEncumbasis (encnumbasis, verMaterial)
306343}
307344
@@ -315,7 +352,5 @@ internal fun decodeMultibaseEncnumbasis(
315352 */
316353internal fun getVerificationMethod (keyId : Int , did : String , decodedEncumbasis : DecodedEncumbasis ) =
317354 VerificationMethodPeerDID (
318- id = " $did #key-$keyId " ,
319- controller = did,
320- verMaterial = decodedEncumbasis.verMaterial
355+ id = " $did #key-$keyId " , controller = did, verMaterial = decodedEncumbasis.verMaterial
321356 )
0 commit comments