2021-01-12 02:13:41 +09:00
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
2020-09-06 02:34:02 +02:00
2020-09-14 18:48:57 +02:00
use deno_core ::error ::AnyError ;
2021-04-28 18:41:50 +02:00
use deno_core ::include_js_files ;
use deno_core ::op_sync ;
use deno_core ::Extension ;
2020-09-10 09:57:45 -04:00
use deno_core ::OpState ;
2020-04-23 05:51:07 -04:00
use deno_core ::ZeroCopyBuf ;
2020-09-18 20:39:47 +02:00
use rand ::rngs ::StdRng ;
2019-08-14 17:03:02 +02:00
use rand ::thread_rng ;
use rand ::Rng ;
2021-04-28 18:41:50 +02:00
use rand ::SeedableRng ;
2021-02-26 22:36:26 +05:30
use std ::path ::PathBuf ;
2019-08-14 17:03:02 +02:00
2020-11-14 02:31:57 +05:30
pub use rand ; // Re-export rand
2021-04-28 18:41:50 +02:00
pub fn init ( maybe_seed : Option < u64 > ) -> Extension {
2021-04-29 00:16:45 +02:00
Extension ::builder ( )
. js ( include_js_files! (
2021-04-30 12:51:48 -07:00
prefix " deno:extensions/crypto " ,
2021-04-28 18:41:50 +02:00
" 01_crypto.js " ,
2021-04-29 00:16:45 +02:00
) )
2021-06-05 14:46:24 +02:00
. ops ( vec! [
(
" op_crypto_get_random_values " ,
op_sync ( op_crypto_get_random_values ) ,
) ,
( " op_crypto_random_uuid " , op_sync ( op_crypto_random_uuid ) ) ,
] )
2021-04-29 00:16:45 +02:00
. state ( move | state | {
2021-04-28 18:41:50 +02:00
if let Some ( seed ) = maybe_seed {
state . put ( StdRng ::seed_from_u64 ( seed ) ) ;
}
Ok ( ( ) )
2021-04-29 00:16:45 +02:00
} )
. build ( )
2019-10-11 11:41:54 -07:00
}
2021-01-15 01:24:38 +01:00
pub fn op_crypto_get_random_values (
2020-09-10 09:57:45 -04:00
state : & mut OpState ,
2021-06-05 19:30:20 +02:00
mut zero_copy : ZeroCopyBuf ,
_ : ( ) ,
2021-04-05 18:40:24 +02:00
) -> Result < ( ) , AnyError > {
2021-06-05 19:30:20 +02:00
if zero_copy . len ( ) > 65536 {
return Err (
deno_web ::DomExceptionQuotaExceededError ::new ( & format! ( " The ArrayBufferView's byte length ( {} ) exceeds the number of bytes of entropy available via this API (65536) " , zero_copy . len ( ) ) )
. into ( ) ,
) ;
}
2020-09-18 20:39:47 +02:00
let maybe_seeded_rng = state . try_borrow_mut ::< StdRng > ( ) ;
if let Some ( seeded_rng ) = maybe_seeded_rng {
2021-04-02 15:47:57 +02:00
seeded_rng . fill ( & mut * zero_copy ) ;
2019-08-14 17:03:02 +02:00
} else {
let mut rng = thread_rng ( ) ;
2021-04-02 15:47:57 +02:00
rng . fill ( & mut * zero_copy ) ;
2019-08-14 17:03:02 +02:00
}
2021-04-05 18:40:24 +02:00
Ok ( ( ) )
2019-08-14 17:03:02 +02:00
}
2021-02-26 22:36:26 +05:30
2021-06-05 14:46:24 +02:00
pub fn op_crypto_random_uuid (
state : & mut OpState ,
2021-06-05 19:30:20 +02:00
_ : ( ) ,
_ : ( ) ,
2021-06-05 14:46:24 +02:00
) -> Result < String , AnyError > {
let maybe_seeded_rng = state . try_borrow_mut ::< StdRng > ( ) ;
let uuid = if let Some ( seeded_rng ) = maybe_seeded_rng {
let mut bytes = [ 0 u8 ; 16 ] ;
seeded_rng . fill ( & mut bytes ) ;
uuid ::Builder ::from_bytes ( bytes )
. set_version ( uuid ::Version ::Random )
. build ( )
} else {
uuid ::Uuid ::new_v4 ( )
} ;
Ok ( uuid . to_string ( ) )
}
2021-02-26 22:36:26 +05:30
pub fn get_declaration ( ) -> PathBuf {
PathBuf ::from ( env! ( " CARGO_MANIFEST_DIR " ) ) . join ( " lib.deno_crypto.d.ts " )
}