All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.http4s.crypto.HmacKeyGenPlatform.scala Maven / Gradle / Ivy

/*
 * Copyright 2021 http4s.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.http4s.crypto

import cats.effect.kernel.Async
import cats.effect.kernel.Sync
import cats.syntax.all._
import scodec.bits.ByteVector

import scala.scalajs.js

private[crypto] trait HmacKeyGenCompanionPlatform {
  @deprecated("Preserved for bincompat", "0.2.3")
  def forAsyncOrSync[F[_]](implicit F0: Priority[Async[F], Sync[F]]): HmacKeyGen[F] =
    forSync(F0.join)

  implicit def forSync[F[_]](implicit F: Sync[F]): HmacKeyGen[F] =
    if (facade.isNodeJSRuntime)
      new UnsealedHmacKeyGen[F] {
        import facade.node._

        override def generateKey[A <: HmacAlgorithm](algorithm: A): F[SecretKey[A]] = {
          val options = new GenerateKeyOptions {
            val length = algorithm.minimumKeyLength * java.lang.Byte.SIZE
          }
          Some(F)
            .collect { case f: Async[F] => f }
            .fold {
              F.delay[SecretKey[A]] {
                val key =
                  crypto.generateKeySync("hmac", options)
                SecretKeySpec(ByteVector.view(key.`export`()), algorithm)
              }
            } { F =>
              F.async_[SecretKey[A]] { cb =>
                crypto.generateKey(
                  "hmac",
                  options,
                  (err, key) =>
                    cb(
                      Option(err)
                        .map(js.JavaScriptException)
                        .toLeft(SecretKeySpec(ByteVector.view(key.`export`()), algorithm)))
                )
              }
            }
        }

      }
    else
      Some(F)
        .collect { case f: Async[F] => f }
        .fold(
          throw new UnsupportedOperationException("HmacKeyGen[F] on browsers requires Async[F]")
        ) { implicit F =>
          new UnsealedHmacKeyGen[F] {
            import facade.browser._
            override def generateKey[A <: HmacAlgorithm](algorithm: A): F[SecretKey[A]] =
              for {
                key <- F.fromPromise(
                  F.delay(
                    crypto
                      .subtle
                      .generateKey(
                        HmacKeyGenParams(algorithm.toStringWebCrypto),
                        true,
                        js.Array("sign"))))
                exported <- F.fromPromise(F.delay(crypto.subtle.exportKey("raw", key)))
              } yield SecretKeySpec(ByteVector.view(exported), algorithm)
          }
        }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy