예제 #1
0
/*============================================================================
 * 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;
}
예제 #2
0
/*============================================================================
 * 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;
}
예제 #3
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_GetSignature
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetSignature(
    OpcUa_CryptoProvider*       a_pProvider,
    OpcUa_ByteString*           a_pCertificate,
    OpcUa_Signature*            a_pSignature)
{
    X509*                   pX509Certificate    = OpcUa_Null;
    const unsigned char*    pTemp               = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetSignature");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificate);
    OpcUa_ReturnErrorIfArgumentNull(a_pSignature);

    /* d2i_X509 modifies the given pointer -> use local replacement */
    pTemp = a_pCertificate->Data;

    d2i_X509(&pX509Certificate, &pTemp, a_pCertificate->Length);

    if(pX509Certificate == OpcUa_Null)
    {
        uStatus = OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    a_pSignature->Signature.Length = pX509Certificate->signature->length;

    a_pSignature->Algorithm = OBJ_obj2nid(pX509Certificate->sig_alg->algorithm);

    if(a_pSignature->Algorithm == NID_undef)
    {
        uStatus = OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(a_pSignature->Signature.Data != OpcUa_Null)
    {
        uStatus = OpcUa_P_Memory_MemCpy(a_pSignature->Signature.Data,
                                        a_pSignature->Signature.Length,
                                        pX509Certificate->signature->data,
                                        pX509Certificate->signature->length);

    }

    X509_free(pX509Certificate);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pX509Certificate != OpcUa_Null)
    {
        X509_free(pX509Certificate);
    }

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_Random_Key_Generate
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_Random_Key_Generate(
    OpcUa_CryptoProvider* a_pProvider,
    OpcUa_Int32           a_keyLen,
    OpcUa_Key*            a_pKey)
{
    OpcUa_CryptoProviderConfig* pConfig = OpcUa_Null;
    OpcUa_Int32                 keyLen  = 0;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "Random_Key_Generate");

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pKey);

    OpcUa_ReferenceParameter(a_pProvider);

    keyLen = a_keyLen;

    if(keyLen < 0)
    {
        if(a_pProvider->Handle != OpcUa_Null)
        {
            /* get default configuration */
            pConfig = (OpcUa_CryptoProviderConfig*)a_pProvider->Handle;
            keyLen = pConfig->SymmetricKeyLength;
        }
        else
        {
            uStatus = OpcUa_BadInvalidArgument;
            OpcUa_GotoErrorIfBad(uStatus);
        }
    }
    else if(keyLen > MAX_GENERATED_OUTPUT_LEN)
    {
            uStatus = OpcUa_BadInvalidArgument;
            OpcUa_GotoErrorIfBad(uStatus);
    }

    a_pKey->Key.Length = keyLen;
    a_pKey->Type = OpcUa_Crypto_KeyType_Random;

    if(a_pKey->Key.Data == OpcUa_Null)
    {
        OpcUa_ReturnStatusCode;
    }

    if(RAND_bytes(a_pKey->Key.Data, a_pKey->Key.Length) == 0)
    {
        uStatus = OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;


OpcUa_FinishErrorHandling;
}
static
OpcUa_StatusCode OpcUa_UadpExtendedNetworkMessageHeader_WriteBinary(OpcUa_UadpNetworkMessage* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize)
{
    OpcUa_Int32 ii;

    OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpExtendedNetworkMessageHeader_WriteBinary")

    if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_Timestamp)
    {
        /* convert structure to UInt64 */
        OpcUa_UInt64 timeValue;
        timeValue = (OpcUa_UInt32)a_pValue->NetworkMessageHeader.Timestamp.dwHighDateTime;
        timeValue <<= 32;
        timeValue += (OpcUa_UInt32)a_pValue->NetworkMessageHeader.Timestamp.dwLowDateTime;
        OpcUa_UadpEncode_Direct(UInt64, &timeValue);
    }
    if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_PicoSeconds)
    {
        OpcUa_UadpEncode_Direct(UInt16, &a_pValue->NetworkMessageHeader.PicoSeconds);
    }
    if(a_pValue->NetworkMessageHeader.NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_PromotedFields)
    {
        OpcUa_Byte *pSizeBuffer;
        OpcUa_UInt16_Wire totalSize16_Wire;
        OpcUa_UInt16 totalSize16;

        if(*a_pSize < sizeof(OpcUa_UInt16_Wire))
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
        }

        pSizeBuffer = *a_pBuffer;
        *a_pBuffer += sizeof(OpcUa_UInt16_Wire);
        *a_pSize   -= sizeof(OpcUa_UInt16_Wire);

        for(ii = 0; ii < a_pValue->NetworkMessageHeader.NoOfPromotedFields; ii++)
        {
            if(a_pValue->NetworkMessageHeader.PromotedFields[ii] >= a_pValue->Payload[0].KeyOrEventMessage.NoOfDataSetFields)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
            }
            uStatus = OpcUa_UadpDataSetField_WriteBinary(a_pValue->Payload[0].KeyOrEventMessage.DataSetFields[a_pValue->NetworkMessageHeader.PromotedFields[ii]],
                                                         a_pValue->Payload[0].Header.FieldEncoding, a_pBuffer, a_pSize);
            OpcUa_GotoErrorIfBad(uStatus);
        }

        totalSize16 = (OpcUa_UInt16)(*a_pBuffer - pSizeBuffer) - sizeof(OpcUa_UInt16_Wire);
        uStatus = OpcUa_UInt16_P_NativeToWire(&totalSize16_Wire, &totalSize16);
        OpcUa_GotoErrorIfBad(uStatus);
        memcpy(pSizeBuffer, &totalSize16_Wire, sizeof(OpcUa_UInt16_Wire));
    }

    OpcUa_ReturnStatusCode;
    OpcUa_BeginErrorHandling;
    /* nothing to do */
    OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_RSA_GenerateKeys
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_GenerateKeys(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_UInt32            a_bits,
    OpcUa_Key*              a_pPublicKey,
    OpcUa_Key*              a_pPrivateKey)
{
    RSA*            pRsa;
    unsigned char*  pData;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_GenerateKeys");

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pPublicKey);
    OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey);

    OpcUa_ReferenceParameter(a_pProvider);

    /* Just 1024 or 2048 bits should be allowed for compatibility reasons */
    if ((a_bits != 1024) && (a_bits != 2048) && (a_bits != 3072) && (a_bits != 4096))
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(a_pPublicKey->Key.Data == OpcUa_Null)
    {
       a_pPublicKey->Key.Length = a_bits;
       OpcUa_ReturnStatusCode;
    }

    if(a_pPrivateKey->Key.Data == OpcUa_Null)
    {
       a_pPrivateKey->Key.Length = a_bits;
       OpcUa_ReturnStatusCode;
    }

    pRsa = RSA_generate_key(a_bits, RSA_F4, NULL, OpcUa_Null);

    pData = a_pPublicKey->Key.Data;
    a_pPublicKey->Key.Length = i2d_RSAPublicKey(pRsa, &pData);

    pData = a_pPrivateKey->Key.Data;
    a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(pRsa, &pData);

    /* clean up */
    if(pRsa != OpcUa_Null)
    {
       RSA_free(pRsa);
    }

    a_pPublicKey->Type = OpcUa_Crypto_Rsa_Alg_Id;
    a_pPrivateKey->Type = OpcUa_Crypto_Rsa_Alg_Id;

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

OpcUa_FinishErrorHandling;
}
예제 #7
0
/*============================================================================
 * 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;
}
예제 #8
0
/*============================================================================
 * Create
 *===========================================================================*/
OpcUa_StatusCode OpcUa_Thread_Create(   OpcUa_Thread*           a_pThread,
                                        OpcUa_PfnThreadMain*    a_pThreadMain,
                                        OpcUa_Void*             a_pThreadArgument)
{
    OpcUa_StatusCode        uStatus = OpcUa_Good;
    OpcUa_ThreadInternal*   pThread = OpcUa_Null;

    OpcUa_DeclareErrorTraceModule(OpcUa_Module_Thread);

    OpcUa_ReturnErrorIfArgumentNull(a_pThread);
    OpcUa_ReturnErrorIfArgumentNull(a_pThreadMain);

    pThread = (OpcUa_ThreadInternal*)OpcUa_Alloc(sizeof(OpcUa_ThreadInternal));

    OpcUa_ReturnErrorIfAllocFailed(pThread);

    OpcUa_MemSet(pThread, 0, sizeof(OpcUa_ThreadInternal));

    pThread->IsRunning      = OpcUa_False;
    pThread->ThreadMain     = a_pThreadMain;
    pThread->ThreadData     = a_pThreadArgument;
    pThread->Mutex          = OpcUa_Null;
    pThread->ShutdownEvent  = OpcUa_Null;

    uStatus = OpcUa_P_Thread_Create(&(pThread->RawThread));
    OpcUa_GotoErrorIfBad(uStatus);

    uStatus = OPCUA_P_SEMAPHORE_CREATE( &(pThread->ShutdownEvent),
                                        1,  /* the initial value is 1 (signalled, 1 free resource) */
                                        1); /* the maximum value is 1 */
    OpcUa_GotoErrorIfBad(uStatus);

    uStatus = OPCUA_P_MUTEX_CREATE(&(pThread->Mutex));
    OpcUa_GotoErrorIfBad(uStatus);

    *a_pThread = pThread;

    return OpcUa_Good;

Error:

    return uStatus;
}
예제 #9
0
/*============================================================================
 * 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;
}
예제 #10
0
/*============================================================================
 * 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;
}
예제 #11
0
/*============================================================================
 * 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;
}
예제 #12
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_Name_AddEntry
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_Name_AddEntry(
    X509_NAME**               a_ppX509Name,
    OpcUa_Crypto_NameEntry*   a_pNameEntry)
{
    X509_NAME_ENTRY*    pEntry  = OpcUa_Null;

    OpcUa_Int           nid;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_Name_AddEntry");

    OpcUa_ReturnErrorIfArgumentNull(a_pNameEntry);

    if((nid = OBJ_txt2nid(a_pNameEntry->key)) == NID_undef)
    {
        uStatus =  OpcUa_BadNotSupported;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(!(pEntry = X509_NAME_ENTRY_create_by_NID(OpcUa_Null, nid, MBSTRING_ASC, (unsigned char*)a_pNameEntry->value, -1)))
    {
        uStatus =  OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(X509_NAME_add_entry(*a_ppX509Name, pEntry,-1,0) != 1)
    {
        uStatus =  OpcUa_Bad;
    }

    if(pEntry != OpcUa_Null)
    {
        X509_NAME_ENTRY_free(pEntry);
    }

OpcUa_ReturnStatusCode;

OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
예제 #13
0
/*============================================================================
 * 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;
}
예제 #14
0
/*============================================================================
 * Start a created thread.
 *===========================================================================*/
OpcUa_StatusCode OpcUa_Thread_Start(OpcUa_Thread a_Thread)
{
    OpcUa_StatusCode        uStatus     = OpcUa_Good;
    OpcUa_ThreadInternal*   pThread     = OpcUa_Null;
    OpcUa_Int32             intThreadId = 0;

    OpcUa_ReturnErrorIfArgumentNull(a_Thread);

    pThread = (OpcUa_ThreadInternal*)a_Thread;

    OPCUA_P_MUTEX_LOCK(pThread->Mutex);
    if(pThread->IsRunning != OpcUa_False)
    {
        OPCUA_P_MUTEX_UNLOCK(pThread->Mutex);
        return OpcUa_Good;
    }

    /* set semaphore to waitable */
    uStatus = OPCUA_P_SEMAPHORE_WAIT((pThread->ShutdownEvent));
    OpcUa_GotoErrorIfBad(uStatus);

    pThread->IsRunning = OpcUa_True;

    intThreadId = OpcUa_P_Thread_Start( pThread->RawThread,
                                        InternalThreadMain,
                                        (OpcUa_Void*)pThread);

    if(intThreadId != 0)
    {
        pThread->IsRunning = OpcUa_False;

        OPCUA_P_MUTEX_UNLOCK(pThread->Mutex);
        uStatus = OpcUa_BadInternalError;
        OpcUa_Trace(OPCUA_TRACE_LEVEL_ERROR, "OpcUa_Thread_Start: Error during thread creation!\n");
        goto Error;
    }
    OPCUA_P_MUTEX_UNLOCK(pThread->Mutex);

    return OpcUa_Good;

Error:

    return uStatus;
}
예제 #15
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_GetCertificateThumbprint
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetCertificateThumbprint(
    OpcUa_CryptoProvider*       a_pProvider,
    OpcUa_ByteString*           a_pCertificate,
    OpcUa_ByteString*           a_pCertificateThumbprint)
{
    X509*                   pX509Certificate    = OpcUa_Null;
    const unsigned char*    pTemp               = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetCertificateThumbprint");

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificate);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificate->Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificateThumbprint);

    /* SHA-1 produces 20 bytes */
    a_pCertificateThumbprint->Length = sizeof(pX509Certificate->sha1_hash);

    if(a_pCertificateThumbprint->Data == OpcUa_Null)
    {
        OpcUa_ReturnStatusCode;
    }

    /* d2i_X509 modifies the given pointer -> use local replacement */
    pTemp = a_pCertificate->Data;

    d2i_X509(&pX509Certificate, &pTemp, a_pCertificate->Length);

    if(pX509Certificate == OpcUa_Null)
    {
        uStatus = OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    /* update pX509Certificate->sha1_hash */
    X509_check_purpose(pX509Certificate, -1, 0);
    uStatus = OpcUa_P_Memory_MemCpy(a_pCertificateThumbprint->Data, a_pCertificateThumbprint->Length,
                                    pX509Certificate->sha1_hash, sizeof(pX509Certificate->sha1_hash));
    X509_free(pX509Certificate);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/**
* @brief Builds a connection record for the given parameters and returns it.
*
* @return: Status Code;
*/
OpcUa_StatusCode OpcUa_TcpListener_ConnectionManager_AddConnection(
    OpcUa_TcpListener_ConnectionManager*    a_pConnectionManager,
    OpcUa_TcpListener_Connection*           a_pConnection)
{
    OpcUa_StatusCode    uStatus = OpcUa_Good;

    OpcUa_GotoErrorIfArgumentNull(a_pConnection);
    OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager);
    OpcUa_GotoErrorIfArgumentNull(a_pConnectionManager->Connections);

    a_pConnection->ConnectTime = OPCUA_P_DATETIME_UTCNOW(); /* expiration of connection would be DisconnectTime+Lifetime */

    OpcUa_List_Enter(a_pConnectionManager->Connections);
    uStatus = OpcUa_List_AddElement(a_pConnectionManager->Connections, a_pConnection);
    OpcUa_List_Leave(a_pConnectionManager->Connections);
    OpcUa_GotoErrorIfBad(uStatus);
    OpcUa_Trace(OPCUA_TRACE_LEVEL_DEBUG, "OpcUa_TcpListener_ConnectionManager_AddConnection: Connection added!\n");

    return OpcUa_Good;

Error:
    return uStatus;
}
예제 #17
0
/*============================================================================
 * Create a server socket
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_CreateServer(  OpcUa_SocketManager         a_pSocketManager,
                                                                    OpcUa_StringA               a_sAddress,
                                                                    OpcUa_Boolean               a_bListenOnAllInterfaces,
                                                                    OpcUa_Socket_EventCallback  a_pfnSocketCallBack,
                                                                    OpcUa_Void*                 a_pCallbackData,
                                                                    OpcUa_Socket*               a_pSocket)
{
    OpcUa_InternalSocketManager*    pInternalSocketManager  = OpcUa_Null;
    OpcUa_UInt16                    uPort                   = 0;
    OpcUa_StringA                   sRemoteAdress           = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateServer");

#if !OPCUA_MULTITHREADED
    if(a_pSocketManager == OpcUa_Null)
    {
        a_pSocketManager = OpcUa_Socket_g_SocketManager;
    }
#endif

    OpcUa_ReturnErrorIfArgumentNull(a_pSocketManager);
    OpcUa_ReturnErrorIfArgumentNull(a_pSocket);

    pInternalSocketManager = (OpcUa_InternalSocketManager*)a_pSocketManager;

    /* parse address */
    uStatus = OpcUa_P_ParseUrl( a_sAddress,
                                &sRemoteAdress,
                                &uPort);

    OpcUa_ReturnErrorIfBad(uStatus);
    if(a_bListenOnAllInterfaces)
    {
        if(sRemoteAdress != OpcUa_Null)
        {
            OpcUa_P_Memory_Free(sRemoteAdress);
            sRemoteAdress = OpcUa_Null;
        }
    }

    uStatus = OpcUa_SocketManager_InternalCreateServer( pInternalSocketManager,
                                                        sRemoteAdress,
                                                        uPort,
                                                        a_pfnSocketCallBack,
                                                        a_pCallbackData,
                                                        a_pSocket);
    OpcUa_GotoErrorIfBad(uStatus);


    OpcUa_P_SocketManager_InterruptLoop(pInternalSocketManager,
                                        OPCUA_SOCKET_RENEWLOOP_EVENT,
                                        OpcUa_False);

    if(sRemoteAdress != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(sRemoteAdress);
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(sRemoteAdress != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(sRemoteAdress);
    }

OpcUa_FinishErrorHandling;
}
예제 #18
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_GetPrivateKey
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetPrivateKey(
    OpcUa_CryptoProvider*       a_pProvider,
    OpcUa_StringA               a_certificateFileName,
    OpcUa_StringA               a_password,             /* this is optional */
    OpcUa_Key*                  a_pPrivateKey)
{
    BIO*            pCertFile       = OpcUa_Null;
    PKCS12*         pPKCS12Cert     = OpcUa_Null;
    EVP_PKEY*       pPrivateKey     = OpcUa_Null;
    RSA*            pRsaPrivateKey  = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetPrivateKey");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_certificateFileName);
    OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey);

    /* import certificate from file by the given encoding type */
    pCertFile = BIO_new_file((const char*)a_certificateFileName, "r");
    OpcUa_ReturnErrorIfArgumentNull(pCertFile);

    /* convert certificate file handle to PKCS12 structure */
    d2i_PKCS12_bio(pCertFile, &pPKCS12Cert);

    /* close certificat file handle */
    BIO_free(pCertFile);

    if(pPKCS12Cert != OpcUa_Null)
    {
        /* get the private key from the PKCS12 structure*/
        PKCS12_parse(pPKCS12Cert, a_password, &pPrivateKey, OpcUa_Null, OpcUa_Null);
    }
    else
    {
        uStatus = OpcUa_Bad;
        OpcUa_ReturnStatusCode;
    }

    if(pPKCS12Cert != OpcUa_Null)
    {
        PKCS12_free(pPKCS12Cert);
        pPKCS12Cert = OpcUa_Null;
    }

    switch(EVP_PKEY_type(pPrivateKey->type))
    {
    case EVP_PKEY_RSA:
        {
            /* convert to intermediary openssl struct */
            pRsaPrivateKey = EVP_PKEY_get1_RSA(pPrivateKey);
            EVP_PKEY_free(pPrivateKey);
            OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad);

            /* get required length */
            a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null);
            OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad);

            if(a_pPrivateKey->Key.Data == OpcUa_Null)
            {
                OpcUa_ReturnStatusCode;
            }

            /* do real conversion */
            a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(  pRsaPrivateKey,
                                                            &a_pPrivateKey->Key.Data);
            OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad);

            if(pRsaPrivateKey != OpcUa_Null)
            {
                RSA_free(pRsaPrivateKey);
                pRsaPrivateKey = OpcUa_Null;
            }

            /* correct buffer pointer */
            a_pPrivateKey->Key.Data -= a_pPrivateKey->Key.Length;

            a_pPrivateKey->Type = OpcUa_Crypto_KeyType_Rsa_Private;

            break;
        }
    case EVP_PKEY_EC:
    case EVP_PKEY_DSA:
    case EVP_PKEY_DH:
    default:
        {
            uStatus =  OpcUa_BadNotSupported;
            OpcUa_GotoErrorIfBad(uStatus);
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pRsaPrivateKey != OpcUa_Null)
    {
        RSA_free(pRsaPrivateKey);
    }

    if(pPrivateKey != OpcUa_Null)
    {
        EVP_PKEY_free(pPrivateKey);
    }

OpcUa_FinishErrorHandling;
}
예제 #19
0
/*===========================================================================*
OpcUa_P_OpenSSL_RSA_Public_Encrypt
*===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_Encrypt(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Byte*             a_pPlainText,
    OpcUa_UInt32            a_plainTextLen,
    OpcUa_Key*              a_publicKey,
    OpcUa_Int16             a_padding,
    OpcUa_Byte*             a_pCipherText,
    OpcUa_UInt32*           a_pCipherTextLen)
{
    EVP_PKEY*       pPublicKey      = OpcUa_Null;

    OpcUa_UInt32    uKeySize            = 0;
    OpcUa_UInt32    uEncryptedDataSize  = 0;
    OpcUa_UInt32    uPlainTextPosition  = 0;
    OpcUa_UInt32    uCipherTextPosition = 0;
    OpcUa_UInt32    uBytesToEncrypt     = 0;
    OpcUa_Int32     iEncryptedBytes     = 0;
    const unsigned char *pData;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Encrypt");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_publicKey);
    OpcUa_ReturnErrorIfArgumentNull(a_publicKey->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pCipherTextLen);

    *a_pCipherTextLen = 0;

    if((OpcUa_Int32)a_plainTextLen < 1)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(a_publicKey->Type != OpcUa_Crypto_KeyType_Rsa_Public)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pData = a_publicKey->Key.Data;
    pPublicKey = d2i_PublicKey(EVP_PKEY_RSA, OpcUa_Null, &pData, a_publicKey->Key.Length);

    if ( pPublicKey != OpcUa_Null )
    {
        uKeySize = RSA_size(pPublicKey->pkey.rsa);
    }
    else
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    /* check padding type */
    switch(a_padding)
    {
    case RSA_PKCS1_PADDING:
        {
            uEncryptedDataSize = uKeySize - 11;
            break;
        }
    case RSA_PKCS1_OAEP_PADDING:
        {
            uEncryptedDataSize = uKeySize - 42;
            break;
        }
    case RSA_NO_PADDING:
        {
            uEncryptedDataSize = uKeySize;
            break;
        }
    default:
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadNotSupported);
        }
    }

    if(a_plainTextLen < uEncryptedDataSize)
    {
        uBytesToEncrypt = a_plainTextLen;
    }
    else
    {
        uBytesToEncrypt = uEncryptedDataSize;
    }

    while(uPlainTextPosition < a_plainTextLen)
    {

        /* the last part could be smaller */
        if((a_plainTextLen >= uEncryptedDataSize) && ((a_plainTextLen - uPlainTextPosition) < uEncryptedDataSize))
        {
            uBytesToEncrypt = a_plainTextLen - uPlainTextPosition;
        }

        if((a_pCipherText != OpcUa_Null) && (a_pPlainText != OpcUa_Null))
        {
            iEncryptedBytes = RSA_public_encrypt(   uBytesToEncrypt,      /* how much to encrypt  */
                                                    a_pPlainText + uPlainTextPosition,      /* what to encrypt      */
                                                    a_pCipherText + uCipherTextPosition,/* where to encrypt     */
                                                    pPublicKey->pkey.rsa,                  /* public key           */
                                                    a_padding);        /* padding mode         */
            if(iEncryptedBytes < 0)
            {
                const char*     sError          = OpcUa_Null;
                unsigned long   error           = 0;

                error = ERR_get_error();

                ERR_load_crypto_strings();

                sError = ERR_reason_error_string(error);
                sError = ERR_func_error_string(error);
                sError = ERR_lib_error_string(error);

                uStatus = OpcUa_Bad;
                OpcUa_GotoError;
            }

        }
        else
        {
            iEncryptedBytes = uKeySize;
        }

        *a_pCipherTextLen = *a_pCipherTextLen + iEncryptedBytes;
        uCipherTextPosition += uKeySize;
        uPlainTextPosition  += uBytesToEncrypt;
    }

    EVP_PKEY_free(pPublicKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pPublicKey != OpcUa_Null)
    {
        EVP_PKEY_free(pPublicKey);
    }

    *a_pCipherTextLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
예제 #20
0
/*============================================================================
 * OpcUa_ProxyStub_Initialize
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_ProxyStub_Initialize(OpcUa_Handle                  a_pPlatformLayerCalltable,
                                                          OpcUa_ProxyStubConfiguration* a_pProxyStubConfiguration)
{
    OpcUa_Boolean bSkip = OpcUa_False;

OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "Initialize");

    OpcUa_ReturnErrorIfArgumentNull(a_pProxyStubConfiguration)
    OpcUa_ReturnErrorIfArgumentNull(a_pPlatformLayerCalltable);

    /* set global platform layer handle */
    OpcUa_ProxyStub_g_PlatformLayerCalltable = (OpcUa_Port_CallTable *)a_pPlatformLayerCalltable;

#if OPCUA_USE_SYNCHRONISATION
    if(OpcUa_ProxyStub_g_hGlobalsMutex == OpcUa_Null)
    {
        uStatus = OPCUA_P_MUTEX_CREATE(&OpcUa_ProxyStub_g_hGlobalsMutex);
        OpcUa_GotoErrorIfBad(uStatus);
    }
#endif /* OPCUA_USE_SYNCHRONISATION */

#if OPCUA_USE_SYNCHRONISATION
    OPCUA_P_MUTEX_LOCK(OpcUa_ProxyStub_g_hGlobalsMutex);
#endif /* OPCUA_USE_SYNCHRONISATION */

    OpcUa_ProxyStub_g_uNoOfInits++;

    if(OpcUa_ProxyStub_g_uNoOfInits > 1)
    {
        bSkip = OpcUa_True;
    }

#if OPCUA_USE_SYNCHRONISATION
    OPCUA_P_MUTEX_UNLOCK(OpcUa_ProxyStub_g_hGlobalsMutex);
#endif /* OPCUA_USE_SYNCHRONISATION */

    if(bSkip == OpcUa_False)
    {
        /* set global configuration object */
        uStatus = OpcUa_ProxyStub_ReInitialize(a_pProxyStubConfiguration);
        OpcUa_GotoErrorIfBad(uStatus);

        /* initialize tracer */
#if OPCUA_TRACE_ENABLE
        uStatus = OpcUa_Trace_Initialize();
        OpcUa_GotoErrorIfBad(uStatus);
        OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Tracer has been initialized!\n");
#endif /* OPCUA_TRACE_ENABLE */

        /* initialize networking. */
        OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Network Module...\n");
        uStatus = OPCUA_P_INITIALIZENETWORK();
        OpcUa_GotoErrorIfBad(uStatus);
        OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_ProxyStub_Initialize: Network Module done!\n");

        uStatus = OpcUa_EncodeableTypeTable_Create(&OpcUa_ProxyStub_g_EncodeableTypes);
        OpcUa_GotoErrorIfBad(uStatus);

        uStatus = OpcUa_EncodeableTypeTable_AddTypes(&OpcUa_ProxyStub_g_EncodeableTypes, OpcUa_KnownEncodeableTypes);
        OpcUa_GotoErrorIfBad(uStatus);

        OpcUa_StringTable_Initialize(&OpcUa_ProxyStub_g_NamespaceUris);
        uStatus = OpcUa_StringTable_AddStringList(&OpcUa_ProxyStub_g_NamespaceUris, OpcUa_ProxyStub_StandardNamespaceUris);
        OpcUa_GotoErrorIfBad(uStatus);
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    OpcUa_ProxyStub_Clear();

OpcUa_FinishErrorHandling;
}
예제 #21
0
OpcUa_StatusCode  fill_Variant_for_value_attribute(_VariableKnoten_*  p_Node, OpcUa_String* p_Index, OpcUa_DataValue* p_Results)
{
	OpcUa_Int					i;
	OpcUa_StatusCode			uStatus     = OpcUa_Good;
	extern my_Variant			all_ValueAttribute_of_VariableTypeNodes_VariableNodes[];

	OpcUa_ReturnErrorIfArgumentNull(p_Node);
	/*OpcUa_ReturnErrorIfArgumentNull(p_Index);*/
	OpcUa_ReturnErrorIfArgumentNull(p_Results);
	if(p_Node->ValueIndex == (-1))
	{
		OpcUa_GotoErrorWithStatus(OpcUa_BadNotReadable)
	}
	
	if(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].ArrayType==OpcUa_VariantArrayType_Scalar)
	{
		switch(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Datatype)
		{
		case OpcUaId_Double:
			{
				p_Results->Value.Value.Double=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Double;
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Double, OpcUa_VariantArrayType_Scalar,0);
				break;
			}
		case OpcUaId_DateTime:
			{
				p_Results->Value.Value.DateTime=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.DateTime;
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_DateTime, OpcUa_VariantArrayType_Scalar,0);
				break;
			}
		case OpcUaId_String:
			{
				uStatus= OpcUa_String_AttachCopy(&(p_Results->Value.Value.String),all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.String);
				OpcUa_GotoErrorIfBad(uStatus)
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_String, OpcUa_VariantArrayType_Scalar,0);
				break;
			}
		case OpcUaId_UInt32:
			{
				p_Results->Value.Value.UInt32=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.UInt32;
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Scalar,0);
				break;
			}
		case OpcUaId_Boolean:
			{
				p_Results->Value.Value.Boolean=all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Boolean;
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Boolean, OpcUa_VariantArrayType_Scalar,0);
				break;
			}
		}
	
	}

	if(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].ArrayType==OpcUa_VariantArrayType_Array)
	{
		switch(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Datatype)
		{
		case OpcUaId_Double:
			{
				p_Results->Value.Value.Array.Value.DoubleArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double));
				OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.DoubleArray))
				
				OpcUa_MemCpy((p_Results->Value.Value.Array.Value.DoubleArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.DoubleArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Double));
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_Double, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);
				break;
			}
		case OpcUaId_String:
			{
				p_Results->Value.Value.Array.Value.StringArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_String));
				OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.DoubleArray))

				for(i=0;i<(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);i++)
				{
					uStatus= OpcUa_String_AttachCopy((p_Results->Value.Value.Array.Value.StringArray)+i,*(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.StringArray+i));
					if(OpcUa_IsBad(uStatus))
						OpcUa_GotoError
				}
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_String, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);
				break;
			}
		case OpcUaId_UInt32:
			{
				p_Results->Value.Value.Array.Value.UInt32Array=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32));
				OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.UInt32Array))

				OpcUa_MemCpy((p_Results->Value.Value.Array.Value.UInt32Array),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.UInt32Array),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_UInt32));
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);
				break;
			}
		case OpcUaId_Boolean:
			{
				p_Results->Value.Value.Array.Value.BooleanArray=OpcUa_Memory_Alloc((all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean));
				OpcUa_GotoErrorIfAllocFailed((p_Results->Value.Value.Array.Value.BooleanArray))

				OpcUa_MemCpy((p_Results->Value.Value.Array.Value.BooleanArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Value.BooleanArray),(all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length)*sizeof(OpcUa_Boolean));
				fill_datatype_arraytype_in_my_Variant(p_Results,OpcUaId_UInt32, OpcUa_VariantArrayType_Array,all_ValueAttribute_of_VariableTypeNodes_VariableNodes[p_Node->ValueIndex].Value.Array.Length);
				break;
			}
		}
	}
	
	OpcUa_ReturnStatusCode;
    OpcUa_BeginErrorHandling;
	
	p_Results->StatusCode=uStatus;
	OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_Random_Key_PSHA256_Derive
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_Random_Key_PSHA256_Derive(
    OpcUa_CryptoProvider* a_pProvider,
    OpcUa_ByteString      a_secret, /* clientnonce | servernonce, servernonce | clientnonce */
    OpcUa_ByteString      a_seed,
    OpcUa_Int32           a_keyLen, /* output len */
    OpcUa_Key*            a_pKey)
{
    OpcUa_P_OpenSSL_PSHA256_Ctx*pCtx            = OpcUa_Null;
    OpcUa_Byte*                 pBuffer         = OpcUa_Null;

    OpcUa_Int                   bufferlength;
    OpcUa_Int                   i;
    OpcUa_Int                   iterations;

    OpcUa_CryptoProviderConfig* pConfig         = OpcUa_Null;
    OpcUa_Int32                 keyLen          = 0;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "Random_Key_PSHA256_Derive");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_secret.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_seed.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pKey);

    keyLen = a_keyLen;

    if(keyLen < 0)
    {
        if(a_pProvider->Handle != OpcUa_Null)
        {
            /* get default configuration */
            pConfig = (OpcUa_CryptoProviderConfig*)a_pProvider->Handle;
            keyLen = pConfig->SymmetricKeyLength;
        }
        else
        {
            uStatus = OpcUa_BadInvalidArgument;
            OpcUa_GotoErrorIfBad(uStatus);
        }
    }
    else if(keyLen > MAX_DERIVED_OUTPUT_LEN)
    {
            uStatus = OpcUa_BadInvalidArgument;
            OpcUa_GotoErrorIfBad(uStatus);
    }

    if(a_pKey->Key.Data == OpcUa_Null)
    {
        a_pKey->Key.Length = keyLen;
        OpcUa_ReturnStatusCode;
    }

    a_pKey->Type = OpcUa_Crypto_KeyType_Random;

    /** start creating key **/

    pCtx = (OpcUa_P_OpenSSL_PSHA256_Ctx*)OpcUa_Null;

    iterations = keyLen/32 + (keyLen%32?1:0);
    bufferlength = iterations*32;

    pBuffer = (OpcUa_Byte *)OpcUa_P_Memory_Alloc(bufferlength * sizeof(OpcUa_Byte));

    pCtx = OpcUa_P_OpenSSL_PSHA256_Context_Create(a_secret.Data, a_secret.Length, a_seed.Data, a_seed.Length);

    for(i=0; i<iterations; i++)
    {
        /* SHA256 produces 32 Bytes of output for every iteration */
        uStatus = OpcUa_P_OpenSSL_PSHA256_Hash_Generate(pCtx, pBuffer + (i*32));
        OpcUa_GotoErrorIfBad(uStatus);
    }

    OpcUa_P_Memory_MemCpy(a_pKey->Key.Data, a_pKey->Key.Length, pBuffer, keyLen);

    if(pCtx != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(pCtx);
        pCtx = OpcUa_Null;
    }

    if(pBuffer != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(pBuffer);
        pBuffer = OpcUa_Null;
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pCtx != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(pCtx);
        pCtx = OpcUa_Null;
    }

    if(pBuffer != OpcUa_Null)
    {
        OpcUa_P_Memory_Free(pBuffer);
        pBuffer = OpcUa_Null;
    }

OpcUa_FinishErrorHandling;
}
예제 #23
0
/*============================================================================
 * 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;
}
예제 #24
0
/**
  @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;
}
예제 #25
0
/*============================================================================
 * 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;
}
예제 #26
0
/*
    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;
}
예제 #27
0
/*
    ToDo:   Create Access to OpenSSL certificate store
            => Only API to In-Memory-Store is available for version 0.9.8x
            => Wait until Directory- and/or File-Store is available
*/
OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_SaveCertificate(
    OpcUa_PKIProvider*          a_pProvider,
    OpcUa_ByteString*           a_pCertificate,
    OpcUa_Void*                 a_pCertificateStore,
    OpcUa_Void*                 a_pSaveHandle)      /* Index or number within store/destination filepath */
{
    X509*                                       pX509Certificate        = OpcUa_Null;
    FILE*                                       pCertificateFile        = OpcUa_Null;

    const unsigned char*                        p;

    OpcUa_UInt32                                i;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_SaveCertificate");


    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificate);
    OpcUa_ReturnErrorIfArgumentNull(a_pCertificateStore);
    OpcUa_ReturnErrorIfArgumentNull(a_pSaveHandle);

    /* save DER certificate */
    pCertificateFile = fopen((const char*)a_pSaveHandle, "w");

    /* check for valid file handle */
    OpcUa_GotoErrorIfTrue((pCertificateFile == OpcUa_Null), OpcUa_BadInvalidArgument);

    /* convert openssl X509 certificate to DER encoded bytestring certificate */
    p = a_pCertificate->Data;
    while (p < a_pCertificate->Data + a_pCertificate->Length)
    {
        if(!(pX509Certificate = d2i_X509((X509**)OpcUa_Null, &p, a_pCertificate->Data + a_pCertificate->Length - p)))
        {
            fclose(pCertificateFile);
            uStatus = OpcUa_Bad;
            OpcUa_GotoErrorIfBad(uStatus);
        }

        i = i2d_X509_fp(pCertificateFile, pX509Certificate);

        if(i < 1)
        {
            fclose(pCertificateFile);
            uStatus =  OpcUa_Bad;
            OpcUa_GotoErrorIfBad(uStatus);
        }

        X509_free(pX509Certificate);
        pX509Certificate = OpcUa_Null;
    }

    if(fclose(pCertificateFile) != 0)
    {
        uStatus =  OpcUa_Bad;
        OpcUa_GotoErrorIfBad(uStatus);
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if (pX509Certificate != OpcUa_Null)
    {
        X509_free(pX509Certificate);
    }

OpcUa_FinishErrorHandling;
}
예제 #28
0
/*============================================================================
 * 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;
}
예제 #29
0
/*============================================================================
 * OpcUa_P_OpenSSL_CertificateStore_Open
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_PKI_OpenCertificateStore(
    OpcUa_PKIProvider*          a_pProvider,
    OpcUa_Void**                a_ppCertificateStore)           /* type depends on store implementation */
{
    OpcUa_P_OpenSSL_CertificateStore_Config*    pCertificateStoreCfg;
    X509_STORE*         pStore;
    X509_LOOKUP*        pLookup;
    char                CertFile[MAX_PATH];
    struct dirent **dirlist = NULL;
    int numCertificates = 0, i;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "PKI_OpenCertificateStore");

    OpcUa_ReturnErrorIfArgumentNull(a_pProvider);
    OpcUa_ReturnErrorIfArgumentNull(a_pProvider->Handle);
    OpcUa_ReturnErrorIfArgumentNull(a_ppCertificateStore);

    *a_ppCertificateStore = OpcUa_Null;

    pCertificateStoreCfg = (OpcUa_P_OpenSSL_CertificateStore_Config*)a_pProvider->Handle;

    if(!(*a_ppCertificateStore = pStore = X509_STORE_new()))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    X509_STORE_set_verify_cb_func(pStore, OpcUa_P_OpenSSL_CertificateStore_Verify_Callback);

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_USE_DEFAULT_CERT_CRL_LOOKUP_METHOD)
    {
        if(X509_STORE_set_default_paths(pStore) != 1)
        {
            OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_STORE_set_default_paths!\n");
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }
    }

    if(!(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_DONT_ADD_TRUST_LIST_TO_ROOT_CERTIFICATES))
    {
        if(pCertificateStoreCfg->CertificateTrustListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateTrustListLocation[0] == '\0')
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }

        /* how to search for certificate & CRLs */
        if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file())))
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }

        /* how to search for certificate & CRLs */
        numCertificates = scandir(pCertificateStoreCfg->CertificateTrustListLocation, &dirlist, certificate_filter_der, alphasort);
        for (i=0; i<numCertificates; i++)
        {
            uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateTrustListLocation, dirlist[i]->d_name, MAX_PATH, CertFile);
            OpcUa_GotoErrorIfBad(uStatus);

            /* add CACertificate lookup */
            if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/
            {
                OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile);
            }
        }
        for (i=0; i<numCertificates; i++)
        {
            free(dirlist[i]);
        }
        free(dirlist);
        dirlist = NULL;
    }

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ADD_UNTRUSTED_LIST_TO_ROOT_CERTIFICATES)
    {
        if(pCertificateStoreCfg->CertificateUntrustedListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateUntrustedListLocation[0] == '\0')
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }

        if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_UNTRUSTED_LIST_IS_INDEX)
        {
            /* how to search for certificate */
            if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir())))
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }

            /* add hash lookup */
            if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateUntrustedListLocation, X509_FILETYPE_ASN1) != 1) /*DER encoded*/
            {
                OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n");
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }
        }
        else
        {
            /* how to search for certificate & CRLs */
            if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file())))
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }

            numCertificates = scandir(pCertificateStoreCfg->CertificateUntrustedListLocation, &dirlist, certificate_filter_der, alphasort);
            for (i=0; i<numCertificates; i++)
            {
                uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateUntrustedListLocation, dirlist[i]->d_name, MAX_PATH, CertFile);
                OpcUa_GotoErrorIfBad(uStatus);

                /* add CACertificate lookup */
                if(X509_LOOKUP_load_file(pLookup, CertFile, X509_FILETYPE_ASN1) != 1) /*DER encoded*/
                {
                    OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_load_file: skipping %s\n", CertFile);
                }
            }
            for (i=0; i<numCertificates; i++)
            {
                free(dirlist[i]);
            }
            free(dirlist);
            dirlist = NULL;
        }
    }

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL)
    {
        if(pCertificateStoreCfg->CertificateRevocationListLocation == OpcUa_Null || pCertificateStoreCfg->CertificateRevocationListLocation[0] == '\0')
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }

        if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_INDEX)
        {
            /* how to search for certificate & CRLs */
            if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir())))
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }

            /* add CRL lookup */
            if(X509_LOOKUP_add_dir(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/
            {
                OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_LOOKUP_add_dir!\n");
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }
        }
        else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_REVOCATION_LIST_IS_CONCATENATED_PEM_FILE)
        {
            /* how to search for certificate & CRLs */
            if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file())))
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }

            /* add CRL lookup */
            if(X509_load_crl_file(pLookup, pCertificateStoreCfg->CertificateRevocationListLocation, X509_FILETYPE_PEM) != 1) /*PEM encoded*/
            {
                OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file!\n");
            }
        }
        else
        {
            /* how to search for certificate & CRLs */
            if(!(pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file())))
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }

            numCertificates = scandir(pCertificateStoreCfg->CertificateRevocationListLocation, &dirlist, certificate_filter_crl, alphasort);
            for (i=0; i<numCertificates; i++)
            {
                uStatus = OpcUa_P_OpenSSL_BuildFullPath(pCertificateStoreCfg->CertificateRevocationListLocation, dirlist[i]->d_name, MAX_PATH, CertFile);
                OpcUa_GotoErrorIfBad(uStatus);

                if(X509_load_crl_file(pLookup, CertFile, X509_FILETYPE_PEM) != 1) /*PEM encoded*/
                {
                    OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "error at X509_load_crl_file: skipping %s\n", CertFile);
                }
            }
            for (i=0; i<numCertificates; i++)
            {
                free(dirlist[i]);
            }
            free(dirlist);
            dirlist = NULL;
        }

        if((pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL) == OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ALL)
        {
            /* set the flags of the store so that CRLs are consulted */
            if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) != 1)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }
        }
        else if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_REVOCATION_ONLY_LEAF)
        {
            /* set the flags of the store so that CRLs are consulted */
            if(X509_STORE_set_flags(pStore, X509_V_FLAG_CRL_CHECK) != 1)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_Bad);
            }
        }
    }

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_CHECK_SELF_SIGNED_SIGNATURE)
    {
        /* set the flags of the store so that CRLs are consulted */
        if(X509_STORE_set_flags(pStore, X509_V_FLAG_CHECK_SS_SIGNATURE) != 1)
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }
    }

    if(pCertificateStoreCfg->Flags & OPCUA_P_PKI_OPENSSL_ALLOW_PROXY_CERTIFICATES)
    {
        /* set the flags of the store so that CRLs are consulted */
        if(X509_STORE_set_flags(pStore, X509_V_FLAG_ALLOW_PROXY_CERTS) != 1)
        {
            OpcUa_GotoErrorWithStatus(OpcUa_Bad);
        }
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(dirlist != NULL)
    {
        for (i=0; i<numCertificates; i++)
        {
            free(dirlist[i]);
        }
        free(dirlist);
    }

    if(*a_ppCertificateStore != OpcUa_Null)
    {
        X509_STORE_free((X509_STORE*)*a_ppCertificateStore);
        *a_ppCertificateStore = OpcUa_Null;
    }

OpcUa_FinishErrorHandling;
}
예제 #30
0
/*============================================================================
 * Create a client socket
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketManager_CreateClient(  OpcUa_SocketManager         a_hSocketManager,
                                                                    OpcUa_StringA               a_sRemoteAddress,
                                                                    OpcUa_UInt16                a_uLocalPort,
                                                                    OpcUa_Socket_EventCallback  a_pfnSocketCallBack,
                                                                    OpcUa_Void*                 a_pCallbackData,
                                                                    OpcUa_Socket*               a_pSocket)
{
    OpcUa_InternalSocket*        pNewClientSocket       = OpcUa_Null;
    OpcUa_InternalSocketManager* pInternalSocketManager = OpcUa_Null;
    OpcUa_UInt16                 uPort                  = 0;
    OpcUa_StringA                sRemoteAdress          = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateClient");

#if !OPCUA_MULTITHREADED
    if(a_hSocketManager == OpcUa_Null)
    {
        a_hSocketManager = OpcUa_Socket_g_SocketManager;
    }
#endif

    OpcUa_ReturnErrorIfArgumentNull(a_hSocketManager);
    OpcUa_ReturnErrorIfArgumentNull(a_pSocket);
    OpcUa_ReturnErrorIfArgumentNull(a_sRemoteAddress);

    /* parse address */
    uStatus = OpcUa_P_ParseUrl( a_sRemoteAddress,
                                &sRemoteAdress,
                                &uPort);
    OpcUa_ReturnErrorIfBad(uStatus);

    pInternalSocketManager = (OpcUa_InternalSocketManager*)a_hSocketManager;

    pNewClientSocket = (OpcUa_InternalSocket*)OpcUa_SocketManager_FindFreeSocket(   (OpcUa_SocketManager)pInternalSocketManager,
                                                                                    OpcUa_False);
    if (pNewClientSocket == OpcUa_Null)
    {
        OpcUa_P_Memory_Free(sRemoteAdress);
        uStatus = OpcUa_BadMaxConnectionsReached; /* no socket left in the list. */
        goto Error;
    }

    /* Create client socket. */
    pNewClientSocket->rawSocket = OpcUa_P_Socket_CreateClient(  a_uLocalPort,
                                                                uPort,
                                                                sRemoteAdress,
                                                                &uStatus);

    OpcUa_P_Memory_Free(sRemoteAdress);

    OpcUa_GotoErrorIfTrue(  pNewClientSocket->rawSocket == (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID,
                            OpcUa_BadCommunicationError);

    pNewClientSocket->pfnEventCallback       = a_pfnSocketCallBack;
    pNewClientSocket->pvUserData             = a_pCallbackData;
    pNewClientSocket->Flags.bOwnThread       = OpcUa_False;
    pNewClientSocket->Flags.EventMask        = OPCUA_SOCKET_READ_EVENT
                                             | OPCUA_SOCKET_EXCEPT_EVENT
                                             | OPCUA_SOCKET_CONNECT_EVENT
                                             | OPCUA_SOCKET_TIMEOUT_EVENT;

    OPCUA_SOCKET_SETVALID(pNewClientSocket);

    /* return the new client socket */
    *a_pSocket = pNewClientSocket;

    /* break loop to add new socket into eventing */
    uStatus = OpcUa_P_SocketManager_InterruptLoop(  a_hSocketManager,
                                                    OPCUA_SOCKET_RENEWLOOP_EVENT,
                                                    OpcUa_False);
    OpcUa_GotoErrorIfBad(uStatus);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pNewClientSocket != OpcUa_Null)
    {
        if(pNewClientSocket->rawSocket != (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID)
        {
            OpcUa_P_RawSocket_Close(pNewClientSocket->rawSocket);
            pNewClientSocket->rawSocket = (OpcUa_RawSocket)OPCUA_P_SOCKET_INVALID;
        }
        OPCUA_SOCKET_INVALIDATE(pNewClientSocket);
    }

OpcUa_FinishErrorHandling;
}