Author: phater
Date: Tue May 16 17:20:56 2017
New Revision: 74558
URL:
http://svn.reactos.org/svn/reactos?rev=74558&view=rev
Log:
[MSTSC] Switch most MSTSC from internal "ssl" functions to CryptoAPI and
implement/enable certificate functions CORE-13259
Modified:
trunk/reactos/base/applications/mstsc/secure.c
trunk/reactos/base/applications/mstsc/ssl_calls.c
Modified: trunk/reactos/base/applications/mstsc/secure.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mstsc/se…
==============================================================================
--- trunk/reactos/base/applications/mstsc/secure.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/mstsc/secure.c [iso-8859-1] Tue May 16 17:20:56 2017
@@ -58,6 +58,19 @@
int
rdssl_sign_ok(char* e_data, int e_len, char* n_data, int n_len,
char* sign_data, int sign_len, char* sign_data2, int sign_len2, char*
testkey);
+PCCERT_CONTEXT
+rdssl_cert_read(uint8 * data, uint32 len);
+void
+rdssl_cert_free(PCCERT_CONTEXT context);
+uint8 *
+rdssl_cert_to_rkey(PCCERT_CONTEXT cert, uint32 * key_len);
+RD_BOOL
+rdssl_certs_ok(PCCERT_CONTEXT server_cert, PCCERT_CONTEXT cacert);
+int
+rdssl_rkey_get_exp_mod(uint8 * rkey, uint8 * exponent, uint32 max_exp_len, uint8 *
modulus,
+ uint32 max_mod_len);
+void
+rdssl_rkey_free(uint8 * rkey);
extern char g_hostname[16];
extern int g_width;
@@ -640,9 +653,9 @@
uint8 ** server_random, uint8 * modulus, uint8 * exponent)
{
uint32 crypt_level, random_len, rsa_info_len;
- uint32 /*cacert_len, cert_len,*/ flags;
- //RDSSL_CERT *cacert, *server_cert;
- //RDSSL_RKEY *server_public_key;
+ uint32 cacert_len, cert_len, flags;
+ PCCERT_CONTEXT cacert, server_cert;
+ BYTE *server_public_key;
uint16 tag, length;
uint8 *next_tag, *end;
@@ -706,7 +719,6 @@
}
else
{
-#if 0
uint32 certcount;
DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
@@ -719,7 +731,7 @@
for (; certcount > 2; certcount--)
{ /* ignore all the certificates between the root and the signing CA */
uint32 ignorelen;
- RDSSL_CERT *ignorecert;
+ PCCERT_CONTEXT ignorecert;
DEBUG_RDP5(("Ignored certs left: %d\n", certcount));
in_uint32_le(s, ignorelen);
@@ -797,7 +809,6 @@
}
rdssl_rkey_free(server_public_key);
return True; /* There's some garbage here we don't care about */
-#endif
}
return s_check_end(s);
}
Modified: trunk/reactos/base/applications/mstsc/ssl_calls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mstsc/ss…
==============================================================================
--- trunk/reactos/base/applications/mstsc/ssl_calls.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/mstsc/ssl_calls.c [iso-8859-1] Tue May 16 17:20:56
2017
@@ -22,733 +22,576 @@
#include "precomp.h"
-#define APP_CC
-
/*****************************************************************************/
static void * g_malloc(int size, int zero)
{
- void * p;
-
- p = xmalloc(size);
- if (zero)
- {
- memset(p, 0, size);
- }
- return p;
+ void * p;
+
+ p = CryptMemAlloc(size);
+ if (zero)
+ {
+ memset(p, 0, size);
+ }
+ return p;
}
/*****************************************************************************/
static void g_free(void * in)
{
- xfree(in);
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-/* rc4 stuff */
-/* An implementation of the ARC4 algorithm
- *
- * Copyright (C) 2001-2003 Christophe Devine
- */
+ CryptMemFree(in);
+}
+
struct rc4_state
{
- int x;
- int y;
- int m[256];
+ HCRYPTPROV hCryptProv;
+ HCRYPTKEY hKey;
};
-
-/*****************************************************************************/
-void* APP_CC
+/*****************************************************************************/
+void*
rdssl_rc4_info_create(void)
{
- return g_malloc(sizeof(struct rc4_state), 1);
-}
-
-/*****************************************************************************/
-void APP_CC
+ struct rc4_state *info = g_malloc(sizeof(struct rc4_state), 1);
+ BOOL ret;
+ DWORD dwErr;
+ if (!info)
+ {
+ error("rdssl_rc4_info_create no memory\n");
+ return NULL;
+ }
+ ret = CryptAcquireContext(&info->hCryptProv,
+ NULL,
+ MS_ENHANCED_PROV,
+ PROV_RSA_FULL,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptAcquireContext failed with %lx\n", dwErr);
+ g_free(info);
+ return NULL;
+ }
+ return info;
+}
+
+/*****************************************************************************/
+void
rdssl_rc4_info_delete(void* rc4_info)
{
- g_free(rc4_info);
-}
-
-/*****************************************************************************/
-void APP_CC
+ struct rc4_state *info = rc4_info;
+ BOOL ret = TRUE;
+ DWORD dwErr;
+ if (!info)
+ {
+ //error("rdssl_rc4_info_delete rc4_info is null\n");
+ return;
+ }
+ if (info->hKey)
+ {
+ ret = CryptDestroyKey(info->hKey);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptDestroyKey failed with %lx\n", dwErr);
+ }
+ }
+ if (info->hCryptProv)
+ {
+ ret = CryptReleaseContext(info->hCryptProv, 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptReleaseContext failed with %lx\n", dwErr);
+ }
+ }
+ g_free(rc4_info);
+}
+
+/*****************************************************************************/
+void
rdssl_rc4_set_key(void* rc4_info, char* key, int len)
{
- int i;
- int j;
- int k;
- int a;
- int* m;
- struct rc4_state* s;
-
- s = (struct rc4_state*)rc4_info;
- s->x = 0;
- s->y = 0;
- m = s->m;
- for (i = 0; i < 256; i++)
- {
- m[i] = i;
- }
- j = 0;
- k = 0;
- for (i = 0; i < 256; i++)
- {
- a = m[i];
- j = (unsigned char)(j + a + key[k]);
- m[i] = m[j];
- m[j] = a;
- k++;
- if (k >= len)
- {
- k = 0;
- }
- }
-}
-
-/*****************************************************************************/
-void APP_CC
+ struct rc4_state *info = rc4_info;
+ BOOL ret;
+ DWORD dwErr;
+ BYTE * blob;
+ PUBLICKEYSTRUC *desc;
+ DWORD * keySize;
+ BYTE * keyBuf;
+ if (!rc4_info || !key || !len || !info->hCryptProv)
+ {
+ error("rdssl_rc4_set_key %p %p %d\n", rc4_info, key, len);
+ return;
+ }
+ blob = g_malloc(sizeof(PUBLICKEYSTRUC) + sizeof(DWORD) + len, 0);
+ if (!blob)
+ {
+ error("rdssl_rc4_set_key no memory\n");
+ return;
+ }
+ desc = (PUBLICKEYSTRUC *)blob;
+ keySize = (DWORD *)(blob + sizeof(PUBLICKEYSTRUC));
+ keyBuf = blob + sizeof(PUBLICKEYSTRUC) + sizeof(DWORD);
+ desc->aiKeyAlg = CALG_RC4;
+ desc->bType = PLAINTEXTKEYBLOB;
+ desc->bVersion = CUR_BLOB_VERSION;
+ desc->reserved = 0;
+ *keySize = len;
+ memcpy(keyBuf, key, len);
+ if (info->hKey)
+ {
+ CryptDestroyKey(info->hKey);
+ info->hKey = 0;
+ }
+ ret = CryptImportKey(info->hCryptProv,
+ blob,
+ sizeof(PUBLICKEYSTRUC) + sizeof(DWORD) + len,
+ 0,
+ CRYPT_EXPORTABLE,
+ &info->hKey);
+ g_free(blob);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptImportKey failed with %lx\n", dwErr);
+ }
+}
+
+/*****************************************************************************/
+void
rdssl_rc4_crypt(void* rc4_info, char* in_data, char* out_data, int len)
{
- int i;
- int x;
- int y;
- int a;
- int b;
- int* m;
- struct rc4_state* s;
-
- s = (struct rc4_state*)rc4_info;
- x = s->x;
- y = s->y;
- m = s->m;
- for (i = 0; i < len; i++)
- {
- x = (unsigned char)(x + 1);
- a = m[x];
- y = (unsigned char)(y + a);
- b = m[y];
- m[x] = b;
- m[y] = a;
- out_data[i] = in_data[i] ^ (m[(unsigned char)(a + b)]);
- }
- s->x = x;
- s->y = y;
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-/* sha1 stuff */
-/* FIPS-180-1 compliant SHA-1 implementation
- *
- * Copyright (C) 2001-2003 Christophe Devine
- */
-struct sha1_context
-{
- int total[2];
- int state[5];
- char buffer[64];
+ struct rc4_state *info = rc4_info;
+ BOOL ret;
+ DWORD dwErr;
+ BYTE * intermediate_data;
+ DWORD dwLen = len;
+ if (!rc4_info || !in_data || !out_data || !len || !info->hKey)
+ {
+ error("rdssl_rc4_crypt %p %p %p %d\n", rc4_info, in_data, out_data,
len);
+ return;
+ }
+ intermediate_data = g_malloc(len, 0);
+ if (!intermediate_data)
+ {
+ error("rdssl_rc4_set_key no memory\n");
+ return;
+ }
+ memcpy(intermediate_data, in_data, len);
+ ret = CryptEncrypt(info->hKey,
+ 0,
+ FALSE,
+ 0,
+ intermediate_data,
+ &dwLen,
+ dwLen);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(intermediate_data);
+ error("CryptEncrypt failed with %lx\n", dwErr);
+ return;
+ }
+ memcpy(out_data, intermediate_data, len);
+ g_free(intermediate_data);
+}
+
+struct hash_context
+{
+ HCRYPTPROV hCryptProv;
+ HCRYPTKEY hHash;
};
/*****************************************************************************/
-void* APP_CC
+void*
+rdssl_hash_info_create(ALG_ID id)
+{
+ struct hash_context *info = g_malloc(sizeof(struct hash_context), 1);
+ BOOL ret;
+ DWORD dwErr;
+ if (!info)
+ {
+ error("rdssl_hash_info_create %d no memory\n", id);
+ return NULL;
+ }
+ ret = CryptAcquireContext(&info->hCryptProv,
+ NULL,
+ MS_ENHANCED_PROV,
+ PROV_RSA_FULL,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(info);
+ error("CryptAcquireContext failed with %lx\n", dwErr);
+ return NULL;
+ }
+ ret = CryptCreateHash(info->hCryptProv,
+ id,
+ 0,
+ 0,
+ &info->hHash);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ CryptReleaseContext(info->hCryptProv, 0);
+ g_free(info);
+ error("CryptCreateHash failed with %lx\n", dwErr);
+ return NULL;
+ }
+ return info;
+}
+
+/*****************************************************************************/
+void
+rdssl_hash_info_delete(void* hash_info)
+{
+ struct hash_context *info = hash_info;
+ if (!info)
+ {
+ //error("ssl_hash_info_delete hash_info is null\n");
+ return;
+ }
+ if (info->hHash)
+ {
+ CryptDestroyHash(info->hHash);
+ }
+ if (info->hCryptProv)
+ {
+ CryptReleaseContext(info->hCryptProv, 0);
+ }
+ g_free(hash_info);
+}
+
+/*****************************************************************************/
+void
+rdssl_hash_clear(void* hash_info, ALG_ID id)
+{
+ struct hash_context *info = hash_info;
+ BOOL ret;
+ DWORD dwErr;
+ if (!info || !info->hHash || !info->hCryptProv)
+ {
+ error("rdssl_hash_clear %p\n", info);
+ return;
+ }
+ ret = CryptDestroyHash(info->hHash);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptDestroyHash failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptCreateHash(info->hCryptProv,
+ id,
+ 0,
+ 0,
+ &info->hHash);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptCreateHash failed with %lx\n", dwErr);
+ }
+}
+
+void
+rdssl_hash_transform(void* hash_info, char* data, int len)
+{
+ struct hash_context *info = hash_info;
+ BOOL ret;
+ DWORD dwErr;
+ if (!info || !info->hHash || !info->hCryptProv || !data || !len)
+ {
+ error("rdssl_hash_transform %p %p %d\n", hash_info, data, len);
+ return;
+ }
+ ret = CryptHashData(info->hHash,
+ (BYTE *)data,
+ len,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptHashData failed with %lx\n", dwErr);
+ }
+}
+
+/*****************************************************************************/
+void
+rdssl_hash_complete(void* hash_info, char* data)
+{
+ struct hash_context *info = hash_info;
+ BOOL ret;
+ DWORD dwErr, dwDataLen;
+ if (!info || !info->hHash || !info->hCryptProv || !data)
+ {
+ error("rdssl_hash_complete %p %p\n", hash_info, data);
+ return;
+ }
+ ret = CryptGetHashParam(info->hHash,
+ HP_HASHVAL,
+ NULL,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptGetHashParam(info->hHash,
+ HP_HASHVAL,
+ (BYTE *)data,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ }
+}
+
+/*****************************************************************************/
+void*
rdssl_sha1_info_create(void)
{
- return g_malloc(sizeof(struct sha1_context), 1);
-}
-
-/*****************************************************************************/
-void APP_CC
+ return rdssl_hash_info_create(CALG_SHA1);
+}
+
+/*****************************************************************************/
+void
rdssl_sha1_info_delete(void* sha1_info)
{
- g_free(sha1_info);
-}
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_info_delete(sha1_info);
+}
+
+/*****************************************************************************/
+void
rdssl_sha1_clear(void* sha1_info)
{
- struct sha1_context* ctx;
-
- ctx = (struct sha1_context*)sha1_info;
- memset(ctx, 0, sizeof(struct sha1_context));
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
- ctx->state[4] = 0xC3D2E1F0;
-}
-
-#undef GET_UINT32
-#define GET_UINT32(n, b, i) \
-{ \
- (n) = ((b)[(i) + 0] << 24) | \
- ((b)[(i) + 1] << 16) | \
- ((b)[(i) + 2] << 8) | \
- ((b)[(i) + 3] << 0); \
-}
-
-#undef PUT_UINT32
-#define PUT_UINT32(n, b, i) \
-{ \
- (b)[(i) + 0] = ((n) >> 24); \
- (b)[(i) + 1] = ((n) >> 16); \
- (b)[(i) + 2] = ((n) >> 8); \
- (b)[(i) + 3] = ((n) >> 0); \
-}
-
-/*****************************************************************************/
-static void APP_CC
-sha1_process(struct sha1_context* ctx, char* in_data)
-{
- int temp;
- int W[16];
- int A;
- int B;
- int C;
- int D;
- int E;
- unsigned char* data;
-
- data = (unsigned char*)in_data;
-
- GET_UINT32(W[0], data, 0);
- GET_UINT32(W[1], data, 4);
- GET_UINT32(W[2], data, 8);
- GET_UINT32(W[3], data, 12);
- GET_UINT32(W[4], data, 16);
- GET_UINT32(W[5], data, 20);
- GET_UINT32(W[6], data, 24);
- GET_UINT32(W[7], data, 28);
- GET_UINT32(W[8], data, 32);
- GET_UINT32(W[9], data, 36);
- GET_UINT32(W[10], data, 40);
- GET_UINT32(W[11], data, 44);
- GET_UINT32(W[12], data, 48);
- GET_UINT32(W[13], data, 52);
- GET_UINT32(W[14], data, 56);
- GET_UINT32(W[15], data, 60);
-
-#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#define R(t) \
-( \
- temp = W[(t - 3) & 0x0F] ^ \
- W[(t - 8) & 0x0F] ^ \
- W[(t - 14) & 0x0F] ^ \
- W[(t - 0) & 0x0F], \
- (W[t & 0x0F] = S(temp, 1)) \
-)
-
-#undef P
-#define P(a, b, c, d, e, x) \
-{ \
- e += S(a, 5) + F(b, c, d) + K + x; \
- b = S(b, 30); \
-}
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
- E = ctx->state[4];
-
-#define F(x, y, z) (z ^ (x & (y ^ z)))
-#define K 0x5A827999
-
- P(A, B, C, D, E, W[0]);
- P(E, A, B, C, D, W[1]);
- P(D, E, A, B, C, W[2]);
- P(C, D, E, A, B, W[3]);
- P(B, C, D, E, A, W[4]);
- P(A, B, C, D, E, W[5]);
- P(E, A, B, C, D, W[6]);
- P(D, E, A, B, C, W[7]);
- P(C, D, E, A, B, W[8]);
- P(B, C, D, E, A, W[9]);
- P(A, B, C, D, E, W[10]);
- P(E, A, B, C, D, W[11]);
- P(D, E, A, B, C, W[12]);
- P(C, D, E, A, B, W[13]);
- P(B, C, D, E, A, W[14]);
- P(A, B, C, D, E, W[15]);
- P(E, A, B, C, D, R(16));
- P(D, E, A, B, C, R(17));
- P(C, D, E, A, B, R(18));
- P(B, C, D, E, A, R(19));
-
-#undef K
-#undef F
-
-#define F(x, y, z) (x ^ y ^ z)
-#define K 0x6ED9EBA1
-
- P(A, B, C, D, E, R(20));
- P(E, A, B, C, D, R(21));
- P(D, E, A, B, C, R(22));
- P(C, D, E, A, B, R(23));
- P(B, C, D, E, A, R(24));
- P(A, B, C, D, E, R(25));
- P(E, A, B, C, D, R(26));
- P(D, E, A, B, C, R(27));
- P(C, D, E, A, B, R(28));
- P(B, C, D, E, A, R(29));
- P(A, B, C, D, E, R(30));
- P(E, A, B, C, D, R(31));
- P(D, E, A, B, C, R(32));
- P(C, D, E, A, B, R(33));
- P(B, C, D, E, A, R(34));
- P(A, B, C, D, E, R(35));
- P(E, A, B, C, D, R(36));
- P(D, E, A, B, C, R(37));
- P(C, D, E, A, B, R(38));
- P(B, C, D, E, A, R(39));
-
-#undef K
-#undef F
-
-#define F(x, y, z) ((x & y) | (z & (x | y)))
-#define K 0x8F1BBCDC
-
- P(A, B, C, D, E, R(40));
- P(E, A, B, C, D, R(41));
- P(D, E, A, B, C, R(42));
- P(C, D, E, A, B, R(43));
- P(B, C, D, E, A, R(44));
- P(A, B, C, D, E, R(45));
- P(E, A, B, C, D, R(46));
- P(D, E, A, B, C, R(47));
- P(C, D, E, A, B, R(48));
- P(B, C, D, E, A, R(49));
- P(A, B, C, D, E, R(50));
- P(E, A, B, C, D, R(51));
- P(D, E, A, B, C, R(52));
- P(C, D, E, A, B, R(53));
- P(B, C, D, E, A, R(54));
- P(A, B, C, D, E, R(55));
- P(E, A, B, C, D, R(56));
- P(D, E, A, B, C, R(57));
- P(C, D, E, A, B, R(58));
- P(B, C, D, E, A, R(59));
-
-#undef K
-#undef F
-
-#define F(x, y, z) (x ^ y ^ z)
-#define K 0xCA62C1D6
-
- P(A, B, C, D, E, R(60));
- P(E, A, B, C, D, R(61));
- P(D, E, A, B, C, R(62));
- P(C, D, E, A, B, R(63));
- P(B, C, D, E, A, R(64));
- P(A, B, C, D, E, R(65));
- P(E, A, B, C, D, R(66));
- P(D, E, A, B, C, R(67));
- P(C, D, E, A, B, R(68));
- P(B, C, D, E, A, R(69));
- P(A, B, C, D, E, R(70));
- P(E, A, B, C, D, R(71));
- P(D, E, A, B, C, R(72));
- P(C, D, E, A, B, R(73));
- P(B, C, D, E, A, R(74));
- P(A, B, C, D, E, R(75));
- P(E, A, B, C, D, R(76));
- P(D, E, A, B, C, R(77));
- P(C, D, E, A, B, R(78));
- P(B, C, D, E, A, R(79));
-
-#undef K
-#undef F
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
- ctx->state[4] += E;
-}
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_clear(sha1_info, CALG_SHA1);
+}
+
+/*****************************************************************************/
+void
rdssl_sha1_transform(void* sha1_info, char* data, int len)
{
- int left;
- int fill;
- struct sha1_context* ctx;
-
- ctx = (struct sha1_context*)sha1_info;
- if (len == 0)
- {
- return;
- }
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += len;
- ctx->total[0] &= 0xFFFFFFFF;
- if (ctx->total[0] < len)
- {
- ctx->total[1]++;
- }
- if (left && (len >= fill))
- {
- memcpy(ctx->buffer + left, data, fill);
- sha1_process(ctx, ctx->buffer);
- len -= fill;
- data += fill;
- left = 0;
- }
- while (len >= 64)
- {
- sha1_process(ctx, data);
- len -= 64;
- data += 64;
- }
- if (len != 0)
- {
- memcpy(ctx->buffer + left, data, len);
- }
-}
-
-static unsigned char sha1_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_transform(sha1_info, data, len);
+}
+
+/*****************************************************************************/
+void
rdssl_sha1_complete(void* sha1_info, char* data)
{
- int last;
- int padn;
- int high;
- int low;
- char msglen[8];
- struct sha1_context* ctx;
-
- ctx = (struct sha1_context*)sha1_info;
- high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
- low = (ctx->total[0] << 3);
- PUT_UINT32(high, msglen, 0);
- PUT_UINT32(low, msglen, 4);
- last = ctx->total[0] & 0x3F;
- padn = (last < 56) ? (56 - last) : (120 - last);
- rdssl_sha1_transform(ctx, (char *)sha1_padding, padn);
- rdssl_sha1_transform(ctx, msglen, 8);
- PUT_UINT32(ctx->state[0], data, 0);
- PUT_UINT32(ctx->state[1], data, 4);
- PUT_UINT32(ctx->state[2], data, 8);
- PUT_UINT32(ctx->state[3], data, 12);
- PUT_UINT32(ctx->state[4], data, 16);
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-/* md5 stuff */
-/* RFC 1321 compliant MD5 implementation
- *
- * Copyright (C) 2001-2003 Christophe Devine
- */
-
-struct md5_context
-{
- int total[2];
- int state[4];
- char buffer[64];
-};
-
-/*****************************************************************************/
-void* APP_CC
+ rdssl_hash_complete(sha1_info, data);
+}
+
+/*****************************************************************************/
+void*
rdssl_md5_info_create(void)
{
- return g_malloc(sizeof(struct md5_context), 1);
-}
-
-/*****************************************************************************/
-void APP_CC
+ return rdssl_hash_info_create(CALG_MD5);
+}
+
+/*****************************************************************************/
+void
rdssl_md5_info_delete(void* md5_info)
{
- g_free(md5_info);
-}
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_info_delete(md5_info);
+}
+
+/*****************************************************************************/
+void
rdssl_md5_clear(void* md5_info)
{
- struct md5_context* ctx;
-
- ctx = (struct md5_context*)md5_info;
- memset(ctx, 0, sizeof(struct md5_context));
- ctx->state[0] = 0x67452301;
- ctx->state[1] = 0xEFCDAB89;
- ctx->state[2] = 0x98BADCFE;
- ctx->state[3] = 0x10325476;
-}
-
-#undef GET_UINT32
-#define GET_UINT32(n, b, i) \
-{ \
- (n) = ((b)[(i) + 0] << 0) | \
- ((b)[(i) + 1] << 8) | \
- ((b)[(i) + 2] << 16) | \
- ((b)[(i) + 3] << 24); \
-}
-
-#undef PUT_UINT32
-#define PUT_UINT32(n, b, i) \
-{ \
- (b)[(i) + 0] = ((n) >> 0); \
- (b)[(i) + 1] = ((n) >> 8); \
- (b)[(i) + 2] = ((n) >> 16); \
- (b)[(i) + 3] = ((n) >> 24); \
-}
-
-/*****************************************************************************/
-static void
-md5_process(struct md5_context* ctx, char* in_data)
-{
- int X[16];
- int A;
- int B;
- int C;
- int D;
- unsigned char* data;
-
- data = (unsigned char*)in_data;
- GET_UINT32(X[0], data, 0);
- GET_UINT32(X[1], data, 4);
- GET_UINT32(X[2], data, 8);
- GET_UINT32(X[3], data, 12);
- GET_UINT32(X[4], data, 16);
- GET_UINT32(X[5], data, 20);
- GET_UINT32(X[6], data, 24);
- GET_UINT32(X[7], data, 28);
- GET_UINT32(X[8], data, 32);
- GET_UINT32(X[9], data, 36);
- GET_UINT32(X[10], data, 40);
- GET_UINT32(X[11], data, 44);
- GET_UINT32(X[12], data, 48);
- GET_UINT32(X[13], data, 52);
- GET_UINT32(X[14], data, 56);
- GET_UINT32(X[15], data, 60);
-
-#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#undef P
-#define P(a, b, c, d, k, s, t) \
-{ \
- a += F(b, c, d) + X[k] + t; \
- a = S(a, s) + b; \
-}
-
- A = ctx->state[0];
- B = ctx->state[1];
- C = ctx->state[2];
- D = ctx->state[3];
-
-#define F(x, y, z) (z ^ (x & (y ^ z)))
-
- P(A, B, C, D, 0, 7, 0xD76AA478);
- P(D, A, B, C, 1, 12, 0xE8C7B756);
- P(C, D, A, B, 2, 17, 0x242070DB);
- P(B, C, D, A, 3, 22, 0xC1BDCEEE);
- P(A, B, C, D, 4, 7, 0xF57C0FAF);
- P(D, A, B, C, 5, 12, 0x4787C62A);
- P(C, D, A, B, 6, 17, 0xA8304613);
- P(B, C, D, A, 7, 22, 0xFD469501);
- P(A, B, C, D, 8, 7, 0x698098D8);
- P(D, A, B, C, 9, 12, 0x8B44F7AF);
- P(C, D, A, B, 10, 17, 0xFFFF5BB1);
- P(B, C, D, A, 11, 22, 0x895CD7BE);
- P(A, B, C, D, 12, 7, 0x6B901122);
- P(D, A, B, C, 13, 12, 0xFD987193);
- P(C, D, A, B, 14, 17, 0xA679438E);
- P(B, C, D, A, 15, 22, 0x49B40821);
-
-#undef F
-
-#define F(x, y, z) (y ^ (z & (x ^ y)))
-
- P(A, B, C, D, 1, 5, 0xF61E2562);
- P(D, A, B, C, 6, 9, 0xC040B340);
- P(C, D, A, B, 11, 14, 0x265E5A51);
- P(B, C, D, A, 0, 20, 0xE9B6C7AA);
- P(A, B, C, D, 5, 5, 0xD62F105D);
- P(D, A, B, C, 10, 9, 0x02441453);
- P(C, D, A, B, 15, 14, 0xD8A1E681);
- P(B, C, D, A, 4, 20, 0xE7D3FBC8);
- P(A, B, C, D, 9, 5, 0x21E1CDE6);
- P(D, A, B, C, 14, 9, 0xC33707D6);
- P(C, D, A, B, 3, 14, 0xF4D50D87);
- P(B, C, D, A, 8, 20, 0x455A14ED);
- P(A, B, C, D, 13, 5, 0xA9E3E905);
- P(D, A, B, C, 2, 9, 0xFCEFA3F8);
- P(C, D, A, B, 7, 14, 0x676F02D9);
- P(B, C, D, A, 12, 20, 0x8D2A4C8A);
-
-#undef F
-
-#define F(x, y, z) (x ^ y ^ z)
-
- P(A, B, C, D, 5, 4, 0xFFFA3942);
- P(D, A, B, C, 8, 11, 0x8771F681);
- P(C, D, A, B, 11, 16, 0x6D9D6122);
- P(B, C, D, A, 14, 23, 0xFDE5380C);
- P(A, B, C, D, 1, 4, 0xA4BEEA44);
- P(D, A, B, C, 4, 11, 0x4BDECFA9);
- P(C, D, A, B, 7, 16, 0xF6BB4B60);
- P(B, C, D, A, 10, 23, 0xBEBFBC70);
- P(A, B, C, D, 13, 4, 0x289B7EC6);
- P(D, A, B, C, 0, 11, 0xEAA127FA);
- P(C, D, A, B, 3, 16, 0xD4EF3085);
- P(B, C, D, A, 6, 23, 0x04881D05);
- P(A, B, C, D, 9, 4, 0xD9D4D039);
- P(D, A, B, C, 12, 11, 0xE6DB99E5);
- P(C, D, A, B, 15, 16, 0x1FA27CF8);
- P(B, C, D, A, 2, 23, 0xC4AC5665);
-
-#undef F
-
-#define F(x, y, z) (y ^ (x | ~z))
-
- P(A, B, C, D, 0, 6, 0xF4292244);
- P(D, A, B, C, 7, 10, 0x432AFF97);
- P(C, D, A, B, 14, 15, 0xAB9423A7);
- P(B, C, D, A, 5, 21, 0xFC93A039);
- P(A, B, C, D, 12, 6, 0x655B59C3);
- P(D, A, B, C, 3, 10, 0x8F0CCC92);
- P(C, D, A, B, 10, 15, 0xFFEFF47D);
- P(B, C, D, A, 1, 21, 0x85845DD1);
- P(A, B, C, D, 8, 6, 0x6FA87E4F);
- P(D, A, B, C, 15, 10, 0xFE2CE6E0);
- P(C, D, A, B, 6, 15, 0xA3014314);
- P(B, C, D, A, 13, 21, 0x4E0811A1);
- P(A, B, C, D, 4, 6, 0xF7537E82);
- P(D, A, B, C, 11, 10, 0xBD3AF235);
- P(C, D, A, B, 2, 15, 0x2AD7D2BB);
- P(B, C, D, A, 9, 21, 0xEB86D391);
-
-#undef F
-
- ctx->state[0] += A;
- ctx->state[1] += B;
- ctx->state[2] += C;
- ctx->state[3] += D;
-}
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_clear(md5_info, CALG_MD5);
+}
+
+/*****************************************************************************/
+void
rdssl_md5_transform(void* md5_info, char* data, int len)
{
- int left;
- int fill;
- struct md5_context* ctx;
-
- ctx = (struct md5_context*)md5_info;
- if (len == 0)
- {
- return;
- }
- left = ctx->total[0] & 0x3F;
- fill = 64 - left;
- ctx->total[0] += len;
- ctx->total[0] &= 0xFFFFFFFF;
- if (ctx->total[0] < len)
- {
- ctx->total[1]++;
- }
- if (left && (len >= fill))
- {
- memcpy(ctx->buffer + left, data, fill);
- md5_process(ctx, ctx->buffer);
- len -= fill;
- data += fill;
- left = 0;
- }
- while (len >= 64)
- {
- md5_process(ctx, data);
- len -= 64;
- data += 64;
- }
- if (len != 0)
- {
- memcpy(ctx->buffer + left, data, len);
- }
-}
-
-static unsigned char md5_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*****************************************************************************/
-void APP_CC
+ rdssl_hash_transform(md5_info, data, len);
+}
+
+/*****************************************************************************/
+void
rdssl_md5_complete(void* md5_info, char* data)
{
- int last;
- int padn;
- int high;
- int low;
- char msglen[8];
- struct md5_context* ctx;
-
- ctx = (struct md5_context*)md5_info;
- high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
- low = (ctx->total[0] << 3);
- PUT_UINT32(low, msglen, 0);
- PUT_UINT32(high, msglen, 4);
- last = ctx->total[0] & 0x3F;
- padn = (last < 56) ? (56 - last) : (120 - last);
- rdssl_md5_transform(ctx, (char *)md5_padding, padn);
- rdssl_md5_transform(ctx, msglen, 8);
- PUT_UINT32(ctx->state[0], data, 0);
- PUT_UINT32(ctx->state[1], data, 4);
- PUT_UINT32(ctx->state[2], data, 8);
- PUT_UINT32(ctx->state[3], data, 12);
-}
-
-void APP_CC
+ rdssl_hash_complete(md5_info, data);
+}
+
+/*****************************************************************************/
+void
rdssl_hmac_md5(char* key, int keylen, char* data, int len, char* output)
{
- int i;
- char ipad[64];
- char opad[64];
- char sum[16];
- void* ctx;
-
- if( keylen > 64 )
- {
- ctx = rdssl_md5_info_create();
- rdssl_md5_transform(ctx, key, keylen);
- rdssl_md5_complete(ctx, sum);
- rdssl_md5_info_delete(ctx);
- keylen = 16;
- key = sum;
- }
-
- memset( ipad, 0x36, sizeof(ipad) );
- memset( opad, 0x5C, sizeof(opad) );
-
- for( i = 0; i < keylen; i++ )
- {
- ipad[i] = ipad[i] ^ key[i];
- opad[i] = opad[i] ^ key[i];
- }
- ctx = rdssl_md5_info_create();
- rdssl_md5_transform(ctx, ipad, sizeof(ipad));
- rdssl_md5_transform(ctx, data, len);
- rdssl_md5_complete(ctx, sum);
- rdssl_md5_info_delete(ctx);
- ctx = rdssl_md5_info_create();
- rdssl_md5_transform(ctx, opad, sizeof(opad));
- rdssl_md5_complete(ctx, output);
- rdssl_md5_info_delete(ctx);
+ HCRYPTPROV hCryptProv;
+ HCRYPTKEY hKey;
+ HCRYPTKEY hHash;
+ BOOL ret;
+ DWORD dwErr, dwDataLen;
+ HMAC_INFO info;
+ BYTE * blob;
+ PUBLICKEYSTRUC *desc;
+ DWORD * keySize;
+ BYTE * keyBuf;
+ BYTE sum[16];
+
+ if (!key || !keylen || !data || !len ||!output)
+ {
+ error("rdssl_hmac_md5 %p %d %p %d %p\n", key, keylen, data, len,
output);
+ return;
+ }
+ blob = g_malloc(sizeof(PUBLICKEYSTRUC) + sizeof(DWORD) + keylen, 0);
+ desc = (PUBLICKEYSTRUC *)blob;
+ keySize = (DWORD *)(blob + sizeof(PUBLICKEYSTRUC));
+ keyBuf = blob + sizeof(PUBLICKEYSTRUC) + sizeof(DWORD);
+ if (!blob)
+ {
+ error("rdssl_hmac_md5 %d no memory\n");
+ return;
+ }
+ ret = CryptAcquireContext(&hCryptProv,
+ NULL,
+ MS_ENHANCED_PROV,
+ PROV_RSA_FULL,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(blob);
+ error("CryptAcquireContext failed with %lx\n", dwErr);
+ return;
+ }
+ desc->aiKeyAlg = CALG_RC4;
+ desc->bType = PLAINTEXTKEYBLOB;
+ desc->bVersion = CUR_BLOB_VERSION;
+ desc->reserved = 0;
+ if (keylen > 64)
+ {
+ HCRYPTKEY hHash;
+ ret = CryptCreateHash(hCryptProv,
+ CALG_MD5,
+ 0,
+ 0,
+ &hHash);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(blob);
+ error("CryptCreateHash failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptHashData(hHash,
+ (BYTE *)key,
+ keylen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(blob);
+ error("CryptHashData failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptGetHashParam(hHash,
+ HP_HASHVAL,
+ NULL,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(blob);
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptGetHashParam(hHash,
+ HP_HASHVAL,
+ sum,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(blob);
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ keylen = dwDataLen;
+ key = (char *)sum;
+ }
+ *keySize = keylen;
+ memcpy(keyBuf, key, keylen);
+ ret = CryptImportKey(hCryptProv,
+ blob,
+ sizeof(PUBLICKEYSTRUC) + sizeof(DWORD) + keylen,
+ 0,
+ CRYPT_EXPORTABLE,
+ &hKey);
+ g_free(blob);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptImportKey failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptCreateHash(hCryptProv,
+ CALG_HMAC,
+ hKey,
+ 0,
+ &hHash);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptCreateHash failed with %lx\n", dwErr);
+ return;
+ }
+ info.HashAlgid = CALG_MD5;
+ info.cbInnerString = 0;
+ info.cbOuterString = 0;
+ ret = CryptSetHashParam(hHash,
+ HP_HMAC_INFO,
+ (BYTE *)&info,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptSetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptHashData(hHash,
+ (BYTE *)data,
+ len,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptHashData failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptGetHashParam(hHash,
+ HP_HASHVAL,
+ NULL,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ ret = CryptGetHashParam(hHash,
+ HP_HASHVAL,
+ (BYTE *)output,
+ &dwDataLen,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptGetHashParam failed with %lx\n", dwErr);
+ return;
+ }
+ CryptDestroyHash(hHash);
+ ret = CryptReleaseContext(hCryptProv, 0);
}
/*****************************************************************************/
@@ -816,7 +659,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
mpAdd(DIGIT_T* w, DIGIT_T* u, DIGIT_T* v, unsigned int ndigits)
{
/* Calculates w = u + v
@@ -852,7 +695,7 @@
}
/*****************************************************************************/
-static void APP_CC
+static void
mpSetDigit(DIGIT_T* a, DIGIT_T d, unsigned int ndigits)
{ /* Sets a = d where d is a single digit */
unsigned int i;
@@ -865,7 +708,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
mpCompare(DIGIT_T* a, DIGIT_T* b, unsigned int ndigits)
{
/* Returns sign of (a - b) */
@@ -888,7 +731,7 @@
}
/*****************************************************************************/
-static void APP_CC
+static void
mpSetZero(DIGIT_T* a, unsigned int ndigits)
{ /* Sets a = 0 */
unsigned int i;
@@ -900,7 +743,7 @@
}
/*****************************************************************************/
-static void APP_CC
+static void
mpSetEqual(DIGIT_T* a, DIGIT_T* b, unsigned int ndigits)
{ /* Sets a = b */
unsigned int i;
@@ -912,7 +755,7 @@
}
/*****************************************************************************/
-static unsigned int APP_CC
+static unsigned int
mpSizeof(DIGIT_T* a, unsigned int ndigits)
{ /* Returns size of significant digits in a */
while (ndigits--)
@@ -926,7 +769,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
mpShiftLeft(DIGIT_T* a, DIGIT_T* b, unsigned int x, unsigned int ndigits)
{ /* Computes a = b << x */
unsigned int i;
@@ -962,7 +805,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
mpShiftRight(DIGIT_T* a, DIGIT_T* b, unsigned int x, unsigned int ndigits)
{ /* Computes a = b >> x */
unsigned int i;
@@ -999,7 +842,7 @@
}
/*****************************************************************************/
-static void APP_CC
+static void
spMultSub(DIGIT_T* uu, DIGIT_T qhat, DIGIT_T v1, DIGIT_T v0)
{
/* Compute uu = uu - q(v1v0)
@@ -1022,7 +865,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
spMultiply(DIGIT_T* p, DIGIT_T x, DIGIT_T y)
{ /* Computes p = x * y */
/* Ref: Arbitrary Precision Computation
@@ -1093,7 +936,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
spDivide(DIGIT_T* q, DIGIT_T* r, DIGIT_T* u, DIGIT_T v)
{ /* Computes quotient q = u / v, remainder r = u mod v
where u is a double digit
@@ -1234,7 +1077,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
QhatTooBig(DIGIT_T qhat, DIGIT_T rhat, DIGIT_T vn2, DIGIT_T ujn2)
{ /* Returns true if Qhat is too big
i.e. if (Qhat * Vn-2) > (b.Rhat + Uj+n-2) */
@@ -1257,7 +1100,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
mpShortDiv(DIGIT_T* q, DIGIT_T* u, DIGIT_T v, unsigned int ndigits)
{
/* Calculates quotient q = u div v
@@ -1316,7 +1159,7 @@
}
/*****************************************************************************/
-static DIGIT_T APP_CC
+static DIGIT_T
mpMultSub(DIGIT_T wn, DIGIT_T* w, DIGIT_T* v, DIGIT_T q, unsigned int n)
{ /* Compute w = w - qv
where w = (WnW[n-1]...W[0])
@@ -1355,7 +1198,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
mpDivide(DIGIT_T* q, DIGIT_T* r, DIGIT_T* u, unsigned int udigits,
DIGIT_T* v, unsigned int vdigits)
{ /* Computes quotient q = u / v and remainder r = u mod v
@@ -1501,7 +1344,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
mpModulo(DIGIT_T* r, DIGIT_T* u, unsigned int udigits,
DIGIT_T* v, unsigned int vdigits)
{
@@ -1528,7 +1371,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
mpMultiply(DIGIT_T* w, DIGIT_T* u, DIGIT_T* v, unsigned int ndigits)
{
/* Computes product w = u * v
@@ -1586,7 +1429,7 @@
}
/*****************************************************************************/
-static int APP_CC
+static int
mpModMult(DIGIT_T* a, DIGIT_T* x, DIGIT_T* y,
DIGIT_T* m, unsigned int ndigits)
{ /* Computes a = (x * y) mod m */
@@ -1602,7 +1445,7 @@
}
/*****************************************************************************/
-int APP_CC
+int
rdssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len)
{
@@ -1752,3 +1595,139 @@
return memcmp(sign_data, sign_data2, sign_len2);
}
+/*****************************************************************************/
+PCCERT_CONTEXT rdssl_cert_read(uint8 * data, uint32 len)
+{
+ PCCERT_CONTEXT res;
+ if (!data || !len)
+ {
+ error("rdssl_cert_read %p %ld\n", data, len);
+ return NULL;
+ }
+ res = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data,
len);
+ if (!res)
+ {
+ error("CertCreateCertificateContext call failed with %lx\n",
GetLastError());
+ }
+ return res;
+}
+
+/*****************************************************************************/
+void rdssl_cert_free(PCCERT_CONTEXT context)
+{
+ if (context)
+ CertFreeCertificateContext(context);
+}
+
+/*****************************************************************************/
+uint8 *rdssl_cert_to_rkey(PCCERT_CONTEXT cert, uint32 * key_len)
+{
+ HCRYPTPROV hCryptProv;
+ HCRYPTKEY hKey;
+ BOOL ret;
+ BYTE * rkey;
+ DWORD dwSize, dwErr;
+ ret = CryptAcquireContext(&hCryptProv,
+ NULL,
+ MS_ENHANCED_PROV,
+ PROV_RSA_FULL,
+ 0);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ error("CryptAcquireContext call failed with %lx\n", dwErr);
+ return NULL;
+ }
+ ret = CryptImportPublicKeyInfoEx(hCryptProv,
+ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ &(cert->pCertInfo->SubjectPublicKeyInfo),
+ 0,
+ 0,
+ NULL,
+ &hKey);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ CryptReleaseContext(hCryptProv, 0);
+ error("CryptImportPublicKeyInfoEx call failed with %lx\n", dwErr);
+ return NULL;
+ }
+ ret = CryptExportKey(hKey,
+ 0,
+ PUBLICKEYBLOB,
+ 0,
+ NULL,
+ &dwSize);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ CryptDestroyKey(hKey);
+ CryptReleaseContext(hCryptProv, 0);
+ error("CryptExportKey call failed with %lx\n", dwErr);
+ return NULL;
+ }
+ rkey = g_malloc(dwSize, 0);
+ ret = CryptExportKey(hKey,
+ 0,
+ PUBLICKEYBLOB,
+ 0,
+ rkey,
+ &dwSize);
+ if (!ret)
+ {
+ dwErr = GetLastError();
+ g_free(rkey);
+ CryptDestroyKey(hKey);
+ CryptReleaseContext(hCryptProv, 0);
+ error("CryptExportKey call failed with %lx\n", dwErr);
+ return NULL;
+ }
+ CryptDestroyKey(hKey);
+ CryptReleaseContext(hCryptProv, 0);
+ return rkey;
+}
+
+/*****************************************************************************/
+RD_BOOL rdssl_certs_ok(PCCERT_CONTEXT server_cert, PCCERT_CONTEXT cacert)
+{
+ /* FIXME should we check for expired certificates??? */
+ DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG; /* CERT_STORE_TIME_VALIDITY_FLAG */
+ BOOL ret = CertVerifySubjectCertificateContext(server_cert,
+ cacert,
+ &dwFlags);
+ if (!ret)
+ {
+ error("CertVerifySubjectCertificateContext call failed with %lx\n",
GetLastError());
+ }
+ if (dwFlags)
+ {
+ error("CertVerifySubjectCertificateContext check failed %lx\n",
dwFlags);
+ }
+ return (dwFlags == 0);
+}
+
+/*****************************************************************************/
+int rdssl_rkey_get_exp_mod(uint8 * rkey, uint8 * exponent, uint32 max_exp_len, uint8 *
modulus,
+ uint32 max_mod_len)
+{
+ RSAPUBKEY *desc = (RSAPUBKEY *)(rkey + sizeof(PUBLICKEYSTRUC));
+ if (!rkey || !exponent || !max_exp_len || !modulus || !max_mod_len)
+ {
+ error("rdssl_rkey_get_exp_mod %p %p %ld %p %ld\n", rkey, exponent,
max_exp_len, modulus, max_mod_len);
+ return -1;
+ }
+ memcpy (exponent, &desc->pubexp, max_exp_len);
+ memcpy (modulus, rkey + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY), max_mod_len);
+ return 0;
+}
+
+/*****************************************************************************/
+void rdssl_rkey_free(uint8 * rkey)
+{
+ if (!rkey)
+ {
+ error("rdssl_rkey_free rkey is null\n");
+ return;
+ }
+ g_free(rkey);
+}