mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
Updated wincrypto to not use global vars for state
This commit is contained in:
@@ -1681,19 +1681,19 @@ duk_ret_t ILibDuktape_MeshAgent_GenerateCertsForDiagnosticAgent(duk_context *ctx
|
||||
duk_push_object(ctx);
|
||||
|
||||
#ifdef WIN32
|
||||
PCCERT_CONTEXT certCtx = NULL;
|
||||
char *certCtx_data = NULL;
|
||||
if (agent->noCertStore == 0 && wincrypto_open_ex(TRUE, rootSubject, &certCtx) == 0) // Force certificate re-generation
|
||||
wincrypto_object j = NULL;
|
||||
char *cert_der = NULL, *cert_pfx = NULL;
|
||||
if (agent->noCertStore == 0 && (j=wincrypto_open(TRUE, rootSubject)) != NULL) // Force certificate re-generation
|
||||
{
|
||||
int l;
|
||||
do {
|
||||
// Finish off work with our own certificate
|
||||
l = wincrypto_getcert_ex(&certCtx_data, certCtx);
|
||||
l = wincrypto_getcert(&cert_der, j);
|
||||
if (l > 0)
|
||||
{
|
||||
util_from_cer(certCtx_data, l, &tmpCert);
|
||||
util_from_cer(cert_der, l, &tmpCert);
|
||||
util_keyhash(tmpCert, tmp);
|
||||
if (((int*)tmp)[0] == 0) { wincrypto_close_ex(certCtx); wincrypto_open_ex(1, rootSubject, &certCtx); }
|
||||
if (((int*)tmp)[0] == 0) { wincrypto_close(j); j=wincrypto_open(1, rootSubject); }
|
||||
}
|
||||
} while (l != 0 && ((int*)tmp)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros.
|
||||
|
||||
@@ -1706,10 +1706,10 @@ duk_ret_t ILibDuktape_MeshAgent_GenerateCertsForDiagnosticAgent(duk_context *ctx
|
||||
duk_put_prop_string(ctx, -3, "der"); // [object][root][buffer]
|
||||
duk_pop(ctx); // [object][root]
|
||||
duk_put_prop_string(ctx, -2, "root"); // [object]
|
||||
memcpy_s(rootBuffer, l, certCtx_data, l);
|
||||
memcpy_s(rootBuffer, l, cert_der, l);
|
||||
|
||||
// Generate a new TLS certificate & save it.
|
||||
l = wincrypto_mkCert(rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &certCtx_data);
|
||||
l = wincrypto_mkCert(j, rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &cert_pfx);
|
||||
|
||||
duk_push_object(ctx); // [object][tls]
|
||||
char *buffer = duk_push_fixed_buffer(ctx, l); // [object][tls][buffer]
|
||||
@@ -1718,8 +1718,9 @@ duk_ret_t ILibDuktape_MeshAgent_GenerateCertsForDiagnosticAgent(duk_context *ctx
|
||||
duk_pop(ctx); // [object][tls]
|
||||
duk_push_string(ctx, "hidden"); duk_put_prop_string(ctx, -2, "passphrase");
|
||||
duk_put_prop_string(ctx, -2, "tls"); // [object]
|
||||
memcpy_s(buffer, l, certCtx_data, l);
|
||||
util_free(certCtx_data);
|
||||
memcpy_s(buffer, l, cert_pfx, l);
|
||||
util_free(cert_pfx);
|
||||
wincrypto_close(j);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -1945,24 +1946,26 @@ int agent_GenerateCertificates(MeshAgentHostContainer *agent, char* certfile)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
char *rootSubject = (agent->capabilities & MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY) == MeshCommand_AuthInfo_CapabilitiesMask_RECOVERY ? "CN=MeshNodeDiagnosticCertificate" : "CN=MeshNodeCertificate";
|
||||
if (agent->noCertStore == 0 && wincrypto_open(TRUE, rootSubject) == 0) // Force certificate re-generation
|
||||
|
||||
if (agent->noCertStore == 0 && (agent->certObject = wincrypto_open(TRUE, rootSubject)) != NULL) // Force certificate re-generation
|
||||
{
|
||||
int l;
|
||||
do {
|
||||
do
|
||||
{
|
||||
// Finish off work with our own certificate
|
||||
l = wincrypto_getcert(&str);
|
||||
l = wincrypto_getcert(&str, agent->certObject);
|
||||
if (l > 0)
|
||||
{
|
||||
util_from_cer(str, l, &(agent->selfcert));
|
||||
util_keyhash(agent->selfcert, agent->g_selfid);
|
||||
if (((int*)agent->g_selfid)[0] == 0) { wincrypto_close(); wincrypto_open(1, rootSubject); }
|
||||
if (((int*)agent->g_selfid)[0] == 0) { wincrypto_close(agent->certObject); agent->certObject = wincrypto_open(1, rootSubject); }
|
||||
}
|
||||
} while (l != 0 && ((int*)agent->g_selfid)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros.
|
||||
|
||||
if (l > 0)
|
||||
{
|
||||
// Generate a new TLS certificate & save it.
|
||||
l = wincrypto_mkCert(rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &str);
|
||||
l = wincrypto_mkCert(agent->certObject, rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &str);
|
||||
util_from_p12(str, l, "hidden", &(agent->selftlscert));
|
||||
ILibSimpleDataStore_PutEx(agent->masterDb, "SelfNodeTlsCert", 15, str, l);
|
||||
util_free(str);
|
||||
@@ -2056,19 +2059,19 @@ int agent_LoadCertificates(MeshAgentHostContainer *agent)
|
||||
|
||||
// No cert in this .db file. Try to load or generate a root certificate from a Windows crypto provider. This can be TPM backed which is great.
|
||||
// However, if we don't have the second cert created, we need to regen the root...
|
||||
if (agent->noCertStore == 0 && wincrypto_open(FALSE, rootSubject) == 0 && ILibSimpleDataStore_Get(agent->masterDb, "SelfNodeTlsCert", NULL, 0) != 0)
|
||||
if (agent->noCertStore == 0 && (agent->certObject = wincrypto_open(FALSE, rootSubject)) != NULL && ILibSimpleDataStore_Get(agent->masterDb, "SelfNodeTlsCert", NULL, 0) != 0)
|
||||
{
|
||||
char* str = NULL;
|
||||
int l;
|
||||
|
||||
do {
|
||||
// Finish off work with our own certificate
|
||||
l = wincrypto_getcert(&str);
|
||||
l = wincrypto_getcert(&str, agent->certObject);
|
||||
if (l > 0)
|
||||
{
|
||||
util_from_cer(str, l, &(agent->selfcert));
|
||||
util_keyhash(agent->selfcert, agent->g_selfid);
|
||||
if (((int*)agent->g_selfid)[0] == 0) { wincrypto_open(TRUE, rootSubject); } // Force generation of a new certificate.
|
||||
if (((int*)agent->g_selfid)[0] == 0) { wincrypto_close(agent->certObject); agent->certObject = wincrypto_open(TRUE, rootSubject); } // Force generation of a new certificate.
|
||||
}
|
||||
} while (l != 0 && ((int*)agent->g_selfid)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros.
|
||||
|
||||
@@ -2081,7 +2084,7 @@ int agent_LoadCertificates(MeshAgentHostContainer *agent)
|
||||
if (len == 0) {
|
||||
// Generate a new TLS certificate & save it.
|
||||
util_freecert(&(agent->selftlscert));
|
||||
l = wincrypto_mkCert(rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &str);
|
||||
l = wincrypto_mkCert(agent->certObject, rootSubject, L"CN=localhost", CERTIFICATE_TLS_SERVER, L"hidden", &str);
|
||||
if (l > 0) {
|
||||
util_from_p12(str, l, "hidden", &(agent->selftlscert));
|
||||
ILibSimpleDataStore_PutEx(agent->masterDb, "SelfNodeTlsCert", 15, str, l);
|
||||
@@ -2514,7 +2517,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
|
||||
// Create a PKCS7 signature using Windows crypto & send it
|
||||
char* signature = NULL;
|
||||
signLen = wincrypto_sign((unsigned char*)ILibScratchPad, sizeof(AuthRequest->serverHash) + UTIL_SHA384_HASHSIZE + UTIL_SHA384_HASHSIZE, &signature);
|
||||
signLen = wincrypto_sign(agent->certObject, (unsigned char*)ILibScratchPad, sizeof(AuthRequest->serverHash) + UTIL_SHA384_HASHSIZE + UTIL_SHA384_HASHSIZE, &signature);
|
||||
if (signLen > 0)
|
||||
{
|
||||
// Signature succesful, send the result to the server
|
||||
|
||||
@@ -182,6 +182,7 @@ typedef struct MeshAgentHostContainer
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
#ifdef WIN32
|
||||
int noCertStore;
|
||||
void* certObject;
|
||||
#endif
|
||||
struct util_cert selfcert;
|
||||
struct util_cert selftlscert;
|
||||
|
||||
@@ -28,12 +28,17 @@ extern "C"
|
||||
{
|
||||
#include "wincrypto.h"
|
||||
#include "../microstack/ILibParsers.h"
|
||||
HCRYPTPROV wincrypto_hProv = NULL;
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
|
||||
LPWSTR wincrypto_CngProviders[3] = { L"Microsoft Platform Crypto Provider", MS_KEY_STORAGE_PROVIDER, NULL };
|
||||
HANDLE wincrypto_hCertStore = NULL;
|
||||
PCCERT_CONTEXT wincrypto_certCtx = NULL;
|
||||
|
||||
typedef struct wincrypto_data
|
||||
{
|
||||
HCRYPTPROV hProv;
|
||||
HANDLE hCertStore;
|
||||
PCCERT_CONTEXT certCtx;
|
||||
}wincrypto_data;
|
||||
|
||||
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
|
||||
|
||||
#define wincrypto_TlsServerOid "1.3.6.1.5.5.7.3.1" // TLS Server certificate
|
||||
@@ -120,26 +125,20 @@ int __fastcall wincrypto_getregistryA(char* name, char** value)
|
||||
return len;
|
||||
}
|
||||
|
||||
int __fastcall wincrypto_isopen()
|
||||
int __fastcall wincrypto_isopen(wincrypto_object j)
|
||||
{
|
||||
return (wincrypto_hProv != NULL && wincrypto_hCertStore != NULL && wincrypto_certCtx != NULL);
|
||||
return (((wincrypto_data*)j)->hProv != NULL && ((wincrypto_data*)j)->hCertStore != NULL && ((wincrypto_data*)j)->certCtx != NULL);
|
||||
}
|
||||
|
||||
void __fastcall wincrypto_close_ex(PCCERT_CONTEXT certCtx)
|
||||
void __fastcall wincrypto_close(wincrypto_object j)
|
||||
{
|
||||
if (certCtx != NULL)
|
||||
{
|
||||
CertFreeCertificateContext(certCtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wincrypto_certCtx != NULL) { CertFreeCertificateContext(wincrypto_certCtx); wincrypto_certCtx = NULL; }
|
||||
if (wincrypto_hProv != NULL) { NCryptFreeObject(wincrypto_hProv); wincrypto_hProv = NULL; }
|
||||
if (wincrypto_hCertStore != NULL) { CertCloseStore(wincrypto_hCertStore, 0); wincrypto_hCertStore = NULL; }
|
||||
}
|
||||
if(((wincrypto_data*)j)->certCtx != NULL) { CertFreeCertificateContext(((wincrypto_data*)j)->certCtx); }
|
||||
if(((wincrypto_data*)j)->hProv != NULL) { NCryptFreeObject(((wincrypto_data*)j)->hProv); }
|
||||
if(((wincrypto_data*)j)->hCertStore != NULL) { CertCloseStore(((wincrypto_data*)j)->hCertStore, 0); }
|
||||
ILibMemory_Free(j);
|
||||
}
|
||||
|
||||
int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT *certCtx)
|
||||
wincrypto_object __fastcall wincrypto_open(int newcert, char *rootSubject)
|
||||
{
|
||||
DWORD KeyLength = 3072;
|
||||
NCRYPT_KEY_HANDLE hKeyNode = NULL;
|
||||
@@ -175,23 +174,23 @@ int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT
|
||||
char akeycontainer[255]; // MAX Length of X509 distinguished name is 64 characters, so this should be OK
|
||||
int akeyLen;
|
||||
size_t wkeyLen;
|
||||
if (rootSubject == NULL || strnlen_s(rootSubject, 255) > 64) { return(1); } // X509 distinguished name must be specifified and limited to 64 characters.
|
||||
if (rootSubject == NULL || strnlen_s(rootSubject, 255) > 64) { return(NULL); } // X509 distinguished name must be specifified and limited to 64 characters.
|
||||
|
||||
akeyLen = sprintf_s(akeycontainer, sizeof(akeycontainer), "%s_privatekey", rootSubject);
|
||||
if (mbstowcs_s(&wkeyLen, (wchar_t*)wkeycontainer, sizeof(wkeycontainer) / 2, (char*)akeycontainer, 64) != 0) { return(1); } // Error creating privatekey container name
|
||||
if (certCtx == NULL) { certCtx = &wincrypto_certCtx; }
|
||||
|
||||
if (mbstowcs_s(&wkeyLen, (wchar_t*)wkeycontainer, sizeof(wkeycontainer) / 2, (char*)akeycontainer, 64) != 0) { return(NULL); } // Error creating privatekey container name
|
||||
ZeroMemory(&exts, sizeof(exts));
|
||||
wincrypto_close_ex(*certCtx);
|
||||
|
||||
wincrypto_data *ret = (wincrypto_data*)ILibMemory_SmartAllocate(sizeof(wincrypto_data));
|
||||
|
||||
// Open the best CNG possible
|
||||
while (providerName == NULL && wincrypto_CngProviders[r] != NULL) {
|
||||
while (providerName == NULL && wincrypto_CngProviders[r] != NULL)
|
||||
{
|
||||
providerName = wincrypto_CngProviders[r];
|
||||
NCryptOpenStorageProvider(&wincrypto_hProv, providerName, 0);
|
||||
if (wincrypto_hProv == NULL) providerName = NULL;
|
||||
NCryptOpenStorageProvider(&(ret->hProv), providerName, 0);
|
||||
if (ret->hProv == NULL) providerName = NULL;
|
||||
r++;
|
||||
}
|
||||
if (wincrypto_hProv == NULL) goto error;
|
||||
if (ret->hProv == NULL) goto error;
|
||||
|
||||
// Create cert subject string in format csp understands
|
||||
if (!CertStrToName(X509_ASN_ENCODING, (LPCTSTR)rootSubject, CERT_X500_NAME_STR, NULL, NULL, &subjectEncodedSize, NULL)) goto error;
|
||||
@@ -200,36 +199,28 @@ int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT
|
||||
sib.cbData = subjectEncodedSize;
|
||||
sib.pbData = subjectEncoded;
|
||||
|
||||
#ifdef _CONSOLE
|
||||
wincrypto_hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, wincrypto_hProv, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); // CERT_STORE_NO_CRYPT_RELEASE_FLAG
|
||||
if (!wincrypto_hCertStore) goto error;
|
||||
#else
|
||||
wincrypto_hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, wincrypto_hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); // CERT_STORE_NO_CRYPT_RELEASE_FLAG // CERT_SYSTEM_STORE_LOCAL_MACHINE
|
||||
if (!wincrypto_hCertStore) goto error;
|
||||
#endif
|
||||
ret->hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, ret->hProv, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); // CERT_STORE_NO_CRYPT_RELEASE_FLAG
|
||||
if (!ret->hCertStore) goto error;
|
||||
|
||||
// Look for cert and if exists, delete it
|
||||
wincrypto_certCtx = CertFindCertificateInStore(wincrypto_hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL );
|
||||
ret->certCtx = CertFindCertificateInStore(ret->hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL );
|
||||
|
||||
// Check if we can get the private key
|
||||
if (wincrypto_certCtx != NULL)
|
||||
if (ret->certCtx != NULL)
|
||||
{
|
||||
if (!CryptAcquireCertificatePrivateKey(wincrypto_certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) { newcert = 1; }
|
||||
if (!CryptAcquireCertificatePrivateKey(ret->certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) { newcert = 1; }
|
||||
if (hKeyNodeSpec != CERT_NCRYPT_KEY_SPEC) { newcert = 1; } // If this private key is not CNG, don't use it.
|
||||
if (hFreeKeyNode && hKeyNode != NULL) { if (hKeyNodeSpec == CERT_NCRYPT_KEY_SPEC) NCryptFreeObject(hKeyNode); else CryptReleaseContext(hKeyNode, 0); }
|
||||
}
|
||||
|
||||
// Check if have a certificate already, or need to create a new one
|
||||
if (wincrypto_certCtx != NULL && newcert == 0) goto end;
|
||||
if (wincrypto_certCtx) { status = CertDeleteCertificateFromStore(wincrypto_certCtx); if (!status) goto error; wincrypto_certCtx = NULL; }
|
||||
if (ret->certCtx != NULL && newcert == 0) goto end;
|
||||
if (ret->certCtx) { status = CertDeleteCertificateFromStore(ret->certCtx); if (!status) goto error; ret->certCtx = NULL; }
|
||||
|
||||
// Generate node RSA key-pair
|
||||
#ifdef _CONSOLE
|
||||
if (FAILED(status = NCryptCreatePersistedKey(wincrypto_hProv, &hKeyNode, BCRYPT_RSA_ALGORITHM, (LPCWSTR)wkeycontainer, 0, NCRYPT_OVERWRITE_KEY_FLAG))) goto error;
|
||||
#else
|
||||
if (FAILED(status = NCryptCreatePersistedKey(wincrypto_hProv, &hKeyNode, BCRYPT_RSA_ALGORITHM, (LPCWSTR)wkeycontainer, 0, NCRYPT_MACHINE_KEY_FLAG | NCRYPT_OVERWRITE_KEY_FLAG))) goto error;
|
||||
#endif
|
||||
if (FAILED(status = NCryptSetProperty(hKeyNode, NCRYPT_LENGTH_PROPERTY, (PBYTE)&KeyLength, 4, NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG))) {
|
||||
if (FAILED(status = NCryptCreatePersistedKey(ret->hProv, &hKeyNode, BCRYPT_RSA_ALGORITHM, (LPCWSTR)wkeycontainer, 0, NCRYPT_OVERWRITE_KEY_FLAG))) goto error;
|
||||
if (FAILED(status = NCryptSetProperty(hKeyNode, NCRYPT_LENGTH_PROPERTY, (PBYTE)&KeyLength, 4, NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG)))
|
||||
{
|
||||
KeyLength = 2048; // If 3072 is not supported, go down to 2048.
|
||||
if (FAILED(status = NCryptSetProperty(hKeyNode, NCRYPT_LENGTH_PROPERTY, (PBYTE)&KeyLength, 4, NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG))) { goto error; }
|
||||
}
|
||||
@@ -292,12 +283,12 @@ int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT
|
||||
ZeroMemory(&sa, sizeof(sa));
|
||||
sa.pszObjId = szOID_RSA_SHA384RSA; // Using SHA384
|
||||
|
||||
wincrypto_certCtx = CertCreateSelfSignCertificate(NULL, &sib, 0, &kpi, &sa, &st1, &st2, &exts);
|
||||
if (!wincrypto_certCtx) { goto error; }
|
||||
ret->certCtx = CertCreateSelfSignCertificate(NULL, &sib, 0, &kpi, &sa, &st1, &st2, &exts);
|
||||
if (!ret->certCtx) { goto error; }
|
||||
|
||||
// Note this is a different context to certCtx, this ctx is the in-store ctx
|
||||
status = CertAddCertificateContextToStore(wincrypto_hCertStore, wincrypto_certCtx, CERT_STORE_ADD_REPLACE_EXISTING, &wincrypto_certCtx);
|
||||
if (!status || wincrypto_certCtx == NULL) goto error;
|
||||
status = CertAddCertificateContextToStore(ret->hCertStore, ret->certCtx, CERT_STORE_ADD_REPLACE_EXISTING, &ret->certCtx);
|
||||
if (!status || ret->certCtx == NULL) goto error;
|
||||
|
||||
// Get the selected provider name and save it in the registry
|
||||
if (providerName != NULL) wincrypto_setregistry(L"KeyStore", providerName);
|
||||
@@ -307,12 +298,12 @@ int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT
|
||||
error:
|
||||
// Clean up
|
||||
if (hKeyNode != NULL) NCryptFreeObject(hKeyNode);
|
||||
wincrypto_close_ex(*certCtx);
|
||||
return 1;
|
||||
wincrypto_close(ret);
|
||||
return(NULL);
|
||||
|
||||
end:
|
||||
if (subjectEncoded != NULL) free(subjectEncoded);
|
||||
return 0;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void __fastcall wincrypto_random(int length, char* result)
|
||||
@@ -352,7 +343,7 @@ int __fastcall wincrypto_sha256(char* data, int datalen, char* result) { return
|
||||
int __fastcall wincrypto_sha384(char* data, int datalen, char* result) { return wincrypto_hash(BCRYPT_SHA384_ALGORITHM, data, datalen, result, 32); }
|
||||
|
||||
// Sign the data with the Mesh Agent certificate and return a PKCS7 result.
|
||||
int __fastcall wincrypto_sign(char* data, int len, char** signature)
|
||||
int __fastcall wincrypto_sign(wincrypto_object j, char* data, int len, char** signature)
|
||||
{
|
||||
int signatureLen = 0;
|
||||
DWORD cbSignedBlob;
|
||||
@@ -370,7 +361,7 @@ int __fastcall wincrypto_sign(char* data, int len, char** signature)
|
||||
BOOL hFreeKeyNode = FALSE;
|
||||
|
||||
// Check that we have open context
|
||||
if (wincrypto_hProv == NULL || wincrypto_hCertStore == NULL || wincrypto_certCtx == NULL) return 0;
|
||||
if (!wincrypto_isopen(j)) { return(0); }
|
||||
|
||||
// Initialize the algorithm identifier structure.
|
||||
HashAlgSize = sizeof(HashAlgorithm);
|
||||
@@ -380,9 +371,9 @@ int __fastcall wincrypto_sign(char* data, int len, char** signature)
|
||||
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.
|
||||
memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
|
||||
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
|
||||
if (!CryptAcquireCertificatePrivateKey(wincrypto_certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) { r = 10; goto end; }
|
||||
if (!CryptAcquireCertificatePrivateKey(((wincrypto_data*)j)->certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) { r = 10; goto end; }
|
||||
SignerEncodeInfo.hNCryptKey = hKeyNode;
|
||||
SignerEncodeInfo.pCertInfo = wincrypto_certCtx->pCertInfo;
|
||||
SignerEncodeInfo.pCertInfo = ((wincrypto_data*)j)->certCtx->pCertInfo;
|
||||
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
|
||||
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
|
||||
SignerEncodeInfo.pvHashAuxInfo = NULL;
|
||||
@@ -391,8 +382,8 @@ int __fastcall wincrypto_sign(char* data, int len, char** signature)
|
||||
SignerEncodeInfoArray[0] = SignerEncodeInfo;
|
||||
|
||||
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.
|
||||
SignerCertBlob.cbData = wincrypto_certCtx->cbCertEncoded;
|
||||
SignerCertBlob.pbData = wincrypto_certCtx->pbCertEncoded;
|
||||
SignerCertBlob.cbData = ((wincrypto_data*)j)->certCtx->cbCertEncoded;
|
||||
SignerCertBlob.pbData = ((wincrypto_data*)j)->certCtx->pbCertEncoded;
|
||||
|
||||
// Initialize the array of one CertBlob.
|
||||
SignerCertBlobArray[0] = SignerCertBlob;
|
||||
@@ -447,7 +438,7 @@ static BOOL WINAPI wincrypto_CmsgStreamOutputCallback(IN const void *pvArg, IN B
|
||||
}
|
||||
|
||||
// Decrypt the PKCS7 block and return the content.
|
||||
int __fastcall wincrypto_decrypt(char* encdata, int encdatalen, char** data)
|
||||
int __fastcall wincrypto_decrypt(wincrypto_object j, char* encdata, int encdatalen, char** data)
|
||||
{
|
||||
int datalen = 0;
|
||||
HCRYPTMSG hMsg = NULL;
|
||||
@@ -457,7 +448,7 @@ int __fastcall wincrypto_decrypt(char* encdata, int encdatalen, char** data)
|
||||
struct wincrypto_stream StreamArg;
|
||||
|
||||
// Check that we have open context
|
||||
if (wincrypto_hProv == NULL || wincrypto_hCertStore == NULL || wincrypto_certCtx == NULL) return 0;
|
||||
if (!wincrypto_isopen(j)) { return(0); }
|
||||
|
||||
// Perform setup
|
||||
if ((StreamArg.buf = (char*)malloc(encdatalen)) == NULL) ILIBCRITICALEXIT(254);
|
||||
@@ -470,7 +461,7 @@ int __fastcall wincrypto_decrypt(char* encdata, int encdatalen, char** data)
|
||||
if (!CryptMsgUpdate(hMsg, (BYTE*)encdata, encdatalen, TRUE)) goto end;
|
||||
|
||||
// Setup the certificate
|
||||
if (!CryptAcquireCertificatePrivateKey(wincrypto_certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &decryptPara.hCryptProv, &decryptPara.dwKeySpec, &flagHandle)) goto end;
|
||||
if (!CryptAcquireCertificatePrivateKey(((wincrypto_data*)j)->certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &decryptPara.hCryptProv, &decryptPara.dwKeySpec, &flagHandle)) goto end;
|
||||
decryptPara.dwRecipientIndex = 0;
|
||||
|
||||
// Perform the decrypt
|
||||
@@ -487,23 +478,15 @@ end:
|
||||
}
|
||||
|
||||
// Get the X509 certificate including the public key (Direct reference, no need to free this).
|
||||
int __fastcall wincrypto_getcert_ex(char** data, PCCERT_CONTEXT certCtx)
|
||||
int __fastcall wincrypto_getcert(char** data, wincrypto_object j)
|
||||
{
|
||||
if (certCtx != NULL)
|
||||
{
|
||||
*data = (char*)certCtx->pbCertEncoded;
|
||||
return (int)certCtx->cbCertEncoded;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wincrypto_certCtx == NULL) { *data = NULL; return 0; }
|
||||
*data = (char*)wincrypto_certCtx->pbCertEncoded;
|
||||
return (int)wincrypto_certCtx->cbCertEncoded;
|
||||
}
|
||||
if (((wincrypto_data*)j)->certCtx == NULL) { *data = NULL; return(0); }
|
||||
*data = (char*)((wincrypto_data*)j)->certCtx->pbCertEncoded;
|
||||
return((int)((wincrypto_data*)j)->certCtx->cbCertEncoded);
|
||||
}
|
||||
|
||||
// Create an X509, RSA 3027bit certificate with the MeshAgent certificate as signing root.
|
||||
int __fastcall wincrypto_mkCert(char* rootSubject, wchar_t* subject, int certtype, wchar_t* password, char** data)
|
||||
int __fastcall wincrypto_mkCert(wincrypto_object j, char* rootSubject, wchar_t* subject, int certtype, wchar_t* password, char** data) // certtype: 1=Root, 2=Server, 3=Client
|
||||
{
|
||||
NCRYPT_KEY_HANDLE hKeyNode = NULL;
|
||||
DWORD hKeyNodeSpec = 0;
|
||||
@@ -552,7 +535,7 @@ int __fastcall wincrypto_mkCert(char* rootSubject, wchar_t* subject, int certtyp
|
||||
DWORD pfxExportFlags = EXPORT_PRIVATE_KEYS; // | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY;
|
||||
|
||||
// Check that we have open context
|
||||
if (wincrypto_hProv == NULL || wincrypto_hCertStore == NULL || wincrypto_certCtx == NULL) return 0;
|
||||
if (!wincrypto_isopen(j)) { return(0); }
|
||||
|
||||
*data = NULL;
|
||||
ZeroMemory(&kpi, sizeof(kpi));
|
||||
@@ -663,7 +646,7 @@ int __fastcall wincrypto_mkCert(char* rootSubject, wchar_t* subject, int certtyp
|
||||
}
|
||||
|
||||
// Sign the certificate with the MeshAgent private key
|
||||
if (!CryptAcquireCertificatePrivateKey(wincrypto_certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) goto end;
|
||||
if (!CryptAcquireCertificatePrivateKey(((wincrypto_data*)j)->certCtx, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyNode, &hKeyNodeSpec, &hFreeKeyNode)) goto end;
|
||||
if (!CryptSignAndEncodeCertificate(hKeyNode, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, (LPVOID)&certInfo, &(certInfo.SignatureAlgorithm), NULL, NULL, &certSize)) goto end;
|
||||
if ((certData = (BYTE*)malloc(certSize)) == NULL) ILIBCRITICALEXIT(254);
|
||||
if (!CryptSignAndEncodeCertificate(hKeyNode, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, (LPVOID)&certInfo, &(certInfo.SignatureAlgorithm), NULL, certData, &certSize)) goto end;
|
||||
|
||||
@@ -18,23 +18,22 @@ limitations under the License.
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef void* wincrypto_object;
|
||||
void __fastcall wincrypto_setregistry(LPWSTR name, LPWSTR value);
|
||||
void __fastcall wincrypto_setregistryA(char* name, char* value);
|
||||
int __fastcall wincrypto_getregistry(LPCWSTR name, char** value);
|
||||
int __fastcall wincrypto_getregistryA(char* name, char** value);
|
||||
int __fastcall wincrypto_isopen();
|
||||
void __fastcall wincrypto_close_ex(PCCERT_CONTEXT certCtx);
|
||||
#define wincrypto_close() wincrypto_close_ex(NULL)
|
||||
#define wincrypto_open(newCert, rootSubject) wincrypto_open_ex(newCert, rootSubject, NULL)
|
||||
int __fastcall wincrypto_open_ex(int newcert, char *rootSubject, PCCERT_CONTEXT *certCtx);
|
||||
|
||||
int __fastcall wincrypto_isopen(wincrypto_object j);
|
||||
void __fastcall wincrypto_close(wincrypto_object j);
|
||||
wincrypto_object __fastcall wincrypto_open(int newcert, char *rootSubject);
|
||||
void __fastcall wincrypto_random(int length, char* result);
|
||||
int __fastcall wincrypto_md5(char* data, int datalen, char* result);
|
||||
int __fastcall wincrypto_sha256(char* data, int datalen, char* result);
|
||||
int __fastcall wincrypto_sha384(char* data, int datalen, char* result);
|
||||
int __fastcall wincrypto_sign(char* data, int len, char** signature);
|
||||
int __fastcall wincrypto_decrypt(char* encdata, int encdatalen, char** data);
|
||||
#define wincrypto_getcert(data) wincrypto_getcert_ex(data, NULL)
|
||||
int __fastcall wincrypto_getcert_ex(char** data, PCCERT_CONTEXT certCtx);
|
||||
int __fastcall wincrypto_mkCert(char* rootSubject, wchar_t* subject, int certtype, wchar_t* password, char** data); // certtype: 1=Root, 2=Server, 3=Client
|
||||
int __fastcall wincrypto_sign(wincrypto_object j, char* data, int len, char** signature);
|
||||
int __fastcall wincrypto_decrypt(wincrypto_object j, char* encdata, int encdatalen, char** data);
|
||||
int __fastcall wincrypto_getcert(char** data, wincrypto_object j);
|
||||
int __fastcall wincrypto_mkCert(wincrypto_object j, char* rootSubject, wchar_t* subject, int certtype, wchar_t* password, char** data); // certtype: 1=Root, 2=Server, 3=Client
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user