WIP: scodec and circe implementations of PureCodec's (#104)

* Introducing codec-bits

* Introducing codec-circe

* PureCodec in AesCrypt
This commit is contained in:
Dmitry Kurinskiy 2018-04-06 13:11:49 +03:00 committed by GitHub
parent 994194b31f
commit dc8806de44
4 changed files with 16 additions and 14 deletions

View File

@ -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._

View File

@ -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)
}

View File

@ -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

View File

@ -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)))
}
}
}