diff --git a/.gitattributes b/.gitattributes index 956f086e8f9509668b0ed2e950c38053038ce3f2..f90b6c3f70635097be4430743719deae18e61ebe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -381,6 +381,7 @@ testfont binary /src/modules/_Crypto/lib/sha.c foreign_ident /src/modules/_Crypto/md5.c foreign_ident /src/modules/_Crypto/md5.pike foreign_ident +/src/modules/_Crypto/nt.c foreign_ident /src/modules/_Crypto/pipe.c foreign_ident /src/modules/_Crypto/rc4.c foreign_ident /src/modules/_Crypto/sha.c foreign_ident diff --git a/lib/modules/Crypto/randomness.pmod b/lib/modules/Crypto/randomness.pmod index 0336bedd6da50b034055a79b686b15f9913f6159..b1879bad78d375e15dfe3786d27d66aed684ef8c 100644 --- a/lib/modules/Crypto/randomness.pmod +++ b/lib/modules/Crypto/randomness.pmod @@ -1,4 +1,4 @@ -/* $Id: randomness.pmod,v 1.13 1999/11/25 23:10:52 grubba Exp $ +/* $Id: randomness.pmod,v 1.14 1999/12/01 22:37:22 marcus Exp $ */ //! module Crypto @@ -41,6 +41,22 @@ PRIVATE object global_rc4; // Executes several programs to generate some entropy from their output. PRIVATE string some_entropy() { +#ifdef __NT__ + object ctx = Crypto.nt.CryptAcquireContext(0, 0, Crypto.nt.PROV_RSA_FULL, + Crypto.nt.CRYPT_VERIFYCONTEXT + /*|Crypto.nt.CRYPT_SILENT*/); + if(!ctx) + throw(({ "Crypto.random: couldn't create crypto context\n", backtrace()})); + + string res = ctx->CryptGenRandom(8192); + + if(!res) + throw(({ "Crypto.random: couldn't generate randomness\n", backtrace()})); + + destruct(ctx); + + return res; +#else /* !__NT__ */ string res; object parent_pipe, child_pipe; mapping env=getenv()+([]); @@ -50,13 +66,8 @@ PRIVATE string some_entropy() if (!child_pipe) throw( ({ "Crypto.random->popen: couldn't create pipe\n", backtrace() }) ); - -#ifndef __NT__ object null=Stdio.File("/dev/null","rw"); env["PATH"]=PATH; -#else - object null=Stdio.File("nul:","rw"); -#endif foreach(SYSTEM_COMMANDS, string cmd) { @@ -72,6 +83,7 @@ PRIVATE string some_entropy() destruct(child_pipe); return parent_pipe->read(); +#endif } diff --git a/src/modules/_Crypto/Makefile.in b/src/modules/_Crypto/Makefile.in index aa04a2b015490182696d55827b9df06a01c17e51..5ebbdea60232187d64c7d64a010bcc9fa4369d32 100644 --- a/src/modules/_Crypto/Makefile.in +++ b/src/modules/_Crypto/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.19 1999/11/18 08:01:48 hubbe Exp $ +# $Id: Makefile.in,v 1.20 1999/12/01 22:37:22 marcus Exp $ @make_variables@ VPATH=@srcdir@:@srcdir@/../..:../.. @@ -6,7 +6,7 @@ VPATH=@srcdir@:@srcdir@/../..:../.. MASS_DESTRUCTION_OBJS = idea.o des.o cast.o rc4.o # END NATIONAL SECURITY -OBJS= $(MASS_DESTRUCTION_OBJS) crypto.o invert.o sha.o md5.o pipe.o cbc.o +OBJS= $(MASS_DESTRUCTION_OBJS) crypto.o invert.o sha.o md5.o pipe.o cbc.o nt.o MODULE_ARCHIVES=lib/algorithms.a MODULE_SUBDIRS=lib diff --git a/src/modules/_Crypto/nt.c b/src/modules/_Crypto/nt.c new file mode 100644 index 0000000000000000000000000000000000000000..ce2f8445e95f4b4c80259a11d47ce9756421fb2a --- /dev/null +++ b/src/modules/_Crypto/nt.c @@ -0,0 +1,171 @@ +/* + * $Id: nt.c,v 1.1 1999/12/01 22:37:22 marcus Exp $ + * + * NT crypto stuff for Pike + */ + +#include "global.h" +#include "stralloc.h" +#include "interpret.h" +#include "svalue.h" +#include "object.h" +#include "error.h" +#include "las.h" +#include "module_support.h" + +#ifdef __NT__ + + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#include <wincrypt.h> + + +static struct program *cryptcontext_program = NULL; + +struct cryptcontext_storage { + HCRYPTPROV handle; +}; + +#define THIS_CRYPTCONTEXT ((struct cryptcontext_storage *)(fp->current_storage)) + +static void init_cryptcontext_struct(struct object *o) +{ + struct cryptcontext_storage *c = THIS_CRYPTCONTEXT; + + c->handle = 0; +} + +static void exit_cryptcontext_struct(struct object *o) +{ + struct cryptcontext_storage *c = THIS_CRYPTCONTEXT; + + if(c->handle) + CryptReleaseContext(c->handle, 0); +} + +static void f_CryptGenRandom(INT32 args) +{ + struct cryptcontext_storage *c = THIS_CRYPTCONTEXT; + struct pike_string *str = NULL, *res; + INT32 siz; + + get_all_args("CryptGenRandom()", args, (args>1? "%i%S":"%i"), &siz, &str); + + if(siz == 0 && str != NULL) + siz = str->len; + + res = begin_shared_string(siz); + if(str != NULL && siz > 0) + memcpy(res->str, str->str, (str->len<siz? str->len : siz)); + if(CryptGenRandom(c->handle, siz, (BYTE*)res->str)) { + pop_n_elems(args); + push_string(end_shared_string(res)); + } else { + pop_n_elems(args); + free_string(end_shared_string(res)); + push_int(0); + } +} + +static void f_CryptAcquireContext(INT32 args) +{ + char *str1=NULL, *str2=NULL; + INT32 typ, flags, fake1, fake2; + int nullflag=0; + HCRYPTPROV prov; + + if(args>0 && sp[-args].type == T_INT && sp[-args].u.integer == 0) + nullflag |= 1; + if(args>1 && sp[1-args].type == T_INT && sp[1-args].u.integer == 0) + nullflag |= 2; + + switch(nullflag) { + case 0: + get_all_args("Crypto.nt.CryptAcquireContext()", args, "%s%s%i%i", + &str1, &str2, &typ, &flags); + break; + case 1: + get_all_args("Crypto.nt.CryptAcquireContext()", args, "%i%s%i%i", + &fake1, &str2, &typ, &flags); + break; + case 2: + get_all_args("Crypto.nt.CryptAcquireContext()", args, "%s%i%i%i", + &str1, &fake2, &typ, &flags); + break; + case 3: + get_all_args("Crypto.nt.CryptAcquireContext()", args, "%i%i%i%i", + &fake1, &fake2, &typ, &flags); + break; + } + + if(!CryptAcquireContext(&prov, str1, str2, typ, flags)) { + pop_n_elems(args); + push_int(0); + return; + } + + pop_n_elems(args); + push_object(clone_object(cryptcontext_program, 0)); + ((struct cryptcontext_storage *)get_storage(sp[-1].u.object, + cryptcontext_program))->handle = + prov; +} + + +#endif /* __NT__ */ + + +void pike_nt_init(void) +{ +#ifdef __NT__ + +#define SIMPCONST(X) \ + add_integer_constant(#X,X,0); + + start_new_program(); + + SIMPCONST(PROV_RSA_FULL); + SIMPCONST(PROV_RSA_SIG); + SIMPCONST(PROV_DSS); + SIMPCONST(PROV_FORTEZZA); + SIMPCONST(PROV_MS_EXCHANGE); + SIMPCONST(PROV_SSL); + + SIMPCONST(CRYPT_VERIFYCONTEXT); + SIMPCONST(CRYPT_NEWKEYSET); + SIMPCONST(CRYPT_DELETEKEYSET); +#ifdef CRYPT_MACHINE_KEYSET + SIMPCONST(CRYPT_MACHINE_KEYSET); +#endif +#ifdef CRYPT_SILENT + SIMPCONST(CRYPT_SILENT); +#endif + + add_function_constant("CryptAcquireContext",f_CryptAcquireContext, + "function(string,string,int,int:object)", 0); + + end_class("nt", 0); + + start_new_program(); + ADD_STORAGE(struct cryptcontext_storage); + /* function(int,string|void:string) */ + ADD_FUNCTION("CryptGenRandom", f_CryptGenRandom, + tFunc(tInt tOr(tString,tVoid),tString), 0); + set_init_callback(init_cryptcontext_struct); + set_exit_callback(exit_cryptcontext_struct); + cryptcontext_program = end_program(); + +#endif /* __NT__ */ +} + +void pike_nt_exit(void) +{ +#ifdef __NT__ + if(cryptcontext_program) { + free_program(cryptcontext_program); + cryptcontext_program=NULL; + } +#endif /* __NT__ */ +}