Skip to content

Commit

Permalink
Merge pull request #202 from FabioPinheiro/fix/message_verification_a…
Browse files Browse the repository at this point in the history
…nd_tooling

Fix/message verification and tooling
  • Loading branch information
FabioPinheiro authored Feb 24, 2024
2 parents c233965 + e230f37 commit 4cbb229
Show file tree
Hide file tree
Showing 28 changed files with 466 additions and 253 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ inThisBuild(
// NO NEED ATM "-Ykind-projector"
) ++
// Because DeriveJson(Decoder/Encoder).gen[DidFail] exceeded maximal number of successive inlines (default is 32)
Seq("-Xmax-inlines", "38")
Seq("-Xmax-inlines", "42")

// ### commonSettings ###
// Compile / doc / sources := Nil,
Expand Down
16 changes: 11 additions & 5 deletions demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,22 @@ docker build --tag scala_did_demo ./demo/
docker tag scala_did_demo registry.fly.io/scala-did-demo
# flyctl auth docker
docker push registry.fly.io/scala-did-demo
# 2024/02/05 +- 119.3MB
# 2023/11/15 +- 124.1MB
# 2023/10/28 +- 118.1MB
# 2023/10/20 +- 117.3MB
# 2023/09/24 +- 115.1MB
# +- 52MB
flyctl image update -a scala-did-demo
flyctl deploy ./demo/ -i registry.fly.io/scala-did-demo
```

## History of deployments

Size of the last docker layer:
- 2024/02/18 +- 121.2MB
- 2024/02/13 +- 120.8MB
- 2024/02/05 +- 119.3MB
- 2023/11/15 +- 124.1MB
- 2023/10/28 +- 118.1MB
- 2023/10/20 +- 117.3MB
- 2023/09/24 +- 115.1MB

## Others

Sort by file size
Expand Down
11 changes: 5 additions & 6 deletions demo/jvm/src/main/scala/fmgp/did/demo/AppServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import fmgp.did.comm.protocol._
import fmgp.did.method.peer.DidPeerResolver
import fmgp.did.method.hardcode.HardcodeResolver
import fmgp.did.uniresolver.Uniresolver
import fmgp.util._
import fmgp.did.framework.Operator
import fmgp.util._

// import zio.http.endpoint.RoutesMiddleware

Expand Down Expand Up @@ -50,7 +50,8 @@ object AppServer extends ZIOAppDefault {
// http://localhost:8080/oob?_oob=eyJ0eXBlIjoiaHR0cHM6Ly9kaWRjb21tLm9yZy9vdXQtb2YtYmFuZC8yLjAvaW52aXRhdGlvbiIsImlkIjoiNTk5ZjM2MzgtYjU2My00OTM3LTk0ODctZGZlNTUwOTlkOTAwIiwiZnJvbSI6ImRpZDpleGFtcGxlOnZlcmlmaWVyIiwiYm9keSI6eyJnb2FsX2NvZGUiOiJzdHJlYW1saW5lZC12cCIsImFjY2VwdCI6WyJkaWRjb21tL3YyIl19fQ
).toHttpApp @@ (Middleware.requestLogging(loggedRequestHeaders = Set(Header.Host, Header.Origin)) ++ Middleware.debug)

def appOther = Routes(
def appOther = appOtherRoutes.logErrorAndRespond.toHttpApp
def appOtherRoutes: Routes[Resolver, Throwable] = Routes( // TODO outes[Resolver, DidException]
Method.GET / "oob" -> handler { (req: Request) =>
for {
_ <- ZIO.log("oob")
Expand All @@ -65,11 +66,9 @@ object AppServer extends ZIOAppDefault {
Method.POST / "ops" -> handler { (req: Request) =>
req.body.asString
.tap(e => ZIO.log("ops"))
.tap(e => ZIO.logTrace(s"ops: $e"))
.flatMap(e => OperationsServerRPC.ops(e))
.flatMap(e => OperationsServerRPC.ops(e).tapErrorCause(cause => ZIO.logErrorCause(cause)))
.map(e => Response.text(e))
},

// ### MAKE KEYS ###
Method.POST / "makeKey" -> handler { (req: Request) =>
req.body.asString
Expand Down Expand Up @@ -100,7 +99,7 @@ object AppServer extends ZIOAppDefault {
case Left(error) => ZIO.succeed(Response.text(error.error).copy(status = Status.BadRequest)).debug
case Right(value) => ZIO.succeed(Response.text("DID:" + value)).debug
},
).sandbox.toHttpApp
)

def appWebsite = Routes(
// Method.GET / trailing -> handler { // html.Html.fromDomElement()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object OperationsServerRPC {
case SignOpInput(agent, msg) =>
operations
.sign(msg)
.provideEnvironment(ZEnvironment(agent))
.provideEnvironment(ZEnvironment(agent, resolver))
.mapBoth(ex => SignOpOutput(Left(ex)), e => SignOpOutput(Right(e)))
.merge
case VerifyOpInput(msg) =>
Expand Down
12 changes: 12 additions & 0 deletions demo/jvm/src/main/scala/fmgp/util/RoutesExtra.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fmgp.util

import zio._
import zio.http._

extension [Env, Err](r: Routes[Env, Err])
def logErrorAndRespond(using trace: Trace): Routes[Env, Nothing] =
Routes.fromIterable(
r.routes
.map(e => e.transform(x => x.tapErrorCauseZIO(c => ZIO.logErrorCause(c))))
.map(_.handleErrorCause(Response.fromCause(_)))
)
20 changes: 11 additions & 9 deletions did-imp/js/src/main/scala/fmgp/crypto/UtilsJS.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ object UtilsJS {
}

// TODO make private
def toKeyLike: IO[UnknownError.type, (KeyLike, String)] = {
val aux = key.toJWK
ZIO
.fromPromiseJS(importJWK(aux))
.map(k => (k.asInstanceOf[KeyLike], aux.alg.get))
.orElseFail(UnknownError)
def toKeyLike: IO[CryptoFailed, (KeyLike, String, String)] = {
key.kid match
case None => ZIO.fail(FailToExtractKid(s"Fail to extract kid from ${key.toJson}"))
case Some(kid) =>
val aux = key.toJWK
ZIO
.fromPromiseJS(importJWK(aux))
.map(k => (k.asInstanceOf[KeyLike], aux.alg.get, kid))
.orElseFail(UnknownError)
}

def verify(jwm: SignedMessage): IO[CryptoFailed, Boolean] =
Expand All @@ -113,15 +116,14 @@ object UtilsJS {
extension (key: PrivateKey) {
def sign(payload: Array[Byte]): IO[CryptoFailed, SignedMessage] = {
val data = js.typedarray.Uint8Array.from(payload.toSeq.map(_.toShort).toJSIterable)

key.toKeyLike
.flatMap { (thisKey, alg) =>
.flatMap { (thisKey, alg, kid) =>
ZIO
.fromPromiseJS(
GeneralSign(data) // We can also use CompactSign
.tap(
_.addSignature(thisKey.asInstanceOf[KeyLike])
.setProtectedHeader(CompactJWSHeaderParameters(alg))
.setProtectedHeader(CompactJWSHeaderParameters(alg).set("kid", kid))
)
.sign()
)
Expand Down
5 changes: 3 additions & 2 deletions did-imp/js/src/test/scala/fmgp/crypto/JWMSuiteJS.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ import scala.util.Failure
import scala.util.Success
import scala.util.Try

/** didImpJS/testOnly fmgp.crypto.JWMSuiteJS */
class JWMSuiteJS extends ZSuite {

import scala.scalajs.js

testZ("sign and verify an example") {
val key: ECPrivateKey = JWKExamples.senderKeySecp256k1.fromJson[ECPrivateKey].toOption.get
sign(key, DIDCommExamples.plaintextMessageObj).flatMap { jwsObject =>
verify(key.toPublicKey, jwsObject).map(e => assert(e))
<&> verify(key.toPublicKey, SignedMessageExamples.exampleSignatureES256K_obj).map(e => assert(e))
verify(key.toPublicKey, jwsObject).map(e => assert(e)) <&>
verify(key.toPublicKey, SignedMessageExamples.exampleSignatureES256K_obj).map(e => assert(e))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ object PlatformSpecificOperations {

def sign(key: PrivateKey, payload: Array[Byte]): IO[CurveError, SignedMessage] =
key match {
case okp: OKPPrivateKey if okp.crv == Curve.Ed25519 =>
ZIO.succeed(okp.toJWK.signWithEd25519(payload, key.jwaAlgorithmtoSign))
case okp: OKPPrivateKey =>
ZIO.fail(UnsupportedCurve(obtained = okp.crv, supported = Set(Curve.Ed25519)))
case okp @ OKPPrivateKey(kty, Curve.Ed25519, d, x, kid) =>
ZIO.succeed(okpKeySignWithEd25519(okpKey2JWK(okp), payload, key.jwaAlgorithmtoSign))
case okp @ OKPPrivateKey(kty, crv, d, x, kid) =>
ZIO.fail(UnsupportedCurve(obtained = crv, supported = Set(Curve.Ed25519)))
case ec: ECPrivateKey =>
ZIO.succeed(ec.toJWK.sign(payload, key.jwaAlgorithmtoSign))
ZIO.succeed(ecKeySign(ec.toJWK, payload, key.jwaAlgorithmtoSign))
}

def verify(key: PublicKey, jwm: SignedMessage): UIO[Boolean] =
ZIO.succeed(key.match {
case okp: OKPPublicKey => okp.toJWK.verify(jwm, key.jwaAlgorithmtoSign)
case ec: ECPublicKey => ec.toJWK.verify(jwm, key.jwaAlgorithmtoSign)
})
def verify(key: PublicKey, jwm: SignedMessage): IO[CurveError, Boolean] =
key.match {
case okp @ OKPPublicKey(kty, Curve.Ed25519, x, kid) =>
ZIO.succeed(okpKeyVerifyWithEd25519(okpKey2JWK(okp), jwm, key.jwaAlgorithmtoSign))
case okp @ OKPPublicKey(kty, crv, x, kid) =>
ZIO.fail(UnsupportedCurve(obtained = crv, supported = Set(Curve.Ed25519)))
case ec: ECPublicKey =>
ZIO.succeed(ecKeyVerify(ec.toJWK, jwm, key.jwaAlgorithmtoSign))
}

}
Loading

0 comments on commit 4cbb229

Please sign in to comment.