Skip to content

Commit

Permalink
Merge pull request #18 from DenisRybas/validations-improvement-001
Browse files Browse the repository at this point in the history
Validations improvement
  • Loading branch information
ashcherbakov authored Oct 5, 2021
2 parents 22888e2 + 25eb05d commit 3d64fb3
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
10 changes: 3 additions & 7 deletions lib/src/main/kotlin/org/didcommx/crypto/JWE.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ import org.didcommx.didcomm.exceptions.UnsupportedAlgorithm
import org.didcommx.didcomm.exceptions.UnsupportedCurveException
import org.didcommx.didcomm.exceptions.UnsupportedJWKException
import org.didcommx.didcomm.utils.asKeys
import java.security.MessageDigest
import org.didcommx.didcomm.utils.calculateAPV

fun authEncrypt(payload: String, auth: AuthCryptAlg, from: Key, to: List<Key>): EncryptResult {
val digest = MessageDigest.getInstance("SHA-256")

val skid = from.id
val kids = to.map { it.id }.sorted()

val apu = Base64URL.encode(from.id)
val apv = Base64URL.encode(digest.digest(kids.joinToString(".").encodeToByteArray()))
val apv = calculateAPV(kids)

val (alg, enc) = when (auth) {
AuthCryptAlg.A256CBC_HS512_ECDH_1PU_A256KW -> Pair(JWEAlgorithm.ECDH_1PU_A256KW, EncryptionMethod.A256CBC_HS512)
Expand Down Expand Up @@ -80,10 +78,8 @@ fun authEncrypt(payload: String, auth: AuthCryptAlg, from: Key, to: List<Key>):
}

fun anonEncrypt(payload: String, anon: AnonCryptAlg, to: List<Key>): EncryptResult {
val digest = MessageDigest.getInstance("SHA-256")

val kids = to.map { it.id }.sorted()
val apv = Base64URL.encode(digest.digest(kids.joinToString(".").encodeToByteArray()))
val apv = calculateAPV(kids)

val (alg, enc) = when (anon) {
AnonCryptAlg.A256CBC_HS512_ECDH_ES_A256KW -> Pair(JWEAlgorithm.ECDH_ES_A256KW, EncryptionMethod.A256CBC_HS512)
Expand Down
21 changes: 21 additions & 0 deletions lib/src/main/kotlin/org/didcommx/operations/Unpack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.didcommx.didcomm.message.Message
import org.didcommx.didcomm.model.Metadata
import org.didcommx.didcomm.model.UnpackParams
import org.didcommx.didcomm.model.UnpackResult
import org.didcommx.didcomm.utils.calculateAPV

fun unpack(params: UnpackParams, keySelector: RecipientKeySelector): UnpackResult {
val metadataBuilder = Metadata.Builder()
Expand Down Expand Up @@ -60,13 +61,23 @@ private fun ParseResult.JWE.authUnpack(
decryptByAllKeys: Boolean,
metadataBuilder: Metadata.Builder
): Message {
if (message.header.senderKeyID != null &&
message.header.agreementPartyUInfo.decodeToString() != message.header.senderKeyID
)
throw MalformedMessageException("apu is not equal to skid")

val sender = message.header?.senderKeyID
?: message.header.agreementPartyUInfo.decodeToString()
?: throw MalformedMessageException("The \"skid\" header must be present")

val recipients = message.recipients?.mapNotNull { it?.header?.keyID }
?: throw MalformedMessageException("JWE Unprotected Per-Recipient header must be present")

if (message.header.agreementPartyVInfo != null &&
message.header.agreementPartyVInfo != calculateAPV(recipients)
)
throw MalformedMessageException("apv is invalid")

val (from, to) = keySelector.findAuthCryptKeys(sender, recipients)
val decrypted = authDecrypt(message, decryptByAllKeys, from, to)

Expand All @@ -90,9 +101,19 @@ private fun ParseResult.JWE.anonUnpack(
decryptByAllKeys: Boolean,
metadataBuilder: Metadata.Builder
): Message {
if (message.header.senderKeyID != null &&
message.header.agreementPartyUInfo.decodeToString() != message.header.senderKeyID
)
throw MalformedMessageException("apu is not equal to skid")

val recipients = message.recipients?.mapNotNull { it?.header?.keyID }
?: throw MalformedMessageException("JWE Unprotected Per-Recipient header must be present")

if (message.header.agreementPartyVInfo != null &&
message.header.agreementPartyVInfo != calculateAPV(recipients)
)
throw MalformedMessageException("apv is invalid")

val to = keySelector.findAnonCryptKeys(recipients)
val decrypted = anonDecrypt(message, decryptByAllKeys, to)

Expand Down
8 changes: 8 additions & 0 deletions lib/src/main/kotlin/org/didcommx/utils/DIDUtils.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.didcommx.didcomm.utils

import com.nimbusds.jose.util.Base64URL
import java.security.MessageDigest

fun isDIDFragment(str: String) = str.contains("#")

fun divideDIDFragment(str: String) = str.split("#")
Expand All @@ -8,3 +11,8 @@ fun isDID(str: String): Boolean {
val parts = str.split(":")
return parts.size == 3 && parts[0] == "did"
}

fun calculateAPV(kids: List<String>): Base64URL? {
val digest = MessageDigest.getInstance("SHA-256")
return Base64URL.encode(digest.digest(kids.joinToString(".").encodeToByteArray()))
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import org.didcommx.didcomm.common.AnonCryptAlg
import org.didcommx.didcomm.common.AuthCryptAlg
import org.didcommx.didcomm.common.SignAlg
import org.didcommx.didcomm.exceptions.DIDCommException
import org.didcommx.didcomm.exceptions.DIDDocException
import org.didcommx.didcomm.exceptions.IncompatibleCryptoException
import org.didcommx.didcomm.exceptions.MalformedMessageException
import org.didcommx.didcomm.exceptions.UnsupportedAlgorithm
import org.didcommx.didcomm.message.Message
Expand Down Expand Up @@ -1060,9 +1058,9 @@ class JWE {

NegativeTestVector(
packedMessage = MESSAGE_ALICE_SKID_NOT_FOUND,
expectedThrow = DIDDocException::
expectedThrow = MalformedMessageException::
class,
expectedMessage = "Verification method 'did:example:alice#key-x25519-5' not found in DID Doc 'did:example:alice'",
expectedMessage = "apu is not equal to skid",
unpackParams = UnpackParams
.Builder(
MESSAGE_ALICE_SKID_NOT_FOUND
Expand All @@ -1073,9 +1071,9 @@ class JWE {

NegativeTestVector(
packedMessage = MESSAGE_ALICE_AND_BOB_KEYS_FROM_DIFFERENT_CURVES,
expectedThrow = IncompatibleCryptoException::
expectedThrow = MalformedMessageException::
class,
expectedMessage = "The recipient 'did:example:bob#key-p384-1' curve is not compatible to 'X25519'",
expectedMessage = "apv is invalid",
unpackParams = UnpackParams
.Builder(
MESSAGE_ALICE_AND_BOB_KEYS_FROM_DIFFERENT_CURVES
Expand Down

0 comments on commit 3d64fb3

Please sign in to comment.