mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-24 04:04:31 +00:00
Much improved, better stability, lots of fixes
This commit is contained in:
@@ -621,34 +621,39 @@ void ILibAsyncServerSocket_RemoveFromChain(ILibAsyncServerSocket_ServerModule se
|
||||
*/
|
||||
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(void *Chain, int MaxConnections, unsigned short PortNumber, int initialBufferSize, int loopbackFlag, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize)
|
||||
{
|
||||
int i;
|
||||
int ra = 1;
|
||||
int off = 0;
|
||||
int receivingAddressLength = sizeof(struct sockaddr_in6);
|
||||
struct sockaddr_in6 localif;
|
||||
struct sockaddr_in6 localAddress;
|
||||
struct ILibAsyncServerSocketModule *RetVal;
|
||||
|
||||
memset(&localif, 0, sizeof(struct sockaddr_in6));
|
||||
|
||||
if (loopbackFlag != 2 && ILibDetectIPv6Support())
|
||||
{
|
||||
// Setup the IPv6 any or loopback address, this socket will also work for IPv4 traffic on IPv6 stack
|
||||
localif.sin6_family = AF_INET6;
|
||||
localif.sin6_addr = (loopbackFlag != 0?in6addr_loopback:in6addr_any);
|
||||
localif.sin6_addr = (loopbackFlag != 0 ? in6addr_loopback : in6addr_any);
|
||||
localif.sin6_port = htons(PortNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
// IPv4-only detected
|
||||
localif.sin6_family = AF_INET;
|
||||
#ifdef WINSOCK2
|
||||
((struct sockaddr_in*)&localif)->sin_addr.S_un.S_addr = htonl((loopbackFlag != 0?INADDR_LOOPBACK:INADDR_ANY));
|
||||
#ifdef WIN32
|
||||
((struct sockaddr_in*)&localif)->sin_addr.S_un.S_addr = htonl((loopbackFlag != 0 ? INADDR_LOOPBACK : INADDR_ANY));
|
||||
#else
|
||||
((struct sockaddr_in*)&localif)->sin_addr.s_addr = htonl((loopbackFlag != 0?INADDR_LOOPBACK:INADDR_ANY));
|
||||
((struct sockaddr_in*)&localif)->sin_addr.s_addr = htonl((loopbackFlag != 0 ? INADDR_LOOPBACK : INADDR_ANY));
|
||||
#endif
|
||||
((struct sockaddr_in*)&localif)->sin_port = htons(PortNumber);
|
||||
}
|
||||
|
||||
return(ILibCreateAsyncServerSocketModuleWithMemoryEx(Chain, MaxConnections, initialBufferSize, (struct sockaddr*)&localif, OnConnect, OnDisconnect, OnReceive, OnInterrupt, OnSendOK, ServerUserMappedMemorySize, SessionUserMappedMemorySize));
|
||||
}
|
||||
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx(void *Chain, int MaxConnections, int initialBufferSize, struct sockaddr *local, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize)
|
||||
{
|
||||
int i;
|
||||
int ra = 1;
|
||||
int off = 0;
|
||||
int receivingAddressLength = sizeof(struct sockaddr_in6);
|
||||
struct ILibAsyncServerSocketModule *RetVal;
|
||||
struct sockaddr_in6 localAddress;
|
||||
|
||||
// Instantiate a new AsyncServer module
|
||||
RetVal = (struct ILibAsyncServerSocketModule*)ILibChain_Link_Allocate(sizeof(struct ILibAsyncServerSocketModule), ServerUserMappedMemorySize);
|
||||
|
||||
@@ -664,15 +669,14 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(v
|
||||
RetVal->MaxConnection = MaxConnections;
|
||||
RetVal->AsyncSockets = (void**)malloc(MaxConnections * sizeof(void*));
|
||||
if (RetVal->AsyncSockets == NULL) { free(RetVal); ILIBMARKPOSITION(253); return NULL; }
|
||||
RetVal->portNumber = (unsigned short)PortNumber;
|
||||
RetVal->loopbackFlag = loopbackFlag;
|
||||
RetVal->initialPortNumber = PortNumber;
|
||||
|
||||
RetVal->portNumber = ntohs(((struct sockaddr_in6*)local)->sin6_port);
|
||||
RetVal->initialPortNumber = RetVal->portNumber;
|
||||
|
||||
// Get our listening socket
|
||||
if ((RetVal->ListenSocket = socket(localif.sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
if ((RetVal->ListenSocket = socket(((struct sockaddr_in6*)local)->sin6_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
|
||||
// Setup the IPv6 & IPv4 support on same socket
|
||||
if (localif.sin6_family == AF_INET6) if (setsockopt(RetVal->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
|
||||
if (((struct sockaddr_in6*)local)->sin6_family == AF_INET6) if (setsockopt(RetVal->ListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&off, sizeof(off)) != 0) ILIBCRITICALERREXIT(253);
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
setsockopt(RetVal->ListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&ra, sizeof(int)); // Turn off SIGPIPE if writing to disconnected socket
|
||||
@@ -688,9 +692,9 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(v
|
||||
|
||||
// Bind the socket
|
||||
#if defined(WIN32)
|
||||
if (bind(RetVal->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { closesocket(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
if (bind(RetVal->ListenSocket, local, INET_SOCKADDR_LENGTH(((struct sockaddr_in6*)local)->sin6_family)) != 0) { closesocket(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
#else
|
||||
if (bind(RetVal->ListenSocket, (struct sockaddr*)&localif, INET_SOCKADDR_LENGTH(localif.sin6_family)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
if (bind(RetVal->ListenSocket, local, INET_SOCKADDR_LENGTH(((struct sockaddr_in6*)local)->sin6_family)) != 0) { close(RetVal->ListenSocket); free(RetVal->AsyncSockets); free(RetVal); return 0; }
|
||||
#endif
|
||||
|
||||
// Fetch the local port number
|
||||
|
||||
@@ -114,6 +114,8 @@ extern const int ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE;
|
||||
|
||||
#define ILibCreateAsyncServerSocketModule(Chain, MaxConnections, PortNumber, initialBufferSize, loopbackFlag, OnConnect, OnDisconnect, OnReceive, OnInterrupt, OnSendOK) ILibCreateAsyncServerSocketModuleWithMemory(Chain, MaxConnections, PortNumber, initialBufferSize, loopbackFlag, OnConnect, OnDisconnect, OnReceive, OnInterrupt, OnSendOK, 0, 0)
|
||||
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(void *Chain, int MaxConnections, unsigned short PortNumber, int initialBufferSize, int loopbackFlag, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize);
|
||||
ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx(void *Chain, int MaxConnections, int initialBufferSize, struct sockaddr* local, ILibAsyncServerSocket_OnConnect OnConnect, ILibAsyncServerSocket_OnDisconnect OnDisconnect, ILibAsyncServerSocket_OnReceive OnReceive, ILibAsyncServerSocket_OnInterrupt OnInterrupt, ILibAsyncServerSocket_OnSendOK OnSendOK, int ServerUserMappedMemorySize, int SessionUserMappedMemorySize);
|
||||
|
||||
|
||||
void *ILibAsyncServerSocket_GetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule);
|
||||
void ILibAsyncServerSocket_SetTag(ILibAsyncServerSocket_ServerModule ILibAsyncSocketModule, void *user);
|
||||
|
||||
@@ -1960,7 +1960,7 @@ void ILibAsyncSocket_ModuleOnConnect(ILibAsyncSocket_SocketModule socketModule)
|
||||
\param ssl_ctx SSL_CTX Context object
|
||||
\param server ILibAsyncSocket_TLS_Mode Configuration
|
||||
*/
|
||||
SSL* ILibAsyncSocket_SetSSLContext(ILibAsyncSocket_SocketModule socketModule, SSL_CTX *ssl_ctx, ILibAsyncSocket_TLS_Mode server)
|
||||
SSL* ILibAsyncSocket_SetSSLContextEx(ILibAsyncSocket_SocketModule socketModule, SSL_CTX *ssl_ctx, ILibAsyncSocket_TLS_Mode server, char *hostName)
|
||||
{
|
||||
if (socketModule != NULL)
|
||||
{
|
||||
@@ -1992,6 +1992,7 @@ SSL* ILibAsyncSocket_SetSSLContext(ILibAsyncSocket_SocketModule socketModule, SS
|
||||
SSL_set_bio(module->ssl, module->readBio, module->writeBio);
|
||||
if (server == ILibAsyncSocket_TLS_Mode_Client)
|
||||
{
|
||||
if (hostName != NULL) { SSL_set_tlsext_host_name(module->ssl, hostName); }
|
||||
SSL_set_connect_state(module->ssl);
|
||||
status = SSL_do_handshake(module->ssl);
|
||||
if (status <= 0) { status = SSL_get_error(module->ssl, status); }
|
||||
|
||||
@@ -212,7 +212,8 @@ typedef enum ILibAsyncSocket_TLS_Mode
|
||||
#endif
|
||||
}ILibAsyncSocket_TLS_Mode;
|
||||
|
||||
SSL* ILibAsyncSocket_SetSSLContext(ILibAsyncSocket_SocketModule socketModule, SSL_CTX *ssl_ctx, ILibAsyncSocket_TLS_Mode server);
|
||||
SSL* ILibAsyncSocket_SetSSLContextEx(ILibAsyncSocket_SocketModule socketModule, SSL_CTX *ssl_ctx, ILibAsyncSocket_TLS_Mode server, char *hostname);
|
||||
#define ILibAsyncSocket_SetSSLContext(socketModule, ssl_ctx, tlsMode) ILibAsyncSocket_SetSSLContextEx(socketModule, ssl_ctx, tlsMode, NULL)
|
||||
SSL_CTX *ILibAsyncSocket_GetSSLContext(ILibAsyncSocket_SocketModule socketModule);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#else
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "microstack/sha.h"
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
@@ -561,10 +562,10 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i
|
||||
X509_NAME *cname = NULL;
|
||||
X509 **x509p = NULL;
|
||||
EVP_PKEY **pkeyp = NULL;
|
||||
int hashlen = UTIL_HASHSIZE;
|
||||
char hash[UTIL_HASHSIZE];
|
||||
int hashlen = UTIL_SHA384_HASHSIZE;
|
||||
char hash[UTIL_SHA384_HASHSIZE];
|
||||
char serial[8];
|
||||
char nameStr[(UTIL_HASHSIZE * 2) + 2];
|
||||
char nameStr[(UTIL_SHA384_HASHSIZE * 2) + 2];
|
||||
BIGNUM *oBigNbr;
|
||||
|
||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
@@ -616,7 +617,7 @@ int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, i
|
||||
//util_sha256((char*)x->cert_info->key->public_key->data, x->cert_info->key->public_key->length, hash); // OpenSSL 1.0
|
||||
X509_pubkey_digest(x, EVP_sha384(), (unsigned char*)hash, (unsigned int*)&hashlen); // OpenSSL 1.1
|
||||
|
||||
util_tohex(hash, UTIL_HASHSIZE, nameStr);
|
||||
util_tohex(hash, UTIL_SHA384_HASHSIZE, nameStr);
|
||||
X509_NAME_add_entry_by_txt(cname, "CN", MBSTRING_ASC, (unsigned char*)nameStr, -1, -1, 0);
|
||||
}
|
||||
else
|
||||
@@ -682,7 +683,7 @@ err:
|
||||
|
||||
int __fastcall util_keyhash(struct util_cert cert, char* result)
|
||||
{
|
||||
int hashlen = UTIL_HASHSIZE;
|
||||
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
|
||||
@@ -691,7 +692,7 @@ int __fastcall util_keyhash(struct util_cert cert, char* result)
|
||||
|
||||
int __fastcall util_keyhash2(X509* cert, char* result)
|
||||
{
|
||||
int hashlen = UTIL_HASHSIZE;
|
||||
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
|
||||
@@ -702,11 +703,11 @@ int __fastcall util_keyhash2(X509* cert, char* result)
|
||||
int __fastcall util_sign(struct util_cert cert, char* data, int datalen, char** signature)
|
||||
{
|
||||
int size = 0;
|
||||
unsigned int hashsize = UTIL_HASHSIZE;
|
||||
unsigned int hashsize = UTIL_SHA384_HASHSIZE;
|
||||
BIO *in = NULL;
|
||||
PKCS7 *message = NULL;
|
||||
*signature = NULL;
|
||||
if (datalen <= UTIL_HASHSIZE) return 0;
|
||||
if (datalen <= UTIL_SHA384_HASHSIZE) return 0;
|
||||
|
||||
// Add hash of the certificate to start of data
|
||||
X509_digest(cert.x509, EVP_sha384(), (unsigned char*)data, &hashsize);
|
||||
@@ -730,7 +731,7 @@ int __fastcall util_verify(char* signature, int signlen, struct util_cert* cert,
|
||||
BIO *out = NULL;
|
||||
PKCS7 *message = NULL;
|
||||
char* data2 = NULL;
|
||||
char hash[UTIL_HASHSIZE];
|
||||
char hash[UTIL_SHA256_HASHSIZE];
|
||||
STACK_OF(X509) *st = NULL;
|
||||
|
||||
cert->x509 = NULL;
|
||||
@@ -750,7 +751,7 @@ int __fastcall util_verify(char* signature, int signlen, struct util_cert* cert,
|
||||
|
||||
// If data block contains less than 32 bytes, fail.
|
||||
size = (unsigned int)BIO_get_mem_data(out, &data2);
|
||||
if (size <= UTIL_HASHSIZE) goto error;
|
||||
if (size <= UTIL_SHA256_HASHSIZE) goto error;
|
||||
|
||||
// Copy the data block
|
||||
*data = (char*)malloc(size + 1);
|
||||
@@ -764,11 +765,11 @@ int __fastcall util_verify(char* signature, int signlen, struct util_cert* cert,
|
||||
sk_X509_free(st);
|
||||
|
||||
// Get a full certificate hash of the signer
|
||||
r = UTIL_HASHSIZE;
|
||||
r = UTIL_SHA256_HASHSIZE;
|
||||
X509_digest(cert->x509, EVP_sha256(), (unsigned char*)hash, &r);
|
||||
|
||||
// Check certificate hash with first 32 bytes of data.
|
||||
if (memcmp(hash, *data, UTIL_HASHSIZE) != 0) goto error;
|
||||
if (memcmp(hash, *data, UTIL_SHA256_HASHSIZE) != 0) goto error;
|
||||
|
||||
// Approved, cleanup and return.
|
||||
BIO_free(out);
|
||||
|
||||
@@ -35,18 +35,31 @@ BOOL util_CopyFile(_In_ LPCSTR lpExistingFileName, _In_ LPCSTR lpNewFileName, _I
|
||||
void __fastcall util_random(int length, char* result);
|
||||
void __fastcall util_randomtext(int length, char* result);
|
||||
|
||||
#define UTIL_HASHSIZE 48
|
||||
#define NONCE_SIZE 48
|
||||
#define UTIL_MD5_HASHSIZE 16
|
||||
#define UTIL_SHA1_HASHSIZE 20
|
||||
#define UTIL_SHA256_HASHSIZE 32
|
||||
#define UTIL_SHA384_HASHSIZE 48
|
||||
#define UTIL_SHA512_HASHSIZE 64
|
||||
|
||||
#ifdef MICROSTACK_NOTLS
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "microstack/SHA256.h"
|
||||
#include "microstack/SHA.h"
|
||||
|
||||
#define SHA256_CTX struct sha256_ctx
|
||||
#define SHA256_Init(ctx) __sha256_init_ctx(ctx)
|
||||
#define SHA256_Update(ctx, data, len) __sha256_process_bytes(data, len, ctx)
|
||||
#define SHA256_Final(md, ctx) __sha256_finish_ctx(ctx, md)
|
||||
#define SHA256_CTX SHA256Context
|
||||
#define SHA512_CTX SHA512Context
|
||||
|
||||
#define SHA256_Init(ctx) SHA256Reset (ctx)
|
||||
#define SHA256_Update(ctx, data, len) SHA256Input(ctx, (uint8_t*)data, len)
|
||||
#define SHA256_Final(md, ctx) SHA256Result (ctx, md)
|
||||
|
||||
#define SHA384_Init(ctx) SHA384Reset (ctx)
|
||||
#define SHA384_Update(ctx, data, len) SHA384Input(ctx, (uint8_t*)data, len)
|
||||
#define SHA384_Final(md, ctx) SHA384Result (ctx, md)
|
||||
|
||||
#define SHA512_Init(ctx) SHA512Reset (ctx)
|
||||
#define SHA512_Update(ctx, data, len) SHA512Input(ctx, (uint8_t*)data, len)
|
||||
#define SHA512_Final(md, ctx) SHA512Result (ctx, md)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ void CALLBACK ILibIPAddressMonitor_dispatch(
|
||||
IN DWORD dwFlags
|
||||
)
|
||||
{
|
||||
if (dwError == 0)
|
||||
if (dwError == 0 && lpOverlapped->hEvent != NULL)
|
||||
{
|
||||
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)lpOverlapped->hEvent;
|
||||
ILibChain_RunOnMicrostackThread(obj->chainLink.ParentChain, ILibIPAddressMonitor_MicrostackThreadDispatch, obj);
|
||||
@@ -60,6 +60,7 @@ void ILibIPAddressMonitor_Destroy(void *object)
|
||||
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)object;
|
||||
|
||||
#ifdef WIN32
|
||||
obj->reserved.hEvent = NULL;
|
||||
closesocket(obj->mSocket);
|
||||
obj->mSocket = INVALID_SOCKET;
|
||||
#elif defined(_POSIX)
|
||||
|
||||
@@ -5104,9 +5104,17 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
|
||||
TempStringLength2 = TempStringLength-result2->FirstResult->datalength;
|
||||
if (Path != NULL)
|
||||
{
|
||||
if ((*Path = (char*)malloc(TempStringLength2 + 1)) == NULL) ILIBCRITICALEXIT(254);
|
||||
memcpy_s(*Path, TempStringLength2 + 1, TempString + (result2->FirstResult->datalength), TempStringLength2);
|
||||
(*Path)[TempStringLength2] = '\0';
|
||||
if ((*Path = (char*)malloc(TempStringLength2 + 2)) == NULL) ILIBCRITICALEXIT(254);
|
||||
if (TempStringLength2 == 0)
|
||||
{
|
||||
(*Path)[0] = '/';
|
||||
(*Path)[1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy_s(*Path, TempStringLength2 + 2, TempString + (result2->FirstResult->datalength), TempStringLength2);
|
||||
(*Path)[TempStringLength2] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Parse Port Number
|
||||
@@ -5333,7 +5341,7 @@ void ILibSetDirective(struct packetheader *packet, char* Directive, int Directiv
|
||||
|
||||
if (packet->ReservedMemory != NULL)
|
||||
{
|
||||
if (ILibMemory_AllocateA_Size(packet->ReservedMemory) > (DirectiveLength + DirectiveObjLength + 2))
|
||||
if (ILibMemory_AllocateA_Size(packet->ReservedMemory) > (unsigned int)(DirectiveLength + DirectiveObjLength + 2))
|
||||
{
|
||||
packet->Directive = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)DirectiveLength + 1);
|
||||
packet->DirectiveObj = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)DirectiveObjLength + 1);
|
||||
|
||||
@@ -306,10 +306,10 @@ int ILibIsRunningOnChainThread(void* chain);
|
||||
#else
|
||||
#define ILibMemory_AllocateA(bufferLen) ILibMemory_AllocateA_InitMem(alloca(8+bufferLen+sizeof(void*)), (size_t)(8+bufferLen+sizeof(void*)))
|
||||
#endif
|
||||
#define ILibMemory_AllocateA_Size(buffer) (((int*)((char*)(buffer)-4))[0])
|
||||
#define ILibMemory_AllocateA_Size(buffer) (((unsigned int*)((char*)(buffer)-4))[0])
|
||||
#define ILibMemory_AllocateA_Next(buffer) (((void**)((char*)(buffer)-4-sizeof(void*)))[0])
|
||||
#define ILibMemory_AllocateA_Raw(buffer) ((void*)((char*)(buffer)-4-sizeof(void*)-4))
|
||||
#define ILibMemory_AllocateA_RawSize(buffer) (((int*)((char*)(buffer)-4-sizeof(void*)-4))[0])
|
||||
#define ILibMemory_AllocateA_RawSize(buffer) (((unsigned int*)((char*)(buffer)-4-sizeof(void*)-4))[0])
|
||||
|
||||
void* ILibMemory_AllocateA_Get(void *buffer, size_t sz);
|
||||
void* ILibMemory_AllocateA_InitMem(void *buffer, size_t bufferLen);
|
||||
|
||||
@@ -162,6 +162,10 @@ typedef struct ILibProcessPipe_WaitHandle
|
||||
void *user;
|
||||
ILibProcessPipe_WaitHandle_Handler callback;
|
||||
}ILibProcessPipe_WaitHandle;
|
||||
HANDLE ILibProcessPipe_Manager_GetWorkerThread(ILibProcessPipe_Manager mgr)
|
||||
{
|
||||
return(((ILibProcessPipe_Manager_Object*)mgr)->workerThread);
|
||||
}
|
||||
|
||||
int ILibProcessPipe_Manager_WindowsWaitHandles_Remove_Comparer(void *source, void *matchWith)
|
||||
{
|
||||
@@ -181,6 +185,7 @@ void __stdcall ILibProcessPipe_WaitHandle_Remove_APC(ULONG_PTR obj)
|
||||
waiter = (ILibProcessPipe_WaitHandle*)ILibLinkedList_GetDataFromNode(node);
|
||||
free(waiter);
|
||||
ILibLinkedList_Remove(node);
|
||||
SetEvent(manager->updateEvent);
|
||||
}
|
||||
free((void*)obj);
|
||||
}
|
||||
@@ -497,21 +502,36 @@ ILibProcessPipe_PipeObject* ILibProcessPipe_CreatePipe(ILibProcessPipe_Manager m
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void ILibProcessPipe_Process_Destroy(ILibProcessPipe_Process_Object *p)
|
||||
#ifdef WIN32
|
||||
void __stdcall ILibProcessPipe_Process_Destroy_WinRunThread(ULONG_PTR obj)
|
||||
{
|
||||
ILibProcessPipe_Process_Object *p = (ILibProcessPipe_Process_Object*)obj;
|
||||
if (p->exiting != 0) { return; }
|
||||
if (p->stdIn != NULL) { ILibProcessPipe_FreePipe(p->stdIn); }
|
||||
if (p->stdOut != NULL) { ILibProcessPipe_FreePipe(p->stdOut); }
|
||||
if (p->stdErr != NULL) { ILibProcessPipe_FreePipe(p->stdErr); }
|
||||
free(p);
|
||||
}
|
||||
#ifndef WIN32
|
||||
void ILibProcessPipe_Process_BrokenPipeSink(ILibProcessPipe_PipeObject* sender)
|
||||
#endif
|
||||
void ILibProcessPipe_Process_Destroy(ILibProcessPipe_Process_Object *p)
|
||||
{
|
||||
ILibProcessPipe_Process_Object *p = sender->mProcess;
|
||||
#ifdef WIN32
|
||||
// We can't destroy this now, because we're on the MicrostackThread. We must destroy this on the WindowsRunLoop Thread.
|
||||
QueueUserAPC((PAPCFUNC)ILibProcessPipe_Process_Destroy_WinRunThread, p->parent->workerThread, (ULONG_PTR)p);
|
||||
#else
|
||||
if (p->exiting != 0) { return; }
|
||||
if (p->stdIn != NULL) { ILibProcessPipe_FreePipe(p->stdIn); }
|
||||
if (p->stdOut != NULL) { ILibProcessPipe_FreePipe(p->stdOut); }
|
||||
if (p->stdErr != NULL) { ILibProcessPipe_FreePipe(p->stdErr); }
|
||||
free(p);
|
||||
#endif
|
||||
}
|
||||
#ifndef WIN32
|
||||
void ILibProcessPipe_Process_BrokenPipeSink(ILibProcessPipe_Pipe sender)
|
||||
{
|
||||
ILibProcessPipe_Process_Object *p = ((ILibProcessPipe_PipeObject*)sender)->mProcess;
|
||||
int status;
|
||||
|
||||
if (ILibIsRunningOnChainThread(sender->manager->ChainLink.ParentChain) != 0)
|
||||
if (ILibIsRunningOnChainThread(((ILibProcessPipe_PipeObject*)sender)->manager->ChainLink.ParentChain) != 0)
|
||||
{
|
||||
// This was called from the Reader
|
||||
if (p->exitHandler != NULL)
|
||||
@@ -685,13 +705,14 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx2(ILibProcessPipe_
|
||||
retVal->stdIn = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(pipeManager, pipe, extraMemorySize);
|
||||
retVal->stdIn->mProcess = retVal;
|
||||
retVal->stdOut = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(pipeManager, pipe, extraMemorySize);
|
||||
ILibProcessPipe_Pipe_SetBrokenPipeHandler(retVal->stdOut, ILibProcessPipe_Process_BrokenPipeSink);
|
||||
retVal->stdOut->mProcess = retVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal->stdIn = ILibProcessPipe_CreatePipe(pipeManager, 4096, NULL, extraMemorySize);
|
||||
retVal->stdIn->mProcess = retVal;
|
||||
retVal->stdOut = ILibProcessPipe_CreatePipe(pipeManager, 4096, &ILibProcessPipe_Process_BrokenPipeSink, extraMemorySize);
|
||||
retVal->stdOut = ILibProcessPipe_CreatePipe(pipeManager, 4096, (ILibProcessPipe_GenericBrokenPipeHandler) ILibProcessPipe_Process_BrokenPipeSink, extraMemorySize);
|
||||
retVal->stdOut->mProcess = retVal;
|
||||
pid = vfork();
|
||||
}
|
||||
@@ -859,7 +880,6 @@ void ILibProcessPipe_Process_ReadHandler(void* user)
|
||||
|
||||
#endif
|
||||
ILibLinkedList_Remove(ILibLinkedList_GetNode_Search(pipeObject->manager->ActivePipes, NULL, pipeObject));
|
||||
|
||||
if (pipeObject->brokenPipeHandler != NULL)
|
||||
{
|
||||
((ILibProcessPipe_GenericBrokenPipeHandler)pipeObject->brokenPipeHandler)(pipeObject);
|
||||
@@ -1240,6 +1260,11 @@ void ILibProcessPipe_Process_PipeHandler_StdIn(void *user1, void *user2)
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
void __stdcall ILibProcessPipe_Process_OnExit_ChainSink_DestroySink(ULONG_PTR obj)
|
||||
{
|
||||
ILibProcessPipe_Process_Object* j = (ILibProcessPipe_Process_Object*)obj;
|
||||
if (j->exiting == 0) { ILibProcessPipe_Process_Destroy(j); }
|
||||
}
|
||||
void ILibProcessPipe_Process_OnExit_ChainSink(void *chain, void *user)
|
||||
{
|
||||
ILibProcessPipe_Process_Object* j = (ILibProcessPipe_Process_Object*)user;
|
||||
@@ -1250,8 +1275,9 @@ void ILibProcessPipe_Process_OnExit_ChainSink(void *chain, void *user)
|
||||
j->exiting = 1;
|
||||
j->exitHandler(j, exitCode, j->userObject);
|
||||
j->exiting ^= 1;
|
||||
|
||||
if (j->exiting == 0) { ILibProcessPipe_Process_Destroy(j); }
|
||||
|
||||
// We can't destroy this now, because we're on the MicrostackThread. We must destroy this on the WindowsRunLoop Thread.
|
||||
QueueUserAPC((PAPCFUNC)ILibProcessPipe_Process_OnExit_ChainSink_DestroySink, j->parent->workerThread, (ULONG_PTR)j);
|
||||
}
|
||||
BOOL ILibProcessPipe_Process_OnExit(HANDLE event, void* user)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef enum ILibProcessPipe_Pipe_ReaderHandleType
|
||||
ILibProcessPipe_Pipe_ReaderHandleType_NotOverLapped = 0, //!< Spawn a I/O processing thread
|
||||
ILibProcessPipe_Pipe_ReaderHandleType_Overlapped = 1 //!< Use Overlapped I/O
|
||||
}ILibProcessPipe_Pipe_ReaderHandleType;
|
||||
HANDLE ILibProcessPipe_Manager_GetWorkerThread(ILibProcessPipe_Manager mgr);
|
||||
#endif
|
||||
|
||||
ILibTransport_DoneState ILibProcessPipe_Pipe_Write(ILibProcessPipe_Pipe writePipe, char* buffer, int bufferLen, ILibTransport_MemoryOwnership ownership);
|
||||
|
||||
@@ -247,6 +247,7 @@ typedef struct ILibWebClientDataObject
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibWebClient_RequestToken_HTTPS requestMode;
|
||||
char *sniHost;
|
||||
#endif
|
||||
|
||||
char* CertificateHashPtr; // Points to the certificate hash (next field) if set
|
||||
@@ -342,7 +343,15 @@ void ILibWebClient_DestroyWebRequest(struct ILibWebRequest *wr)
|
||||
|
||||
if (wr == NULL) return;
|
||||
if (wr != NULL && wr->connectionCloseWasSpecified != 0 && wr->DisconnectSink != NULL) { wr->DisconnectSink(wr->requestToken); }
|
||||
if (wr->buffered != NULL) { free(wr->buffered); }
|
||||
if (wr->buffered != NULL)
|
||||
{
|
||||
while (wr->buffered != NULL)
|
||||
{
|
||||
ILibWebRequest_buffer * rb = wr->buffered->next;
|
||||
free(wr->buffered);
|
||||
wr->buffered = rb;
|
||||
}
|
||||
}
|
||||
if (wr->streamedState != NULL)
|
||||
{
|
||||
while (ILibQueue_IsEmpty(wr->streamedState->BufferQueue) == 0)
|
||||
@@ -472,6 +481,9 @@ void ILibWebClient_DestroyWebClientDataObject(ILibWebClient_StateObject token)
|
||||
|
||||
ILibQueue_Destroy(wcdo->RequestQueue);
|
||||
if (wcdo->DigestData != NULL) { free(ILibMemory_AllocateA_Raw(wcdo->DigestData)); }
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (wcdo->sniHost != NULL) { free(wcdo->sniHost); }
|
||||
#endif
|
||||
free(wcdo);
|
||||
}
|
||||
|
||||
@@ -739,8 +751,11 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
|
||||
SEM_TRACK(WebClient_TrackLock("ILibWebClient_FinishedResponse", 1, wcdo->Parent);)
|
||||
sem_wait(&(wcdo->Parent->QLock));
|
||||
wr = (struct ILibWebRequest*)ILibQueue_DeQueue(wcdo->RequestQueue);
|
||||
wr->connectionCloseWasSpecified = 2;
|
||||
ILibWebClient_DestroyWebRequest(wr);
|
||||
if (wr != NULL)
|
||||
{
|
||||
wr->connectionCloseWasSpecified = 2;
|
||||
ILibWebClient_DestroyWebRequest(wr);
|
||||
}
|
||||
SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_FinishedResponse", 2, wcdo->Parent);)
|
||||
sem_post(&(wcdo->Parent->QLock));
|
||||
return;
|
||||
@@ -795,12 +810,12 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
|
||||
//
|
||||
ILibAsyncSocket_Send(wcdo->SOCK, wr->Buffer[i], wr->BufferLength[i], ILibAsyncSocket_MemoryOwnership_STATIC);
|
||||
}
|
||||
while (wr->buffered != NULL)
|
||||
|
||||
b = wr->buffered;
|
||||
while (b != NULL)
|
||||
{
|
||||
b = wr->buffered->next;
|
||||
ILibAsyncSocket_Send(wcdo->SOCK, wr->buffered->buffer, wr->buffered->bufferLength, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
free(wr->buffered);
|
||||
wr->buffered = b;
|
||||
ILibAsyncSocket_Send(wcdo->SOCK, b->buffer, b->bufferLength, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
b = b->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1140,7 +1155,7 @@ void ILibWebClient_ProcessChunk(ILibAsyncSocket_SocketModule socketModule, struc
|
||||
wcdo->NeedFlush = 0;
|
||||
ILibWebClient_FinishedResponse_Server(wcdo);
|
||||
}
|
||||
if (ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
if (socketModule==NULL || ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
{
|
||||
//
|
||||
// Free the resources associated with this chunk
|
||||
@@ -1556,7 +1571,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
wcdo->source.sin_addr.s_addr = ILibAsyncSocket_GetRemoteInterface(socketModule);
|
||||
wcdo->source.sin_port = htons(ILibAsyncSocket_GetRemotePort(socketModule));
|
||||
*/
|
||||
ILibAsyncSocket_GetRemoteInterface(socketModule, (struct sockaddr*)(&wcdo->source));
|
||||
if (socketModule != NULL) { ILibAsyncSocket_GetRemoteInterface(socketModule, (struct sockaddr*)(&wcdo->source)); }
|
||||
|
||||
wcdo->HeaderLength = i + 4;
|
||||
wcdo->WaitForClose = 1;
|
||||
@@ -1654,7 +1669,14 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
}
|
||||
if (wcdo->header->StatusCode >= 100 && wcdo->header->StatusCode <= 199)
|
||||
{
|
||||
if (wcdo->header->StatusCode == 101 && wr->requestToken->WebSocketKey != NULL)
|
||||
if (wr->requestToken == NULL)
|
||||
{
|
||||
int zro = 0;
|
||||
if (wr->OnResponse != NULL) { wr->OnResponse(wcdo, 0, wcdo->header, NULL, &zro, 0, ILibWebClient_ReceiveStatus_Connection_Established, wr->user1, wr->user2, &(wcdo->PAUSE)); }
|
||||
*p_beginPointer += wcdo->HeaderLength;
|
||||
return;
|
||||
}
|
||||
else if (wcdo->header->StatusCode == 101 && wr->requestToken->WebSocketKey != NULL)
|
||||
{
|
||||
// WebSocket
|
||||
char* skey = ILibGetHeaderLine(wcdo->header, "Sec-WebSocket-Accept", 20);
|
||||
@@ -1812,7 +1834,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
wr->user2,
|
||||
&(wcdo->PAUSE));
|
||||
}
|
||||
if (ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
if (socketModule==NULL || ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
{
|
||||
wcdo->HeaderLength = 0;
|
||||
*p_beginPointer = i+4+zero;
|
||||
@@ -1856,31 +1878,28 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
wr->user1,
|
||||
wr->user2,
|
||||
&(wcdo->PAUSE));
|
||||
if (ILibAsyncSocket_IsFree(socketModule)!=0)
|
||||
if (wcdo->FinHeader == 0)
|
||||
{
|
||||
//
|
||||
// The user sent a response already, so advance the
|
||||
// beginPointer and return.
|
||||
//
|
||||
// If the user sent a response, and it wasn't in relation to a 100 Continue, then the
|
||||
// user is in ERROR, because the done flag is not set here, which means that
|
||||
// the entire request did not get received yet. Simply answering the request
|
||||
// without receiving the entire request, without closing the socket is in
|
||||
// VIOLATION of the http specification.
|
||||
//
|
||||
*p_beginPointer = i + 4;
|
||||
return;
|
||||
}
|
||||
if (socketModule != NULL && ILibAsyncSocket_IsFree(socketModule)!=0)
|
||||
{
|
||||
//
|
||||
// The user closed the socket, so just return
|
||||
//
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wcdo->FinHeader==0)
|
||||
{
|
||||
//
|
||||
// The user sent a response already, so advance the
|
||||
// beginPointer and return.
|
||||
//
|
||||
// If the user sent a response, and it wasn't in relation to a 100 Continue, then the
|
||||
// user is in ERROR, because the done flag is not set here, which means that
|
||||
// the entire request did not get received yet. Simply answering the request
|
||||
// without receiving the entire request, without closing the socket is in
|
||||
// VIOLATION of the http specification.
|
||||
//
|
||||
*p_beginPointer = i + 4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1950,7 +1969,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
wr->user2,
|
||||
&(wcdo->PAUSE));
|
||||
}
|
||||
if (ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
if (socketModule==NULL || ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
{
|
||||
if (wcdo->WaitForClose==0)
|
||||
{
|
||||
@@ -1979,7 +1998,7 @@ void ILibWebClient_OnData(ILibAsyncSocket_SocketModule socketModule, char* buffe
|
||||
}
|
||||
//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}
|
||||
}
|
||||
if (ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
if (socketModule==NULL || ILibAsyncSocket_IsFree(socketModule)==0)
|
||||
{
|
||||
//
|
||||
// If the user said to pause this connection, do so
|
||||
@@ -2054,12 +2073,11 @@ void ILibWebClient_OnConnect(ILibAsyncSocket_SocketModule socketModule, int Conn
|
||||
ILibAsyncSocket_Send(socketModule, r->Buffer[i], r->BufferLength[i], (enum ILibAsyncSocket_MemoryOwnership)-1);
|
||||
}
|
||||
|
||||
while (r->buffered != NULL)
|
||||
b = r->buffered;
|
||||
while (b != NULL)
|
||||
{
|
||||
ILibAsyncSocket_Send(socketModule, r->buffered->buffer, r->buffered->bufferLength, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
b = r->buffered;
|
||||
r->buffered = r->buffered->next;
|
||||
free(b);
|
||||
ILibAsyncSocket_Send(socketModule, b->buffer, b->bufferLength, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
b = b->next;
|
||||
}
|
||||
if (r->streamedState != NULL)
|
||||
{
|
||||
@@ -2214,27 +2232,6 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
|
||||
wr->user2,
|
||||
&(wcdo->PAUSE));
|
||||
|
||||
if (ILibAsyncSocket_IsFree(socketModule) != 0)
|
||||
{
|
||||
//
|
||||
// If the underlying socket is gone, then Finished Response won't clear
|
||||
// the pending request
|
||||
//
|
||||
SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect", 5, wcdo->Parent);)
|
||||
sem_wait(&(wcdo->Parent->QLock));
|
||||
wr = (struct ILibWebRequest*)ILibQueue_DeQueue(wcdo->RequestQueue);
|
||||
SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect", 6, wcdo->Parent);)
|
||||
sem_post(&(wcdo->Parent->QLock));
|
||||
if (wr != NULL)
|
||||
{
|
||||
if (wcdo->IsWebSocket != 0)
|
||||
{
|
||||
free(((ILibWebClient_WebSocketState*)wr->Buffer[0])->WebSocketFragmentBuffer);
|
||||
}
|
||||
wr->connectionCloseWasSpecified = 2;
|
||||
ILibWebClient_DestroyWebRequest(wr);
|
||||
}
|
||||
}
|
||||
if (wcdo->IsOrphan != 0 || wcdo->IsWebSocket != 0)
|
||||
{
|
||||
ILibWebClient_FinishedResponse(socketModule, wcdo);
|
||||
@@ -2244,20 +2241,6 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
|
||||
{
|
||||
ILibWebClient_FinishedResponse(socketModule, wcdo);
|
||||
}
|
||||
//SEM_TRACK(WebClient_TrackLock("ILibWebClient_OnDisconnect", 7, wcdo->Parent);)
|
||||
//sem_wait(&(wcdo->Parent->QLock));
|
||||
//wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
|
||||
//SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_OnDisconnect", 8, wcdo->Parent);)
|
||||
//sem_post(&(wcdo->Parent->QLock));
|
||||
//if (wr == NULL)
|
||||
//{
|
||||
// if (wcdo->IsWebSocket != 0)
|
||||
// {
|
||||
// // This was a websocket, so we must destroy the WCDO object, because it won't be destroyed anywhere else
|
||||
// ILibWebClient_DestroyWebClientDataObject(wcdo);
|
||||
// }
|
||||
// return;
|
||||
//}
|
||||
}
|
||||
|
||||
// Make Another Connection and Continue
|
||||
@@ -2357,7 +2340,7 @@ void ILibWebClient_PreProcess(void* WebClientModule, fd_set *readset, fd_set *wr
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (wcm->ssl_ctx != NULL && wcdo->requestMode == ILibWebClient_RequestToken_USE_HTTPS)
|
||||
{
|
||||
SSL* ssl = ILibAsyncSocket_SetSSLContext(wcdo->SOCK, wcm->ssl_ctx, 0);
|
||||
SSL* ssl = ILibAsyncSocket_SetSSLContextEx(wcdo->SOCK, wcm->ssl_ctx, 0, wcdo->sniHost);
|
||||
if (ssl != NULL && ILibWebClientDataObjectIndex >= 0)
|
||||
{
|
||||
SSL_set_ex_data(ssl, ILibWebClientDataObjectIndex, wcdo);
|
||||
@@ -3256,7 +3239,7 @@ ILibTransport_DoneState ILibWebClient_StreamRequestBody(
|
||||
|
||||
if (t != NULL && t->wcdo != NULL)
|
||||
{
|
||||
wr = (struct ILibWebRequest*)ILibQueue_PeekTail(t->wcdo->RequestQueue);
|
||||
wr = t->parent;
|
||||
if (t->wcdo->SOCK == NULL || ILibQueue_GetCount(t->wcdo->RequestQueue)>1)
|
||||
{
|
||||
// Connection not established yet, so buffer the data
|
||||
@@ -3583,6 +3566,12 @@ void ILibWebClient_Request_SetHTTPS(ILibWebClient_RequestToken reqToken, ILibWeb
|
||||
{
|
||||
((struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(reqToken))->requestMode = requestMode;
|
||||
}
|
||||
void ILibWebClient_Request_SetSNI(ILibWebClient_RequestToken reqToken, char *host, int hostLen)
|
||||
{
|
||||
((struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(reqToken))->sniHost = ILibMemory_Allocate(hostLen + 1, 0, NULL, NULL);
|
||||
memcpy_s(((struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(reqToken))->sniHost, hostLen, host, hostLen);
|
||||
((struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(reqToken))->sniHost[hostLen] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ILibWebClient_GetLocalInterface(void* socketModule, struct sockaddr *localAddress)
|
||||
|
||||
@@ -257,9 +257,7 @@ void* ILibWebClient_GetChainFromWebStateObject(ILibWebClient_StateObject wcdo);
|
||||
|
||||
typedef enum ILibWebClient_RequestToken_HTTPS
|
||||
{
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibWebClient_RequestToken_USE_HTTPS = 0,
|
||||
#endif
|
||||
ILibWebClient_RequestToken_USE_HTTP = 1
|
||||
}ILibWebClient_RequestToken_HTTPS;
|
||||
|
||||
@@ -267,6 +265,7 @@ typedef enum ILibWebClient_RequestToken_HTTPS
|
||||
void ILibWebClient_SetTLS(ILibWebClient_RequestManager manager, void *ssl_ctx, ILibWebClient_OnSslConnection OnSslConnection);
|
||||
int ILibWebClient_EnableHTTPS(ILibWebClient_RequestManager manager, struct util_cert* leafCert, X509* nonLeafCert, ILibWebClient_OnHttpsConnection OnHttpsConnection);
|
||||
void ILibWebClient_Request_SetHTTPS(ILibWebClient_RequestToken reqToken, ILibWebClient_RequestToken_HTTPS requestMode);
|
||||
void ILibWebClient_Request_SetSNI(ILibWebClient_RequestToken reqToken, char *host, int hostLen);
|
||||
#endif
|
||||
|
||||
// Added methods
|
||||
|
||||
@@ -1141,7 +1141,7 @@ int ILibWebServer_Digest_ParseAuthenticationHeader2(char* value, int valueLen, c
|
||||
*token = value;
|
||||
|
||||
len = ILibTrimString(token, i);
|
||||
(*token)[len] = 0;
|
||||
//(*token)[len] = 0;
|
||||
*tokenLen = len;
|
||||
|
||||
*tokenValue = value + i + 1;
|
||||
@@ -1157,7 +1157,7 @@ int ILibWebServer_Digest_ParseAuthenticationHeader2(char* value, int valueLen, c
|
||||
{
|
||||
len -= 1;
|
||||
}
|
||||
(*tokenValue)[len] = 0;
|
||||
//(*tokenValue)[len] = 0;
|
||||
*tokenValueLen = len;
|
||||
return 0;
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ int ILibWebServer_Digest_IsCorrectRealmAndNonce(struct ILibWebServer_Session *se
|
||||
int userRealmLen;
|
||||
char* nonce = NULL;
|
||||
char* opaque = NULL;
|
||||
int opaqueLen;
|
||||
int opaqueLen, nonceLen;
|
||||
long long current;
|
||||
char expiration[8];
|
||||
char calculatedNonce[33];
|
||||
@@ -1205,7 +1205,7 @@ int ILibWebServer_Digest_IsCorrectRealmAndNonce(struct ILibWebServer_Session *se
|
||||
|
||||
ILibWebServer_Digest_ParseAuthenticationHeader(ILibWebServer_Session_GetSystemData(session)->DigestTable, auth, authLen);
|
||||
ILibGetEntryEx(ILibWebServer_Session_GetSystemData(session)->DigestTable, "realm", 5, (void**)&userRealm, &userRealmLen);
|
||||
nonce = (char*)ILibGetEntry(ILibWebServer_Session_GetSystemData(session)->DigestTable, "nonce", 5);
|
||||
ILibGetEntryEx(ILibWebServer_Session_GetSystemData(session)->DigestTable, "nonce", 5, (void**)&nonce, &nonceLen);
|
||||
ILibGetEntryEx(ILibWebServer_Session_GetSystemData(session)->DigestTable, "opaque", 6, (void**)&opaque, &opaqueLen);
|
||||
|
||||
if (opaque != NULL && userRealm != NULL && userRealmLen == realmLen && strncmp(userRealm, realm, realmLen) == 0)
|
||||
@@ -1217,7 +1217,7 @@ int ILibWebServer_Digest_IsCorrectRealmAndNonce(struct ILibWebServer_Session *se
|
||||
if (((long long*)expiration)[0] < current) { return 0; } // Opaque Block Expired
|
||||
|
||||
ILibWebServer_Digest_CalculateNonce(session, ((long long*)expiration)[0], calculatedNonce);
|
||||
return(strcmp(nonce, calculatedNonce) == 0 ? 1 : 0);
|
||||
return((nonceLen == 32 && strncmp(nonce, calculatedNonce, 32)) == 0 ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1304,7 +1304,7 @@ ILibExportMethod int ILibWebServer_Digest_ValidatePassword(struct ILibWebServer_
|
||||
MD5_Final((unsigned char*)val, &mctx);
|
||||
util_tohex_lower(val, 16, result3);
|
||||
|
||||
retVal = strcmp(result3, response) == 0 ? 1 : 0;
|
||||
retVal = (responseLen == 32 && strncmp(result3, response, 32)) == 0 ? 1 : 0;
|
||||
// if (retVal == 0) { ILibWebServer_Digest_SendUnauthorized(session, realm, strlen(realm)); }
|
||||
|
||||
return retVal;
|
||||
|
||||
@@ -59,8 +59,8 @@ typedef struct
|
||||
struct util_cert selftlscert;
|
||||
struct util_cert selftlsclientcert;
|
||||
SSL_CTX* ctx;
|
||||
char tlsServerCertThumbprint[32];
|
||||
char g_selfid[UTIL_HASHSIZE];
|
||||
char tlsServerCertThumbprint[UTIL_SHA256_HASHSIZE];
|
||||
char g_selfid[UTIL_SHA256_HASHSIZE];
|
||||
|
||||
ILibWebRTC_TURN_ConnectFlags mTurnSetting;
|
||||
struct sockaddr_in6 mTurnServer;
|
||||
|
||||
61
microstack/sha-private.h
Normal file
61
microstack/sha-private.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*************************** sha-private.h ***************************/
|
||||
|
||||
/*
|
||||
https://github.com/Yubico/yubico-c-client
|
||||
|
||||
Copyright (c) 2006-2013 Yubico AB
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/********************** See RFC 4634 for details *********************/
|
||||
#ifndef _SHA_PRIVATE__H
|
||||
#define _SHA_PRIVATE__H
|
||||
/*
|
||||
* These definitions are defined in FIPS-180-2, section 4.1.
|
||||
* Ch() and Maj() are defined identically in sections 4.1.1,
|
||||
* 4.1.2 and 4.1.3.
|
||||
*
|
||||
* The definitions used in FIPS-180-2 are as follows:
|
||||
*/
|
||||
|
||||
#ifndef USE_MODIFIED_MACROS
|
||||
#define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* USE_MODIFIED_MACROS */
|
||||
/*
|
||||
* The following definitions are equivalent and potentially faster.
|
||||
*/
|
||||
|
||||
#define SHA_Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z))
|
||||
#define SHA_Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
|
||||
#endif /* USE_MODIFIED_MACROS */
|
||||
|
||||
#define SHA_Parity(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
#endif /* _SHA_PRIVATE__H */
|
||||
303
microstack/sha.h
Normal file
303
microstack/sha.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/**************************** sha.h ****************************/
|
||||
|
||||
/*
|
||||
https://github.com/Yubico/yubico-c-client
|
||||
|
||||
Copyright (c) 2006-2013 Yubico AB
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/******************* See RFC 4634 for details ******************/
|
||||
#ifndef _SHA_H_
|
||||
#define _SHA_H_
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* This file implements the Secure Hash Signature Standard
|
||||
* algorithms as defined in the National Institute of Standards
|
||||
* and Technology Federal Information Processing Standards
|
||||
* Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
|
||||
* published on August 1, 2002, and the FIPS PUB 180-2 Change
|
||||
* Notice published on February 28, 2004.
|
||||
*
|
||||
* A combined document showing all algorithms is available at
|
||||
* http://csrc.nist.gov/publications/fips/
|
||||
* fips180-2/fips180-2withchangenotice.pdf
|
||||
*
|
||||
* The five hashes are defined in these sizes:
|
||||
* SHA-1 20 byte / 160 bit
|
||||
* SHA-224 28 byte / 224 bit
|
||||
* SHA-256 32 byte / 256 bit
|
||||
* SHA-384 48 byte / 384 bit
|
||||
* SHA-512 64 byte / 512 bit
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
/*
|
||||
* If you do not have the ISO standard stdint.h header file, then you
|
||||
* must typedef the following:
|
||||
* name meaning
|
||||
* uint64_t unsigned 64 bit integer
|
||||
* uint32_t unsigned 32 bit integer
|
||||
* uint8_t unsigned 8 bit integer (i.e., unsigned char)
|
||||
* int_least16_t integer of >= 16 bits
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SHA_enum_
|
||||
#define _SHA_enum_
|
||||
/*
|
||||
* All SHA functions return one of these values.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
shaSuccess = 0,
|
||||
shaNull, /* Null pointer parameter */
|
||||
shaInputTooLong, /* input data too long */
|
||||
shaStateError, /* called Input after FinalBits or Result */
|
||||
shaBadParam /* passed a bad parameter */
|
||||
};
|
||||
#endif /* _SHA_enum_ */
|
||||
|
||||
/*
|
||||
* These constants hold size information for each of the SHA
|
||||
* hashing operations
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SHA1_Message_Block_Size = 64, SHA224_Message_Block_Size = 64,
|
||||
SHA256_Message_Block_Size = 64, SHA384_Message_Block_Size = 128,
|
||||
SHA512_Message_Block_Size = 128,
|
||||
USHA_Max_Message_Block_Size = SHA512_Message_Block_Size,
|
||||
|
||||
SHA1HashSize = 20, SHA224HashSize = 28, SHA256HashSize = 32,
|
||||
SHA384HashSize = 48, SHA512HashSize = 64,
|
||||
USHAMaxHashSize = SHA512HashSize,
|
||||
|
||||
SHA1HashSizeBits = 160, SHA224HashSizeBits = 224,
|
||||
SHA256HashSizeBits = 256, SHA384HashSizeBits = 384,
|
||||
SHA512HashSizeBits = 512, USHAMaxHashSizeBits = SHA512HashSizeBits
|
||||
};
|
||||
|
||||
/*
|
||||
* These constants are used in the USHA (unified sha) functions.
|
||||
*/
|
||||
typedef enum SHAversion
|
||||
{
|
||||
SHA1, SHA224, SHA256, SHA384, SHA512
|
||||
} SHAversion;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the SHA-1
|
||||
* hashing operation.
|
||||
*/
|
||||
typedef struct SHA1Context
|
||||
{
|
||||
uint32_t Intermediate_Hash[SHA1HashSize / 4]; /* Message Digest */
|
||||
|
||||
uint32_t Length_Low; /* Message length in bits */
|
||||
uint32_t Length_High; /* Message length in bits */
|
||||
|
||||
int_least16_t Message_Block_Index; /* Message_Block array index */
|
||||
/* 512-bit message blocks */
|
||||
uint8_t Message_Block[SHA1_Message_Block_Size];
|
||||
|
||||
int Computed; /* Is the digest computed? */
|
||||
int Corrupted; /* Is the digest corrupted? */
|
||||
} SHA1Context;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the SHA-256
|
||||
* hashing operation.
|
||||
*/
|
||||
typedef struct SHA256Context
|
||||
{
|
||||
uint32_t Intermediate_Hash[SHA256HashSize / 4]; /* Message Digest */
|
||||
|
||||
uint32_t Length_Low; /* Message length in bits */
|
||||
uint32_t Length_High; /* Message length in bits */
|
||||
|
||||
int_least16_t Message_Block_Index; /* Message_Block array index */
|
||||
/* 512-bit message blocks */
|
||||
uint8_t Message_Block[SHA256_Message_Block_Size];
|
||||
|
||||
int Computed; /* Is the digest computed? */
|
||||
int Corrupted; /* Is the digest corrupted? */
|
||||
} SHA256Context;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the SHA-512
|
||||
* hashing operation.
|
||||
*/
|
||||
typedef struct SHA512Context
|
||||
{
|
||||
#ifdef USE_32BIT_ONLY
|
||||
uint32_t Intermediate_Hash[SHA512HashSize / 4]; /* Message Digest */
|
||||
uint32_t Length[4]; /* Message length in bits */
|
||||
#else /* !USE_32BIT_ONLY */
|
||||
uint64_t Intermediate_Hash[SHA512HashSize / 8]; /* Message Digest */
|
||||
uint64_t Length_Low, Length_High; /* Message length in bits */
|
||||
#endif /* USE_32BIT_ONLY */
|
||||
int_least16_t Message_Block_Index; /* Message_Block array index */
|
||||
/* 1024-bit message blocks */
|
||||
uint8_t Message_Block[SHA512_Message_Block_Size];
|
||||
|
||||
int Computed; /* Is the digest computed? */
|
||||
int Corrupted; /* Is the digest corrupted? */
|
||||
} SHA512Context;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the SHA-224
|
||||
* hashing operation. It uses the SHA-256 structure for computation.
|
||||
*/
|
||||
typedef struct SHA256Context SHA224Context;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the SHA-384
|
||||
* hashing operation. It uses the SHA-512 structure for computation.
|
||||
*/
|
||||
typedef struct SHA512Context SHA384Context;
|
||||
|
||||
/*
|
||||
* This structure holds context information for all SHA
|
||||
* hashing operations.
|
||||
*/
|
||||
typedef struct USHAContext
|
||||
{
|
||||
int whichSha; /* which SHA is being used */
|
||||
union
|
||||
{
|
||||
SHA1Context sha1Context;
|
||||
SHA224Context sha224Context;
|
||||
SHA256Context sha256Context;
|
||||
SHA384Context sha384Context;
|
||||
SHA512Context sha512Context;
|
||||
} ctx;
|
||||
} USHAContext;
|
||||
|
||||
/*
|
||||
* This structure will hold context information for the HMAC
|
||||
* keyed hashing operation.
|
||||
*/
|
||||
typedef struct HMACContext
|
||||
{
|
||||
int whichSha; /* which SHA is being used */
|
||||
int hashSize; /* hash size of SHA being used */
|
||||
int blockSize; /* block size of SHA being used */
|
||||
USHAContext shaContext; /* SHA context */
|
||||
unsigned char k_opad[USHA_Max_Message_Block_Size];
|
||||
/* outer padding - key XORd with opad */
|
||||
} HMACContext;
|
||||
|
||||
/*
|
||||
* Function Prototypes
|
||||
*/
|
||||
|
||||
/* SHA-1 */
|
||||
extern int SHA1Reset(SHA1Context *);
|
||||
extern int SHA1Input(SHA1Context *, const uint8_t * bytes,
|
||||
unsigned int bytecount);
|
||||
extern int SHA1FinalBits(SHA1Context *, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize]);
|
||||
|
||||
/* SHA-224 */
|
||||
extern int SHA224Reset(SHA224Context *);
|
||||
extern int SHA224Input(SHA224Context *, const uint8_t * bytes,
|
||||
unsigned int bytecount);
|
||||
extern int SHA224FinalBits(SHA224Context *, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int SHA224Result(SHA224Context *,
|
||||
uint8_t Message_Digest[SHA224HashSize]);
|
||||
|
||||
/* SHA-256 */
|
||||
extern int SHA256Reset(SHA256Context *);
|
||||
extern int SHA256Input(SHA256Context *, const uint8_t * bytes,
|
||||
unsigned int bytecount);
|
||||
extern int SHA256FinalBits(SHA256Context *, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int SHA256Result(SHA256Context *,
|
||||
uint8_t Message_Digest[SHA256HashSize]);
|
||||
|
||||
/* SHA-384 */
|
||||
extern int SHA384Reset(SHA384Context *);
|
||||
extern int SHA384Input(SHA384Context *, const uint8_t * bytes,
|
||||
unsigned int bytecount);
|
||||
extern int SHA384FinalBits(SHA384Context *, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int SHA384Result(SHA384Context *,
|
||||
uint8_t Message_Digest[SHA384HashSize]);
|
||||
|
||||
/* SHA-512 */
|
||||
extern int SHA512Reset(SHA512Context *);
|
||||
extern int SHA512Input(SHA512Context *, const uint8_t * bytes,
|
||||
unsigned int bytecount);
|
||||
extern int SHA512FinalBits(SHA512Context *, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int SHA512Result(SHA512Context *,
|
||||
uint8_t Message_Digest[SHA512HashSize]);
|
||||
|
||||
/* Unified SHA functions, chosen by whichSha */
|
||||
extern int USHAReset(USHAContext *, SHAversion whichSha);
|
||||
extern int USHAInput(USHAContext *,
|
||||
const uint8_t * bytes, unsigned int bytecount);
|
||||
extern int USHAFinalBits(USHAContext *,
|
||||
const uint8_t bits, unsigned int bitcount);
|
||||
extern int USHAResult(USHAContext *,
|
||||
uint8_t Message_Digest[USHAMaxHashSize]);
|
||||
extern int USHABlockSize(enum SHAversion whichSha);
|
||||
extern int USHAHashSize(enum SHAversion whichSha);
|
||||
extern int USHAHashSizeBits(enum SHAversion whichSha);
|
||||
|
||||
/*
|
||||
* HMAC Keyed-Hashing for Message Authentication, RFC2104,
|
||||
* for all SHAs.
|
||||
* This interface allows a fixed-length text input to be used.
|
||||
*/
|
||||
extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */
|
||||
const unsigned char *text, /* pointer to data stream */
|
||||
int text_len, /* length of data stream */
|
||||
const unsigned char *key, /* pointer to authentication key */
|
||||
int key_len, /* length of authentication key */
|
||||
uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */
|
||||
|
||||
/*
|
||||
* HMAC Keyed-Hashing for Message Authentication, RFC2104,
|
||||
* for all SHAs.
|
||||
* This interface allows any length of text input to be used.
|
||||
*/
|
||||
extern int hmacReset(HMACContext * ctx, enum SHAversion whichSha,
|
||||
const unsigned char *key, int key_len);
|
||||
extern int hmacInput(HMACContext * ctx, const unsigned char *text,
|
||||
int text_len);
|
||||
|
||||
extern int hmacFinalBits(HMACContext * ctx, const uint8_t bits,
|
||||
unsigned int bitcount);
|
||||
extern int hmacResult(HMACContext * ctx, uint8_t digest[USHAMaxHashSize]);
|
||||
|
||||
#endif /* _SHA_H_ */
|
||||
636
microstack/sha224-256.c
Normal file
636
microstack/sha224-256.c
Normal file
@@ -0,0 +1,636 @@
|
||||
/*************************** sha224-256.c ***************************/
|
||||
/*
|
||||
https://github.com/Yubico/yubico-c-client
|
||||
|
||||
Copyright (c) 2006-2013 Yubico AB
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/********************* See RFC 4634 for details *********************/
|
||||
/*
|
||||
* Description:
|
||||
* This file implements the Secure Hash Signature Standard
|
||||
* algorithms as defined in the National Institute of Standards
|
||||
* and Technology Federal Information Processing Standards
|
||||
* Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
|
||||
* published on August 1, 2002, and the FIPS PUB 180-2 Change
|
||||
* Notice published on February 28, 2004.
|
||||
*
|
||||
* A combined document showing all algorithms is available at
|
||||
* http://csrc.nist.gov/publications/fips/
|
||||
* fips180-2/fips180-2withchangenotice.pdf
|
||||
*
|
||||
* The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit
|
||||
* message digests for a given data stream. It should take about
|
||||
* 2**n steps to find a message with the same digest as a given
|
||||
* message and 2**(n/2) to find any two messages with the same
|
||||
* digest, when n is the digest size in bits. Therefore, this
|
||||
* algorithm can serve as a means of providing a
|
||||
* "fingerprint" for a message.
|
||||
*
|
||||
* Portability Issues:
|
||||
* SHA-224 and SHA-256 are defined in terms of 32-bit "words".
|
||||
* This code uses <stdint.h> (included via "sha.h") to define 32
|
||||
* and 8 bit unsigned integer types. If your C compiler does not
|
||||
* support 32 bit unsigned integers, this code is not
|
||||
* appropriate.
|
||||
*
|
||||
* Caveats:
|
||||
* SHA-224 and SHA-256 are designed to work with messages less
|
||||
* than 2^64 bits long. This implementation uses SHA224/256Input()
|
||||
* to hash the bits that are a multiple of the size of an 8-bit
|
||||
* character, and then uses SHA224/256FinalBits() to hash the
|
||||
* final few bits of the input.
|
||||
*/
|
||||
|
||||
#include "sha.h"
|
||||
#include "sha-private.h"
|
||||
/* Define the SHA shift, rotate left and rotate right macro */
|
||||
#define SHA256_SHR(bits,word) ((word) >> (bits))
|
||||
#define SHA256_ROTL(bits,word) \
|
||||
(((word) << (bits)) | ((word) >> (32-(bits))))
|
||||
#define SHA256_ROTR(bits,word) \
|
||||
(((word) >> (bits)) | ((word) << (32-(bits))))
|
||||
|
||||
/* Define the SHA SIGMA and sigma macros */
|
||||
#define SHA256_SIGMA0(word) \
|
||||
(SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word))
|
||||
#define SHA256_SIGMA1(word) \
|
||||
(SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word))
|
||||
#define SHA256_sigma0(word) \
|
||||
(SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word))
|
||||
#define SHA256_sigma1(word) \
|
||||
(SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word))
|
||||
|
||||
/*
|
||||
* add "length" to the length
|
||||
*/
|
||||
static uint32_t addTemp;
|
||||
#define SHA224_256AddLength(context, length) \
|
||||
(addTemp = (context)->Length_Low, (context)->Corrupted = \
|
||||
(((context)->Length_Low += (length)) < addTemp) && \
|
||||
(++(context)->Length_High == 0) ? 1 : 0)
|
||||
|
||||
/* Local Function Prototypes */
|
||||
static void SHA224_256Finalize(SHA256Context * context, uint8_t Pad_Byte);
|
||||
static void SHA224_256PadMessage(SHA256Context * context, uint8_t Pad_Byte);
|
||||
static void SHA224_256ProcessMessageBlock(SHA256Context * context);
|
||||
static int SHA224_256Reset(SHA256Context * context, uint32_t * H0);
|
||||
static int SHA224_256ResultN(SHA256Context * context,
|
||||
uint8_t Message_Digest[], int HashSize);
|
||||
|
||||
/* Initial Hash Values: FIPS-180-2 Change Notice 1 */
|
||||
static uint32_t SHA224_H0[SHA256HashSize / 4] = {
|
||||
0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
|
||||
0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
|
||||
};
|
||||
|
||||
/* Initial Hash Values: FIPS-180-2 section 5.3.2 */
|
||||
static uint32_t SHA256_H0[SHA256HashSize / 4] = {
|
||||
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA224Reset
|
||||
*
|
||||
* Description:
|
||||
* This function will initialize the SHA384Context in preparation
|
||||
* for computing a new SHA224 message digest.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to reset.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA224Reset(SHA224Context * context)
|
||||
{
|
||||
return SHA224_256Reset(context, SHA224_H0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224Input
|
||||
*
|
||||
* Description:
|
||||
* This function accepts an array of octets as the next portion
|
||||
* of the message.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
* message_array: [in]
|
||||
* An array of characters representing the next portion of
|
||||
* the message.
|
||||
* length: [in]
|
||||
* The length of the message in message_array
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*
|
||||
*/
|
||||
int
|
||||
SHA224Input(SHA224Context * context, const uint8_t * message_array,
|
||||
unsigned int length)
|
||||
{
|
||||
return SHA256Input(context, message_array, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224FinalBits
|
||||
*
|
||||
* Description:
|
||||
* This function will add in any final bits of the message.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
* message_bits: [in]
|
||||
* The final bits of the message, in the upper portion of the
|
||||
* byte. (Use 0b###00000 instead of 0b00000### to input the
|
||||
* three bits ###.)
|
||||
* length: [in]
|
||||
* The number of bits in message_bits, between 1 and 7.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA224FinalBits(SHA224Context * context,
|
||||
const uint8_t message_bits, unsigned int length)
|
||||
{
|
||||
return SHA256FinalBits(context, message_bits, length);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224Result
|
||||
*
|
||||
* Description:
|
||||
* This function will return the 224-bit message
|
||||
* digest into the Message_Digest array provided by the caller.
|
||||
* NOTE: The first octet of hash is stored in the 0th element,
|
||||
* the last octet of hash in the 28th element.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to use to calculate the SHA hash.
|
||||
* Message_Digest: [out]
|
||||
* Where the digest is returned.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA224Result(SHA224Context * context, uint8_t Message_Digest[SHA224HashSize])
|
||||
{
|
||||
return SHA224_256ResultN(context, Message_Digest, SHA224HashSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA256Reset
|
||||
*
|
||||
* Description:
|
||||
* This function will initialize the SHA256Context in preparation
|
||||
* for computing a new SHA256 message digest.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to reset.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA256Reset(SHA256Context * context)
|
||||
{
|
||||
return SHA224_256Reset(context, SHA256_H0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA256Input
|
||||
*
|
||||
* Description:
|
||||
* This function accepts an array of octets as the next portion
|
||||
* of the message.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
* message_array: [in]
|
||||
* An array of characters representing the next portion of
|
||||
* the message.
|
||||
* length: [in]
|
||||
* The length of the message in message_array
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA256Input(SHA256Context * context, const uint8_t * message_array,
|
||||
unsigned int length)
|
||||
{
|
||||
if (!length)
|
||||
return shaSuccess;
|
||||
|
||||
if (!context || !message_array)
|
||||
return shaNull;
|
||||
|
||||
if (context->Computed)
|
||||
{
|
||||
context->Corrupted = shaStateError;
|
||||
return shaStateError;
|
||||
}
|
||||
|
||||
if (context->Corrupted)
|
||||
return context->Corrupted;
|
||||
|
||||
while (length-- && !context->Corrupted)
|
||||
{
|
||||
context->Message_Block[context->Message_Block_Index++] =
|
||||
(*message_array & 0xFF);
|
||||
|
||||
if (!SHA224_256AddLength(context, 8) &&
|
||||
(context->Message_Block_Index == SHA256_Message_Block_Size))
|
||||
SHA224_256ProcessMessageBlock(context);
|
||||
|
||||
message_array++;
|
||||
}
|
||||
|
||||
return shaSuccess;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA256FinalBits
|
||||
*
|
||||
* Description:
|
||||
* This function will add in any final bits of the message.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
* message_bits: [in]
|
||||
* The final bits of the message, in the upper portion of the
|
||||
* byte. (Use 0b###00000 instead of 0b00000### to input the
|
||||
* three bits ###.)
|
||||
* length: [in]
|
||||
* The number of bits in message_bits, between 1 and 7.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA256FinalBits(SHA256Context * context,
|
||||
const uint8_t message_bits, unsigned int length)
|
||||
{
|
||||
uint8_t masks[8] = {
|
||||
/* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
|
||||
/* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
|
||||
/* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
|
||||
/* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
|
||||
};
|
||||
uint8_t markbit[8] = {
|
||||
/* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
|
||||
/* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
|
||||
/* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
|
||||
/* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
|
||||
};
|
||||
|
||||
if (!length)
|
||||
return shaSuccess;
|
||||
|
||||
if (!context)
|
||||
return shaNull;
|
||||
|
||||
if ((context->Computed) || (length >= 8) || (length == 0))
|
||||
{
|
||||
context->Corrupted = shaStateError;
|
||||
return shaStateError;
|
||||
}
|
||||
|
||||
if (context->Corrupted)
|
||||
return context->Corrupted;
|
||||
|
||||
SHA224_256AddLength(context, length);
|
||||
SHA224_256Finalize(context, (uint8_t)
|
||||
((message_bits & masks[length]) | markbit[length]));
|
||||
|
||||
return shaSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA256Result
|
||||
*
|
||||
* Description:
|
||||
* This function will return the 256-bit message
|
||||
* digest into the Message_Digest array provided by the caller.
|
||||
* NOTE: The first octet of hash is stored in the 0th element,
|
||||
* the last octet of hash in the 32nd element.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to use to calculate the SHA hash.
|
||||
* Message_Digest: [out]
|
||||
* Where the digest is returned.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
int
|
||||
SHA256Result(SHA256Context * context, uint8_t Message_Digest[])
|
||||
{
|
||||
return SHA224_256ResultN(context, Message_Digest, SHA256HashSize);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224_256Finalize
|
||||
*
|
||||
* Description:
|
||||
* This helper function finishes off the digest calculations.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
* Pad_Byte: [in]
|
||||
* The last byte to add to the digest before the 0-padding
|
||||
* and length. This will contain the last bits of the message
|
||||
* followed by another single bit. If the message was an
|
||||
* exact multiple of 8-bits long, Pad_Byte will be 0x80.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
static void
|
||||
SHA224_256Finalize(SHA256Context * context, uint8_t Pad_Byte)
|
||||
{
|
||||
int i;
|
||||
SHA224_256PadMessage(context, Pad_Byte);
|
||||
/* message may be sensitive, so clear it out */
|
||||
for (i = 0; i < SHA256_Message_Block_Size; ++i)
|
||||
context->Message_Block[i] = 0;
|
||||
context->Length_Low = 0; /* and clear length */
|
||||
context->Length_High = 0;
|
||||
context->Computed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224_256PadMessage
|
||||
*
|
||||
* Description:
|
||||
* According to the standard, the message must be padded to an
|
||||
* even 512 bits. The first padding bit must be a '1'. The
|
||||
* last 64 bits represent the length of the original message.
|
||||
* All bits in between should be 0. This helper function will pad
|
||||
* the message according to those rules by filling the
|
||||
* Message_Block array accordingly. When it returns, it can be
|
||||
* assumed that the message digest has been computed.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to pad
|
||||
* Pad_Byte: [in]
|
||||
* The last byte to add to the digest before the 0-padding
|
||||
* and length. This will contain the last bits of the message
|
||||
* followed by another single bit. If the message was an
|
||||
* exact multiple of 8-bits long, Pad_Byte will be 0x80.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
static void
|
||||
SHA224_256PadMessage(SHA256Context * context, uint8_t Pad_Byte)
|
||||
{
|
||||
/*
|
||||
* Check to see if the current message block is too small to hold
|
||||
* the initial padding bits and length. If so, we will pad the
|
||||
* block, process it, and then continue padding into a second
|
||||
* block.
|
||||
*/
|
||||
if (context->Message_Block_Index >= (SHA256_Message_Block_Size - 8))
|
||||
{
|
||||
context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
|
||||
while (context->Message_Block_Index < SHA256_Message_Block_Size)
|
||||
context->Message_Block[context->Message_Block_Index++] = 0;
|
||||
SHA224_256ProcessMessageBlock(context);
|
||||
}
|
||||
else
|
||||
context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
|
||||
|
||||
while (context->Message_Block_Index < (SHA256_Message_Block_Size - 8))
|
||||
context->Message_Block[context->Message_Block_Index++] = 0;
|
||||
|
||||
/*
|
||||
* Store the message length as the last 8 octets
|
||||
*/
|
||||
context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
|
||||
context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
|
||||
context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
|
||||
context->Message_Block[59] = (uint8_t)(context->Length_High);
|
||||
context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
|
||||
context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
|
||||
context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
|
||||
context->Message_Block[63] = (uint8_t)(context->Length_Low);
|
||||
|
||||
SHA224_256ProcessMessageBlock(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224_256ProcessMessageBlock
|
||||
*
|
||||
* Description:
|
||||
* This function will process the next 512 bits of the message
|
||||
* stored in the Message_Block array.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The SHA context to update
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*
|
||||
* Comments:
|
||||
* Many of the variable names in this code, especially the
|
||||
* single character names, were used because those were the
|
||||
* names used in the publication.
|
||||
*/
|
||||
static void
|
||||
SHA224_256ProcessMessageBlock(SHA256Context * context)
|
||||
{
|
||||
/* Constants defined in FIPS-180-2, section 4.2.2 */
|
||||
static const uint32_t K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
|
||||
0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
|
||||
0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
|
||||
0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
|
||||
0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
|
||||
0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
|
||||
0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
|
||||
0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
|
||||
0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
int t, t4; /* Loop counter */
|
||||
uint32_t temp1, temp2; /* Temporary word value */
|
||||
uint32_t W[64]; /* Word sequence */
|
||||
uint32_t A, B, C, D, E, F, G, H; /* Word buffers */
|
||||
|
||||
/*
|
||||
* Initialize the first 16 words in the array W
|
||||
*/
|
||||
for (t = t4 = 0; t < 16; t++, t4 += 4)
|
||||
W[t] = (((uint32_t)context->Message_Block[t4]) << 24) |
|
||||
(((uint32_t)context->Message_Block[t4 + 1]) << 16) |
|
||||
(((uint32_t)context->Message_Block[t4 + 2]) << 8) |
|
||||
(((uint32_t)context->Message_Block[t4 + 3]));
|
||||
|
||||
for (t = 16; t < 64; t++)
|
||||
W[t] = SHA256_sigma1(W[t - 2]) + W[t - 7] +
|
||||
SHA256_sigma0(W[t - 15]) + W[t - 16];
|
||||
|
||||
A = context->Intermediate_Hash[0];
|
||||
B = context->Intermediate_Hash[1];
|
||||
C = context->Intermediate_Hash[2];
|
||||
D = context->Intermediate_Hash[3];
|
||||
E = context->Intermediate_Hash[4];
|
||||
F = context->Intermediate_Hash[5];
|
||||
G = context->Intermediate_Hash[6];
|
||||
H = context->Intermediate_Hash[7];
|
||||
|
||||
for (t = 0; t < 64; t++)
|
||||
{
|
||||
temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E, F, G) + K[t] + W[t];
|
||||
temp2 = SHA256_SIGMA0(A) + SHA_Maj(A, B, C);
|
||||
H = G;
|
||||
G = F;
|
||||
F = E;
|
||||
E = D + temp1;
|
||||
D = C;
|
||||
C = B;
|
||||
B = A;
|
||||
A = temp1 + temp2;
|
||||
}
|
||||
|
||||
context->Intermediate_Hash[0] += A;
|
||||
context->Intermediate_Hash[1] += B;
|
||||
context->Intermediate_Hash[2] += C;
|
||||
context->Intermediate_Hash[3] += D;
|
||||
context->Intermediate_Hash[4] += E;
|
||||
context->Intermediate_Hash[5] += F;
|
||||
context->Intermediate_Hash[6] += G;
|
||||
context->Intermediate_Hash[7] += H;
|
||||
|
||||
context->Message_Block_Index = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224_256Reset
|
||||
*
|
||||
* Description:
|
||||
* This helper function will initialize the SHA256Context in
|
||||
* preparation for computing a new SHA256 message digest.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to reset.
|
||||
* H0
|
||||
* The initial hash value to use.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
static int
|
||||
SHA224_256Reset(SHA256Context * context, uint32_t * H0)
|
||||
{
|
||||
if (!context)
|
||||
return shaNull;
|
||||
|
||||
context->Length_Low = 0;
|
||||
context->Length_High = 0;
|
||||
context->Message_Block_Index = 0;
|
||||
|
||||
context->Intermediate_Hash[0] = H0[0];
|
||||
context->Intermediate_Hash[1] = H0[1];
|
||||
context->Intermediate_Hash[2] = H0[2];
|
||||
context->Intermediate_Hash[3] = H0[3];
|
||||
context->Intermediate_Hash[4] = H0[4];
|
||||
context->Intermediate_Hash[5] = H0[5];
|
||||
context->Intermediate_Hash[6] = H0[6];
|
||||
context->Intermediate_Hash[7] = H0[7];
|
||||
|
||||
context->Computed = 0;
|
||||
context->Corrupted = 0;
|
||||
|
||||
return shaSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA224_256ResultN
|
||||
*
|
||||
* Description:
|
||||
* This helper function will return the 224-bit or 256-bit message
|
||||
* digest into the Message_Digest array provided by the caller.
|
||||
* NOTE: The first octet of hash is stored in the 0th element,
|
||||
* the last octet of hash in the 28th/32nd element.
|
||||
*
|
||||
* Parameters:
|
||||
* context: [in/out]
|
||||
* The context to use to calculate the SHA hash.
|
||||
* Message_Digest: [out]
|
||||
* Where the digest is returned.
|
||||
* HashSize: [in]
|
||||
* The size of the hash, either 28 or 32.
|
||||
*
|
||||
* Returns:
|
||||
* sha Error Code.
|
||||
*/
|
||||
static int
|
||||
SHA224_256ResultN(SHA256Context * context,
|
||||
uint8_t Message_Digest[], int HashSize)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!context || !Message_Digest)
|
||||
return shaNull;
|
||||
|
||||
if (context->Corrupted)
|
||||
return context->Corrupted;
|
||||
|
||||
if (!context->Computed)
|
||||
SHA224_256Finalize(context, 0x80);
|
||||
|
||||
for (i = 0; i < HashSize; ++i)
|
||||
Message_Digest[i] = (uint8_t)
|
||||
(context->Intermediate_Hash[i >> 2] >> 8 * (3 - (i & 0x03)));
|
||||
|
||||
return shaSuccess;
|
||||
}
|
||||
1090
microstack/sha384-512.c
Normal file
1090
microstack/sha384-512.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user