scala-js/scala-js-dom

`SubtleCrypto.verify` should return `js.Promise[Boolean]`

armanbilge opened this issue · 5 comments

Reported by @bblfish on Discord.

def verify(algorithm: AlgorithmIdentifier, key: CryptoKey, signature: BufferSource,
data: BufferSource): js.Promise[js.Any] = js.native

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify

There may be other signatures that can be improved in the crypto APIs as well.

Thanks for writing this up. Another example is

  def sign(
    algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource
): js.Promise[js.Any] = js.native

that should return a Promise[ArrayBuffer] https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign#return_value

So the spec/idl actually says Promise<any>: https://w3c.github.io/webcrypto/#webidl-451956974
But when reading the description of a few methods, it seems that they are somewhat typed, for example except for verify and sign, there is encrypt: https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-encrypt

Let ciphertext be the result of performing the encrypt operation specified by normalizedAlgorithm using algorithm and key and with data as plaintext.

Resolve promise with ciphertext.

TypeScript uses ArrayBuffer for a few cases instead of any: https://github.com/microsoft/TypeScript/blob/226dd0b7bf5cb5e5bb4dc34ab0e8e14f408f3e20/lib/lib.webworker.d.ts#L3010

Personally, I think we should type them as TypeScript...but spec is spec :P

Thanks for looking into that! You're right, good catch.

Let result be the result of performing the verify operation specified by normalizedAlgorithm using key, algorithm and signature and with data as message.

I guess the fundamental issue is that these methods have to support various cryptography algorithms, including ones that may be introduced in the future.

In theory, the "verify operation" for an algorithm could return something that is not a Boolean. I'm not sure if there are any concrete examples of that, but clearly they are not ruling it out.

IMHO we should leave this as-is. My opinion is that Scala.js DOM's purpose is to facade according to the spec without getting too tangled up in "usability" concerns (see related discussion in #481).

Instead to "fix" these issues the door is open for wrapper libraries to emerge, with idiomatic Scala APIs. e.g. https://github.com/typelevel/bobcats

Understandable, however there is one actual mistake in the signatures as far as I can see, according to the spec deriveBits(it should return an Promise of ArrayBuffer:

Promise<ArrayBuffer> deriveBits(AlgorithmIdentifier algorithm,
CryptoKey baseKey,
unsigned long length);

and in scala-js-dom it's a js.Any:

def deriveBits(algorithm: AlgorithmIdentifier, baseKey: CryptoKey, length: Double): js.Promise[js.Any] = js.native

I can open a PR if you like, should I make a new issue for it?

@zetashift great, let's fix that one then!