/*============================================================================ * OpcUa_P_OpenSSL_AES_CBC_Encrypt *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_AES_CBC_Encrypt( OpcUa_CryptoProvider* a_pProvider, OpcUa_Byte* a_pPlainText, OpcUa_UInt32 a_plainTextLen, OpcUa_Key* a_key, OpcUa_Byte* a_pInitalVector, OpcUa_Byte* a_pCipherText, OpcUa_UInt32* a_pCipherTextLen) { AES_KEY key; OpcUa_Byte pInitalVector[16]; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "AES_CBC_Encrypt"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pPlainText); OpcUa_ReturnErrorIfArgumentNull(a_key); OpcUa_ReturnErrorIfArgumentNull(a_key->Key.Data); OpcUa_ReturnErrorIfArgumentNull(a_pInitalVector); OpcUa_ReturnErrorIfArgumentNull(a_pCipherTextLen); if(a_plainTextLen % 16 != 0) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } *a_pCipherTextLen = a_plainTextLen; /* if just the output length is needed for the caller of this function */ if(a_pCipherText == OpcUa_Null) { OpcUa_ReturnStatusCode; } /* we have to pass the key length in bits instead of bytes */ if(AES_set_encrypt_key(a_key->Key.Data, a_key->Key.Length * 8, &key) < 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* copy the IV because the AES_cbc_encrypt function overwrites it. */ OpcUa_P_Memory_MemCpy(pInitalVector, 16, a_pInitalVector, 16); /* encrypt data */ AES_cbc_encrypt( a_pPlainText, a_pCipherText, a_plainTextLen, &key, pInitalVector, AES_ENCRYPT); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Create a UDP sender socket *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketUdp_CreateSender( OpcUa_StringA a_LocalIpAddress, OpcUa_StringA a_RemoteIpAddress, OpcUa_Int16 a_RemotePort, OpcUa_Byte a_TimeToLive, OpcUa_Socket* a_pSocket) { OpcUa_InternalUdpSocket* pInternalSocket = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateUdpSender"); OpcUa_ReturnErrorIfArgumentNull(a_pSocket); *a_pSocket = OpcUa_Null; OpcUa_GotoErrorIfArgumentNull(a_RemoteIpAddress); if(a_RemotePort == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument); } pInternalSocket = (OpcUa_InternalUdpSocket*)OpcUa_P_Memory_Alloc(sizeof(OpcUa_InternalUdpSocket)); OpcUa_GotoErrorIfAllocFailed(pInternalSocket); pInternalSocket->pSocketServiceTable = &OpcUa_UdpSocketServiceTable; if(strchr(a_RemoteIpAddress, ':')) { uStatus = OpcUa_P_RawSocket_CreateUdpV6(&pInternalSocket->rawSocket, OpcUa_True, a_LocalIpAddress, a_RemoteIpAddress, a_RemotePort, a_TimeToLive); OpcUa_GotoErrorIfBad(uStatus); } else { uStatus = OpcUa_P_RawSocket_CreateUdp(&pInternalSocket->rawSocket, OpcUa_True, a_LocalIpAddress, a_RemoteIpAddress, a_RemotePort, a_TimeToLive); OpcUa_GotoErrorIfBad(uStatus); } *a_pSocket = pInternalSocket; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pInternalSocket != OpcUa_Null) { OpcUa_P_Memory_Free(pInternalSocket); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_GetSignature *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetSignature( OpcUa_CryptoProvider* a_pProvider, OpcUa_ByteString* a_pCertificate, OpcUa_Signature* a_pSignature) { X509* pX509Certificate = OpcUa_Null; const unsigned char* pTemp = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetSignature"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); OpcUa_ReturnErrorIfArgumentNull(a_pSignature); /* d2i_X509 modifies the given pointer -> use local replacement */ pTemp = a_pCertificate->Data; d2i_X509(&pX509Certificate, &pTemp, a_pCertificate->Length); if(pX509Certificate == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } a_pSignature->Signature.Length = pX509Certificate->signature->length; a_pSignature->Algorithm = OBJ_obj2nid(pX509Certificate->sig_alg->algorithm); if(a_pSignature->Algorithm == NID_undef) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(a_pSignature->Signature.Data != OpcUa_Null) { uStatus = OpcUa_P_Memory_MemCpy(a_pSignature->Signature.Data, a_pSignature->Signature.Length, pX509Certificate->signature->data, pX509Certificate->signature->length); } X509_free(pX509Certificate); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pX509Certificate != OpcUa_Null) { X509_free(pX509Certificate); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_Random_Key_Generate *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_Random_Key_Generate( OpcUa_CryptoProvider* a_pProvider, OpcUa_Int32 a_keyLen, OpcUa_Key* a_pKey) { OpcUa_CryptoProviderConfig* pConfig = OpcUa_Null; OpcUa_Int32 keyLen = 0; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "Random_Key_Generate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pKey); OpcUa_ReferenceParameter(a_pProvider); keyLen = a_keyLen; if(keyLen < 0) { if(a_pProvider->Handle != OpcUa_Null) { /* get default configuration */ pConfig = (OpcUa_CryptoProviderConfig*)a_pProvider->Handle; keyLen = pConfig->SymmetricKeyLength; } else { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } } else if(keyLen > MAX_GENERATED_OUTPUT_LEN) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } a_pKey->Key.Length = keyLen; a_pKey->Type = OpcUa_Crypto_KeyType_Random; if(a_pKey->Key.Data == OpcUa_Null) { OpcUa_ReturnStatusCode; } if(RAND_bytes(a_pKey->Key.Data, a_pKey->Key.Length) == 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
static OpcUa_StatusCode OpcUa_UadpExtendedNetworkMessageHeader_WriteBinary(OpcUa_UadpNetworkMessage* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize) { OpcUa_Int32 ii; OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpExtendedNetworkMessageHeader_WriteBinary") if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_Timestamp) { /* convert structure to UInt64 */ OpcUa_UInt64 timeValue; timeValue = (OpcUa_UInt32)a_pValue->NetworkMessageHeader.Timestamp.dwHighDateTime; timeValue <<= 32; timeValue += (OpcUa_UInt32)a_pValue->NetworkMessageHeader.Timestamp.dwLowDateTime; OpcUa_UadpEncode_Direct(UInt64, &timeValue); } if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_PicoSeconds) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->NetworkMessageHeader.PicoSeconds); } if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_PromotedFields) { OpcUa_Byte *pSizeBuffer; OpcUa_UInt16_Wire totalSize16_Wire; OpcUa_UInt16 totalSize16; if(*a_pSize < sizeof(OpcUa_UInt16_Wire)) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } pSizeBuffer = *a_pBuffer; *a_pBuffer += sizeof(OpcUa_UInt16_Wire); *a_pSize -= sizeof(OpcUa_UInt16_Wire); for(ii = 0; ii < a_pValue->NetworkMessageHeader.NoOfPromotedFields; ii++) { if(a_pValue->NetworkMessageHeader.PromotedFields[ii] >= a_pValue->Payload[0].KeyOrEventMessage.NoOfDataSetFields) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } uStatus = OpcUa_UadpDataSetField_WriteBinary(a_pValue->Payload[0].KeyOrEventMessage.DataSetFields[a_pValue->NetworkMessageHeader.PromotedFields[ii]], a_pValue->Payload[0].Header.FieldEncoding, a_pBuffer, a_pSize); OpcUa_GotoErrorIfBad(uStatus); } totalSize16 = (OpcUa_UInt16)(*a_pBuffer - pSizeBuffer) - sizeof(OpcUa_UInt16_Wire); uStatus = OpcUa_UInt16_P_NativeToWire(&totalSize16_Wire, &totalSize16); OpcUa_GotoErrorIfBad(uStatus); memcpy(pSizeBuffer, &totalSize16_Wire, sizeof(OpcUa_UInt16_Wire)); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; /* nothing to do */ OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_RSA_GenerateKeys *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_GenerateKeys( OpcUa_CryptoProvider* a_pProvider, OpcUa_UInt32 a_bits, OpcUa_Key* a_pPublicKey, OpcUa_Key* a_pPrivateKey) { RSA* pRsa; unsigned char* pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_GenerateKeys"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pPublicKey); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); OpcUa_ReferenceParameter(a_pProvider); /* Just 1024 or 2048 bits should be allowed for compatibility reasons */ if ((a_bits != 1024) && (a_bits != 2048) && (a_bits != 3072) && (a_bits != 4096)) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } if(a_pPublicKey->Key.Data == OpcUa_Null) { a_pPublicKey->Key.Length = a_bits; OpcUa_ReturnStatusCode; } if(a_pPrivateKey->Key.Data == OpcUa_Null) { a_pPrivateKey->Key.Length = a_bits; OpcUa_ReturnStatusCode; } pRsa = RSA_generate_key(a_bits, RSA_F4, NULL, OpcUa_Null); pData = a_pPublicKey->Key.Data; a_pPublicKey->Key.Length = i2d_RSAPublicKey(pRsa, &pData); pData = a_pPrivateKey->Key.Data; a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(pRsa, &pData); /* clean up */ if(pRsa != OpcUa_Null) { RSA_free(pRsa); } a_pPublicKey->Type = OpcUa_Crypto_Rsa_Alg_Id; a_pPrivateKey->Type = OpcUa_Crypto_Rsa_Alg_Id; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_MemoryStream_CreateReadable *===========================================================================*/ OpcUa_StatusCode OpcUa_MemoryStream_CreateReadable( OpcUa_Byte* buffer, OpcUa_UInt32 bufferSize, OpcUa_InputStream** istrm) { OpcUa_StatusCode uStatus = OpcUa_Good; OpcUa_MemoryStream* handle = OpcUa_Null; OpcUa_DeclareErrorTraceModule(OpcUa_Module_MemoryStream); OpcUa_ReturnErrorIfNull(istrm, OpcUa_BadInvalidArgument); *istrm = OpcUa_Null; handle = (OpcUa_MemoryStream*)OpcUa_Alloc(sizeof(OpcUa_MemoryStream)); OpcUa_GotoErrorIfAllocFailed(handle); OpcUa_MemSet(handle, 0, sizeof(OpcUa_MemoryStream)); handle->SanityCheck = OpcUa_MemoryStream_SanityCheck; handle->pBuffer = OpcUa_Null; handle->Closed = OpcUa_False; uStatus = OpcUa_Buffer_Create(buffer, bufferSize, bufferSize, bufferSize, OpcUa_False, (OpcUa_Buffer**)&handle->pBuffer); OpcUa_GotoErrorIfBad(uStatus); *istrm = (OpcUa_InputStream*)OpcUa_Alloc(sizeof(OpcUa_InputStream)); OpcUa_GotoErrorIfAllocFailed(*istrm); (*istrm)->Type = OpcUa_StreamType_Input; (*istrm)->Handle = handle; (*istrm)->GetPosition = OpcUa_MemoryStream_GetPosition; (*istrm)->SetPosition = OpcUa_MemoryStream_SetPosition; (*istrm)->Close = OpcUa_MemoryStream_Close; (*istrm)->Delete = OpcUa_MemoryStream_Delete; (*istrm)->Read = OpcUa_MemoryStream_Read; (*istrm)->AttachBuffer = OpcUa_MemoryStream_AttachBuffer; (*istrm)->DetachBuffer = OpcUa_MemoryStream_DetachBuffer; (*istrm)->GetChunkLength = OpcUa_MemoryStream_GetChunkLength; (*istrm)->NonBlocking = OpcUa_False; (*istrm)->CanSeek = OpcUa_True; return OpcUa_Good; Error: if (handle != OpcUa_Null && handle->pBuffer != OpcUa_Null) { OpcUa_Buffer_Delete((OpcUa_Buffer**)&handle->pBuffer); } OpcUa_Free(handle); OpcUa_Free(*istrm); *istrm = OpcUa_Null; return uStatus; }
/*============================================================================ * Create *===========================================================================*/ OpcUa_StatusCode OpcUa_Thread_Create( OpcUa_Thread* a_pThread, OpcUa_PfnThreadMain* a_pThreadMain, OpcUa_Void* a_pThreadArgument) { OpcUa_StatusCode uStatus = OpcUa_Good; OpcUa_ThreadInternal* pThread = OpcUa_Null; OpcUa_DeclareErrorTraceModule(OpcUa_Module_Thread); OpcUa_ReturnErrorIfArgumentNull(a_pThread); OpcUa_ReturnErrorIfArgumentNull(a_pThreadMain); pThread = (OpcUa_ThreadInternal*)OpcUa_Alloc(sizeof(OpcUa_ThreadInternal)); OpcUa_ReturnErrorIfAllocFailed(pThread); OpcUa_MemSet(pThread, 0, sizeof(OpcUa_ThreadInternal)); pThread->IsRunning = OpcUa_False; pThread->ThreadMain = a_pThreadMain; pThread->ThreadData = a_pThreadArgument; pThread->Mutex = OpcUa_Null; pThread->ShutdownEvent = OpcUa_Null; uStatus = OpcUa_P_Thread_Create(&(pThread->RawThread)); OpcUa_GotoErrorIfBad(uStatus); uStatus = OPCUA_P_SEMAPHORE_CREATE( &(pThread->ShutdownEvent), 1, /* the initial value is 1 (signalled, 1 free resource) */ 1); /* the maximum value is 1 */ OpcUa_GotoErrorIfBad(uStatus); uStatus = OPCUA_P_MUTEX_CREATE(&(pThread->Mutex)); OpcUa_GotoErrorIfBad(uStatus); *a_pThread = pThread; return OpcUa_Good; Error: return uStatus; }
/*============================================================================ * Create a new signal socket *===========================================================================*/ OpcUa_StatusCode OpcUa_P_SocketManager_NewSignalSocket(OpcUa_SocketManager a_pSocketManager) { OpcUa_InternalSocket* pIntSignalSocket = OpcUa_Null; OpcUa_InternalSocketManager* pInternalSocketManager = (OpcUa_InternalSocketManager*)a_pSocketManager; OpcUa_InitializeStatus(OpcUa_Module_Socket, "NewSignalSocket"); OpcUa_GotoErrorIfArgumentNull(a_pSocketManager); pIntSignalSocket = (OpcUa_InternalSocket*)OpcUa_SocketManager_FindFreeSocket(a_pSocketManager, OpcUa_True); if(pIntSignalSocket == OpcUa_Null) { uStatus = OpcUa_BadResourceUnavailable; goto Error; } uStatus = OpcUa_P_RawSocket_CreateSocketPair( &pIntSignalSocket->rawSocket, &pInternalSocketManager->pCookie); OpcUa_GotoErrorIfBad(uStatus); pIntSignalSocket->Flags.EventMask = OPCUA_SOCKET_CLOSE_EVENT | OPCUA_SOCKET_READ_EVENT | OPCUA_SOCKET_EXCEPT_EVENT | OPCUA_SOCKET_TIMEOUT_EVENT; uStatus = OpcUa_P_RawSocket_SetBlockMode (pIntSignalSocket->rawSocket, OpcUa_False); if (OpcUa_IsBad(uStatus)) { OpcUa_P_RawSocket_Close(pIntSignalSocket->rawSocket); OpcUa_P_RawSocket_Close(pInternalSocketManager->pCookie); OpcUa_GotoErrorWithStatus(uStatus); } uStatus = OpcUa_P_RawSocket_SetBlockMode (pInternalSocketManager->pCookie, OpcUa_False); if (OpcUa_IsBad(uStatus)) { OpcUa_P_RawSocket_Close(pIntSignalSocket->rawSocket); OpcUa_P_RawSocket_Close(pInternalSocketManager->pCookie); OpcUa_GotoErrorWithStatus(uStatus); } OPCUA_SOCKET_SETVALID(pIntSignalSocket); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pIntSignalSocket) { pIntSignalSocket->rawSocket = (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID; OPCUA_SOCKET_INVALIDATE(pIntSignalSocket); } OpcUa_FinishErrorHandling; }
/*============================================================================ * Clean the platform network interface up. *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_Socket_CleanupNetwork(OpcUa_Void) { OpcUa_InitializeStatus(OpcUa_Module_Socket, "CleanupNetwork"); /* cleanup platform networking */ uStatus = OpcUa_P_RawSocket_CleanupNetwork(); OpcUa_GotoErrorIfBad(uStatus); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_ProxyStub_AddTypes *===========================================================================*/ OpcUa_StatusCode OpcUa_ProxyStub_AddTypes(OpcUa_EncodeableType** a_ppTypes) { OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "AddTypes"); uStatus = OpcUa_EncodeableTypeTable_AddTypes( &OpcUa_ProxyStub_g_EncodeableTypes, a_ppTypes); OpcUa_GotoErrorIfBad(uStatus); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_Name_AddEntry *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_Name_AddEntry( X509_NAME** a_ppX509Name, OpcUa_Crypto_NameEntry* a_pNameEntry) { X509_NAME_ENTRY* pEntry = OpcUa_Null; OpcUa_Int nid; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_Name_AddEntry"); OpcUa_ReturnErrorIfArgumentNull(a_pNameEntry); if((nid = OBJ_txt2nid(a_pNameEntry->key)) == NID_undef) { uStatus = OpcUa_BadNotSupported; OpcUa_GotoErrorIfBad(uStatus); } if(!(pEntry = X509_NAME_ENTRY_create_by_NID(OpcUa_Null, nid, MBSTRING_ASC, (unsigned char*)a_pNameEntry->value, -1))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(X509_NAME_add_entry(*a_ppX509Name, pEntry,-1,0) != 1) { uStatus = OpcUa_Bad; } if(pEntry != OpcUa_Null) { X509_NAME_ENTRY_free(pEntry); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_ProxyStub_SetNamespaceUris *===========================================================================*/ OpcUa_StatusCode OpcUa_ProxyStub_SetNamespaceUris(OpcUa_StringA* a_psNamespaceUris) { OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "SetNamespaceUris"); /* discard existing strings */ OpcUa_StringTable_Clear(&OpcUa_ProxyStub_g_NamespaceUris); /* update table */ uStatus = OpcUa_StringTable_AddStringList( &OpcUa_ProxyStub_g_NamespaceUris, a_psNamespaceUris); OpcUa_GotoErrorIfBad(uStatus); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Start a created thread. *===========================================================================*/ OpcUa_StatusCode OpcUa_Thread_Start(OpcUa_Thread a_Thread) { OpcUa_StatusCode uStatus = OpcUa_Good; OpcUa_ThreadInternal* pThread = OpcUa_Null; OpcUa_Int32 intThreadId = 0; OpcUa_ReturnErrorIfArgumentNull(a_Thread); pThread = (OpcUa_ThreadInternal*)a_Thread; OPCUA_P_MUTEX_LOCK(pThread->Mutex); if(pThread->IsRunning != OpcUa_False) { OPCUA_P_MUTEX_UNLOCK(pThread->Mutex); return OpcUa_Good; } /* set semaphore to waitable */ uStatus = OPCUA_P_SEMAPHORE_WAIT((pThread->ShutdownEvent)); OpcUa_GotoErrorIfBad(uStatus); pThread->IsRunning = OpcUa_True; intThreadId = OpcUa_P_Thread_Start( pThread->RawThread, InternalThreadMain, (OpcUa_Void*)pThread); if(intThreadId != 0) { pThread->IsRunning = OpcUa_False; OPCUA_P_MUTEX_UNLOCK(pThread->Mutex); uStatus = OpcUa_BadInternalError; OpcUa_Trace(OPCUA_TRACE_LEVEL_ERROR, "OpcUa_Thread_Start: Error during thread creation!\n"); goto Error; } OPCUA_P_MUTEX_UNLOCK(pThread->Mutex); return OpcUa_Good; Error: return uStatus; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_GetCertificateThumbprint *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetCertificateThumbprint( OpcUa_CryptoProvider* a_pProvider, OpcUa_ByteString* a_pCertificate, OpcUa_ByteString* a_pCertificateThumbprint) { X509* pX509Certificate = OpcUa_Null; const unsigned char* pTemp = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetCertificateThumbprint"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate->Data); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateThumbprint); /* SHA-1 produces 20 bytes */ a_pCertificateThumbprint->Length = sizeof(pX509Certificate->sha1_hash); if(a_pCertificateThumbprint->Data == OpcUa_Null) { OpcUa_ReturnStatusCode; } /* d2i_X509 modifies the given pointer -> use local replacement */ pTemp = a_pCertificate->Data; d2i_X509(&pX509Certificate, &pTemp, a_pCertificate->Length); if(pX509Certificate == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* update pX509Certificate->sha1_hash */ X509_check_purpose(pX509Certificate, -1, 0); uStatus = OpcUa_P_Memory_MemCpy(a_pCertificateThumbprint->Data, a_pCertificateThumbprint->Length, pX509Certificate->sha1_hash, sizeof(pX509Certificate->sha1_hash)); X509_free(pX509Certificate); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/** * @brief Builds a connection record for the given parameters and returns it. * * @return: Status Code; */ OpcUa_StatusCode OpcUa_TcpListener_ConnectionManager_AddConnection( OpcUa_TcpListener_ConnectionManager* a_pConnectionManager, OpcUa_TcpListener_Connection* a_pConnection) { OpcUa_StatusCode uStatus = OpcUa_Good; OpcUa_GotoErrorIfArgumentNull(a_pConnection); OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager); OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager->Connections); a_pConnection->ConnectTime = OPCUA_P_DATETIME_UTCNOW(); /* expiration of connection would be DisconnectTime+Lifetime */ OpcUa_List_Enter(a_pConnectionManager->Connections); uStatus = OpcUa_List_AddElement(a_pConnectionManager->Connections, a_pConnection); OpcUa_List_Leave(a_pConnectionManager->Connections); OpcUa_GotoErrorIfBad(uStatus); OpcUa_Trace(OPCUA_TRACE_LEVEL_DEBUG, "OpcUa_TcpListener_ConnectionManager_AddConnection: Connection added!\n"); return OpcUa_Good; Error: return uStatus; }
/*============================================================================ * Create a server socket *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_CreateServer( OpcUa_SocketManager a_pSocketManager, OpcUa_StringA a_sAddress, OpcUa_Boolean a_bListenOnAllInterfaces, OpcUa_Socket_EventCallback a_pfnSocketCallBack, OpcUa_Void* a_pCallbackData, OpcUa_Socket* a_pSocket) { OpcUa_InternalSocketManager* pInternalSocketManager = OpcUa_Null; OpcUa_UInt16 uPort = 0; OpcUa_StringA sRemoteAdress = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateServer"); #if !OPCUA_MULTITHREADED if(a_pSocketManager == OpcUa_Null) { a_pSocketManager = OpcUa_Socket_g_SocketManager; } #endif OpcUa_ReturnErrorIfArgumentNull(a_pSocketManager); OpcUa_ReturnErrorIfArgumentNull(a_pSocket); pInternalSocketManager = (OpcUa_InternalSocketManager*)a_pSocketManager; /* parse address */ uStatus = OpcUa_P_ParseUrl( a_sAddress, &sRemoteAdress, &uPort); OpcUa_ReturnErrorIfBad(uStatus); if(a_bListenOnAllInterfaces) { if(sRemoteAdress != OpcUa_Null) { OpcUa_P_Memory_Free(sRemoteAdress); sRemoteAdress = OpcUa_Null; } } uStatus = OpcUa_SocketManager_InternalCreateServer( pInternalSocketManager, sRemoteAdress, uPort, a_pfnSocketCallBack, a_pCallbackData, a_pSocket); OpcUa_GotoErrorIfBad(uStatus); OpcUa_P_SocketManager_InterruptLoop(pInternalSocketManager, OPCUA_SOCKET_RENEWLOOP_EVENT, OpcUa_False); if(sRemoteAdress != OpcUa_Null) { OpcUa_P_Memory_Free(sRemoteAdress); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(sRemoteAdress != OpcUa_Null) { OpcUa_P_Memory_Free(sRemoteAdress); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_GetPrivateKey *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetPrivateKey( OpcUa_CryptoProvider* a_pProvider, OpcUa_StringA a_certificateFileName, OpcUa_StringA a_password, /* this is optional */ OpcUa_Key* a_pPrivateKey) { BIO* pCertFile = OpcUa_Null; PKCS12* pPKCS12Cert = OpcUa_Null; EVP_PKEY* pPrivateKey = OpcUa_Null; RSA* pRsaPrivateKey = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetPrivateKey"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_certificateFileName); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); /* import certificate from file by the given encoding type */ pCertFile = BIO_new_file((const char*)a_certificateFileName, "r"); OpcUa_ReturnErrorIfArgumentNull(pCertFile); /* convert certificate file handle to PKCS12 structure */ d2i_PKCS12_bio(pCertFile, &pPKCS12Cert); /* close certificat file handle */ BIO_free(pCertFile); if(pPKCS12Cert != OpcUa_Null) { /* get the private key from the PKCS12 structure*/ PKCS12_parse(pPKCS12Cert, a_password, &pPrivateKey, OpcUa_Null, OpcUa_Null); } else { uStatus = OpcUa_Bad; OpcUa_ReturnStatusCode; } if(pPKCS12Cert != OpcUa_Null) { PKCS12_free(pPKCS12Cert); pPKCS12Cert = OpcUa_Null; } switch(EVP_PKEY_type(pPrivateKey->type)) { case EVP_PKEY_RSA: { /* convert to intermediary openssl struct */ pRsaPrivateKey = EVP_PKEY_get1_RSA(pPrivateKey); EVP_PKEY_free(pPrivateKey); OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad); /* get required length */ a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null); OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad); if(a_pPrivateKey->Key.Data == OpcUa_Null) { OpcUa_ReturnStatusCode; } /* do real conversion */ a_pPrivateKey->Key.Length = i2d_RSAPrivateKey( pRsaPrivateKey, &a_pPrivateKey->Key.Data); OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad); if(pRsaPrivateKey != OpcUa_Null) { RSA_free(pRsaPrivateKey); pRsaPrivateKey = OpcUa_Null; } /* correct buffer pointer */ a_pPrivateKey->Key.Data -= a_pPrivateKey->Key.Length; a_pPrivateKey->Type = OpcUa_Crypto_KeyType_Rsa_Private; break; } case EVP_PKEY_EC: case EVP_PKEY_DSA: case EVP_PKEY_DH: default: { uStatus = OpcUa_BadNotSupported; OpcUa_GotoErrorIfBad(uStatus); } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pRsaPrivateKey != OpcUa_Null) { RSA_free(pRsaPrivateKey); } if(pPrivateKey != OpcUa_Null) { EVP_PKEY_free(pPrivateKey); } OpcUa_FinishErrorHandling; }
/*===========================================================================* OpcUa_P_OpenSSL_RSA_Public_Encrypt *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_Encrypt( OpcUa_CryptoProvider* a_pProvider, OpcUa_Byte* a_pPlainText, OpcUa_UInt32 a_plainTextLen, OpcUa_Key* a_publicKey, OpcUa_Int16 a_padding, OpcUa_Byte* a_pCipherText, OpcUa_UInt32* a_pCipherTextLen) { EVP_PKEY* pPublicKey = OpcUa_Null; OpcUa_UInt32 uKeySize = 0; OpcUa_UInt32 uEncryptedDataSize = 0; OpcUa_UInt32 uPlainTextPosition = 0; OpcUa_UInt32 uCipherTextPosition = 0; OpcUa_UInt32 uBytesToEncrypt = 0; OpcUa_Int32 iEncryptedBytes = 0; const unsigned char *pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Encrypt"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_publicKey); OpcUa_ReturnErrorIfArgumentNull(a_publicKey->Key.Data); OpcUa_ReturnErrorIfArgumentNull(a_pCipherTextLen); *a_pCipherTextLen = 0; if((OpcUa_Int32)a_plainTextLen < 1) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } if(a_publicKey->Type != OpcUa_Crypto_KeyType_Rsa_Public) { OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument); } pData = a_publicKey->Key.Data; pPublicKey = d2i_PublicKey(EVP_PKEY_RSA, OpcUa_Null, &pData, a_publicKey->Key.Length); if ( pPublicKey != OpcUa_Null ) { uKeySize = RSA_size(pPublicKey->pkey.rsa); } else { OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument); } /* check padding type */ switch(a_padding) { case RSA_PKCS1_PADDING: { uEncryptedDataSize = uKeySize - 11; break; } case RSA_PKCS1_OAEP_PADDING: { uEncryptedDataSize = uKeySize - 42; break; } case RSA_NO_PADDING: { uEncryptedDataSize = uKeySize; break; } default: { OpcUa_GotoErrorWithStatus(OpcUa_BadNotSupported); } } if(a_plainTextLen < uEncryptedDataSize) { uBytesToEncrypt = a_plainTextLen; } else { uBytesToEncrypt = uEncryptedDataSize; } while(uPlainTextPosition < a_plainTextLen) { /* the last part could be smaller */ if((a_plainTextLen >= uEncryptedDataSize) && ((a_plainTextLen - uPlainTextPosition) < uEncryptedDataSize)) { uBytesToEncrypt = a_plainTextLen - uPlainTextPosition; } if((a_pCipherText != OpcUa_Null) && (a_pPlainText != OpcUa_Null)) { iEncryptedBytes = RSA_public_encrypt( uBytesToEncrypt, /* how much to encrypt */ a_pPlainText + uPlainTextPosition, /* what to encrypt */ a_pCipherText + uCipherTextPosition,/* where to encrypt */ pPublicKey->pkey.rsa, /* public key */ a_padding); /* padding mode */ if(iEncryptedBytes < 0) { const char* sError = OpcUa_Null; unsigned long error = 0; error = ERR_get_error(); ERR_load_crypto_strings(); sError = ERR_reason_error_string(error); sError = ERR_func_error_string(error); sError = ERR_lib_error_string(error); uStatus = OpcUa_Bad; OpcUa_GotoError; } } else { iEncryptedBytes = uKeySize; } *a_pCipherTextLen = *a_pCipherTextLen + iEncryptedBytes; uCipherTextPosition += uKeySize; uPlainTextPosition += uBytesToEncrypt; } EVP_PKEY_free(pPublicKey); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pPublicKey != OpcUa_Null) { EVP_PKEY_free(pPublicKey); } *a_pCipherTextLen = (OpcUa_UInt32)-1; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_ProxyStub_Initialize *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_ProxyStub_Initialize(OpcUa_Handle a_pPlatformLayerCalltable, OpcUa_ProxyStubConfiguration* a_pProxyStubConfiguration) { OpcUa_Boolean bSkip = OpcUa_False; OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "Initialize"); OpcUa_ReturnErrorIfArgumentNull(a_pProxyStubConfiguration) OpcUa_ReturnErrorIfArgumentNull(a_pPlatformLayerCalltable); /* set global platform layer handle */ OpcUa_ProxyStub_g_PlatformLayerCalltable = (OpcUa_Port_CallTable *)a_pPlatformLayerCalltable; #if OPCUA_USE_SYNCHRONISATION if(OpcUa_ProxyStub_g_hGlobalsMutex == OpcUa_Null) { uStatus = OPCUA_P_MUTEX_CREATE(&OpcUa_ProxyStub_g_hGlobalsMutex); OpcUa_GotoErrorIfBad(uStatus); } #endif /* OPCUA_USE_SYNCHRONISATION */ #if OPCUA_USE_SYNCHRONISATION OPCUA_P_MUTEX_LOCK(OpcUa_ProxyStub_g_hGlobalsMutex); #endif /* OPCUA_USE_SYNCHRONISATION */ OpcUa_ProxyStub_g_uNoOfInits++; if(OpcUa_ProxyStub_g_uNoOfInits > 1) { bSkip = OpcUa_True; } #if OPCUA_USE_SYNCHRONISATION OPCUA_P_MUTEX_UNLOCK(OpcUa_ProxyStub_g_hGlobalsMutex); #endif /* OPCUA_USE_SYNCHRONISATION */ if(bSkip == OpcUa_False) { /* set global configuration object */ uStatus = OpcUa_ProxyStub_ReInitialize(a_pProxyStubConfiguration); OpcUa_GotoErrorIfBad(uStatus); /* initialize tracer */ #if OPCUA_TRACE_ENABLE uStatus = OpcUa_Trace_Initialize(); OpcUa_GotoErrorIfBad(uStatus); OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Tracer has been initialized!\n"); #endif /* OPCUA_TRACE_ENABLE */ /* initialize networking. */ OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Network Module...\n"); uStatus = OPCUA_P_INITIALIZENETWORK(); OpcUa_GotoErrorIfBad(uStatus); OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Network Module done!\n"); uStatus = OpcUa_EncodeableTypeTable_Create(&OpcUa_ProxyStub_g_EncodeableTypes); OpcUa_GotoErrorIfBad(uStatus); uStatus = OpcUa_EncodeableTypeTable_AddTypes(&OpcUa_ProxyStub_g_EncodeableTypes, OpcUa_KnownEncodeableTypes); OpcUa_GotoErrorIfBad(uStatus); OpcUa_StringTable_Initialize(&OpcUa_ProxyStub_g_NamespaceUris); uStatus = OpcUa_StringTable_AddStringList(&OpcUa_ProxyStub_g_NamespaceUris, OpcUa_ProxyStub_StandardNamespaceUris); OpcUa_GotoErrorIfBad(uStatus); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_ProxyStub_Clear(); OpcUa_FinishErrorHandling; }
OpcUa_StatusCode fill_Variant_for_value_attribute(_VariableKnoten_* p_Node, OpcUa_String* p_Index, OpcUa_DataValue* p_Results) { OpcUa_Int i; OpcUa_StatusCode uStatus = OpcUa_Good; extern my_Variant all_ValueAttribute_of_VariableTypeNodes_VariableNodes[]; OpcUa_ReturnErrorIfArgumentNull(p_Node); /*OpcUa_ReturnErrorIfArgumentNull(p_Index);*/ OpcUa_ReturnErrorIfArgumentNull(p_Results); if(p_Node->ValueIndex == (-1)) { OpcUa_GotoErrorWithStatus(OpcUa_BadNotReadable) } if(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].ArrayType==OpcUa_VariantArrayType_Scalar) { switch(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Datatype) { case OpcUaId_Double: { p_Results->Value.Value.Double=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Double; fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Double, OpcUa_VariantArrayType_Scalar,0); break; } case OpcUaId_DateTime: { p_Results->Value.Value.DateTime=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.DateTime; fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_DateTime, OpcUa_VariantArrayType_Scalar,0); break; } case OpcUaId_String: { uStatus= OpcUa_String_AttachCopy(&(p_Results->Value.Value.String),all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.String); OpcUa_GotoErrorIfBad(uStatus) fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_String, OpcUa_VariantArrayType_Scalar,0); break; } case OpcUaId_UInt32: { p_Results->Value.Value.UInt32=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.UInt32; fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Scalar,0); break; } case OpcUaId_Boolean: { p_Results->Value.Value.Boolean=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Boolean; fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Boolean, OpcUa_VariantArrayType_Scalar,0); break; } } } if(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].ArrayType==OpcUa_VariantArrayType_Array) { switch(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Datatype) { case OpcUaId_Double: { p_Results->Value.Value.Array.Value.DoubleArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double)); OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.DoubleArray)) OpcUa_MemCpy((p_Results->Value.Value.Array.Value.DoubleArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.DoubleArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double)); fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Double, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length); break; } case OpcUaId_String: { p_Results->Value.Value.Array.Value.StringArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_String)); OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.DoubleArray)) for(i=0;i<(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);i++) { uStatus= OpcUa_String_AttachCopy((p_Results->Value.Value.Array.Value.StringArray)+i,*(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.StringArray+i)); if(OpcUa_IsBad(uStatus)) OpcUa_GotoError } fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_String, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length); break; } case OpcUaId_UInt32: { p_Results->Value.Value.Array.Value.UInt32Array=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32)); OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.UInt32Array)) OpcUa_MemCpy((p_Results->Value.Value.Array.Value.UInt32Array),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.UInt32Array),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32)); fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length); break; } case OpcUaId_Boolean: { p_Results->Value.Value.Array.Value.BooleanArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean)); OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.BooleanArray)) OpcUa_MemCpy((p_Results->Value.Value.Array.Value.BooleanArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.BooleanArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean)); fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length); break; } } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; p_Results->StatusCode=uStatus; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_Random_Key_PSHA256_Derive *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_Random_Key_PSHA256_Derive( OpcUa_CryptoProvider* a_pProvider, OpcUa_ByteString a_secret, /* clientnonce | servernonce, servernonce | clientnonce */ OpcUa_ByteString a_seed, OpcUa_Int32 a_keyLen, /* output len */ OpcUa_Key* a_pKey) { OpcUa_P_OpenSSL_PSHA256_Ctx*pCtx = OpcUa_Null; OpcUa_Byte* pBuffer = OpcUa_Null; OpcUa_Int bufferlength; OpcUa_Int i; OpcUa_Int iterations; OpcUa_CryptoProviderConfig* pConfig = OpcUa_Null; OpcUa_Int32 keyLen = 0; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "Random_Key_PSHA256_Derive"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_secret.Data); OpcUa_ReturnErrorIfArgumentNull(a_seed.Data); OpcUa_ReturnErrorIfArgumentNull(a_pKey); keyLen = a_keyLen; if(keyLen < 0) { if(a_pProvider->Handle != OpcUa_Null) { /* get default configuration */ pConfig = (OpcUa_CryptoProviderConfig*)a_pProvider->Handle; keyLen = pConfig->SymmetricKeyLength; } else { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } } else if(keyLen > MAX_DERIVED_OUTPUT_LEN) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } if(a_pKey->Key.Data == OpcUa_Null) { a_pKey->Key.Length = keyLen; OpcUa_ReturnStatusCode; } a_pKey->Type = OpcUa_Crypto_KeyType_Random; /** start creating key **/ pCtx = (OpcUa_P_OpenSSL_PSHA256_Ctx*)OpcUa_Null; iterations = keyLen/32 + (keyLen%32?1:0); bufferlength = iterations*32; pBuffer = (OpcUa_Byte *)OpcUa_P_Memory_Alloc(bufferlength * sizeof(OpcUa_Byte)); pCtx = OpcUa_P_OpenSSL_PSHA256_Context_Create(a_secret.Data, a_secret.Length, a_seed.Data, a_seed.Length); for(i=0; i<iterations; i++) { /* SHA256 produces 32 Bytes of output for every iteration */ uStatus = OpcUa_P_OpenSSL_PSHA256_Hash_Generate(pCtx, pBuffer + (i*32)); OpcUa_GotoErrorIfBad(uStatus); } OpcUa_P_Memory_MemCpy(a_pKey->Key.Data, a_pKey->Key.Length, pBuffer, keyLen); if(pCtx != OpcUa_Null) { OpcUa_P_Memory_Free(pCtx); pCtx = OpcUa_Null; } if(pBuffer != OpcUa_Null) { OpcUa_P_Memory_Free(pBuffer); pBuffer = OpcUa_Null; } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pCtx != OpcUa_Null) { OpcUa_P_Memory_Free(pCtx); pCtx = OpcUa_Null; } if(pBuffer != OpcUa_Null) { OpcUa_P_Memory_Free(pBuffer); pBuffer = OpcUa_Null; } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_MemoryStream_CreateWriteable *===========================================================================*/ OpcUa_StatusCode OpcUa_MemoryStream_CreateWriteable( OpcUa_UInt32 a_uBlockSize, OpcUa_UInt32 a_uMaxSize, OpcUa_OutputStream** a_ppOstrm) { OpcUa_MemoryStream* pMemoryStream = OpcUa_Null; #if OPCUA_PREALLOC_MEMORYBLOCK OpcUa_Byte* pbyData = OpcUa_Null; #endif /* OPCUA_PREALLOC_MEMORYBLOCK */ OpcUa_InitializeStatus(OpcUa_Module_MemoryStream, "CreateWriteable"); OpcUa_ReturnErrorIfNull(a_ppOstrm, OpcUa_BadInvalidArgument); *a_ppOstrm = OpcUa_Null; pMemoryStream = (OpcUa_MemoryStream*)OpcUa_Alloc(sizeof(OpcUa_MemoryStream)); OpcUa_GotoErrorIfAllocFailed(pMemoryStream); pMemoryStream->SanityCheck = OpcUa_MemoryStream_SanityCheck; pMemoryStream->pBuffer = OpcUa_Null; pMemoryStream->Closed = OpcUa_False; #if OPCUA_PREALLOC_MEMORYBLOCK pbyData = (OpcUa_Byte*)OpcUa_Alloc(a_uBlockSize); OpcUa_GotoErrorIfAllocFailed(pbyData); uStatus = OpcUa_Buffer_Create( pbyData, /* buffer space */ a_uBlockSize, /* buffer space size */ a_uBlockSize, /* allocation increment */ a_uMaxSize, /* max memory block size */ OpcUa_True, /* release buffer space */ (OpcUa_Buffer**)&pMemoryStream->pBuffer); OpcUa_GotoErrorIfBad(uStatus); #else /* OPCUA_PREALLOC_MEMORYBLOCK */ uStatus = OpcUa_Buffer_Create( OpcUa_Null, /* buffer space */ 0,/* used data in buffer space */ a_uBlockSize, /* allocation increment */ a_uMaxSize, /* max memory block size */ OpcUa_True, /* release buffer space */ (OpcUa_Buffer**)&pMemoryStream->pBuffer); OpcUa_GotoErrorIfBad(uStatus); #endif /* OPCUA_PREALLOC_MEMORYBLOCK */ *a_ppOstrm = (OpcUa_OutputStream*)OpcUa_Alloc(sizeof(OpcUa_OutputStream)); OpcUa_GotoErrorIfAllocFailed(*a_ppOstrm); OpcUa_MemSet(*a_ppOstrm, 0, sizeof(OpcUa_OutputStream)); (*a_ppOstrm)->Type = OpcUa_StreamType_Output; (*a_ppOstrm)->Handle = pMemoryStream; (*a_ppOstrm)->GetPosition = OpcUa_MemoryStream_GetPosition; (*a_ppOstrm)->SetPosition = OpcUa_MemoryStream_SetPosition; (*a_ppOstrm)->Close = OpcUa_MemoryStream_Close; (*a_ppOstrm)->Delete = OpcUa_MemoryStream_Delete; (*a_ppOstrm)->Flush = OpcUa_MemoryStream_Flush; (*a_ppOstrm)->Write = OpcUa_MemoryStream_Write; (*a_ppOstrm)->AttachBuffer = OpcUa_MemoryStream_AttachBuffer; (*a_ppOstrm)->DetachBuffer = OpcUa_MemoryStream_DetachBuffer; (*a_ppOstrm)->GetChunkLength = OpcUa_MemoryStream_GetChunkLength; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pMemoryStream != OpcUa_Null && pMemoryStream->pBuffer != OpcUa_Null) { OpcUa_Buffer_Delete((OpcUa_Buffer**)&pMemoryStream->pBuffer); } OpcUa_Free(pMemoryStream); OpcUa_Free(*a_ppOstrm); *a_ppOstrm = OpcUa_Null; OpcUa_FinishErrorHandling; }
/** @brief Extracts data from a certificate store object. @param pCertificate [in] The certificate to examine. @param pIssuer [out, optional] The issuer name of the certificate. @param pSubject [out, optional] The subject name of the certificate. @param pSubjectUri [out, optional] The subject's URI of the certificate. @param pSubjectIP [out, optional] The subject's IP of the certificate. @param pSubjectDNS [out, optional] The subject's DNS name of the certificate. @param pCertThumbprint [out, optional] The thumbprint of the certificate. @param pSubjectHash [out, optional] The hash code of the certificate. @param pCertRawLength [out, optional] The length of the DER encoded data. can be smaller than the total length of pCertificate in case of chain certificate or garbage follow. */ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_ExtractCertificateData( OpcUa_ByteString* a_pCertificate, OpcUa_ByteString* a_pIssuer, OpcUa_ByteString* a_pSubject, OpcUa_ByteString* a_pSubjectUri, OpcUa_ByteString* a_pSubjectIP, OpcUa_ByteString* a_pSubjectDNS, OpcUa_ByteString* a_pCertThumbprint, OpcUa_UInt32* a_pSubjectHash, OpcUa_UInt32* a_pCertRawLength) { X509* pX509Cert = OpcUa_Null; char* pName = OpcUa_Null; GENERAL_NAMES* pNames = OpcUa_Null; const unsigned char* p; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_ExtractCertificateData"); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); if(a_pIssuer != OpcUa_Null) { a_pIssuer->Data = OpcUa_Null; a_pIssuer->Length = 0; } if(a_pSubject != OpcUa_Null) { a_pSubject->Data = OpcUa_Null; a_pSubject->Length = 0; } if(a_pSubjectUri != OpcUa_Null) { a_pSubjectUri->Data = OpcUa_Null; a_pSubjectUri->Length = 0; } if(a_pSubjectIP != OpcUa_Null) { a_pSubjectIP->Data = OpcUa_Null; a_pSubjectIP->Length = 0; } if(a_pSubjectDNS != OpcUa_Null) { a_pSubjectDNS->Data = OpcUa_Null; a_pSubjectDNS->Length = 0; } if(a_pCertThumbprint != OpcUa_Null) { a_pCertThumbprint->Data = OpcUa_Null; a_pCertThumbprint->Length = 0; } if(a_pSubjectHash != OpcUa_Null) { *a_pSubjectHash = 0; } if(a_pCertRawLength != OpcUa_Null) { *a_pCertRawLength = 0; } /* convert openssl X509 certificate to DER encoded bytestring certificate */ p = a_pCertificate->Data; if(!(pX509Cert = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Length))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(a_pIssuer != OpcUa_Null) { pName = X509_NAME_oneline(X509_get_issuer_name(pX509Cert), NULL, 0); OpcUa_GotoErrorIfAllocFailed(pName); a_pIssuer->Length = strlen(pName)+1; a_pIssuer->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pIssuer->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pIssuer->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pIssuer->Data, a_pIssuer->Length, pName, a_pIssuer->Length); OpcUa_GotoErrorIfBad(uStatus); OPENSSL_free(pName); pName = OpcUa_Null; } if(a_pSubject != OpcUa_Null) { pName = X509_NAME_oneline(X509_get_subject_name(pX509Cert), NULL, 0); OpcUa_GotoErrorIfAllocFailed(pName); a_pSubject->Length = strlen(pName)+1; a_pSubject->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pSubject->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pSubject->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pSubject->Data, a_pSubject->Length, pName, a_pSubject->Length); OpcUa_GotoErrorIfBad(uStatus); OPENSSL_free(pName); pName = OpcUa_Null; } if(a_pSubjectUri != OpcUa_Null || a_pSubjectIP != OpcUa_Null || a_pSubjectDNS != OpcUa_Null) { pNames = X509_get_ext_d2i(pX509Cert, NID_subject_alt_name, OpcUa_Null, OpcUa_Null); if (pNames != OpcUa_Null) { int num; for (num = 0; num < sk_GENERAL_NAME_num(pNames); num++) { GENERAL_NAME *value = sk_GENERAL_NAME_value(pNames, num); switch (value->type) { case GEN_URI: if (a_pSubjectUri != OpcUa_Null && a_pSubjectUri->Data == OpcUa_Null) { a_pSubjectUri->Length = value->d.ia5->length+1; a_pSubjectUri->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pSubjectUri->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pSubjectUri->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pSubjectUri->Data, a_pSubjectUri->Length, value->d.ia5->data, a_pSubjectUri->Length); OpcUa_GotoErrorIfBad(uStatus); } break; case GEN_IPADD: if (a_pSubjectIP != OpcUa_Null && a_pSubjectIP->Data == OpcUa_Null) { a_pSubjectIP->Length = value->d.ip->length; a_pSubjectIP->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pSubjectIP->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pSubjectIP->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pSubjectIP->Data, a_pSubjectIP->Length, value->d.ip->data, a_pSubjectIP->Length); OpcUa_GotoErrorIfBad(uStatus); } break; case GEN_DNS: if (a_pSubjectDNS != OpcUa_Null && a_pSubjectDNS->Data == OpcUa_Null) { a_pSubjectDNS->Length = value->d.ia5->length+1; a_pSubjectDNS->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pSubjectDNS->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pSubjectDNS->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pSubjectDNS->Data, a_pSubjectDNS->Length, value->d.ia5->data, a_pSubjectDNS->Length); OpcUa_GotoErrorIfBad(uStatus); } break; } } sk_GENERAL_NAME_pop_free(pNames, GENERAL_NAME_free); pNames = OpcUa_Null; } } if(a_pCertThumbprint != OpcUa_Null) { /* update pX509Cert->sha1_hash */ X509_check_purpose(pX509Cert, -1, 0); a_pCertThumbprint->Length = sizeof(pX509Cert->sha1_hash); a_pCertThumbprint->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertThumbprint->Length*sizeof(OpcUa_Byte)); OpcUa_GotoErrorIfAllocFailed(a_pCertThumbprint->Data); uStatus = OpcUa_P_Memory_MemCpy(a_pCertThumbprint->Data, a_pCertThumbprint->Length, pX509Cert->sha1_hash, a_pCertThumbprint->Length); OpcUa_GotoErrorIfBad(uStatus); } if(a_pSubjectHash != OpcUa_Null) { *a_pSubjectHash = X509_NAME_hash(X509_get_subject_name(pX509Cert)); } if(a_pCertRawLength != OpcUa_Null) { *a_pCertRawLength = (OpcUa_UInt32)(p - a_pCertificate->Data); } X509_free(pX509Cert); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(a_pIssuer != OpcUa_Null && a_pIssuer->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pIssuer->Data); a_pIssuer->Data = OpcUa_Null; a_pIssuer->Length = 0; } if(a_pSubject != OpcUa_Null && a_pSubject->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pSubject->Data); a_pSubject->Data = OpcUa_Null; a_pSubject->Length = 0; } if(a_pSubjectUri != OpcUa_Null && a_pSubjectUri->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pSubjectUri->Data); a_pSubjectUri->Data = OpcUa_Null; a_pSubjectUri->Length = 0; } if(a_pSubjectIP != OpcUa_Null && a_pSubjectIP->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pSubjectIP->Data); a_pSubjectIP->Data = OpcUa_Null; a_pSubjectIP->Length = 0; } if(a_pSubjectDNS != OpcUa_Null && a_pSubjectDNS->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pSubjectDNS->Data); a_pSubjectDNS->Data = OpcUa_Null; a_pSubjectDNS->Length = 0; } if(a_pCertThumbprint != OpcUa_Null && a_pCertThumbprint->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pCertThumbprint->Data); a_pCertThumbprint->Data = OpcUa_Null; a_pCertThumbprint->Length = 0; } if (pName != OpcUa_Null) { OPENSSL_free(pName); } if (pNames != OpcUa_Null) { sk_GENERAL_NAME_pop_free(pNames, GENERAL_NAME_free); } if(pX509Cert != OpcUa_Null) { X509_free(pX509Cert); } OpcUa_FinishErrorHandling; }
/*============================================================================ * Create a new socket manager or initialize the global one (OpcUa_Null first). *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_Create(OpcUa_SocketManager* a_pSocketManager, OpcUa_UInt32 a_nSockets, OpcUa_UInt32 a_nFlags) { OpcUa_InternalSocketManager* pInternalSocketManager = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_Socket, "SocketManager_Create"); if(a_nFlags & 0xFFFFFFF8) { return OpcUa_BadInvalidArgument; } if(a_nSockets > OPCUA_P_SOCKETMANAGER_NUMBEROFSOCKETS) { return OpcUa_BadInvalidArgument; } /* set number of socket to maximum */ if(a_nSockets == 0) { a_nSockets = OPCUA_P_SOCKETMANAGER_NUMBEROFSOCKETS; } a_nSockets += 1; /* add signal socket to requested sockets */ #if !OPCUA_MULTITHREADED if(a_pSocketManager == OpcUa_Null && OpcUa_Socket_g_SocketManager == OpcUa_Null) { a_pSocketManager = &OpcUa_Socket_g_SocketManager; } #endif if(a_pSocketManager == OpcUa_Null) { return OpcUa_BadInvalidArgument; } *a_pSocketManager = OpcUa_SocketManager_Alloc(); OpcUa_GotoErrorIfAllocFailed(*a_pSocketManager); pInternalSocketManager = (OpcUa_InternalSocketManager*)*a_pSocketManager; OpcUa_SocketManager_Initialize(pInternalSocketManager); #if OPCUA_USE_SYNCHRONISATION uStatus = OpcUa_P_Mutex_Create(&pInternalSocketManager->pMutex); OpcUa_GotoErrorIfBad(uStatus); #endif /* OPCUA_USE_SYNCHRONISATION */ /* preallocate socket structures for all possible sockets (maxsockets) */ uStatus = OpcUa_SocketManager_CreateSockets((OpcUa_SocketManager)pInternalSocketManager, a_nSockets); OpcUa_GotoErrorIfBad(uStatus); pInternalSocketManager->uintLastExternalEvent = OPCUA_SOCKET_NO_EVENT; /* set the behaviour flags */ if((a_nFlags & OPCUA_SOCKET_SPAWN_THREAD_ON_ACCEPT) != OPCUA_SOCKET_NO_FLAG) { pInternalSocketManager->Flags.bSpawnThreadOnAccept = OpcUa_True; } if((a_nFlags & OPCUA_SOCKET_REJECT_ON_NO_THREAD) != OPCUA_SOCKET_NO_FLAG) { pInternalSocketManager->Flags.bRejectOnThreadFail = OpcUa_True; } if((a_nFlags & OPCUA_SOCKET_DONT_CLOSE_ON_EXCEPT) != OPCUA_SOCKET_NO_FLAG) { pInternalSocketManager->Flags.bDontCloseOnExcept = OpcUa_True; } uStatus = OpcUa_P_SocketManager_NewSignalSocket(pInternalSocketManager); OpcUa_GotoErrorIfBad(uStatus); #if OPCUA_MULTITHREADED if (pInternalSocketManager->Flags.bSpawnThreadOnAccept) { /* create a semaphore with no free resources for which a host can wait to be signalled. */ uStatus = OpcUa_P_Semaphore_Create(&pInternalSocketManager->pStartupSemaphore, 0, 1); OpcUa_GotoErrorIfBad(uStatus); pInternalSocketManager->pSocketManagers = OpcUa_P_Memory_Alloc(sizeof(OpcUa_InternalSocketManager*) * OPCUA_SOCKET_MAXMANAGERS); OpcUa_GotoErrorIfAllocFailed(pInternalSocketManager->pSocketManagers); OpcUa_MemSet(pInternalSocketManager->pSocketManagers, 0, sizeof(OpcUa_InternalSocketManager*) * OPCUA_SOCKET_MAXMANAGERS); } /* if multithreaded, create and start the server thread if the list is not the global list. */ uStatus = OpcUa_P_Thread_Create(&pInternalSocketManager->pThread); /* make raw thread */ OpcUa_GotoErrorIfBad(uStatus); uStatus = OpcUa_P_Thread_Start( pInternalSocketManager->pThread, OpcUa_P_SocketManager_ServerLoopThread, (OpcUa_Void*)pInternalSocketManager); OpcUa_GotoErrorIfBad(uStatus); #endif /* OPCUA_MULTITHREADED */ OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pInternalSocketManager != OpcUa_Null) { #if OPCUA_MULTITHREADED if(pInternalSocketManager->pThread != OpcUa_Null) { OpcUa_P_Thread_Delete(&pInternalSocketManager->pThread); } if(pInternalSocketManager->pSocketManagers != OpcUa_Null) { OpcUa_P_Memory_Free(pInternalSocketManager->pSocketManagers); } if(pInternalSocketManager->pStartupSemaphore != OpcUa_Null) { OpcUa_P_Semaphore_Delete(&pInternalSocketManager->pStartupSemaphore); } #endif /* OPCUA_MULTITHREADED */ if(pInternalSocketManager->pCookie != (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID) { OpcUa_P_RawSocket_Close(pInternalSocketManager->pCookie); } if(pInternalSocketManager->pSockets != OpcUa_Null) { if(pInternalSocketManager->pSockets[0].rawSocket != (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID) { OpcUa_P_RawSocket_Close(pInternalSocketManager->pSockets[0].rawSocket); } OpcUa_P_Memory_Free(pInternalSocketManager->pSockets); } #if OPCUA_USE_SYNCHRONISATION if(pInternalSocketManager->pMutex != OpcUa_Null) { OpcUa_P_Mutex_Delete(&pInternalSocketManager->pMutex); } #endif /* OPCUA_USE_SYNCHRONISATION */ OpcUa_P_Memory_Free(pInternalSocketManager); } *a_pSocketManager = OpcUa_Null; OpcUa_FinishErrorHandling; }
/* ToDo: Create Access to OpenSSL certificate store => Only API to In-Memory-Store is available for version 0.9.8x => Wait until Directory- and/or File-Store is available */ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_LoadCertificate( OpcUa_PKIProvider* a_pProvider, OpcUa_Void* a_pLoadHandle, OpcUa_Void* a_pCertificateStore, OpcUa_ByteString* a_pCertificate) { OpcUa_Byte* buf = OpcUa_Null; OpcUa_Byte* p = OpcUa_Null; FILE* pCertificateFile = OpcUa_Null; X509* pTmpCert = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_LoadCertificate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_pLoadHandle); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); /* read DER certificates */ pCertificateFile = fopen((const char*)a_pLoadHandle, "r"); /* check for valid file handle */ OpcUa_GotoErrorIfTrue((pCertificateFile == OpcUa_Null), OpcUa_BadInvalidArgument); if(!(pTmpCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } a_pCertificate->Length = i2d_X509(pTmpCert, NULL); buf = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertificate->Length); OpcUa_GotoErrorIfAllocFailed(buf); p = buf; for (;;) { i2d_X509(pTmpCert, &p); X509_free(pTmpCert); if(!(pTmpCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null))) { break; } p = OpcUa_P_Memory_ReAlloc(buf, a_pCertificate->Length + i2d_X509(pTmpCert, NULL)); OpcUa_GotoErrorIfAllocFailed(p); buf = p; p = buf + a_pCertificate->Length; a_pCertificate->Length += i2d_X509(pTmpCert, NULL); } if(fclose(pCertificateFile) != 0) { pCertificateFile = OpcUa_Null; uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } a_pCertificate->Data = buf; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pCertificateFile != OpcUa_Null) { fclose(pCertificateFile); } if(pTmpCert != OpcUa_Null) { X509_free(pTmpCert); } if(buf != OpcUa_Null) { OpcUa_P_Memory_Free(buf); } OpcUa_FinishErrorHandling; }
/* ToDo: Create Access to OpenSSL certificate store => Only API to In-Memory-Store is available for version 0.9.8x => Wait until Directory- and/or File-Store is available */ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_SaveCertificate( OpcUa_PKIProvider* a_pProvider, OpcUa_ByteString* a_pCertificate, OpcUa_Void* a_pCertificateStore, OpcUa_Void* a_pSaveHandle) /* Index or number within store/destination filepath */ { X509* pX509Certificate = OpcUa_Null; FILE* pCertificateFile = OpcUa_Null; const unsigned char* p; OpcUa_UInt32 i; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_SaveCertificate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore); OpcUa_ReturnErrorIfArgumentNull(a_pSaveHandle); /* save DER certificate */ pCertificateFile = fopen((const char*)a_pSaveHandle, "w"); /* check for valid file handle */ OpcUa_GotoErrorIfTrue((pCertificateFile == OpcUa_Null), OpcUa_BadInvalidArgument); /* convert openssl X509 certificate to DER encoded bytestring certificate */ p = a_pCertificate->Data; while (p < a_pCertificate->Data + a_pCertificate->Length) { if(!(pX509Certificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Data + a_pCertificate->Length - p))) { fclose(pCertificateFile); uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } i = i2d_X509_fp(pCertificateFile, pX509Certificate); if(i < 1) { fclose(pCertificateFile); uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } X509_free(pX509Certificate); pX509Certificate = OpcUa_Null; } if(fclose(pCertificateFile) != 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if (pX509Certificate != OpcUa_Null) { X509_free(pX509Certificate); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_PKI_ValidateCertificate *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_ValidateCertificate( OpcUa_PKIProvider* a_pProvider, OpcUa_ByteString* a_pCertificate, OpcUa_Void* a_pCertificateStore, OpcUa_Int* a_pValidationCode /* Validation return codes from OpenSSL */ ) { OpcUa_P_OpenSSL_CertificateStore_Config* pCertificateStoreCfg; const unsigned char* p; X509* pX509Certificate = OpcUa_Null; STACK_OF(X509)* pX509Chain = OpcUa_Null; X509_STORE_CTX* verify_ctx = OpcUa_Null; /* holds data used during verification process */ char CertFile[MAX_PATH]; struct dirent **dirlist = NULL; int numCertificates = 0, i; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_ValidateCertificate"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore); OpcUa_ReturnErrorIfArgumentNull(a_pValidationCode); pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle; /* convert DER encoded bytestring certificate to openssl X509 certificate */ p = a_pCertificate->Data; if(!(pX509Certificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Length))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } while(p < a_pCertificate->Data + a_pCertificate->Length) { X509* pX509AddCertificate; if(!(pX509AddCertificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Data + a_pCertificate->Length - p))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pX509Chain == NULL) { pX509Chain = sk_X509_new_null(); OpcUa_GotoErrorIfAllocFailed(pX509Chain); } if(!sk_X509_push(pX509Chain, pX509AddCertificate)) { X509_free(pX509AddCertificate); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } /* create verification context and initialize it */ if(!(verify_ctx = X509_STORE_CTX_new())) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } #if (OPENSSL_VERSION_NUMBER > 0x00907000L) if(X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } #else X509_STORE_CTX_init(verify_ctx, (X509_STORE*)a_pCertificateStore, pX509Certificate, pX509Chain); #endif if(X509_STORE_CTX_set_app_data(verify_ctx, pCertificateStoreCfg) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL_EXCEPT_SELF_SIGNED && !verify_ctx->check_issued(verify_ctx, pX509Certificate, pX509Certificate)) { /* set the flags of the store so that CRLs are consulted */ X509_STORE_CTX_set_flags(verify_ctx, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } /* verify the certificate */ *a_pValidationCode = X509_V_OK; if(X509_verify_cert(verify_ctx) <= 0) { *a_pValidationCode = verify_ctx->error; switch(verify_ctx->error) { case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: { uStatus = OpcUa_BadCertificateTimeInvalid; break; } case X509_V_ERR_CERT_REVOKED: { uStatus = OpcUa_BadCertificateRevoked; break; } case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: { uStatus = OpcUa_BadCertificateUntrusted; break; } case X509_V_ERR_CERT_SIGNATURE_FAILURE: { uStatus = OpcUa_BadSecurityChecksFailed; break; } default: { uStatus = OpcUa_BadCertificateInvalid; } } OpcUa_GotoErrorIfBad(uStatus); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REQUIRE_CHAIN_CERTIFICATE_IN_TRUST_LIST) { FILE* pCertificateFile; X509* pTrustCert; STACK_OF(X509)* chain; int trusted, n; chain = X509_STORE_CTX_get_chain(verify_ctx); trusted = 0; if(pCertificateStoreCfg->CertificateTrustListLocation == NULL || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0') { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* read DER certificates */ pCertificateFile = fopen(CertFile, "r"); if(pCertificateFile == OpcUa_Null) { continue; /* ignore access errors */ } pTrustCert = d2i_X509_fp(pCertificateFile, (X509**)OpcUa_Null); fclose(pCertificateFile); if(pTrustCert == OpcUa_Null) { continue; /* ignore parse errors */ } for(n = 0; n < sk_X509_num(chain); n++) { if (X509_cmp(sk_X509_value(chain, n), pTrustCert) == 0) break; } X509_free(pTrustCert); if(n < sk_X509_num(chain)) { trusted = 1; break; } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; if(!trusted) { uStatus = OpcUa_BadCertificateUntrusted; OpcUa_GotoErrorIfBad(uStatus); } } X509_STORE_CTX_free(verify_ctx); X509_free(pX509Certificate); if(pX509Chain != OpcUa_Null) { sk_X509_pop_free(pX509Chain, X509_free); } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(dirlist != NULL) { for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); } if(verify_ctx != OpcUa_Null) { X509_STORE_CTX_free(verify_ctx); } if(pX509Certificate != OpcUa_Null) { X509_free(pX509Certificate); } if(pX509Chain != OpcUa_Null) { sk_X509_pop_free(pX509Chain, X509_free); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_CertificateStore_Open *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_OpenCertificateStore( OpcUa_PKIProvider* a_pProvider, OpcUa_Void** a_ppCertificateStore) /* type depends on store implementation */ { OpcUa_P_OpenSSL_CertificateStore_Config* pCertificateStoreCfg; X509_STORE* pStore; X509_LOOKUP* pLookup; char CertFile[MAX_PATH]; struct dirent **dirlist = NULL; int numCertificates = 0, i; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_OpenCertificateStore"); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle); OpcUa_ReturnErrorIfArgumentNull(a_ppCertificateStore); *a_ppCertificateStore = OpcUa_Null; pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle; if(!(*a_ppCertificateStore = pStore = X509_STORE_new())) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } X509_STORE_set_verify_cb_func(pStore, OpcUa_P_OpenSSL_CertificateStore_Verify_Callback); if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_USE_DEFAULT_CERT_CRL_LOOKUP_METHOD) { if(X509_STORE_set_default_paths(pStore) != 1) { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_STORE_set_default_paths!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } if(!(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_DONT_ADD_TRUST_LIST_TO_ROOT_CERTIFICATES)) { if(pCertificateStoreCfg->CertificateTrustListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* how to search for certificate & CRLs */ numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* add CACertificate lookup */ if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ADD_UNTRUSTED_LIST_TO_ROOT_CERTIFICATES) { if(pCertificateStoreCfg->CertificateUntrustedListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateUntrustedListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_UNTRUSTED_LIST_IS_INDEX) { /* how to search for certificate */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add hash lookup */ if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateUntrustedListLocation, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } numCertificates = scandir(pCertificateStoreCfg->CertificateUntrustedListLocation, &dirlist, certificate_filter_der, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateUntrustedListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); /* add CACertificate lookup */ if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) { if(pCertificateStoreCfg->CertificateRevocationListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateRevocationListLocation[0] == '\0') { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_INDEX) { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add CRL lookup */ if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n"); OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_CONCATENATED_PEM_FILE) { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add CRL lookup */ if(X509_load_crl_file(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file!\n"); } } else { /* how to search for certificate & CRLs */ if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file()))) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } numCertificates = scandir(pCertificateStoreCfg->CertificateRevocationListLocation, &dirlist, certificate_filter_crl, alphasort); for (i=0; i<numCertificates; i++) { uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateRevocationListLocation, dirlist[i]->d_name, MAX_PATH, CertFile); OpcUa_GotoErrorIfBad(uStatus); if(X509_load_crl_file(pLookup, CertFile, X509_FILETYPE_PEM) != 1) /*PEM encoded*/ { OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file: skipping %s\n", CertFile); } } for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); dirlist = NULL; } if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ONLY_LEAF) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_SELF_SIGNED_SIGNATURE) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_CHECK_SS_SIGNATURE) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ALLOW_PROXY_CERTIFICATES) { /* set the flags of the store so that CRLs are consulted */ if(X509_STORE_set_flags(pStore, X509_V_FLAG_ALLOW_PROXY_CERTS) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(dirlist != NULL) { for (i=0; i<numCertificates; i++) { free(dirlist[i]); } free(dirlist); } if(*a_ppCertificateStore != OpcUa_Null) { X509_STORE_free((X509_STORE*)*a_ppCertificateStore); *a_ppCertificateStore = OpcUa_Null; } OpcUa_FinishErrorHandling; }
/*============================================================================ * Create a client socket *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_CreateClient( OpcUa_SocketManager a_hSocketManager, OpcUa_StringA a_sRemoteAddress, OpcUa_UInt16 a_uLocalPort, OpcUa_Socket_EventCallback a_pfnSocketCallBack, OpcUa_Void* a_pCallbackData, OpcUa_Socket* a_pSocket) { OpcUa_InternalSocket* pNewClientSocket = OpcUa_Null; OpcUa_InternalSocketManager* pInternalSocketManager = OpcUa_Null; OpcUa_UInt16 uPort = 0; OpcUa_StringA sRemoteAdress = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateClient"); #if !OPCUA_MULTITHREADED if(a_hSocketManager == OpcUa_Null) { a_hSocketManager = OpcUa_Socket_g_SocketManager; } #endif OpcUa_ReturnErrorIfArgumentNull(a_hSocketManager); OpcUa_ReturnErrorIfArgumentNull(a_pSocket); OpcUa_ReturnErrorIfArgumentNull(a_sRemoteAddress); /* parse address */ uStatus = OpcUa_P_ParseUrl( a_sRemoteAddress, &sRemoteAdress, &uPort); OpcUa_ReturnErrorIfBad(uStatus); pInternalSocketManager = (OpcUa_InternalSocketManager*)a_hSocketManager; pNewClientSocket = (OpcUa_InternalSocket*)OpcUa_SocketManager_FindFreeSocket( (OpcUa_SocketManager)pInternalSocketManager, OpcUa_False); if (pNewClientSocket == OpcUa_Null) { OpcUa_P_Memory_Free(sRemoteAdress); uStatus = OpcUa_BadMaxConnectionsReached; /* no socket left in the list. */ goto Error; } /* Create client socket. */ pNewClientSocket->rawSocket = OpcUa_P_Socket_CreateClient( a_uLocalPort, uPort, sRemoteAdress, &uStatus); OpcUa_P_Memory_Free(sRemoteAdress); OpcUa_GotoErrorIfTrue( pNewClientSocket->rawSocket == (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID, OpcUa_BadCommunicationError); pNewClientSocket->pfnEventCallback = a_pfnSocketCallBack; pNewClientSocket->pvUserData = a_pCallbackData; pNewClientSocket->Flags.bOwnThread = OpcUa_False; pNewClientSocket->Flags.EventMask = OPCUA_SOCKET_READ_EVENT | OPCUA_SOCKET_EXCEPT_EVENT | OPCUA_SOCKET_CONNECT_EVENT | OPCUA_SOCKET_TIMEOUT_EVENT; OPCUA_SOCKET_SETVALID(pNewClientSocket); /* return the new client socket */ *a_pSocket = pNewClientSocket; /* break loop to add new socket into eventing */ uStatus = OpcUa_P_SocketManager_InterruptLoop( a_hSocketManager, OPCUA_SOCKET_RENEWLOOP_EVENT, OpcUa_False); OpcUa_GotoErrorIfBad(uStatus); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pNewClientSocket != OpcUa_Null) { if(pNewClientSocket->rawSocket != (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID) { OpcUa_P_RawSocket_Close(pNewClientSocket->rawSocket); pNewClientSocket->rawSocket = (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID; } OPCUA_SOCKET_INVALIDATE(pNewClientSocket); } OpcUa_FinishErrorHandling; }