Skip to content
Open
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
20 changes: 10 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import sbt._
import sbt.internal.inc.ReflectUtilities

// Scalafix
ThisBuild / scalafixDependencies ++= List(
"org.scalatest" %% "autofix" % "3.1.0.0",
"org.scala-lang.modules" %% "scala-collection-migrations" % "2.1.4"
)
addCompilerPlugin(scalafixSemanticdb)
// ThisBuild / scalafixDependencies ++= List(
// "org.scalatest" %% "autofix" % "3.1.0.0",
// "org.scala-lang.modules" %% "scala-collection-migrations" % "2.1.4"
// )
// addCompilerPlugin(scalafixSemanticdb)

lazy val commonOwaspSettings = Seq(
dependencyCheckAssemblyAnalyzerEnabled := Some(false)
Expand Down Expand Up @@ -102,9 +102,9 @@ lazy val root = (project in file("."))

inScope(Global)(
Seq(
scalaVersion := "2.13.6",
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
scalaVersion := "2.13.14",
// semanticdbEnabled := false,
// semanticdbVersion := scalafixSemanticdb.revision,
organization := "com.wavesplatform",
organizationName := "Waves Platform",
organizationHomepage := Some(url("https://wavesplatform.com")),
Expand All @@ -124,8 +124,8 @@ inScope(Global)(
"-Ymacro-annotations",
"-opt:l:inline",
"-opt-inline-from:scala.**",
"-Yrangepos", // required for scalafix
"-P:semanticdb:synthetics:on",
// "-Yrangepos", // required for scalafix
// "-P:semanticdb:synthetics:on",
// Excluding -byname-implicit is required for Scala 2.13 due to https://github.com/scala/bug/issues/12072
"-Xlint:_,-byname-implicit" // Fixes pureconfig.generic.semiauto.deriveReader
),
Expand Down
6 changes: 3 additions & 3 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object Dependencies {
val cats = "2.6.1"
val catsMacros = "2.1.1"
val catsTaglessMacros = "0.14.0"
val kindProjector = "0.9.10"
val kindProjector = "0.13.3"
val betterMonadicFor = "0.3.1"
val mouse = "1.0.4"
val shapeless = "2.3.7"
Expand All @@ -34,7 +34,7 @@ object Dependencies {
val janino = "3.1.6"
val logbackJsonEncoder = "6.6"

val silencer = "1.7.5"
val silencer = "1.7.19"

val kanela = "1.0.11"
val kamon = "2.5.4"
Expand Down Expand Up @@ -111,7 +111,7 @@ object Dependencies {
private val catsCore = catsModule("core")
private val catsMacros = "org.typelevel" %% s"cats-macros" % Version.catsMacros
private val catsTaglessMacros = "org.typelevel" %% "cats-tagless-macros" % Version.catsTaglessMacros
private val kindProjector = compilerPlugin("org.typelevel" %% "kind-projector" % "0.13.0" cross CrossVersion.full)
private val kindProjector = compilerPlugin("org.typelevel" %% "kind-projector" % "0.13.3" cross CrossVersion.full)
private val betterMonadicFor = compilerPlugin("com.olegpy" %% "better-monadic-for" % Version.betterMonadicFor)
private val mouse = "org.typelevel" %% "mouse" % Version.mouse
private val shapeless = "com.chuusai" %% "shapeless" % Version.shapeless
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.5.3
sbt.version=1.12.11
5 changes: 1 addition & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Seq(
"se.marcuslonnberg" % "sbt-docker" % "1.7.0",
"com.github.sbt" % "sbt-git" % "2.0.0",
"org.scalameta" % "sbt-scalafmt" % "2.0.1",
"ch.epfl.scala" % "sbt-scalafix" % "0.9.29",
// "ch.epfl.scala" % "sbt-scalafix" % "0.9.29",
"com.github.tkawachi" % "sbt-repeat" % "0.1.0",
/*
undeclaredCompileDependencies{test}
Expand All @@ -37,7 +37,4 @@ libraryDependencies ++= Seq(
"commons-codec" % "commons-codec" % "1.14"
)

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full) // Remove after scala 2.13 migration
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.13.0" cross CrossVersion.full)

addDependencyTreePlugin // https://github.com/sbt/sbt-dependency-graph
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import net.ceedubs.ficus.readers.{NameMapper, ValueReader}

import java.io._
import java.net.InetSocketAddress
import java.util.concurrent.TimeUnit
import java.util.concurrent.{Executors, ScheduledExecutorService, TimeUnit}
import scala.concurrent.Future
import scala.jdk.CollectionConverters._

Expand All @@ -26,9 +26,11 @@ class DEXExtension(context: ExtensionContext) extends Extension with ScorexLoggi

implicit val chosenCase: NameMapper = net.ceedubs.ficus.readers.namemappers.implicits.hyphenCase

private val executor: ScheduledExecutorService = Executors.newScheduledThreadPool(4)

implicit private val apiScheduler: Scheduler = Scheduler(
ec = context.actorSystem.dispatchers.lookup("akka.actor.waves-dex-grpc-scheduler"),
executionModel = ExecutionModel.AlwaysAsyncExecution
executor,
ExecutionModel.AlwaysAsyncExecution
)

implicit val byteStrValueReader: ValueReader[ByteStr] = (config: Config, path: String) => {
Expand Down Expand Up @@ -66,6 +68,7 @@ class DEXExtension(context: ExtensionContext) extends Extension with ScorexLoggi
override def shutdown(): Future[Unit] = {
log.info("Shutting down gRPC DEX extension")
if (server != null) server.shutdownNow()
executor.shutdown()
Future.successful(())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,28 @@ package object crypto {

def sign(account: PrivateKey, message: ByteStr): ByteStr = Curve25519.sign(SPrivateKey(account.arr), message)

private val BlacklistedKeys: Array[Array[Byte]] = Array(
Array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
Array(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
Array(0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00),
Array(0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57),
Array(0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
Array(0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f),
Array(0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f)
).map(_.map(_.toByte))

def isWeakPublicKey(publicKey: Array[Byte]): Boolean =
BlacklistedKeys.exists { wk =>
publicKey.view.init.iterator.sameElements(wk.view.init) &&
(publicKey.last == wk.last || (publicKey.last & 0xff) == wk.last + 0x80)
}

def verify(signature: ByteStr, message: ByteStr, publicKey: PublicKey): Boolean =
Curve25519.verify(Signature(signature.arr), message, SPublicKey(publicKey.arr))
verify(signature, message, publicKey, checkWeakPk = true)

def verify(signature: ByteStr, message: ByteStr, publicKey: PublicKey, checkWeakPk: Boolean): Boolean =
(!checkWeakPk || !isWeakPublicKey(publicKey.arr)) &&
Curve25519.verify(Signature(signature.arr), message, SPublicKey(publicKey.arr))

def createKeyPair(seed: Array[Byte]): (Array[Byte], Array[Byte]) = Curve25519.createKeyPair(seed)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.wavesplatform.dex.domain.crypto

import com.wavesplatform.dex.WavesIntegrationSuiteBase
import com.wavesplatform.dex.domain.account.PublicKey
import com.wavesplatform.dex.domain.bytes.ByteStr
import org.scalatest.matchers.should.Matchers

class CryptoSpec extends WavesIntegrationSuiteBase with Matchers {

"CryptoSpec" - {
"isWeakPublicKey" - {
"detects blacklisted keys" in {
val weakKey = Array.fill(32)(0.toByte)
isWeakPublicKey(weakKey) shouldBe true

val weakKey2 = Array(0x01.toByte) ++ Array.fill(31)(0.toByte)
isWeakPublicKey(weakKey2) shouldBe true

// Standard valid public key should not be detected as weak
val seed = Array.fill(32)(1.toByte)
val (_, pkBytes) = createKeyPair(seed)
isWeakPublicKey(pkBytes) shouldBe false
}
}

"verify" - {
"rejects weak public keys by default" in {
val weakKeyBytes = Array.fill(32)(0.toByte)
val weakPublicKey = PublicKey(weakKeyBytes)
val dummyMessage = ByteStr(Array.fill(32)(1.toByte))
val dummySignature = ByteStr(Array.fill(64)(1.toByte))

// By default verify should reject weak public keys
verify(dummySignature, dummyMessage, weakPublicKey) shouldBe false
}

"bypasses weak public key check if checkWeakPk is false" in {
val weakKeyBytes = Array.fill(32)(0.toByte)
val weakPublicKey = PublicKey(weakKeyBytes)
val dummyMessage = ByteStr(Array.fill(32)(1.toByte))
val dummySignature = ByteStr(Array.fill(64)(1.toByte))

// Curve25519.verify will be called and return false, but it won't be blocked immediately by checkWeakPk
verify(dummySignature, dummyMessage, weakPublicKey, checkWeakPk = false) shouldBe false
}

"successfully verifies standard signatures" in {
val seed = Array.fill(32)(1.toByte)
val (skBytes, pkBytes) = createKeyPair(seed)
val messageBytes = Array.fill(32)(5.toByte)

val signatureBytes = scorex.crypto.signatures.Curve25519.sign(
scorex.crypto.signatures.PrivateKey(skBytes),
messageBytes
)

verify(ByteStr(signatureBytes), ByteStr(messageBytes), PublicKey(pkBytes)) shouldBe true
verify(ByteStr(signatureBytes), ByteStr(messageBytes), PublicKey(pkBytes), checkWeakPk = false) shouldBe true
}
}
}
}