b63de32018-01-19Martin Nilsson /* -*- c -*- || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
405b832004-01-30Martin Nilsson 
b63de32018-01-19Martin Nilsson #include "module.h"
405b832004-01-30Martin Nilsson 
e1bca42005-01-06Henrik Grubbström (Grubba) #ifdef __NT__
405b832004-01-30Martin Nilsson  #include "interpret.h" #include "module_support.h" #include "pike_macros.h"
60a5672004-01-30Martin Nilsson #include "nettle.h"
d124672004-03-19Henrik Grubbström (Grubba) #include <winerror.h>
405b832004-01-30Martin Nilsson #include <wincrypt.h>
d124672004-03-19Henrik Grubbström (Grubba) #ifndef NTE_EXISTS #define NTE_EXISTS 0x8009000FL #endif #ifndef NTE_BAD_KEYSET #define NTE_BAD_KEYSET 0x80090016 #endif #ifndef NTE_KEYSET_NOT_DEF #define NTE_KEYSET_NOT_DEF 0x80090019 #endif
405b832004-01-30Martin Nilsson DECLARATIONS /*! @module Crypto */ /*! @module NT */ /*! @class CryptContext *! *! Class representing an HCRYPTPROV handle. */ PIKECLASS CryptContext { CVAR HCRYPTPROV handle;
f6a6ad2013-12-08Henrik Grubbström (Grubba)  /*! @decl void create(string(0..255) name, string(0..255) csp, int type,@
5bd70d2004-03-10Martin Nilsson  *! int flags)
24906f2004-03-18Martin Nilsson  *! @param name *! Key container name. When flags is set to @[CRYPT_VERIFYCONTEXT] *! the name must be @expr{0@}. *! *! @param csp *! The name of the Crypto Service Provider to use. If set to *! @expr{0@} the user default CSP will be used.
8cf6052004-03-10Martin Nilsson  */
f6a6ad2013-12-08Henrik Grubbström (Grubba)  PIKEFUN void create(int|string(0..255) str1, int|string(0..255) str2, int type, int flags)
ecc9382008-06-29Martin Nilsson  flags ID_PROTECTED;
405b832004-01-30Martin Nilsson  { if(THIS->handle) Pike_error("Already initialized.\n");
5a17b52011-10-30Henrik Grubbström (Grubba)  if(TYPEOF(*str1) == T_STRING && str1->u.string->size_shift)
3e4df22007-09-16Martin Nilsson  Pike_error("Bad argument 1. Must be 8-bit string.\n");
5a17b52011-10-30Henrik Grubbström (Grubba)  if(TYPEOF(*str2) == T_STRING && str2->u.string->size_shift)
3e4df22007-09-16Martin Nilsson  Pike_error("Bad argument 2. Must be 8-bit string.\n");
24906f2004-03-18Martin Nilsson  if(!CryptAcquireContext(&THIS->handle,
5a17b52011-10-30Henrik Grubbström (Grubba)  (TYPEOF(*str1) == T_STRING ? str1->u.string->str : 0), (TYPEOF(*str2) == T_STRING ? str2->u.string->str : 0),
5bd70d2004-03-10Martin Nilsson  type, flags)) {
405b832004-01-30Martin Nilsson  INT32 errcode = GetLastError();
24906f2004-03-18Martin Nilsson  switch(errcode) {
d124672004-03-19Henrik Grubbström (Grubba)  case NTE_EXISTS:
24906f2004-03-18Martin Nilsson  Pike_error("CryptContext->create(): Key container already exists.\n"); break;
d124672004-03-19Henrik Grubbström (Grubba)  case NTE_BAD_KEYSET:
405b832004-01-30Martin Nilsson  Pike_error("CryptContext->create(): No default key container.\n");
24906f2004-03-18Martin Nilsson  break;
d124672004-03-19Henrik Grubbström (Grubba)  case NTE_KEYSET_NOT_DEF:
24906f2004-03-18Martin Nilsson  Pike_error("CryptContext->create(): Crypto Service Provider not set up correctly.\n"); break;
2bafd32004-03-19Martin Nilsson  default:
405b832004-01-30Martin Nilsson  Pike_error("CryptContext->create(): Failed with code 0x%08x.\n", errcode);
24906f2004-03-18Martin Nilsson  break; }
405b832004-01-30Martin Nilsson  } }
f6a6ad2013-12-08Henrik Grubbström (Grubba)  /*! @decl string(0..255) read(int size, string(0..255)|void init)
405b832004-01-30Martin Nilsson  *!
8cf6052004-03-10Martin Nilsson  *! Retreive some random data. Calls CryptGenRandom in the NT API.
405b832004-01-30Martin Nilsson  */
f6a6ad2013-12-08Henrik Grubbström (Grubba)  PIKEFUN string(0..255) read(int size, string(0..255)|void init)
1a2b712004-02-14Martin Nilsson  optflags OPT_EXTERNAL_DEPEND;
405b832004-01-30Martin Nilsson  { struct pike_string *res; if(size<0) Pike_error("Negative string length.\n");
f9a39e2004-09-03Henrik Grubbström (Grubba)  if(init) { NO_WIDE_STRING(init);
405b832004-01-30Martin Nilsson  if(size==0)
f9a39e2004-09-03Henrik Grubbström (Grubba)  size = init->len;
405b832004-01-30Martin Nilsson  } res = begin_shared_string(size);
f9a39e2004-09-03Henrik Grubbström (Grubba)  if(init && size>0)
59fc9e2014-09-03Martin Nilsson  memcpy(res->str, init->str, MINIMUM(init->len,size));
405b832004-01-30Martin Nilsson  if(CryptGenRandom(THIS->handle, size, (BYTE*)res->str)) { pop_n_elems(args); push_string(end_shared_string(res)); } else { pop_n_elems(args);
801d392008-06-16Martin Stjernholm  do_free_unlinked_pike_string (res);
405b832004-01-30Martin Nilsson  push_int(0); } }
b467522017-06-25Martin Nilsson #ifdef PIKE_NULL_IS_SPECIAL
405b832004-01-30Martin Nilsson  INIT {
952bc92008-06-28Martin Stjernholm  THIS->handle = 0;
405b832004-01-30Martin Nilsson  }
b467522017-06-25Martin Nilsson #endif
405b832004-01-30Martin Nilsson  EXIT
d3df7c2008-05-30Martin Nilsson  gc_trivial;
405b832004-01-30Martin Nilsson  { if(THIS->handle)
22038d2008-05-30Martin Nilsson  {
405b832004-01-30Martin Nilsson  CryptReleaseContext(THIS->handle, 0);
22038d2008-05-30Martin Nilsson  }
405b832004-01-30Martin Nilsson  } } /*! @endclass */ /*! @endmodule */ /*! @endmodule */
c9eefb2014-08-21Martin Nilsson void nt_init(void)
405b832004-01-30Martin Nilsson { INIT; #define SIMPCONST(X) \ add_integer_constant(#X,X,0); SIMPCONST(PROV_RSA_FULL); SIMPCONST(PROV_RSA_SIG); SIMPCONST(PROV_DSS); SIMPCONST(PROV_FORTEZZA);
a656cf2004-05-10Marcus Agehall #ifdef PROV_MS_EXCHANGE
405b832004-01-30Martin Nilsson  SIMPCONST(PROV_MS_EXCHANGE);
a656cf2004-05-10Marcus Agehall #endif
c9eefb2014-08-21Martin Nilsson void nt_exit(void)
405b832004-01-30Martin Nilsson { EXIT; } #endif /* __NT__ */