]> gitweb.factorcode.org Git - factor.git/blob - basis/random/windows/windows.factor
55d568f01d088cb455f8bd3bf209d2cc433b21a5
[factor.git] / basis / random / windows / windows.factor
1 USING: accessors alien.c-types alien.data byte-arrays
2 combinators.short-circuit continuations destructors init kernel
3 locals namespaces random windows.advapi32 windows.errors
4 windows.kernel32 windows.types math.bitwise sequences fry
5 literals io.backend.windows ;
6 IN: random.windows
7
8 TUPLE: windows-crypto-context < win32-handle provider type ;
9
10 M: windows-crypto-context dispose* ( tuple -- )
11     [ handle>> 0 CryptReleaseContext win32-error=0/f ]
12     [ f >>handle drop ] bi ;
13
14 CONSTANT: factor-crypto-container "FactorCryptoContainer"
15
16 :: (acquire-crypto-context) ( provider type flags -- handle )
17     { HCRYPTPROV } [
18         factor-crypto-container
19         provider
20         type
21         flags
22         CryptAcquireContextW win32-error=0/f
23     ] with-out-parameters ;
24
25 : acquire-crypto-context ( provider type -- handle )
26     CRYPT_MACHINE_KEYSET (acquire-crypto-context) ;
27
28 : create-crypto-context ( provider type -- handle )
29     flags{ CRYPT_MACHINE_KEYSET CRYPT_NEWKEYSET } (acquire-crypto-context) ;
30
31 ERROR: acquire-crypto-context-failed provider type error ;
32
33 : attempt-crypto-context ( provider type -- handle )
34     [ acquire-crypto-context ]
35     [ drop [ create-crypto-context ] [ acquire-crypto-context-failed ] recover ] recover ;
36
37 : initialize-crypto-context ( crypto-context -- crypto-context )
38     dup [ provider>> ] [ type>> ] bi attempt-crypto-context >>handle ;
39
40 : <windows-crypto-context> ( provider type -- windows-crypto-type )
41     windows-crypto-context new-disposable
42         swap >>type
43         swap >>provider
44         initialize-crypto-context ; inline
45
46 M: windows-crypto-context random-bytes* ( n windows-crypto-context -- bytes )    
47     handle>> swap [ ] [ <byte-array> ] bi
48     [ CryptGenRandom win32-error=0/f ] keep ;
49
50 : try-crypto-providers ( seq -- windows-crypto-context )
51     [ first2 <windows-crypto-context> ] attempt-all ;
52
53 [
54     {
55         ${ MS_ENHANCED_PROV PROV_RSA_FULL }
56         ${ MS_DEF_PROV PROV_RSA_FULL }
57     } try-crypto-providers system-random-generator set-global
58
59     {
60         ${ MS_STRONG_PROV PROV_RSA_FULL }
61         ${ MS_ENH_RSA_AES_PROV PROV_RSA_AES }
62     } try-crypto-providers secure-random-generator set-global
63 ] "random.windows" add-startup-hook