2021-01-11 12:13:41 -05:00
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
2020-09-05 20:34:02 -04:00
2020-09-14 12:48:57 -04:00
use deno_core ::error ::AnyError ;
2021-04-28 12:41:50 -04: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 14:39:47 -04:00
use rand ::rngs ::StdRng ;
2019-08-14 11:03:02 -04:00
use rand ::thread_rng ;
use rand ::Rng ;
2021-04-28 12:41:50 -04:00
use rand ::SeedableRng ;
2021-02-26 12:06:26 -05:00
use std ::path ::PathBuf ;
2019-08-14 11:03:02 -04:00
2020-11-13 16:01:57 -05:00
pub use rand ; // Re-export rand
2021-04-28 12:41:50 -04:00
pub fn init ( maybe_seed : Option < u64 > ) -> Extension {
2021-04-28 18:16:45 -04:00
Extension ::builder ( )
. js ( include_js_files! (
2021-04-30 15:51:48 -04:00
prefix " deno:extensions/crypto " ,
2021-04-28 12:41:50 -04:00
" 01_crypto.js " ,
2021-04-28 18:16:45 -04:00
) )
2021-06-05 08:46:24 -04: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-28 18:16:45 -04:00
. state ( move | state | {
2021-04-28 12:41:50 -04:00
if let Some ( seed ) = maybe_seed {
state . put ( StdRng ::seed_from_u64 ( seed ) ) ;
}
Ok ( ( ) )
2021-04-28 18:16:45 -04:00
} )
. build ( )
2019-10-11 14:41:54 -04:00
}
2021-01-14 19:24:38 -05:00
pub fn op_crypto_get_random_values (
2020-09-10 09:57:45 -04:00
state : & mut OpState ,
2021-06-05 13:30:20 -04:00
mut zero_copy : ZeroCopyBuf ,
_ : ( ) ,
2021-04-05 12:40:24 -04:00
) -> Result < ( ) , AnyError > {
2021-06-05 13:30:20 -04: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 14:39:47 -04:00
let maybe_seeded_rng = state . try_borrow_mut ::< StdRng > ( ) ;
if let Some ( seeded_rng ) = maybe_seeded_rng {
2021-04-02 09:47:57 -04:00
seeded_rng . fill ( & mut * zero_copy ) ;
2019-08-14 11:03:02 -04:00
} else {
let mut rng = thread_rng ( ) ;
2021-04-02 09:47:57 -04:00
rng . fill ( & mut * zero_copy ) ;
2019-08-14 11:03:02 -04:00
}
2021-04-05 12:40:24 -04:00
Ok ( ( ) )
2019-08-14 11:03:02 -04:00
}
2021-02-26 12:06:26 -05:00
2021-06-05 08:46:24 -04:00
pub fn op_crypto_random_uuid (
state : & mut OpState ,
2021-06-05 13:30:20 -04:00
_ : ( ) ,
_ : ( ) ,
2021-06-05 08:46:24 -04: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 12:06:26 -05:00
pub fn get_declaration ( ) -> PathBuf {
PathBuf ::from ( env! ( " CARGO_MANIFEST_DIR " ) ) . join ( " lib.deno_crypto.d.ts " )
}