/*============================================================================ * 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 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_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; }
/*============================================================================ * 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; }
/* 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; }
/*============================================================================ * 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; }
/*============================================================================ * 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; }
/*============================================================================ * OpcUa_P_ParseUrl *===========================================================================*/ OpcUa_StatusCode OpcUa_P_ParseUrl( OpcUa_StringA a_psUrl, OpcUa_StringA* a_psIpAddress, OpcUa_UInt16* a_puPort) { OpcUa_StringA sHostName = OpcUa_Null; OpcUa_UInt32 uHostNameLength = 0; OpcUa_CharA* sPort = OpcUa_Null; OpcUa_CharA* pcCursor; OpcUa_Int nIndex1 = 0; OpcUa_Int nIpStart; struct addrinfo* pAddrInfo = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_Utilities, "P_ParseUrl"); OpcUa_ReturnErrorIfArgumentNull(a_psUrl); OpcUa_ReturnErrorIfArgumentNull(a_psIpAddress); OpcUa_ReturnErrorIfArgumentNull(a_puPort); *a_psIpAddress = OpcUa_Null; /* check for // (end of protocol header) */ pcCursor = strstr(a_psUrl, "//"); if(pcCursor != OpcUa_Null) { /* begin of host address */ pcCursor += 2; nIndex1 = (OpcUa_Int)(pcCursor - a_psUrl); } /* skip protocol prefix and store beginning of ip adress */ nIpStart = nIndex1; /* skip host address (IPv6 address can contain colons!) */ while(a_psUrl[nIndex1] != '/' && a_psUrl[nIndex1] != 0) { if(a_psUrl[nIndex1] == ':') { sPort = &a_psUrl[nIndex1 + 1]; uHostNameLength = nIndex1 - nIpStart; } /* handle "opc.tcp://[::1]:4880/" */ if(a_psUrl[nIndex1] == ']' && sPort != OpcUa_Null && a_psUrl[nIpStart] == '[') { nIpStart++; uHostNameLength = nIndex1 - nIpStart; sPort = OpcUa_Null; if(a_psUrl[nIndex1 + 1] == ':') { sPort = &a_psUrl[nIndex1 + 2]; } break; } nIndex1++; } if(uHostNameLength == 0) { uHostNameLength = nIndex1 - nIpStart; } /* scan port */ if(sPort != OpcUa_Null) { /* convert port */ *a_puPort = (OpcUa_UInt16)OpcUa_P_CharAToInt(sPort); } else { /* return default port */ *a_puPort = OPCUA_TCP_DEFAULT_PORT; } sHostName = (OpcUa_StringA)OpcUa_P_Memory_Alloc(uHostNameLength + 1); if(sHostName == NULL) { OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory); } memcpy(sHostName, &a_psUrl[nIpStart], uHostNameLength); sHostName[uHostNameLength] = '\0'; if(getaddrinfo(sHostName, NULL, NULL, &pAddrInfo)) { /* hostname could not be resolved */ pAddrInfo = NULL; OpcUa_GotoErrorWithStatus(OpcUa_BadHostUnknown); } if(pAddrInfo->ai_family == AF_INET) { struct sockaddr_in* pAddr = (struct sockaddr_in*)pAddrInfo->ai_addr; OpcUa_P_Memory_Free(sHostName); sHostName = OpcUa_P_Memory_Alloc(INET_ADDRSTRLEN); OpcUa_GotoErrorIfAllocFailed(sHostName); if(inet_ntop(AF_INET, (void*)&pAddr->sin_addr, sHostName, INET_ADDRSTRLEN) == NULL) { OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError); } } else if(pAddrInfo->ai_family == AF_INET6) { struct sockaddr_in6* pAddr = (struct sockaddr_in6*)pAddrInfo->ai_addr; OpcUa_P_Memory_Free(sHostName); sHostName = OpcUa_P_Memory_Alloc(INET6_ADDRSTRLEN); OpcUa_GotoErrorIfAllocFailed(sHostName); if(inet_ntop(AF_INET6, (void*)&pAddr->sin6_addr, sHostName, INET6_ADDRSTRLEN) == NULL) { OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError); } if(pAddr->sin6_scope_id) { char *pScopeAddress = OpcUa_P_Memory_Alloc(strlen(sHostName) + 12); OpcUa_GotoErrorIfAllocFailed(pScopeAddress); sprintf(pScopeAddress, "%s%%%u", sHostName, pAddr->sin6_scope_id); OpcUa_P_Memory_Free(sHostName); sHostName = pScopeAddress; } } else { OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError); } *a_psIpAddress = sHostName; freeaddrinfo(pAddrInfo); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(sHostName != OpcUa_Null) { OpcUa_P_Memory_Free(sHostName); } if(pAddrInfo != NULL) { freeaddrinfo(pAddrInfo); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_LoadFromFile *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_LoadFromFile( OpcUa_StringA a_fileName, OpcUa_P_FileFormat a_fileFormat, OpcUa_StringA a_sPassword, /* optional: just for OpcUa_PKCS12 */ OpcUa_ByteString* a_pCertificate) { BIO* pCertFile = OpcUa_Null; X509* pCertX509 = OpcUa_Null; PKCS12* pPKCS12Cert = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_LoadFromFile"); /* check filename */ if(OpcUa_P_String_strlen(a_fileName) < 1) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } /* import certificate from file by the given encoding type */ pCertFile = BIO_new_file((const char*)a_fileName, "r"); OpcUa_ReturnErrorIfArgumentNull(pCertFile); switch(a_fileFormat) { case OpcUa_Crypto_Encoding_DER: { pCertX509 = d2i_X509_bio(pCertFile, /* sourcefile */ (X509**)NULL); /* target (if preallocated) */ break; } case OpcUa_Crypto_Encoding_PEM: { pCertX509 = PEM_read_bio_X509( pCertFile, /* sourcefile */ (X509**)OpcUa_Null, /* target (if preallocated) */ OpcUa_Null, /* password callback function */ OpcUa_Null); /* passphrase or callback data */ break; } case OpcUa_Crypto_Encoding_PKCS12: { d2i_PKCS12_bio(pCertFile, &pPKCS12Cert); PKCS12_parse(pPKCS12Cert, a_sPassword, OpcUa_Null, &pCertX509, OpcUa_Null); if(pPKCS12Cert != OpcUa_Null) { PKCS12_free(pPKCS12Cert); /*OPENSSL_free(pPKCS12Cert);*/ } break; } default: { BIO_free(pCertFile); return OpcUa_BadNotSupported; } } BIO_free(pCertFile); pCertFile = OpcUa_Null; if(pCertX509 == OpcUa_Null) { /* error in OpenSSL - maybe certificate file was corrupt */ return OpcUa_Bad; } /* prepare container */ memset(a_pCertificate, 0, sizeof(OpcUa_ByteString)); /* get required length for conversion target buffer */ a_pCertificate->Length = i2d_X509( pCertX509, NULL); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } /* allocate conversion target buffer */ a_pCertificate->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pCertificate->Data); /* convert into DER */ a_pCertificate->Length = i2d_X509( pCertX509, &(a_pCertificate->Data)); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } else { /* correct pointer incrementation by i2d_X509() */ a_pCertificate->Data -= a_pCertificate->Length; } X509_free(pCertX509); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pCertX509 != OpcUa_Null) { X509_free(pCertX509); } if(pPKCS12Cert != OpcUa_Null) { OPENSSL_free(pPKCS12Cert); } if(a_pCertificate->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pCertificate->Data); a_pCertificate->Data = OpcUa_Null; } if(pCertFile != OpcUa_Null) { BIO_free(pCertFile); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_SelfSigned_Custom_Create *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_SelfSigned_Custom_Create( OpcUa_CryptoProvider* a_pProvider, OpcUa_Int32 a_serialNumber, OpcUa_UInt32 a_validToInSec, OpcUa_Crypto_NameEntry* a_pNameEntries, /* will be used for issuer and subject thus it's selfigned cert */ OpcUa_UInt a_nameEntriesCount, /* will be used for issuer and subject thus it's selfigned cert */ OpcUa_Key a_pSubjectPublicKey, /* EVP_PKEY* - type defines also public key algorithm */ OpcUa_Crypto_Extension* a_pExtensions, OpcUa_UInt a_extensionsCount, OpcUa_UInt a_signatureHashAlgorithm, /* EVP_sha1(),... */ OpcUa_Key a_pIssuerPrivateKey, /* EVP_PKEY* - type defines also signature algorithm */ OpcUa_ByteString* a_pCertificate) { OpcUa_UInt i; X509_NAME* pSubj = OpcUa_Null; X509V3_CTX ctx; const EVP_MD* pDigest = OpcUa_Null; X509* pCert = OpcUa_Null; EVP_PKEY* pSubjectPublicKey = OpcUa_Null; EVP_PKEY* pIssuerPrivateKey = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_SelfSigned_Custom_Create"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pNameEntries); OpcUa_ReturnErrorIfArgumentNull(a_pExtensions); OpcUa_ReturnErrorIfArgumentNull(a_pIssuerPrivateKey.Key.Data); OpcUa_ReturnErrorIfArgumentNull(a_pCertificate); if(a_pSubjectPublicKey.Type != OpcUa_Crypto_KeyType_Rsa_Public) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } if(a_pIssuerPrivateKey.Type != OpcUa_Crypto_KeyType_Rsa_Private) { uStatus = OpcUa_BadInvalidArgument; OpcUa_GotoErrorIfBad(uStatus); } pSubjectPublicKey = d2i_PublicKey(EVP_PKEY_RSA,OpcUa_Null,((const unsigned char**)&(a_pSubjectPublicKey.Key.Data)),a_pSubjectPublicKey.Key.Length); if(pSubjectPublicKey == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } pIssuerPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA,OpcUa_Null,((const unsigned char**)&(a_pIssuerPrivateKey.Key.Data)),a_pIssuerPrivateKey.Key.Length); if(pIssuerPrivateKey == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* create new certificate object */ pCert = X509_new(); if(pCert == OpcUa_Null) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set version of certificate (V3 since internal representation starts versioning from 0) */ if(X509_set_version(pCert, 2L) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* generate a unique number for a serial number if none provided. */ if(a_serialNumber == 0) { ASN1_INTEGER* pSerialNumber = X509_get_serialNumber(pCert); pSerialNumber->type = V_ASN1_INTEGER; pSerialNumber->data = OPENSSL_realloc(pSerialNumber->data, 16); pSerialNumber->length = 16; if(pSerialNumber->data == NULL || OpcUa_P_Guid_Create((OpcUa_Guid*)pSerialNumber->data) == NULL) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } } /* use the integer passed in - note the API should not be using a 32-bit integer - must fix sometime */ else if(ASN1_INTEGER_set(X509_get_serialNumber(pCert), a_serialNumber) == 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* add key to the request */ if(X509_set_pubkey(pCert, pSubjectPublicKey) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(pSubjectPublicKey != OpcUa_Null) { EVP_PKEY_free(pSubjectPublicKey); pSubjectPublicKey = OpcUa_Null; } /* assign the subject name */ pSubj = X509_NAME_new(); if(!pSubj) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* create and add entries to subject name */ for(i=0; i<a_nameEntriesCount; i++) { uStatus = OpcUa_P_OpenSSL_X509_Name_AddEntry(&pSubj, a_pNameEntries + i); OpcUa_GotoErrorIfBad(uStatus); } /* set subject name in request */ if(X509_set_subject_name(pCert, pSubj) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set name of issuer (CA) */ if(X509_set_issuer_name(pCert, pSubj) != 1) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(!(X509_gmtime_adj(X509_get_notBefore(pCert), 0))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* set ending time of the certificate */ if(!(X509_gmtime_adj(X509_get_notAfter(pCert), a_validToInSec))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } /* add x509v3 extensions */ X509V3_set_ctx(&ctx, pCert, pCert, OpcUa_Null, OpcUa_Null, 0); for(i=0; i<a_extensionsCount; i++) { uStatus = OpcUa_P_OpenSSL_X509_AddCustomExtension(&pCert, a_pExtensions+i, &ctx); OpcUa_GotoErrorIfBad(uStatus); } /* sign certificate with the CA private key */ switch(a_signatureHashAlgorithm) { case OPCUA_P_SHA_160: pDigest = EVP_sha1(); break; case OPCUA_P_SHA_224: pDigest = EVP_sha224(); break; case OPCUA_P_SHA_256: pDigest = EVP_sha256(); break; case OPCUA_P_SHA_384: pDigest = EVP_sha384(); break; case OPCUA_P_SHA_512: pDigest = EVP_sha512(); break; default: uStatus = OpcUa_BadNotSupported; OpcUa_GotoErrorIfBad(uStatus); } if(!(X509_sign(pCert, pIssuerPrivateKey, pDigest))) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(X509_verify(pCert, pIssuerPrivateKey) <= 0) { uStatus = OpcUa_Bad; OpcUa_GotoErrorIfBad(uStatus); } if(pIssuerPrivateKey != OpcUa_Null) { EVP_PKEY_free(pIssuerPrivateKey); pIssuerPrivateKey = OpcUa_Null; } if(pSubj != OpcUa_Null) { X509_NAME_free(pSubj); pSubj = OpcUa_Null; } /* prepare container */ memset(a_pCertificate, 0, sizeof(OpcUa_ByteString)); /* get required length for conversion target buffer */ a_pCertificate->Length = i2d_X509(pCert, NULL); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } /* allocate conversion target buffer */ a_pCertificate->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pCertificate->Data); /* convert into DER */ a_pCertificate->Length = i2d_X509(pCert, &(a_pCertificate->Data)); if(a_pCertificate->Length <= 0) { /* conversion to DER not possible */ uStatus = OpcUa_Bad; } else { /* correct pointer incrementation by i2d_X509() */ a_pCertificate->Data -= a_pCertificate->Length; } X509_free(pCert); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; X509_free(pCert); if(pSubjectPublicKey != OpcUa_Null) { EVP_PKEY_free(pSubjectPublicKey); } if(pIssuerPrivateKey != OpcUa_Null) { EVP_PKEY_free(pIssuerPrivateKey); } if(pSubj != OpcUa_Null) { X509_NAME_free(pSubj); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_TcpSecureChannel_Create *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_Create(OpcUa_SecureChannel** a_ppSecureChannel) { OpcUa_TcpSecureChannel* pTcpSecureChannel = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Create"); *a_ppSecureChannel = OpcUa_Null; pTcpSecureChannel = (OpcUa_TcpSecureChannel*)OpcUa_Alloc(sizeof(OpcUa_TcpSecureChannel)); OpcUa_ReturnErrorIfAllocFailed(pTcpSecureChannel); OpcUa_MemSet(pTcpSecureChannel, 0, sizeof(OpcUa_TcpSecureChannel)); *a_ppSecureChannel = (OpcUa_SecureChannel*)OpcUa_Alloc(sizeof(OpcUa_SecureChannel)); OpcUa_GotoErrorIfAllocFailed(*a_ppSecureChannel); OpcUa_MemSet(*a_ppSecureChannel, 0, sizeof(OpcUa_SecureChannel)); (*a_ppSecureChannel)->SecureChannelId = OPCUA_SECURECHANNEL_ID_INVALID; (*a_ppSecureChannel)->NextTokenId = 1; (*a_ppSecureChannel)->uLastSequenceNumberRcvd = 0xFFFFFFFFU; (*a_ppSecureChannel)->uLastSequenceNumberSent = OPCUA_SECURECHANNEL_STARTING_SEQUENCE_NUMBER; (*a_ppSecureChannel)->Handle = pTcpSecureChannel; (*a_ppSecureChannel)->Open = OpcUa_TcpSecureChannel_Open; (*a_ppSecureChannel)->Renew = OpcUa_TcpSecureChannel_Renew; (*a_ppSecureChannel)->Close = OpcUa_TcpSecureChannel_Close; (*a_ppSecureChannel)->GenerateSecurityToken = OpcUa_TcpSecureChannel_GenerateSecurityToken; (*a_ppSecureChannel)->RenewSecurityToken = OpcUa_TcpSecureChannel_RenewSecurityToken; (*a_ppSecureChannel)->GetSecuritySet = OpcUa_TcpSecureChannel_GetSecuritySet; (*a_ppSecureChannel)->GetCurrentSecuritySet = OpcUa_TcpSecureChannel_GetCurrentSecuritySet; (*a_ppSecureChannel)->ReleaseSecuritySet = OpcUa_TcpSecureChannel_ReleaseSecuritySet; (*a_ppSecureChannel)->GetSequenceNumber = OpcUa_TcpSecureChannel_GetSequenceNumber; (*a_ppSecureChannel)->CheckSequenceNumber = OpcUa_TcpSecureChannel_CheckSequenceNumber; (*a_ppSecureChannel)->LockWriteMutex = OpcUa_TcpSecureChannel_LockWriteMutex; (*a_ppSecureChannel)->UnlockWriteMutex = OpcUa_TcpSecureChannel_UnlockWriteMutex; (*a_ppSecureChannel)->IsOpen = OpcUa_SecureChannel_IsOpen; (*a_ppSecureChannel)->DiscoveryOnly = OpcUa_False; (*a_ppSecureChannel)->MessageSecurityMode = OpcUa_MessageSecurityMode_None; uStatus = OPCUA_P_MUTEX_CREATE(&((*a_ppSecureChannel)->hSyncAccess)); OpcUa_GotoErrorIfBad(uStatus); uStatus = OPCUA_P_MUTEX_CREATE(&((*a_ppSecureChannel)->hWriteMutex)); OpcUa_GotoErrorIfBad(uStatus); OpcUa_String_Initialize(&((*a_ppSecureChannel)->SecurityPolicyUri)); OpcUa_String_Initialize(&((*a_ppSecureChannel)->sPeerInfo)); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if (*a_ppSecureChannel != OpcUa_Null) { if((*a_ppSecureChannel)->hSyncAccess != OpcUa_Null) { OPCUA_P_MUTEX_DELETE(&((*a_ppSecureChannel)->hSyncAccess)); } if((*a_ppSecureChannel)->hWriteMutex != OpcUa_Null) { OPCUA_P_MUTEX_DELETE(&((*a_ppSecureChannel)->hWriteMutex)); } OpcUa_Free(*a_ppSecureChannel); *a_ppSecureChannel = OpcUa_Null; } OpcUa_Free(pTcpSecureChannel); OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_SecureChannel_Renew *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_Renew( OpcUa_SecureChannel* a_pSecureChannel, OpcUa_Handle a_hTransportConnection, OpcUa_ChannelSecurityToken a_ChannelSecurityToken, OpcUa_MessageSecurityMode a_eMessageSecurityMode, OpcUa_ByteString* a_pbsClientCertificate, OpcUa_ByteString* a_pbsServerCertificate, OpcUa_SecurityKeyset* a_pNewReceivingKeyset, OpcUa_SecurityKeyset* a_pNewSendingKeyset, OpcUa_CryptoProvider* a_pNewCryptoProvider) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Renew"); OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OpcUa_ReturnErrorIfArgumentNull(a_hTransportConnection); OpcUa_ReturnErrorIfArgumentNull(a_pNewCryptoProvider); OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel); OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_TcpSecureChannel_Renew: New token id for channel %u is %u\n", a_pSecureChannel->SecureChannelId, a_ChannelSecurityToken.TokenId); if(a_pSecureChannel->TransportConnection != a_hTransportConnection) { OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid); } if(a_pSecureChannel->SecureChannelId != a_ChannelSecurityToken.ChannelId) { OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid); } /*** TCP SECURECHANNEL ***/ /* Previous objects will be overwritten by current objects */ a_pSecureChannel->bCurrentTokenActive = OpcUa_False; /* set channelSecurityToken members */ a_pSecureChannel->PreviousChannelSecurityToken.ChannelId = a_pSecureChannel->CurrentChannelSecurityToken.ChannelId; a_pSecureChannel->PreviousChannelSecurityToken.TokenId = a_pSecureChannel->CurrentChannelSecurityToken.TokenId; a_pSecureChannel->PreviousChannelSecurityToken.CreatedAt = a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt; a_pSecureChannel->PreviousChannelSecurityToken.RevisedLifetime = a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime; /* set current channelSecurityToken */ a_pSecureChannel->CurrentChannelSecurityToken.ChannelId = a_ChannelSecurityToken.ChannelId; a_pSecureChannel->CurrentChannelSecurityToken.TokenId = a_ChannelSecurityToken.TokenId; a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt = a_ChannelSecurityToken.CreatedAt; a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime = a_ChannelSecurityToken.RevisedLifetime; /*** SECURECHANNEL ***/ a_pSecureChannel->State = OpcUa_SecureChannelState_Opened; a_pSecureChannel->MessageSecurityMode = a_eMessageSecurityMode; a_pSecureChannel->uExpirationCounter = (OpcUa_UInt32)(a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL); a_pSecureChannel->uOverlapCounter = (OpcUa_UInt32)((a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime>>2)/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL); /* free old certificate and add new one */ OpcUa_ByteString_Clear(&a_pSecureChannel->ClientCertificate); /* copy client certificate!!! */ if(a_pbsClientCertificate != OpcUa_Null && a_pbsClientCertificate->Length > 0) { a_pSecureChannel->ClientCertificate.Data = (OpcUa_Byte*)OpcUa_Alloc(a_pbsClientCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ClientCertificate.Data); a_pSecureChannel->ClientCertificate.Length = a_pbsClientCertificate->Length; OpcUa_MemCpy( a_pSecureChannel->ClientCertificate.Data, a_pSecureChannel->ClientCertificate.Length, a_pbsClientCertificate->Data, a_pbsClientCertificate->Length); } /* free old certificate and add new one */ OpcUa_ByteString_Clear(&a_pSecureChannel->ServerCertificate); if(a_pbsServerCertificate != OpcUa_Null && a_pbsServerCertificate->Length > 0) { a_pSecureChannel->ServerCertificate.Data = (OpcUa_Byte*)OpcUa_Alloc(a_pbsServerCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ServerCertificate.Data); a_pSecureChannel->ServerCertificate.Length = a_pbsServerCertificate->Length; OpcUa_MemCpy( a_pSecureChannel->ServerCertificate.Data, a_pSecureChannel->ServerCertificate.Length, a_pbsServerCertificate->Data, a_pbsServerCertificate->Length); } /* delete previous keysets */ OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousReceivingKeyset); OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousSendingKeyset); OpcUa_Free(a_pSecureChannel->pPreviousReceivingKeyset); OpcUa_Free(a_pSecureChannel->pPreviousSendingKeyset); a_pSecureChannel->pPreviousReceivingKeyset = OpcUa_Null; a_pSecureChannel->pPreviousSendingKeyset = OpcUa_Null; /* assign current to previous */ a_pSecureChannel->pPreviousReceivingKeyset = a_pSecureChannel->pCurrentReceivingKeyset; a_pSecureChannel->pPreviousSendingKeyset = a_pSecureChannel->pCurrentSendingKeyset; /* delete previous cryptoprovider */ if( a_pSecureChannel->pPreviousCryptoProvider != OpcUa_Null && a_pSecureChannel->pPreviousCryptoProvider != a_pSecureChannel->pCurrentCryptoProvider) { OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pPreviousCryptoProvider); OpcUa_Free(a_pSecureChannel->pPreviousCryptoProvider); a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null; } else { a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null; } /* make current cryptoprovider previous */ a_pSecureChannel->pPreviousCryptoProvider = a_pSecureChannel->pCurrentCryptoProvider; a_pSecureChannel->pCurrentCryptoProvider = a_pNewCryptoProvider; a_pSecureChannel->pCurrentReceivingKeyset = a_pNewReceivingKeyset; a_pSecureChannel->pCurrentSendingKeyset = a_pNewSendingKeyset; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_SecurityKeyset_Clear(a_pNewReceivingKeyset); OpcUa_SecurityKeyset_Clear(a_pNewSendingKeyset); OpcUa_Free(a_pNewReceivingKeyset); OpcUa_Free(a_pNewSendingKeyset); OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_SecureChannel_Open *===========================================================================*/ OpcUa_StatusCode OpcUa_TcpSecureChannel_Open( OpcUa_SecureChannel* a_pSecureChannel, OpcUa_Handle a_hTransportConnection, OpcUa_ChannelSecurityToken a_channelSecurityToken, OpcUa_MessageSecurityMode a_messageSecurityMode, OpcUa_ByteString* a_pbsClientCertificate, OpcUa_ByteString* a_pbsServerCertificate, OpcUa_SecurityKeyset* a_pReceivingKeyset, OpcUa_SecurityKeyset* a_pSendingKeyset, OpcUa_CryptoProvider* a_pCryptoProvider) { OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Open"); OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel); OpcUa_ReturnErrorIfArgumentNull(a_hTransportConnection); OpcUa_ReturnErrorIfArgumentNull(a_pCryptoProvider); OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel); if(a_pSecureChannel->SecureChannelId != a_channelSecurityToken.ChannelId) { OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid); } a_pSecureChannel->bCurrentTokenActive = OpcUa_True; /*** TCP SECURECHANNEL ***/ a_pSecureChannel->CurrentChannelSecurityToken.ChannelId = a_channelSecurityToken.ChannelId; a_pSecureChannel->CurrentChannelSecurityToken.TokenId = a_channelSecurityToken.TokenId; a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt = a_channelSecurityToken.CreatedAt; a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime = a_channelSecurityToken.RevisedLifetime; /*** SECURECHANNEL ***/ a_pSecureChannel->State = OpcUa_SecureChannelState_Opened; a_pSecureChannel->TransportConnection = a_hTransportConnection; a_pSecureChannel->MessageSecurityMode = a_messageSecurityMode; a_pSecureChannel->uExpirationCounter = (OpcUa_UInt32)(a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL); a_pSecureChannel->uOverlapCounter = (OpcUa_UInt32)((a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime>>2)/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL); /* copy client certificate */ if(a_pbsClientCertificate != OpcUa_Null && a_pbsClientCertificate->Length > 0) { a_pSecureChannel->ClientCertificate.Data = (OpcUa_Byte *)OpcUa_Alloc(a_pbsClientCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ClientCertificate.Data); a_pSecureChannel->ClientCertificate.Length = a_pbsClientCertificate->Length; OpcUa_MemCpy( a_pSecureChannel->ClientCertificate.Data, a_pSecureChannel->ClientCertificate.Length, a_pbsClientCertificate->Data, a_pbsClientCertificate->Length); } else { OpcUa_ByteString_Initialize(&a_pSecureChannel->ClientCertificate); } if(a_pbsServerCertificate != OpcUa_Null && a_pbsServerCertificate->Length > 0) { a_pSecureChannel->ServerCertificate.Data = (OpcUa_Byte*)OpcUa_Alloc(a_pbsServerCertificate->Length); OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ServerCertificate.Data); a_pSecureChannel->ServerCertificate.Length = a_pbsServerCertificate->Length; OpcUa_MemCpy( a_pSecureChannel->ServerCertificate.Data, a_pSecureChannel->ServerCertificate.Length, a_pbsServerCertificate->Data, a_pbsServerCertificate->Length); } else { OpcUa_ByteString_Initialize(&a_pSecureChannel->ServerCertificate); } a_pSecureChannel->pCurrentReceivingKeyset = a_pReceivingKeyset; a_pSecureChannel->pCurrentSendingKeyset = a_pSendingKeyset; a_pSecureChannel->pCurrentCryptoProvider = a_pCryptoProvider; OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_SecurityKeyset_Clear(a_pReceivingKeyset); OpcUa_SecurityKeyset_Clear(a_pSendingKeyset); OpcUa_Free(a_pReceivingKeyset); OpcUa_Free(a_pSendingKeyset); OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel); OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_ProxyStub_UpdateConfigString *===========================================================================*/ static OpcUa_StatusCode OpcUa_ProxyStub_UpdateConfigString() { OpcUa_Int iRes = 0; OpcUa_Int iPos = 0; OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "UpdateConfigString"); #if OPCUA_USE_SYNCHRONISATION OPCUA_P_MUTEX_LOCK(OpcUa_ProxyStub_g_hGlobalsMutex); #endif /* OPCUA_USE_SYNCHRONISATION */ if(OpcUa_ProxyStub_g_pConfigString == OpcUa_Null) { OpcUa_ProxyStub_g_pConfigString = (OpcUa_StringA) OpcUa_Alloc(OPCUA_CONFIG_STRING_SIZE + 1); OpcUa_GotoErrorIfAllocFailed(OpcUa_ProxyStub_g_pConfigString); OpcUa_MemSet(OpcUa_ProxyStub_g_pConfigString, 0, OPCUA_CONFIG_STRING_SIZE + 1); } #if OPCUA_USE_SAFE_FUNCTIONS iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceEnabled", (OpcUa_ProxyStub_g_Configuration.bProxyStub_Trace_Enabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceLevel", OpcUa_ProxyStub_g_Configuration.uProxyStub_Trace_Level); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxAlloc", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxByteStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxArrayLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxMessageSize", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_Enabled", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_Enabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MinThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxJobs", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_BlockOnAdd", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_BlockOnAdd != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "uSecureListener_ThreadPool_Timeout", OpcUa_ProxyStub_g_Configuration.uSecureListener_ThreadPool_Timeout); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpListener_ClientThreadsEnabled", (OpcUa_ProxyStub_g_Configuration.bTcpListener_ClientThreadsEnabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpListener_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpConnection_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxMessageLength", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxChunkCount", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpStream_ExpectWriteToBlock", (OpcUa_ProxyStub_g_Configuration.bTcpStream_ExpectWriteToBlock != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} #else /* OPCUA_USE_SAFE_FUNCTIONS */ iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceEnabled", (OpcUa_ProxyStub_g_Configuration.bProxyStub_Trace_Enabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceLevel", OpcUa_ProxyStub_g_Configuration.uProxyStub_Trace_Level); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxAlloc", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxByteStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxArrayLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxMessageSize", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_Enabled", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_Enabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MinThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxJobs", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_BlockOnAdd", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_BlockOnAdd != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "uSecureListener_ThreadPool_Timeout", OpcUa_ProxyStub_g_Configuration.uSecureListener_ThreadPool_Timeout); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpListener_ClientThreadsEnabled", (OpcUa_ProxyStub_g_Configuration.bTcpListener_ClientThreadsEnabled != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpListener_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpConnection_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxMessageLength", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxChunkCount", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpStream_ExpectWriteToBlock", (OpcUa_ProxyStub_g_Configuration.bTcpStream_ExpectWriteToBlock != 0)?1:0); if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);} #endif /* OPCUA_USE_SAFE_FUNCTIONS */ #if OPCUA_USE_SYNCHRONISATION OPCUA_P_MUTEX_UNLOCK(OpcUa_ProxyStub_g_hGlobalsMutex); #endif /* OPCUA_USE_SYNCHRONISATION */ OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile( OpcUa_StringA a_privateKeyFile, OpcUa_P_FileFormat a_fileFormat, OpcUa_StringA a_password, /* optional: just needed encrypted PEM */ OpcUa_ByteString* a_pPrivateKey) { BIO* pPrivateKeyFile = OpcUa_Null; RSA* pRsaPrivateKey = OpcUa_Null; EVP_PKEY* pEvpKey = OpcUa_Null; unsigned char* pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_LoadPrivateKeyFromFile"); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_privateKeyFile); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); if(a_fileFormat == OpcUa_Crypto_Encoding_Invalid) { return OpcUa_BadInvalidArgument; } OpcUa_ReferenceParameter(a_password); /* open file */ pPrivateKeyFile = BIO_new_file((const char*)a_privateKeyFile, "rb"); OpcUa_ReturnErrorIfArgumentNull(pPrivateKeyFile); /* read and convert file */ switch(a_fileFormat) { case OpcUa_Crypto_Encoding_PEM: { /* read from file */ pEvpKey = PEM_read_bio_PrivateKey( pPrivateKeyFile, /* file */ NULL, /* key struct */ 0, /* password callback */ a_password); /* default passphrase or arbitrary handle */ OpcUa_GotoErrorIfNull(pEvpKey, OpcUa_Bad); break; } case OpcUa_Crypto_Encoding_PKCS12: { int iResult = 0; /* read from file. */ PKCS12* pPkcs12 = d2i_PKCS12_bio(pPrivateKeyFile, NULL); if (pPkcs12 == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* parse the certificate. */ iResult = PKCS12_parse(pPkcs12, a_password, &pEvpKey, NULL, NULL); if (iResult == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* free certificate. */ PKCS12_free(pPkcs12); pPkcs12 = NULL; break; } case OpcUa_Crypto_Encoding_DER: default: { uStatus = OpcUa_BadNotSupported; OpcUa_GotoError; } } /* convert to intermediary openssl struct */ pRsaPrivateKey = EVP_PKEY_get1_RSA(pEvpKey); EVP_PKEY_free(pEvpKey); OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad); /* get required length */ a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); /* allocate target buffer */ a_pPrivateKey->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pPrivateKey->Length); OpcUa_GotoErrorIfAllocFailed(a_pPrivateKey->Data); /* do real conversion */ pData = a_pPrivateKey->Data; a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, &pData); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); RSA_free(pRsaPrivateKey); BIO_free(pPrivateKeyFile); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pEvpKey) { EVP_PKEY_free(pEvpKey); } if(a_pPrivateKey != OpcUa_Null) { if(a_pPrivateKey->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pPrivateKey->Data); a_pPrivateKey->Data = OpcUa_Null; a_pPrivateKey->Length = -1; } } if(pPrivateKeyFile != NULL) { BIO_free(pPrivateKeyFile); } if(pRsaPrivateKey != NULL) { RSA_free(pRsaPrivateKey); } 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; }