/*============================================================================ * 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; }
static OpcUa_StatusCode OpcUa_UadpPayloadHeader_WriteBinary(OpcUa_UadpNetworkMessage* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize) { OpcUa_Int32 ii; OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpPayloadHeader_WriteBinary"); OpcUa_ReturnErrorIfArgumentNull(a_pValue); OpcUa_ReturnErrorIfArgumentNull(a_pBuffer); OpcUa_ReturnErrorIfArgumentNull(*a_pBuffer); OpcUa_ReturnErrorIfArgumentNull(a_pSize); if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_Chunk) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->Payload[0].Header.DataSetWriterId); } else { OpcUa_UadpEncode_Direct(Byte, &a_pValue->MessageCount); for(ii = 0; ii < a_pValue->MessageCount; ii++) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->Payload[ii].Header.DataSetWriterId); } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; /* nothing to do */ OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_EnumeratedType_FindValue *===========================================================================*/ OPCUA_EXPORT OpcUa_StatusCode OpcUa_EnumeratedType_FindValue( OpcUa_EnumeratedType* a_pType, OpcUa_StringA a_sName, OpcUa_Int32* a_pValue) { OpcUa_UInt32 ii = 0; OpcUa_InitializeStatus(OpcUa_Module_Serializer, "EnumeratedType_FindValue"); OpcUa_ReturnErrorIfArgumentNull(a_pType); OpcUa_ReturnErrorIfArgumentNull(a_sName); OpcUa_ReturnErrorIfArgumentNull(a_pValue); *a_pValue = 0; for (ii = 0; a_pType->Values[ii].Name != OpcUa_Null; ii++) { if (OpcUa_StrCmpA(a_pType->Values[ii].Name, a_sName) == 0) { *a_pValue = a_pType->Values[ii].Value; break; } } OpcUa_GotoErrorIfTrue(a_pType->Values[ii].Name == OpcUa_Null, OpcUa_BadInvalidArgument); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; /* nothing to do */ OpcUa_FinishErrorHandling; }
/*============================================================================ * Bind to Socket *===========================================================================*/ OpcUa_StatusCode OpcUa_P_RawSocket_Bind( OpcUa_RawSocket a_RawSocket, OpcUa_Int16 a_nPort) { OpcUa_Int32 intSize = 0; SOCKET winSocket = (SOCKET)OPCUA_P_SOCKET_INVALID; struct sockaddr_in srv; struct sockaddr *pName; OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Bind"); OpcUa_GotoErrorIfArgumentNull(a_RawSocket); winSocket = (SOCKET)a_RawSocket; intSize = sizeof(struct sockaddr_in); OpcUa_MemSet(&srv, 0, intSize); srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons(a_nPort); srv.sin_family = AF_INET; pName = (struct sockaddr*)&srv; if(bind(winSocket, pName, intSize) == OPCUA_P_SOCKET_SOCKETERROR) { uStatus = OpcUa_BadCommunicationError; goto Error; } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
static OpcUa_StatusCode OpcUa_UadpGroupHeader_WriteBinary(OpcUa_UadpGroupHeader* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize) { OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpGroupHeader_WriteBinary"); OpcUa_ReturnErrorIfArgumentNull(a_pValue); OpcUa_ReturnErrorIfArgumentNull(a_pBuffer); OpcUa_ReturnErrorIfArgumentNull(*a_pBuffer); OpcUa_ReturnErrorIfArgumentNull(a_pSize); OpcUa_UadpEncode_Direct(Byte, &a_pValue->GroupFlags); if(a_pValue->GroupFlags & OpcUa_UadpGroupHeader_EncodingBit_WriterGroupId) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->WriterGroupId); } if(a_pValue->GroupFlags & OpcUa_UadpGroupHeader_EncodingBit_GroupVersion) { OpcUa_UadpEncode_Direct(UInt32, &a_pValue->GroupVersion); } if(a_pValue->GroupFlags & OpcUa_UadpGroupHeader_EncodingBit_NetworkMessageNumber) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->NetworkMessageNumber); } if(a_pValue->GroupFlags & OpcUa_UadpGroupHeader_EncodingBit_SequenceNumber) { OpcUa_UadpEncode_Direct(UInt16, &a_pValue->SequenceNumber); } a_pValue->SequenceNumber++; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; /* nothing to do */ OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_CheckSequenceNumber *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_CheckSequenceNumber(OpcUa_SecureChannel* a_pSecureChannel, OpcUa_UInt32 a_uSequenceNumber) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "CheckSequenceNumber"); OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel); /* The SequenceNumber shall also monotonically increase for all Messages and shall not wrap around until it is greater than 4 294 966 271 (UInt32.MaxValue - 1 024). The first number after the wrap around shall be less than 1 024. */ if(!((a_uSequenceNumber == a_pSecureChannel->uLastSequenceNumberRcvd + 1) || ((a_uSequenceNumber < 1024) && (a_pSecureChannel->uLastSequenceNumberRcvd > 4294966271u)))) { OpcUa_GotoErrorWithStatus(OpcUa_BadSequenceNumberInvalid); } a_pSecureChannel->uLastSequenceNumberRcvd = a_uSequenceNumber; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_FinishErrorHandling; }
/* * ToDo: problems with RSA_PKCS1_OAEP_PADDING -> RSA_PKCS1_PSS_PADDING is * needed (Version 0.9.9); RSA_PKCS1_OAEP_PADDING is just for encryption */ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Private_Sign( OpcUa_CryptoProvider* a_pProvider, OpcUa_ByteString a_data, OpcUa_Key* a_privateKey, OpcUa_Int16 a_padding, /* e.g. RSA_PKCS1_PADDING */ OpcUa_ByteString* a_pSignature) /* output length >= key length */ { EVP_PKEY* pSSLPrivateKey = OpcUa_Null; const unsigned char* pData = OpcUa_Null; int iErr = 0; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Private_Sign"); /* unused parameters */ OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReferenceParameter(a_padding); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_privateKey); OpcUa_ReturnErrorIfArgumentNull(a_pSignature); pData = a_privateKey->Key.Data; OpcUa_ReturnErrorIfArgumentNull(pData); OpcUa_ReturnErrorIfTrue((a_privateKey->Type != OpcUa_Crypto_KeyType_Rsa_Private), OpcUa_BadInvalidArgument); /* convert private key and check key length against buffer length */ pSSLPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA, OpcUa_Null, &pData, a_privateKey->Key.Length); OpcUa_GotoErrorIfTrue((pSSLPrivateKey == OpcUa_Null), OpcUa_BadUnexpectedError); OpcUa_GotoErrorIfTrue((a_pSignature->Length < RSA_size(pSSLPrivateKey->pkey.rsa)), OpcUa_BadInvalidArgument); /* sign data */ iErr = RSA_sign(NID_sha1, a_data.Data, a_data.Length, a_pSignature->Data, (unsigned int*)&a_pSignature->Length, pSSLPrivateKey->pkey.rsa); OpcUa_GotoErrorIfTrue((iErr != 1), OpcUa_BadUnexpectedError); /* free internal key representation */ EVP_PKEY_free(pSSLPrivateKey); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(OpcUa_IsEqual(OpcUa_BadUnexpectedError)) { long lErr = ERR_get_error(); char* szErr = ERR_error_string(lErr, 0); if(szErr != OpcUa_Null) { OpcUa_P_Trace("*** RSA_Private_Sign: "); OpcUa_P_Trace(szErr); OpcUa_P_Trace(" ***\n"); } } if(pSSLPrivateKey != OpcUa_Null) { EVP_PKEY_free(pSSLPrivateKey); } 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_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; }
/* ToDo: problems with RSA_PKCS1_OAEP_PADDING -> find solution */ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_Verify( OpcUa_CryptoProvider* a_pProvider, OpcUa_ByteString a_data, OpcUa_Key* a_publicKey, OpcUa_Int16 a_padding, OpcUa_ByteString* a_pSignature) { EVP_PKEY* pPublicKey = OpcUa_Null; OpcUa_Int32 keySize = 0; const unsigned char *pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Verify"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReferenceParameter(a_padding); OpcUa_ReturnErrorIfArgumentNull(a_data.Data); OpcUa_ReturnErrorIfArgumentNull(a_publicKey); OpcUa_ReturnErrorIfArgumentNull(a_publicKey->Key.Data); OpcUa_ReturnErrorIfArgumentNull(a_pSignature); 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) { OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument); } keySize = RSA_size(pPublicKey->pkey.rsa); if((a_pSignature->Length%keySize) != 0) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } if (RSA_verify(NID_sha1, a_data.Data, a_data.Length, a_pSignature->Data, a_pSignature->Length, pPublicKey->pkey.rsa) != 1) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } EVP_PKEY_free(pPublicKey); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if (pPublicKey != OpcUa_Null) { EVP_PKEY_free(pPublicKey); } OpcUa_FinishErrorHandling; }
/*============================================================================ * Connect Socket for Client. *===========================================================================*/ OpcUa_StatusCode OpcUa_P_RawSocket_Connect( OpcUa_RawSocket a_RawSocket, OpcUa_Int16 a_nPort, OpcUa_StringA a_sHost) { int intSize = 0; SOCKET winSocket = (SOCKET)OPCUA_P_SOCKET_INVALID; struct sockaddr *pName; struct sockaddr_in srv; char* localhost = "127.0.0.1"; OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Connect"); OpcUa_GotoErrorIfArgumentNull(a_RawSocket); winSocket = (SOCKET)a_RawSocket; intSize = sizeof(struct sockaddr_in); OpcUa_MemSet(&srv, 0, intSize); if(!strcmp("localhost", a_sHost)) { a_sHost = localhost; } srv.sin_addr.s_addr = inet_addr(a_sHost); if(srv.sin_addr.s_addr == INADDR_NONE) { return OpcUa_BadInvalidArgument; } srv.sin_port = htons(a_nPort); srv.sin_family = AF_INET; pName = (struct sockaddr *) &srv; if(connect(winSocket, pName, intSize) == OPCUA_P_SOCKET_SOCKETERROR) { int result = OpcUa_P_RawSocket_GetLastError((OpcUa_RawSocket)winSocket); /* a connect takes some time and this "error" is common with nonblocking sockets */ if(result == WSAEWOULDBLOCK || result == WSAEINPROGRESS) { uStatus = OpcUa_BadWouldBlock; } else { uStatus = OpcUa_BadCommunicationError; } goto Error; } uStatus = OpcUa_Good; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; 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; }
/*============================================================================ * 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_SeedPRNG *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_OpenSSL_SeedPRNG( OpcUa_Byte* seed, OpcUa_Int bytes) { OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "SeedPRNG"); RAND_seed(seed, bytes); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_RenewSecurityToken *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_RenewSecurityToken( OpcUa_SecureChannel* a_pSecureChannel, OpcUa_ChannelSecurityToken* a_pSecurityToken, OpcUa_UInt32 a_tokenLifeTime, OpcUa_ChannelSecurityToken** a_ppSecurityToken) { OpcUa_ChannelSecurityToken* pSecurityToken = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "RenewSecurityToken"); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OpcUa_ReturnErrorIfArgumentNull(a_pSecurityToken); OpcUa_ReturnErrorIfArgumentNull(a_ppSecurityToken); OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel); /* initialize outparameters */ *a_ppSecurityToken = OpcUa_Null; /*** create token ***/ pSecurityToken = (OpcUa_ChannelSecurityToken*)OpcUa_Alloc(sizeof(OpcUa_ChannelSecurityToken)); OpcUa_GotoErrorIfAllocFailed(pSecurityToken); OpcUa_ChannelSecurityToken_Initialize(pSecurityToken); pSecurityToken->TokenId = a_pSecureChannel->NextTokenId; pSecurityToken->ChannelId = a_pSecurityToken->ChannelId; pSecurityToken->CreatedAt = OPCUA_P_DATETIME_UTCNOW(); OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_TcpSecureChannel_RenewSecurityToken: TOKEN ID is %u-%u\n", pSecurityToken->ChannelId, pSecurityToken->TokenId); OpcUa_TcpSecureChannel_ReviseLifetime(a_tokenLifeTime, &pSecurityToken->RevisedLifetime); /* increment renew counter */ a_pSecureChannel->NextTokenId++; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); /* assign outparameter */ *a_ppSecurityToken = pSecurityToken; OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); if(pSecurityToken != OpcUa_Null) { OpcUa_Free(pSecurityToken); } OpcUa_FinishErrorHandling; }
/*============================================================================ * Signal a certain event on a socket. *===========================================================================*/ OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_SignalEvent( OpcUa_SocketManager a_pSocketManager, OpcUa_UInt32 a_uEvent, OpcUa_Boolean a_bAllManagers) { OpcUa_InitializeStatus(OpcUa_Module_Socket, "SignalEvent"); uStatus = OpcUa_P_SocketManager_InterruptLoop(a_pSocketManager, a_uEvent, a_bAllManagers); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_UnlockWriteMutex *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_UnlockWriteMutex(OpcUa_SecureChannel* a_pSecureChannel) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "UnlockWriteMutex"); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OPCUA_SECURECHANNEL_UNLOCK_WRITE(a_pSecureChannel); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Set socket user data *===========================================================================*/ static OpcUa_StatusCode OpcUa_P_SocketService_UdpSetUserData(OpcUa_Socket a_pSocket, OpcUa_Void* a_pvUserData) { OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpSetUserData"); OpcUa_GotoErrorIfArgumentNull(a_pSocket); OpcUa_ReferenceParameter(a_pvUserData); OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_AddCustomExtension *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_AddCustomExtension( X509** a_ppCertificate, OpcUa_Crypto_Extension* a_pExtension, X509V3_CTX* a_pX509V3Context) { X509_EXTENSION* pExtension = OpcUa_Null; char* pName = OpcUa_Null; char* pValue = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_AddCustomExtension"); OpcUa_ReturnErrorIfArgumentNull(a_pX509V3Context); OpcUa_ReturnErrorIfArgumentNull(a_pExtension->key); OpcUa_ReturnErrorIfArgumentNull(a_pExtension->value); pName = (char*)a_pExtension->key; pValue = (char*)a_pExtension->value; /* create the extension. */ pExtension = X509V3_EXT_conf( OpcUa_Null, a_pX509V3Context, pName, pValue); if(pExtension == OpcUa_Null) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* add it to the certificate. */ if(!X509_add_ext(*a_ppCertificate, pExtension, -1)) { OpcUa_GotoErrorWithStatus(OpcUa_Bad); } /* free the extension. */ X509_EXTENSION_free(pExtension); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pExtension != OpcUa_Null) { X509_EXTENSION_free(pExtension); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_Delete *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_Delete(OpcUa_SecureChannel** a_ppSecureChannel) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Delete"); if (a_ppSecureChannel != OpcUa_Null && *a_ppSecureChannel != OpcUa_Null) { OpcUa_TcpSecureChannel_Clear(*a_ppSecureChannel); OpcUa_Free(*a_ppSecureChannel); *a_ppSecureChannel = OpcUa_Null; } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Close UDP Socket. *===========================================================================*/ static OpcUa_StatusCode OpcUa_P_SocketService_UdpClose(OpcUa_Socket a_pSocket) { OpcUa_InternalUdpSocket* pInternalSocket = (OpcUa_InternalUdpSocket*)a_pSocket; OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpClose"); OpcUa_GotoErrorIfArgumentNull(a_pSocket); OpcUa_P_RawSocket_Close(pInternalSocket->rawSocket); OpcUa_P_Memory_Free(pInternalSocket); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Get address information about the peer *===========================================================================*/ OpcUa_StatusCode OpcUa_P_RawSocket_GetPeerInfo( OpcUa_Socket a_RawSocket, OpcUa_CharA* a_achPeerInfoBuffer, OpcUa_UInt32 a_uiPeerInfoBufferSize) { int apiResult = 0; struct sockaddr_in sockAddrIn; size_t TempLen = sizeof(struct sockaddr_in); SOCKET winSocket = (SOCKET)OPCUA_P_SOCKET_INVALID; char* pchAddrBuf = OpcUa_Null; OpcUa_UInt16 usPort = 0; OpcUa_InitializeStatus(OpcUa_Module_Socket, "GetPeerInfo"); /* initial parameter check */ OpcUa_ReturnErrorIfTrue((a_RawSocket == (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID), OpcUa_BadInvalidArgument); OpcUa_ReturnErrorIfTrue((a_uiPeerInfoBufferSize < OPCUA_P_PEERINFO_MIN_SIZE), OpcUa_BadInvalidArgument); OpcUa_ReturnErrorIfArgumentNull(a_achPeerInfoBuffer); winSocket = (SOCKET)a_RawSocket; apiResult = getpeername(winSocket, (struct sockaddr*)&sockAddrIn, (int*)&TempLen); OpcUa_ReturnErrorIfTrue((apiResult != 0), OpcUa_BadInternalError); /* IP */ pchAddrBuf = inet_ntoa(sockAddrIn.sin_addr); OpcUa_GotoErrorIfTrue(pchAddrBuf == OpcUa_Null, OpcUa_BadInternalError); /* Port */ usPort = OpcUa_P_RawSocket_NToHS((OpcUa_UInt16)sockAddrIn.sin_port); /* build result string */ TempLen = strlen(pchAddrBuf); #if OPCUA_USE_SAFE_FUNCTIONS OpcUa_GotoErrorIfTrue((strncpy_s(a_achPeerInfoBuffer, a_uiPeerInfoBufferSize + 1, pchAddrBuf, TempLen) != 0), OpcUa_Bad); a_achPeerInfoBuffer[TempLen] = ':'; TempLen++; sprintf_s(&a_achPeerInfoBuffer[TempLen], a_uiPeerInfoBufferSize - TempLen, "%u", usPort); #else /* OPCUA_USE_SAFE_FUNCTIONS */ OpcUa_GotoErrorIfTrue((strncpy(a_achPeerInfoBuffer, pchAddrBuf, TempLen) != a_achPeerInfoBuffer), OpcUa_Bad); a_achPeerInfoBuffer[TempLen] = ':'; sprintf(&a_achPeerInfoBuffer[TempLen + 1], "%u", usPort); #endif /* OPCUA_USE_SAFE_FUNCTIONS */ OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * Select usable socket. (maxfds ignored in win32) *===========================================================================*/ OpcUa_StatusCode OpcUa_P_RawSocket_Select( OpcUa_RawSocket a_MaxFds, OpcUa_P_Socket_Array* a_pFdSetRead, OpcUa_P_Socket_Array* a_pFdSetWrite, OpcUa_P_Socket_Array* a_pFdSetException, OpcUa_TimeVal* a_pTimeout) { int apiResult = 0; struct timeval timeout; OpcUa_InitializeStatus(OpcUa_Module_Socket, "P_Select"); OpcUa_ReferenceParameter(a_MaxFds); OpcUa_GotoErrorIfArgumentNull(a_pFdSetRead); OpcUa_GotoErrorIfArgumentNull(a_pFdSetWrite); OpcUa_GotoErrorIfArgumentNull(a_pFdSetException); timeout.tv_sec = a_pTimeout->uintSeconds; timeout.tv_usec = a_pTimeout->uintMicroSeconds; apiResult = select( 0, (fd_set*)a_pFdSetRead, (fd_set*)a_pFdSetWrite, (fd_set*)a_pFdSetException, &timeout); if(apiResult == OPCUA_P_SOCKET_SOCKETERROR) { apiResult = WSAGetLastError(); switch(apiResult) { case WSAENOTSOCK: { uStatus = OpcUa_BadInvalidArgument; break; } default: { uStatus = OpcUa_BadCommunicationError; } } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_Close *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_Close(OpcUa_SecureChannel* a_pSecureChannel) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Close"); OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel); a_pSecureChannel->State = OpcUa_SecureChannelState_Closed; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); 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; }
/*============================================================================ * Get IP Address and Port Number of the Peer *===========================================================================*/ static OpcUa_StatusCode OpcUa_P_SocketService_UdpGetPeerInfo( OpcUa_Socket a_pSocket, OpcUa_CharA* a_achPeerInfoBuffer, OpcUa_UInt32 a_uiPeerInfoBufferSize) { OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpGetPeerInfo"); OpcUa_GotoErrorIfArgumentNull(a_pSocket); OpcUa_GotoErrorIfArgumentNull(a_achPeerInfoBuffer); OpcUa_ReferenceParameter(a_uiPeerInfoBufferSize); OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_ReleaseSecuritySet *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_ReleaseSecuritySet( OpcUa_SecureChannel* a_pSecureChannel, OpcUa_UInt32 a_uTokenId) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "ReleaseSecuritySet"); OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OpcUa_ReferenceParameter(a_uTokenId); OpcUa_Trace(OPCUA_TRACE_LEVEL_DEBUG, "ReleaseSecurityKeyset: Keyset for token %u released.\n", a_uTokenId); OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }