diff --git a/microstack/ILibCrypto.c b/microstack/ILibCrypto.c index e721c64..b1610b2 100644 --- a/microstack/ILibCrypto.c +++ b/microstack/ILibCrypto.c @@ -502,10 +502,14 @@ int __fastcall util_add_ext(X509 *cert, int nid, char *value) void __fastcall util_freecert(struct util_cert* cert) { - if (cert->x509 != NULL) X509_free(cert->x509); - if (cert->pkey != NULL) EVP_PKEY_free(cert->pkey); + if ((cert->flags & ILibCrypto_Cert_Ownership_Other) == 0) + { + if (cert->x509 != NULL) X509_free(cert->x509); + if (cert->pkey != NULL) EVP_PKEY_free(cert->pkey); + } cert->x509 = NULL; cert->pkey = NULL; + cert->flags = 0; } int __fastcall util_to_cer(struct util_cert cert, char** data) @@ -764,18 +768,31 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i cert->x509 = x; cert->pkey = pk; + cert->flags = 0; return 1; err: return 0; } +int __fastcall util_certhash(struct util_cert cert, char* result) { + int hashlen = UTIL_SHA384_HASHSIZE; + if (cert.x509 == NULL) return -1; + X509_digest(cert.x509, EVP_sha384(), (unsigned char*)result, (unsigned int *)&hashlen); // OpenSSL 1.1 + return 0; +} + +int __fastcall util_certhash2(X509* cert, char* result) { + int hashlen = UTIL_SHA384_HASHSIZE; + if (cert == NULL) return -1; + X509_digest(cert, EVP_sha384(), (unsigned char*)result, (unsigned int*)&hashlen); // OpenSSL 1.1 + return 0; +} int __fastcall util_keyhash(struct util_cert cert, char* result) { int hashlen = UTIL_SHA384_HASHSIZE; if (cert.x509 == NULL) return -1; - //util_sha256((char*)(cert.x509->cert_info->key->public_key->data), cert.x509->cert_info->key->public_key->length, result); // OpenSSL 1.0 X509_pubkey_digest(cert.x509, EVP_sha384(), (unsigned char*)result,(unsigned int *) &hashlen); // OpenSSL 1.1 return 0; } @@ -784,7 +801,6 @@ int __fastcall util_keyhash2(X509* cert, char* result) { int hashlen = UTIL_SHA384_HASHSIZE; if (cert == NULL) return -1; - //util_sha256((char*)(cert->cert_info->key->public_key->data), cert->cert_info->key->public_key->length, result); // OpenSSL 1.0 X509_pubkey_digest(cert, EVP_sha384(), (unsigned char*)result, (unsigned int*)&hashlen); // OpenSSL 1.1 return 0; } @@ -1030,4 +1046,31 @@ int __fastcall util_rsaverify(X509 *cert, char* data, int datalen, char* sign, i return r; } +#ifdef _DEBUG +// Saves the SSL/TLS session private keys to file. +// Because we do lots of DTLS, we will be saving both client and server randoms pointing to the same key. +// WARNING: THIS IS FOR DEBUG ONLY, NEVER RELEASE THIS. For safety, comment this out. +void __fastcall util_savekeys(SSL* ssl) { + /* + int len; + char clientRandom[32], serverRandom[32], sessionSecret[48], clientRandomHex[65], serverRandomHex[65], sessionSecretHex[97], text[2000]; + + // Get the client random and session key. + if (ssl == NULL) return; + if (SSL_get_client_random(ssl, clientRandom, 32) != 32) return; + if (SSL_get_server_random(ssl, serverRandom, 32) != 32) return; + if (SSL_SESSION_get_master_key(SSL_get_session(ssl), sessionSecret, 48) != 48) return; + + // Convert the randoms and key into hex + util_tohex(clientRandom, 32, clientRandomHex); + util_tohex(serverRandom, 32, serverRandomHex); + util_tohex(sessionSecret, 48, sessionSecretHex); + + // Append the client random and key to the log file. + len = snprintf(text, 1000, "CLIENT_RANDOM %s %s\r\nCLIENT_RANDOM %s %s\r\n", clientRandomHex, sessionSecretHex, serverRandomHex, sessionSecretHex); + util_appendfile("meshagentkeys.log", text, len); + */ +} +#endif + #endif diff --git a/microstack/ILibCrypto.h b/microstack/ILibCrypto.h index 801a7fe..31690de 100644 --- a/microstack/ILibCrypto.h +++ b/microstack/ILibCrypto.h @@ -129,14 +129,17 @@ typedef struct util_cert { X509 *x509; EVP_PKEY *pkey; -}util_cert; + int flags; +} util_cert; + typedef enum CERTIFICATE_TYPES { CERTIFICATE_ROOT = 1, CERTIFICATE_TLS_SERVER = 2, CERTIFICATE_TLS_CLIENT = 3 -}CERTIFICATE_TYPES; +} CERTIFICATE_TYPES; +#define ILibCrypto_Cert_Ownership_Other 0x01 void __fastcall util_openssl_init(); void __fastcall util_openssl_uninit(); @@ -155,6 +158,8 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, void __fastcall util_printcert(struct util_cert cert); void __fastcall util_printcert_pk(struct util_cert cert); +int __fastcall util_certhash(struct util_cert cert, char* result); +int __fastcall util_certhash2(X509* cert, char* result); int __fastcall util_keyhash(struct util_cert cert, char* result); int __fastcall util_keyhash2(X509* cert, char* result); int __fastcall util_sign(struct util_cert cert, char* data, int datalen, char** signature); @@ -166,6 +171,11 @@ int __fastcall util_decrypt(char* encdata, int encdatalen, struct util_cert ce int __fastcall util_rsaencrypt(X509 *cert, char* data, int datalen, char** encdata); int __fastcall util_rsadecrypt(struct util_cert cert, char* data, int datalen, char** decdata); int __fastcall util_rsaverify(X509 *cert, char* data, int datalen, char* sign, int signlen); + +#ifdef _DEBUG +void __fastcall util_savekeys(SSL* ssl); +#endif + #endif diff --git a/microstack/ILibWrapperWebRTC.c b/microstack/ILibWrapperWebRTC.c index 0a80b83..a09a5fc 100644 --- a/microstack/ILibWrapperWebRTC.c +++ b/microstack/ILibWrapperWebRTC.c @@ -55,12 +55,9 @@ typedef struct ILibWrapper_WebRTC_ConnectionFactory mStunModule; ILibSparseArray Connections; int NextConnectionID; - struct util_cert selfcert; - struct util_cert selftlscert; - struct util_cert selftlsclientcert; + struct util_cert cert; SSL_CTX* ctx; char tlsServerCertThumbprint[UTIL_SHA256_HASHSIZE]; - char g_selfid[UTIL_SHA256_HASHSIZE]; ILibWebRTC_TURN_ConnectFlags mTurnSetting; struct sockaddr_in6 mTurnServer; @@ -457,23 +454,22 @@ void ILibWrapper_WebRTC_InitializeCrypto(ILibWrapper_WebRTC_ConnectionFactoryStr SSL_CTX_set_ex_data(factory->ctx, ILibWrapper_WebRTC_ConnectionFactoryIndex, factory); } - if (tls != ILibWebWrapperWebRTC_ConnectionFactory_INIT_CRYPTO_LATER && factory->selftlscert.x509 == NULL) + if (tls != ILibWebWrapperWebRTC_ConnectionFactory_INIT_CRYPTO_LATER && factory->cert.x509 == NULL) { // Init Certs if (tls == NULL) { - util_mkCert(NULL, &(factory->selfcert), 2048, 10000, "localhost", CERTIFICATE_ROOT, NULL); - util_keyhash(factory->selfcert, factory->g_selfid); - util_mkCert(&(factory->selfcert), &(factory->selftlscert), 2048, 10000, "localhost", CERTIFICATE_TLS_SERVER, NULL); + util_mkCert(NULL, &(factory->cert), 2048, 10000, "localhost", CERTIFICATE_ROOT, NULL); } else { - memcpy_s(&(factory->selftlscert), sizeof(struct util_cert), tls, sizeof(struct util_cert)); + memcpy_s(&(factory->cert), sizeof(struct util_cert), tls, sizeof(struct util_cert)); + factory->cert.flags |= ILibCrypto_Cert_Ownership_Other; } - SSL_CTX_use_certificate(factory->ctx, factory->selftlscert.x509); - SSL_CTX_use_PrivateKey(factory->ctx, factory->selftlscert.pkey); - X509_digest(factory->selftlscert.x509, EVP_get_digestbyname("sha256"), (unsigned char*)factory->tlsServerCertThumbprint, (unsigned int*)&l); + SSL_CTX_use_certificate(factory->ctx, factory->cert.x509); + SSL_CTX_use_PrivateKey(factory->ctx, factory->cert.pkey); + X509_digest(factory->cert.x509, EVP_get_digestbyname("sha256"), (unsigned char*)factory->tlsServerCertThumbprint, (unsigned int*)&l); if (factory->mStunModule != NULL) { ILibStunClient_SetOptions(factory->mStunModule, factory->ctx, factory->tlsServerCertThumbprint); } } @@ -484,18 +480,9 @@ void ILibWrapper_WebRTC_UnInitializeCrypto(ILibWrapper_WebRTC_ConnectionFactoryS SSL_CTX_free(factory->ctx); factory->ctx = NULL; - // UnInit Certs - if (factory->selfcert.x509 != NULL) - { - util_freecert(&(factory->selftlsclientcert)); - util_freecert(&(factory->selftlscert)); - util_freecert(&(factory->selfcert)); - } - - memset(&(factory->selftlsclientcert),0,sizeof(struct util_cert)); - memset(&(factory->selftlscert),0,sizeof(struct util_cert)); - memset(&(factory->selfcert),0,sizeof(struct util_cert)); - + // UnInit Cert + if (factory->cert.x509 != NULL) { util_freecert(&(factory->cert)); } + memset(&(factory->cert), 0, sizeof(struct util_cert)); // UnInit SSL util_openssl_uninit();