Skip to content

Commit 425add9

Browse files
authored
Merge pull request #101 from karthik2804/crypto/digest
add sha256 and sha512 digests
2 parents c1c4fde + 93f6f4c commit 425add9

File tree

5 files changed

+121
-4
lines changed

5 files changed

+121
-4
lines changed

Cargo.lock

Lines changed: 44 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/spin-js-engine/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ serde = "1.0.137"
2222
serde_bytes = "0.11"
2323
serde_derive = "1.0.137"
2424
send_wrapper = "0.6.0"
25+
sha2 = "0.10.6"
Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
require('fast-text-encoding')
2+
3+
let encoder = new TextEncoder()
4+
15
/** @internal */
26
declare var _random: {
37
math_rand: () => number
48
get_rand: () => number
9+
get_hash: (algorithm: string, content: ArrayBuffer) => ArrayBuffer
510
}
611

712
/** @internal */
813
export const crypto = {
914
getRandomValues: function <T extends ArrayBufferView | null>(array: T) {
1015
if (array) {
11-
if(array.byteLength > 65536) {
16+
if (array.byteLength > 65536) {
1217
throw "QuotaExceededError"
1318
}
1419
const bytes = Buffer.from(array.buffer)
@@ -17,5 +22,41 @@ export const crypto = {
1722
}
1823
}
1924
return array
25+
},
26+
subtle: {
27+
digest: function (algorithm: string, content: ArrayBuffer) {
28+
if (algorithm == "SHA-256") {
29+
return Promise.resolve(_random.get_hash("sha256", content))
30+
} else if (algorithm == "SHA-512") {
31+
return Promise.resolve(_random.get_hash("sha512", content))
32+
} else {
33+
throw new Error("SHA-256 and SHA-512 are the only supported algorithms");
34+
}
35+
}
36+
},
37+
createHash: function (algorithm: string) {
38+
let data = new Uint8Array()
39+
return {
40+
update(content: string | Uint8Array, inputEncoding: string = "string") {
41+
if (inputEncoding == "string") {
42+
// @ts-ignore
43+
content = encoder.encode(content)
44+
}
45+
let mergedArray = new Uint8Array(data.length + content.length);
46+
mergedArray.set(data);
47+
// @ts-ignore
48+
mergedArray.set(content, data.length);
49+
data = mergedArray
50+
},
51+
digest() {
52+
if (algorithm == "sha256") {
53+
return _random.get_hash("sha256", data.buffer)
54+
} else if (algorithm == "sha512") {
55+
return _random.get_hash("sha512", data.buffer)
56+
} else
57+
throw new Error("sha256 and sha512 are the only supported algorithms");
58+
}
59+
}
2060
}
61+
2162
}

crates/spin-js-engine/src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use {
99
send_wrapper::SendWrapper,
1010
serde::{Deserialize, Serialize},
1111
serde_bytes::ByteBuf,
12+
sha2::Digest,
1213
spin_sdk::{
1314
config,
1415
http::{Request, Response},
@@ -256,6 +257,30 @@ fn get_rand(context: &Context, _this: &Value, _args: &[Value]) -> Result<Value>
256257
context.value_from_u32(thread_rng().gen_range(0..=255))
257258
}
258259

260+
fn get_hash(context: &Context, _this: &Value, args: &[Value]) -> Result<Value> {
261+
match args {
262+
[algorithm, content] => {
263+
let algorithm = &deserialize_helper(algorithm)?;
264+
let content_deserializer = &mut Deserializer::from(content.clone());
265+
let content = ByteBuf::deserialize(content_deserializer)?;
266+
if algorithm == "sha256" {
267+
let hashvalue = sha2::Sha256::digest(content);
268+
let mut serializer = Serializer::from_context(context)?;
269+
hashvalue.serialize(&mut serializer)?;
270+
Ok(serializer.value)
271+
} else if algorithm == "sha512" {
272+
let hashvalue = sha2::Sha512::digest(content);
273+
let mut serializer = Serializer::from_context(context)?;
274+
hashvalue.serialize(&mut serializer)?;
275+
Ok(serializer.value)
276+
} else {
277+
bail!("Invalid algorithm, only sha256 and sha512 are supported")
278+
}
279+
}
280+
_ => bail!("invalid"),
281+
}
282+
}
283+
259284
fn math_rand(context: &Context, _this: &Value, _args: &[Value]) -> Result<Value> {
260285
context.value_from_f64(thread_rng().gen_range(0.0_f64..1.0))
261286
}
@@ -462,6 +487,7 @@ fn do_init() -> Result<()> {
462487
let _random = context.object_value()?;
463488
_random.set_property("math_rand", context.wrap_callback(math_rand)?)?;
464489
_random.set_property("get_rand", context.wrap_callback(get_rand)?)?;
490+
_random.set_property("get_hash", context.wrap_callback(get_hash)?)?;
465491

466492
global.set_property("_random", _random)?;
467493
global.set_property("spinSdk", spin_sdk)?;

types/lib/modules/overrides.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ declare global {
3737
toString(): string
3838
values(): string[]
3939
}
40+
interface Hash {
41+
update(content: string | Uint8Array, inputEncoding?: string): void
42+
digest(): ArrayBuffer
43+
}
4044
const crypto: {
4145
getRandomValues<T extends ArrayBufferView | null>(array: T): T
46+
subtle: {
47+
digest(algorithm: string, content: ArrayBuffer): Promise<ArrayBuffer>
48+
}
49+
createHash(algorithm: string): Hash
4250
}
4351
}
4452

0 commit comments

Comments
 (0)