Skip to content

Commit f5b46f0

Browse files
committed
Add WebCryptoApiTests
1 parent 4a19984 commit f5b46f0

File tree

3 files changed

+123
-22
lines changed

3 files changed

+123
-22
lines changed

tests-chrome/src/test/scala/org/scalajs/dom/tests/chrome/CryptoTests.scala

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests-shared/src/main/scala/org/scalajs/dom/tests/shared/SharedTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.scalajs.dom.tests.shared
33
import org.scalajs.dom.tests.shared.AsyncTesting._
44
import org.junit.Test
55

6-
trait SharedTests {
6+
trait SharedTests extends WebCryptoApiTests {
77

88
// ===================================================================================================================
99
// Tests WITHOUT org.scalajs.dom._ in scope
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package org.scalajs.dom.tests.shared
2+
3+
import org.junit.Assert._
4+
import org.junit.Test
5+
import org.scalajs.dom
6+
import org.scalajs.dom.tests.shared.AsyncTesting._
7+
8+
import scala.scalajs.js
9+
import scala.scalajs.js.typedarray._
10+
11+
trait WebCryptoApiTests {
12+
13+
@Test final def getRandomValuesWork: Unit = {
14+
dom.webcrypto.getRandomValues(Array.ofDim[Byte](8).toTypedArray)
15+
}
16+
17+
@Test final def generateAESEncryptionKeyWorks: AsyncResult = async {
18+
generateAESEncryptionKey()
19+
}
20+
21+
@Test final def aesEncryptionDecryptionTest: AsyncResult = async {
22+
val data = "data"
23+
for {
24+
key <- generateAESEncryptionKey()
25+
iv = generateAESInitializationVector()
26+
encrypted <- aesEncrypt(key, iv, data)
27+
decrypted <- aesDecrypt(key, iv, encrypted)
28+
} yield assertEquals(data, decrypted)
29+
}
30+
31+
@Test final def aesKeyDerivationWorks: AsyncResult = async {
32+
val derivationAlgorithm = "PBKDF2"
33+
val pbdkf2 = new dom.Pbkdf2Params {
34+
val name = derivationAlgorithm
35+
val salt = "salt".getBytes.toTypedArray.buffer
36+
val iterations = 100.toDouble
37+
val hash = "SHA-512"
38+
}
39+
val aesCtr = new dom.AesDerivedKeyParams {
40+
val name = "AES-GCM"
41+
val length = 256
42+
}
43+
44+
for {
45+
pbkdf2Key <- dom.crypto.subtle
46+
.importKey(
47+
dom.KeyFormat.raw,
48+
"password".getBytes.toTypedArray.buffer,
49+
derivationAlgorithm,
50+
false,
51+
js.Array(dom.KeyUsage.deriveKey, dom.KeyUsage.deriveBits)
52+
)
53+
.toFuture
54+
55+
aesKey <- dom.crypto.subtle
56+
.deriveKey(
57+
pbdkf2,
58+
pbkdf2Key,
59+
aesCtr,
60+
true,
61+
js.Array(dom.KeyUsage.encrypt, dom.KeyUsage.decrypt)
62+
)
63+
.toFuture
64+
.map(_.asInstanceOf[dom.CryptoKey])
65+
} yield assertNotNull(aesKey)
66+
}
67+
68+
private def generateAESEncryptionKey() = {
69+
dom.crypto.subtle
70+
.generateKey(
71+
new dom.AesKeyAlgorithm {
72+
val name = "AES-GCM"
73+
val length = 256
74+
},
75+
true,
76+
js.Array(dom.KeyUsage.encrypt, dom.KeyUsage.decrypt)
77+
)
78+
.toFuture
79+
.map(_.asInstanceOf[dom.CryptoKey])
80+
}
81+
82+
private def generateAESInitializationVector() = {
83+
dom.webcrypto.getRandomValues(Array.ofDim[Byte](12).toTypedArray)
84+
}
85+
86+
private def aesEncrypt(key: dom.CryptoKey, iv0: dom.BufferSource, data: String) = {
87+
dom.crypto.subtle
88+
.encrypt(
89+
new dom.AesGcmParams {
90+
val name = "AES-GCM"
91+
val iv = iv0
92+
val tagLength = 128
93+
val additionalData = "".getBytes.toTypedArray.buffer
94+
},
95+
key,
96+
data.getBytes().toTypedArray
97+
)
98+
.toFuture
99+
.map(_.asInstanceOf[ArrayBuffer])
100+
}
101+
102+
private def aesDecrypt(key: dom.CryptoKey, iv0: dom.BufferSource, encrypted: dom.BufferSource) = {
103+
dom.crypto.subtle
104+
.decrypt(
105+
new dom.AesGcmParams {
106+
val name = "AES-GCM"
107+
val iv = iv0
108+
val tagLength = 128
109+
val additionalData = "".getBytes.toTypedArray.buffer
110+
},
111+
key,
112+
encrypted
113+
)
114+
.toFuture
115+
.map(_.asInstanceOf[ArrayBuffer])
116+
.map { buffer =>
117+
val arr = Array.ofDim[Byte](buffer.byteLength)
118+
TypedArrayBuffer.wrap(buffer).get(arr)
119+
new String(arr, "UTF-8")
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)