mirror of
https://github.com/fluencelabs/crypto
synced 2025-04-24 14:22:18 +00:00
WIP: scodec and circe implementations of PureCodec's (#104)
* Introducing codec-bits * Introducing codec-circe * PureCodec in AesCrypt
This commit is contained in:
parent
994194b31f
commit
dc8806de44
@ -18,7 +18,7 @@
|
||||
package fluence.crypto
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.{Files, Paths}
|
||||
import java.nio.file.Files
|
||||
|
||||
import cats.MonadError
|
||||
import cats.syntax.flatMap._
|
||||
|
@ -18,10 +18,9 @@
|
||||
package fluence.crypto.algorithm
|
||||
|
||||
import cats.data.EitherT
|
||||
import cats.syntax.applicative._
|
||||
import cats.syntax.flatMap._
|
||||
import cats.{Applicative, Monad, MonadError}
|
||||
import fluence.codec.Codec
|
||||
import fluence.codec.PureCodec
|
||||
import fluence.crypto.cipher.Crypt
|
||||
import org.bouncycastle.crypto.{CipherParameters, PBEParametersGenerator}
|
||||
import org.bouncycastle.crypto.digests.SHA256Digest
|
||||
@ -52,7 +51,7 @@ case class DataWithParams(data: Array[Byte], params: CipherParameters)
|
||||
*/
|
||||
class AesCrypt[F[_]: Monad, T](password: Array[Char], withIV: Boolean, config: AesConfig)(
|
||||
implicit ME: MonadError[F, Throwable],
|
||||
codec: Codec[F, T, Array[Byte]]
|
||||
codec: PureCodec[T, Array[Byte]]
|
||||
) extends Crypt[F, T, Array[Byte]] with JavaAlgorithm {
|
||||
import CryptoErr._
|
||||
|
||||
@ -72,7 +71,9 @@ class AesCrypt[F[_]: Monad, T](password: Array[Char], withIV: Boolean, config: A
|
||||
|
||||
override def encrypt(plainText: T): F[Array[Byte]] = {
|
||||
val e = for {
|
||||
data ← EitherT.liftF(codec.encode(plainText))
|
||||
data ← codec
|
||||
.direct[F](plainText)
|
||||
.leftMap(err ⇒ CryptoErr("Cannot encode plain text to bytes to encrypt it", Some(err)))
|
||||
key ← initSecretKey(password, salt)
|
||||
extDataWithParams ← extDataWithParams(key)
|
||||
encData ← processData(DataWithParams(data, extDataWithParams._2), extDataWithParams._1, encrypt = true)
|
||||
@ -85,7 +86,7 @@ class AesCrypt[F[_]: Monad, T](password: Array[Char], withIV: Boolean, config: A
|
||||
val e = for {
|
||||
dataWithParams ← detachDataAndGetParams(cipherText, password, salt, withIV)
|
||||
decData ← processData(dataWithParams, None, encrypt = false)
|
||||
plain ← EitherT.liftF[F, CryptoErr, T](codec.decode(decData))
|
||||
plain ← codec.inverse[F](decData).leftMap(err ⇒ CryptoErr("Cannot decode decrypted text", Some(err)))
|
||||
} yield plain
|
||||
|
||||
e.value.flatMap(ME.fromEither)
|
||||
@ -219,14 +220,14 @@ object AesCrypt extends slogging.LazyLogging {
|
||||
def forString[F[_]: Applicative](password: ByteVector, withIV: Boolean, config: AesConfig)(
|
||||
implicit ME: MonadError[F, Throwable]
|
||||
): AesCrypt[F, String] = {
|
||||
implicit val codec: Codec[F, String, Array[Byte]] =
|
||||
Codec[F, String, Array[Byte]](_.getBytes.pure[F], bytes ⇒ new String(bytes).pure[F])
|
||||
implicit val codec: PureCodec[String, Array[Byte]] =
|
||||
PureCodec.liftB[String, Array[Byte]](_.getBytes, new String(_))
|
||||
apply[F, String](password, withIV, config)
|
||||
}
|
||||
|
||||
def apply[F[_]: Applicative, T](password: ByteVector, withIV: Boolean, config: AesConfig)(
|
||||
implicit ME: MonadError[F, Throwable],
|
||||
codec: Codec[F, T, Array[Byte]]
|
||||
codec: PureCodec[T, Array[Byte]]
|
||||
): AesCrypt[F, T] =
|
||||
new AesCrypt(password.toHex.toCharArray, withIV, config)
|
||||
}
|
||||
|
@ -18,8 +18,6 @@
|
||||
package fluence.crypto
|
||||
|
||||
import cats.Monad
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.flatMap._
|
||||
import cats.data.EitherT
|
||||
import fluence.crypto.keypair.KeyPair
|
||||
import io.circe.parser.decode
|
||||
|
@ -23,8 +23,11 @@ import cats.data.EitherT
|
||||
import scala.language.higherKinds
|
||||
import scala.util.control.{NoStackTrace, NonFatal}
|
||||
|
||||
// TODO: it could be useful to add smth like "source" or "trace" field, to help understand where exactly the check happened
|
||||
case class CryptoErr(errorMessage: String) extends Throwable(errorMessage) with NoStackTrace
|
||||
case class CryptoErr(errorMessage: String, causedBy: Option[Throwable] = None)
|
||||
extends Throwable(errorMessage) with NoStackTrace {
|
||||
|
||||
override def getCause: Throwable = causedBy getOrElse super.getCause
|
||||
}
|
||||
|
||||
object CryptoErr {
|
||||
|
||||
@ -32,7 +35,7 @@ object CryptoErr {
|
||||
def nonFatalHandling[F[_]: Applicative, A](a: ⇒ A)(errorText: String): EitherT[F, CryptoErr, A] = {
|
||||
try EitherT.pure(a)
|
||||
catch {
|
||||
case NonFatal(e) ⇒ EitherT.leftT(CryptoErr(errorText + ": " + e.getLocalizedMessage))
|
||||
case NonFatal(e) ⇒ EitherT.leftT(CryptoErr(errorText + ": " + e.getLocalizedMessage, Some(e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user