/*
ToDo: problems with RSA_PKCS1_OAEP_PADDING -> find solution
*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_Verify(
    OpcUa_CryptoProvider* a_pProvider,
    OpcUa_ByteString      a_data,
    OpcUa_Key*            a_publicKey,
    OpcUa_Int16           a_padding,
    OpcUa_ByteString*     a_pSignature)
{
    EVP_PKEY*       pPublicKey      = OpcUa_Null;
    OpcUa_Int32     keySize         = 0;
    const unsigned char *pData;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Verify");

    OpcUa_ReferenceParameter(a_pProvider);
    OpcUa_ReferenceParameter(a_padding);

    OpcUa_ReturnErrorIfArgumentNull(a_data.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_publicKey);
    OpcUa_ReturnErrorIfArgumentNull(a_publicKey->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pSignature);

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

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

    if(pPublicKey == OpcUa_Null)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    keySize = RSA_size(pPublicKey->pkey.rsa);

    if((a_pSignature->Length%keySize) != 0)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    if (RSA_verify(NID_sha1, a_data.Data, a_data.Length, a_pSignature->Data, a_pSignature->Length, pPublicKey->pkey.rsa) != 1)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    EVP_PKEY_free(pPublicKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

OpcUa_FinishErrorHandling;
}
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;
}
/*============================================================================
 * 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;
}
示例#4
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_AddCustomExtension
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_AddCustomExtension(
    X509**                   a_ppCertificate,
    OpcUa_Crypto_Extension*  a_pExtension,
    X509V3_CTX*              a_pX509V3Context)
{
    X509_EXTENSION*     pExtension   = OpcUa_Null;
    char*               pName        = OpcUa_Null;
    char*               pValue       = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_AddCustomExtension");

    OpcUa_ReturnErrorIfArgumentNull(a_pX509V3Context);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->key);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->value);

    pName = (char*)a_pExtension->key;
    pValue = (char*)a_pExtension->value;

    /* create the extension. */
    pExtension = X509V3_EXT_conf(
        OpcUa_Null,
        a_pX509V3Context,
        pName,
        pValue);

    if(pExtension == OpcUa_Null)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* add it to the certificate. */
    if(!X509_add_ext(*a_ppCertificate, pExtension, -1))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* free the extension. */
    X509_EXTENSION_free(pExtension);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pExtension != OpcUa_Null)
    {
        X509_EXTENSION_free(pExtension);
    }

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_TcpSecureChannel_CheckSequenceNumber
 *===========================================================================*/
OpcUa_StatusCode OpcUa_TcpSecureChannel_CheckSequenceNumber(OpcUa_SecureChannel* a_pSecureChannel,
                                                            OpcUa_UInt32         a_uSequenceNumber)
{
OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "CheckSequenceNumber");

    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel);

    OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel);

    /* The SequenceNumber shall also monotonically increase for all Messages
       and shall not wrap around until it is greater than 4 294 966 271
       (UInt32.MaxValue - 1 024). The first number after the wrap around
       shall be less than 1 024. */
    if(!((a_uSequenceNumber == a_pSecureChannel->uLastSequenceNumberRcvd + 1) ||
         ((a_uSequenceNumber < 1024) &&
          (a_pSecureChannel->uLastSequenceNumberRcvd > 4294966271u))))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadSequenceNumberInvalid);
    }

    a_pSecureChannel->uLastSequenceNumberRcvd = a_uSequenceNumber;

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Create a UDP sender socket
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_P_SocketUdp_CreateSender(  OpcUa_StringA    a_LocalIpAddress,
                                                                OpcUa_StringA    a_RemoteIpAddress,
                                                                OpcUa_Int16      a_RemotePort,
                                                                OpcUa_Byte       a_TimeToLive,
                                                                OpcUa_Socket*    a_pSocket)
{
    OpcUa_InternalUdpSocket* pInternalSocket = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_Socket, "CreateUdpSender");

    OpcUa_ReturnErrorIfArgumentNull(a_pSocket);

    *a_pSocket = OpcUa_Null;

    OpcUa_GotoErrorIfArgumentNull(a_RemoteIpAddress);

    if(a_RemotePort == 0)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pInternalSocket = (OpcUa_InternalUdpSocket*)OpcUa_P_Memory_Alloc(sizeof(OpcUa_InternalUdpSocket));
    OpcUa_GotoErrorIfAllocFailed(pInternalSocket);

    pInternalSocket->pSocketServiceTable      = &OpcUa_UdpSocketServiceTable;

    if(strchr(a_RemoteIpAddress, ':'))
    {
        uStatus = OpcUa_P_RawSocket_CreateUdpV6(&pInternalSocket->rawSocket,
                                                OpcUa_True,
                                                a_LocalIpAddress,
                                                a_RemoteIpAddress,
                                                a_RemotePort,
                                                a_TimeToLive);
        OpcUa_GotoErrorIfBad(uStatus);
    }
    else
    {
        uStatus = OpcUa_P_RawSocket_CreateUdp(&pInternalSocket->rawSocket,
                                              OpcUa_True,
                                              a_LocalIpAddress,
                                              a_RemoteIpAddress,
                                              a_RemotePort,
                                              a_TimeToLive);
        OpcUa_GotoErrorIfBad(uStatus);
    }

    *a_pSocket = pInternalSocket;

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_AES_CBC_decrypt
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_AES_CBC_Decrypt(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Byte*             a_pCipherText,
    OpcUa_UInt32            a_cipherTextLen,
    OpcUa_Key*              a_key,
    OpcUa_Byte*             a_pInitalVector,
    OpcUa_Byte*             a_pPlainText,
    OpcUa_UInt32*           a_pPlainTextLen)
{
    AES_KEY         key;
    OpcUa_Byte      pInitalVector[16];

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "AES_CBC_Decrypt");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pCipherText);
    OpcUa_ReturnErrorIfArgumentNull(a_key);
    OpcUa_ReturnErrorIfArgumentNull(a_key->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pInitalVector);
    OpcUa_ReturnErrorIfArgumentNull(a_pPlainTextLen);

    if(a_cipherTextLen % 16 != 0)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    *a_pPlainTextLen = a_cipherTextLen;

    /* if just the output length is needed for the caller of this function */
    if(a_pPlainText == OpcUa_Null)
    {
        OpcUa_ReturnStatusCode;
    }

    /* we have to pass the key length in bits instead of bytes */
    if(AES_set_decrypt_key(a_key->Key.Data, a_key->Key.Length * 8, &key) < 0)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* copy the IV because the AES_cbc_encrypt function overwrites it. */
    OpcUa_P_Memory_MemCpy(pInitalVector, 16, a_pInitalVector, 16);

    /* decrypt ciphertext */
    AES_cbc_encrypt(    a_pCipherText,
                        a_pPlainText,
                        a_cipherTextLen,
                        &key,
                        pInitalVector,
                        AES_DECRYPT);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

OpcUa_FinishErrorHandling;
}
static
OpcUa_StatusCode OpcUa_UadpSecurityHeader_WriteBinary(OpcUa_UadpSecurityHeader* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize)
{
    OpcUa_Byte nonceLength;

    OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpSecurityHeader_WriteBinary");

    OpcUa_ReturnErrorIfArgumentNull(a_pValue);
    OpcUa_ReturnErrorIfArgumentNull(a_pBuffer);
    OpcUa_ReturnErrorIfArgumentNull(*a_pBuffer);
    OpcUa_ReturnErrorIfArgumentNull(a_pSize);

    OpcUa_UadpEncode_Direct(Byte, &a_pValue->SecurityFlags);
    OpcUa_UadpEncode_Direct(UInt32, &a_pValue->SecurityTokenId);
    /* The nonce is stored as ByteString, but the length has to be encoded as Byte */
    if(a_pValue->MessageNonce.Length < 0 || a_pValue->MessageNonce.Length > 0xFF)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
    }

    nonceLength = (OpcUa_Byte)a_pValue->MessageNonce.Length;
    OpcUa_UadpEncode_Direct(Byte, &nonceLength);
    if(*a_pSize < nonceLength)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
    }
    memcpy(*a_pBuffer, a_pValue->MessageNonce.Data, nonceLength);
    *a_pBuffer += nonceLength;
    *a_pSize -= nonceLength;

    if(a_pValue->SecurityFlags & OpcUa_UadpSecurityHeader_SecurityFlags_FooterEnabled)
    {
        OpcUa_UadpEncode_Direct(UInt16, &a_pValue->SecurityFooterSize);
    }

    OpcUa_ReturnStatusCode;
    OpcUa_BeginErrorHandling;
    /* nothing to do */
    OpcUa_FinishErrorHandling;
}
/*============================================================================
 * Set socket user data
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpSetUserData(OpcUa_Socket a_pSocket,
                                                             OpcUa_Void*  a_pvUserData)
{
OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpSetUserData");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    OpcUa_ReferenceParameter(a_pvUserData);

    OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
示例#10
0
/*============================================================================
 * Get IP Address and Port Number of the Peer
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_P_SocketService_UdpGetPeerInfo(  OpcUa_Socket  a_pSocket,
                                                               OpcUa_CharA*  a_achPeerInfoBuffer,
                                                               OpcUa_UInt32  a_uiPeerInfoBufferSize)
{
OpcUa_InitializeStatus(OpcUa_Module_Socket, "UdpGetPeerInfo");

    OpcUa_GotoErrorIfArgumentNull(a_pSocket);
    OpcUa_GotoErrorIfArgumentNull(a_achPeerInfoBuffer);
    OpcUa_ReferenceParameter(a_uiPeerInfoBufferSize);

    OpcUa_GotoErrorWithStatus(OpcUa_BadNotImplemented);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
/*===========================================================================*
OpcUa_P_OpenSSL_RSA_Public_GetKeyLength
*===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_GetKeyLength(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Key               a_publicKey,
    OpcUa_UInt32*           a_pKeyLen)
{
    EVP_PKEY*       pPublicKey      = OpcUa_Null;
    const unsigned char *pData;

    OpcUa_UInt32    uKeySize            = 0;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_GetKeyLength");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_publicKey.Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pKeyLen);

    *a_pKeyLen = 0;

    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);

    uKeySize = RSA_size(pPublicKey->pkey.rsa);

    *a_pKeyLen = uKeySize*8;

    EVP_PKEY_free(pPublicKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

    *a_pKeyLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
示例#12
0
/* SHA-2: 256 Bits output */
OpcUa_StatusCode OpcUa_P_OpenSSL_SHA2_256_Generate(
    OpcUa_CryptoProvider*         a_pProvider,
    OpcUa_Byte*                   a_pData,
    OpcUa_UInt32                  a_dataLen,
    OpcUa_Byte*                   a_pMessageDigest)
{
    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "SHA2_256_Generate");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pData);
    OpcUa_ReturnErrorIfArgumentNull(a_pMessageDigest);

    if(SHA256(a_pData, a_dataLen, a_pMessageDigest) == OpcUa_Null)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

OpcUa_ReturnStatusCode;

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

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

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Encrypt");

    OpcUa_ReferenceParameter(a_pProvider);

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

    *a_pCipherTextLen = 0;

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

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

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

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

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

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

    while(uPlainTextPosition < a_plainTextLen)
    {

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

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

                error = ERR_get_error();

                ERR_load_crypto_strings();

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

                uStatus = OpcUa_Bad;
                OpcUa_GotoError;
            }

        }
        else
        {
            iEncryptedBytes = uKeySize;
        }

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

    EVP_PKEY_free(pPublicKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

    *a_pCipherTextLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile(
    OpcUa_StringA           a_privateKeyFile,
    OpcUa_P_FileFormat      a_fileFormat,
    OpcUa_StringA           a_password,         /* optional: just needed encrypted PEM */
    OpcUa_ByteString*       a_pPrivateKey)
{
    BIO*            pPrivateKeyFile     = OpcUa_Null;
    RSA*            pRsaPrivateKey      = OpcUa_Null;
    EVP_PKEY*       pEvpKey             = OpcUa_Null;
    unsigned char*  pData;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_LoadPrivateKeyFromFile");

    /* check parameters */
    OpcUa_ReturnErrorIfArgumentNull(a_privateKeyFile);
    OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey);

    if(a_fileFormat == OpcUa_Crypto_Encoding_Invalid)
    {
        return OpcUa_BadInvalidArgument;
    }

    OpcUa_ReferenceParameter(a_password);

    /* open file */
    pPrivateKeyFile = BIO_new_file((const char*)a_privateKeyFile, "rb");
    OpcUa_ReturnErrorIfArgumentNull(pPrivateKeyFile);

    /* read and convert file */
    switch(a_fileFormat)
    {
    case OpcUa_Crypto_Encoding_PEM:
        {
            /* read from file */
            pEvpKey = PEM_read_bio_PrivateKey(  pPrivateKeyFile,    /* file                 */
                                                NULL,               /* key struct           */
                                                0,                  /* password callback    */
                                                a_password);        /* default passphrase or arbitrary handle */
            OpcUa_GotoErrorIfNull(pEvpKey, OpcUa_Bad);
            break;
        }
    case OpcUa_Crypto_Encoding_PKCS12:
        {
            int iResult = 0;

            /* read from file. */
            PKCS12* pPkcs12 = d2i_PKCS12_bio(pPrivateKeyFile, NULL);

            if (pPkcs12 == 0)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
            }

            /*  parse the certificate. */
            iResult = PKCS12_parse(pPkcs12, a_password, &pEvpKey, NULL, NULL);

            if (iResult == 0)
            {
                OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
            }

            /*  free certificate. */
            PKCS12_free(pPkcs12);
            pPkcs12 = NULL;
            break;
        }
    case OpcUa_Crypto_Encoding_DER:
    default:
        {
            uStatus = OpcUa_BadNotSupported;
            OpcUa_GotoError;
        }
    }

    /* convert to intermediary openssl struct */
    pRsaPrivateKey = EVP_PKEY_get1_RSA(pEvpKey);
    EVP_PKEY_free(pEvpKey);
    OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad);

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

    /* allocate target buffer */
    a_pPrivateKey->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pPrivateKey->Length);
    OpcUa_GotoErrorIfAllocFailed(a_pPrivateKey->Data);

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

    RSA_free(pRsaPrivateKey);
    BIO_free(pPrivateKeyFile);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pEvpKey)
    {
        EVP_PKEY_free(pEvpKey);
    }

    if(a_pPrivateKey != OpcUa_Null)
    {
        if(a_pPrivateKey->Data != OpcUa_Null)
        {
            OpcUa_P_Memory_Free(a_pPrivateKey->Data);
            a_pPrivateKey->Data = OpcUa_Null;
            a_pPrivateKey->Length = -1;
        }
    }

    if(pPrivateKeyFile != NULL)
    {
        BIO_free(pPrivateKeyFile);
    }

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

OpcUa_FinishErrorHandling;
}
示例#15
0
/*============================================================================
 * OpcUa_ProxyStub_UpdateConfigString
 *===========================================================================*/
static OpcUa_StatusCode OpcUa_ProxyStub_UpdateConfigString()
{
    OpcUa_Int  iRes  = 0;
    OpcUa_Int  iPos  = 0;

OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "UpdateConfigString");

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

    if(OpcUa_ProxyStub_g_pConfigString == OpcUa_Null)
    {
        OpcUa_ProxyStub_g_pConfigString = (OpcUa_StringA) OpcUa_Alloc(OPCUA_CONFIG_STRING_SIZE + 1);
        OpcUa_GotoErrorIfAllocFailed(OpcUa_ProxyStub_g_pConfigString);
        OpcUa_MemSet(OpcUa_ProxyStub_g_pConfigString, 0, OPCUA_CONFIG_STRING_SIZE + 1);
    }

#if OPCUA_USE_SAFE_FUNCTIONS

    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceEnabled", (OpcUa_ProxyStub_g_Configuration.bProxyStub_Trace_Enabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceLevel", OpcUa_ProxyStub_g_Configuration.uProxyStub_Trace_Level);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxAlloc", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxByteStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxArrayLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxMessageSize", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_Enabled", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_Enabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MinThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxJobs", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_BlockOnAdd", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_BlockOnAdd != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "uSecureListener_ThreadPool_Timeout", OpcUa_ProxyStub_g_Configuration.uSecureListener_ThreadPool_Timeout);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpListener_ClientThreadsEnabled", (OpcUa_ProxyStub_g_Configuration.bTcpListener_ClientThreadsEnabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpListener_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpConnection_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxMessageLength", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxChunkCount", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpStream_ExpectWriteToBlock", (OpcUa_ProxyStub_g_Configuration.bTcpStream_ExpectWriteToBlock != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}

#else /* OPCUA_USE_SAFE_FUNCTIONS */

    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceEnabled", (OpcUa_ProxyStub_g_Configuration.bProxyStub_Trace_Enabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "TraceLevel", OpcUa_ProxyStub_g_Configuration.uProxyStub_Trace_Level);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxAlloc", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxByteStringLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxArrayLength", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSerializer_MaxMessageSize", OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_Enabled", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_Enabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MinThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxThreads", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iSecureListener_ThreadPool_MaxJobs", OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bSecureListener_ThreadPool_BlockOnAdd", (OpcUa_ProxyStub_g_Configuration.bSecureListener_ThreadPool_BlockOnAdd != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "uSecureListener_ThreadPool_Timeout", OpcUa_ProxyStub_g_Configuration.uSecureListener_ThreadPool_Timeout);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpListener_ClientThreadsEnabled", (OpcUa_ProxyStub_g_Configuration.bTcpListener_ClientThreadsEnabled != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpListener_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpConnection_DefaultChunkSize", OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxMessageLength", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%i\\", "iTcpTransport_MaxChunkCount", OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}
    iRes = OpcUa_SnPrintfA(&OpcUa_ProxyStub_g_pConfigString[iPos], OPCUA_CONFIG_STRING_SIZE - iPos, "%s:%u\\", "bTcpStream_ExpectWriteToBlock", (OpcUa_ProxyStub_g_Configuration.bTcpStream_ExpectWriteToBlock != 0)?1:0);
    if(iRes > 0){iPos += iRes;}else{OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);}

#endif /* OPCUA_USE_SAFE_FUNCTIONS */

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

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
示例#16
0
/*============================================================================
 * OpcUa_ProxyStub_ReInitialize
 *===========================================================================*/
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_ProxyStub_ReInitialize(OpcUa_ProxyStubConfiguration* a_pProxyStubConfiguration)
{
OpcUa_InitializeStatus(OpcUa_Module_ProxyStub, "ReInitialize");

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

    OpcUa_GotoErrorIfArgumentNull(a_pProxyStubConfiguration);

    if((OpcUa_ProxyStub_g_uNoOfChannels != 0) || (OpcUa_ProxyStub_g_uNoOfEndpoints != 0))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidState);
    }

    /* set global configuration object */
    OpcUa_ProxyStub_g_Configuration = *a_pProxyStubConfiguration;

    /* check for negative values and fall back to default values in opcua_config.h */
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxAlloc                     = OPCUA_SERIALIZER_MAXALLOC; /* currently unused */
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxStringLength              = OPCUA_ENCODER_MAXSTRINGLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxByteStringLength          = OPCUA_ENCODER_MAXBYTESTRINGLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxArrayLength               = OPCUA_ENCODER_MAXARRAYLENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSerializer_MaxMessageSize               = OPCUA_ENCODER_MAXMESSAGELENGTH;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MinThreads    = OPCUA_SECURELISTENER_THREADPOOL_MINTHREADS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxThreads    = OPCUA_SECURELISTENER_THREADPOOL_MAXTHREADS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iSecureListener_ThreadPool_MaxJobs       = OPCUA_SECURELISTENER_THREADPOOL_MAXJOBS;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpListener_DefaultChunkSize            = OPCUA_TCPLISTENER_DEFAULTCHUNKSIZE;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpConnection_DefaultChunkSize          = OPCUA_TCPCONNECTION_DEFAULTCHUNKSIZE;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxChunkCount              = 0;
    }
    if(OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength == -1)
    {
        OpcUa_ProxyStub_g_Configuration.iTcpTransport_MaxMessageLength           = OPCUA_ENCODER_MAXMESSAGELENGTH;
    }

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

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

OpcUa_FinishErrorHandling;
}
示例#17
0
/*============================================================================
 * OpcUa_SecureChannel_Open
 *===========================================================================*/
OpcUa_StatusCode OpcUa_TcpSecureChannel_Open(   OpcUa_SecureChannel*            a_pSecureChannel,
                                                OpcUa_Handle                    a_hTransportConnection,
                                                OpcUa_ChannelSecurityToken      a_channelSecurityToken,
                                                OpcUa_MessageSecurityMode       a_messageSecurityMode,
                                                OpcUa_ByteString*               a_pbsClientCertificate,
                                                OpcUa_ByteString*               a_pbsServerCertificate,
                                                OpcUa_SecurityKeyset*           a_pReceivingKeyset,
                                                OpcUa_SecurityKeyset*           a_pSendingKeyset,
                                                OpcUa_CryptoProvider*           a_pCryptoProvider)
{
OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Open");

    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel);
    OpcUa_ReturnErrorIfArgumentNull(a_hTransportConnection);
    OpcUa_ReturnErrorIfArgumentNull(a_pCryptoProvider);

    OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel);

    if(a_pSecureChannel->SecureChannelId != a_channelSecurityToken.ChannelId)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid);
    }

    a_pSecureChannel->bCurrentTokenActive                           = OpcUa_True;

    /*** TCP SECURECHANNEL ***/
    a_pSecureChannel->CurrentChannelSecurityToken.ChannelId         = a_channelSecurityToken.ChannelId;
    a_pSecureChannel->CurrentChannelSecurityToken.TokenId           = a_channelSecurityToken.TokenId;
    a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt         = a_channelSecurityToken.CreatedAt;
    a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime   = a_channelSecurityToken.RevisedLifetime;

    /*** SECURECHANNEL ***/
    a_pSecureChannel->State                                         = OpcUa_SecureChannelState_Opened;
    a_pSecureChannel->TransportConnection                           = a_hTransportConnection;
    a_pSecureChannel->MessageSecurityMode                           = a_messageSecurityMode;
    a_pSecureChannel->uExpirationCounter                            = (OpcUa_UInt32)(a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL);
    a_pSecureChannel->uOverlapCounter                               = (OpcUa_UInt32)((a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime>>2)/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL);

    /* copy client certificate */
    if(a_pbsClientCertificate != OpcUa_Null && a_pbsClientCertificate->Length > 0)
    {
        a_pSecureChannel->ClientCertificate.Data    = (OpcUa_Byte *)OpcUa_Alloc(a_pbsClientCertificate->Length);
        OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ClientCertificate.Data);
        a_pSecureChannel->ClientCertificate.Length  = a_pbsClientCertificate->Length;
        OpcUa_MemCpy(   a_pSecureChannel->ClientCertificate.Data,
                        a_pSecureChannel->ClientCertificate.Length,
                        a_pbsClientCertificate->Data,
                        a_pbsClientCertificate->Length);
    }
    else
    {
        OpcUa_ByteString_Initialize(&a_pSecureChannel->ClientCertificate);
    }

    if(a_pbsServerCertificate != OpcUa_Null && a_pbsServerCertificate->Length > 0)
    {
        a_pSecureChannel->ServerCertificate.Data    = (OpcUa_Byte*)OpcUa_Alloc(a_pbsServerCertificate->Length);
        OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ServerCertificate.Data);
        a_pSecureChannel->ServerCertificate.Length  = a_pbsServerCertificate->Length;

        OpcUa_MemCpy(   a_pSecureChannel->ServerCertificate.Data,
                        a_pSecureChannel->ServerCertificate.Length,
                        a_pbsServerCertificate->Data,
                        a_pbsServerCertificate->Length);
    }
    else
    {
        OpcUa_ByteString_Initialize(&a_pSecureChannel->ServerCertificate);
    }

    a_pSecureChannel->pCurrentReceivingKeyset   = a_pReceivingKeyset;
    a_pSecureChannel->pCurrentSendingKeyset     = a_pSendingKeyset;
    a_pSecureChannel->pCurrentCryptoProvider    = a_pCryptoProvider;

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    OpcUa_SecurityKeyset_Clear(a_pReceivingKeyset);
    OpcUa_SecurityKeyset_Clear(a_pSendingKeyset);
    OpcUa_Free(a_pReceivingKeyset);
    OpcUa_Free(a_pSendingKeyset);

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_FinishErrorHandling;
}
示例#18
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;
}
static
OpcUa_StatusCode OpcUa_UadpNetworkMessageHeader_WriteBinary(OpcUa_UadpNetworkMessageHeader* a_pValue, OpcUa_Byte **a_pBuffer, OpcUa_UInt32 *a_pSize)
{
    OpcUa_Byte uadpVersionFlags;
    OpcUa_Byte extendedFlags1;
    OpcUa_Byte extendedFlags2;
    OpcUa_UadpDeclare_Context;

    OpcUa_InitializeStatus(OpcUa_Module_PubSub, "OpcUa_UadpNetworkMessageHeader_WriteBinary");

    OpcUa_UadpInit_Context;

    OpcUa_ReturnErrorIfArgumentNull(a_pValue);
    OpcUa_ReturnErrorIfArgumentNull(a_pBuffer);
    OpcUa_ReturnErrorIfArgumentNull(*a_pBuffer);
    OpcUa_ReturnErrorIfArgumentNull(a_pSize);


    /* assign the configured part of the flag bytes */
    uadpVersionFlags = (OpcUa_Byte)a_pValue->NetworkMessageFlags & 0x60; /* Take Byte 0 only */
    /* Bit 0-3: UADP Version, Bit 5: GroupHeader enabled, Bit 6: PayloadHeader enabled */
    uadpVersionFlags |= OPCUA_UADP_VERSION & 0x0F;

    extendedFlags1 = (OpcUa_Byte)((a_pValue->NetworkMessageFlags & 0x7800) >> 8); /* Take Byte 1 only */
    /* Bit 3: DataSetClassId enabled, Bit 4: Security enabled, Bit 5: Timestamp enabled, Bit 6: PicoSeconds enabled */
    extendedFlags2 = (OpcUa_Byte)((a_pValue->NetworkMessageFlags & 0x1F0000) >> 16); /* Take Byte 2 only */
    /* Bit 0: Chunk message, Bit 1: PromotedFields enabled */
    /* ExtendedFlags2 Bit 2-4 NetworkMessageType: 000: DataSetMessage, 001: Discovery Request, 010: Discovery Response */

    /* calculate the remaining bits */
    /* ExtendedFlags1 Bit 0-2 PublisherIdType: */
    if(a_pValue->PublisherId.ArrayType != OpcUa_VariantArrayType_Scalar)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
    }
    switch(a_pValue->PublisherId.Datatype)
    {
    case OpcUaType_Byte:
        /* 0x0 */
        uadpVersionFlags |= 0x10; /* PublisherId enabled */
        break;
    case OpcUaType_UInt16:
        extendedFlags1 |= 0x1;
        uadpVersionFlags |= 0x10; /* PublisherId enabled */
        break;
    case OpcUaType_UInt32:
        extendedFlags1 |= 0x2;
        uadpVersionFlags |= 0x10; /* PublisherId enabled */
        break;
    case OpcUaType_UInt64:
        extendedFlags1 |= 0x3;
        uadpVersionFlags |= 0x10; /* PublisherId enabled */
        break;
    case OpcUaType_String:
        extendedFlags1 |= 0x4;
        uadpVersionFlags |= 0x10; /* PublisherId enabled */
        break;
    case OpcUaType_Null:
        /* keep PublisherId disabled */
        break;
    default:
        /* unsupported data type */
        OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError);
        break;
    }

    /* ExtendedFlags1 Bit 7 ExtendedFlags2 enabled: */
    if(extendedFlags2)
    {
        extendedFlags1 |= 0x80;
    }

    /* UADPFlags Bit 7 ExtendedFlags1 enabled */
    if(extendedFlags1)
    {
        uadpVersionFlags |= 0x80;
    }

    OpcUa_UadpEncode_Direct(Byte, &uadpVersionFlags);
    if(extendedFlags1)
    {
        OpcUa_UadpEncode_Direct(Byte, &extendedFlags1);
    }
    if(extendedFlags2)
    {
        OpcUa_UadpEncode_Direct(Byte, &extendedFlags2);
    }

    /* cast away the const pointer */
    switch(a_pValue->PublisherId.Datatype)
    {
    case OpcUaType_Byte:
        OpcUa_UadpEncode_Direct(Byte, &a_pValue->PublisherId.Value.Byte);
        break;
    case OpcUaType_UInt16:
        OpcUa_UadpEncode_Direct(UInt16, &a_pValue->PublisherId.Value.UInt16);
        break;
    case OpcUaType_UInt32:
        OpcUa_UadpEncode_Direct(UInt32, &a_pValue->PublisherId.Value.UInt32);
        break;
    case OpcUaType_UInt64:
        OpcUa_UadpEncode_Direct(UInt64, &a_pValue->PublisherId.Value.UInt64);
        break;
    case OpcUaType_String:
        OpcUa_UadpEncode_Simple(String, &a_pValue->PublisherId.Value.String);
        break;
    case OpcUaType_Null:
        break;
    }

    if(a_pValue->NetworkMessageFlags & OpcUa_UadpNetworkMessageFlags_DataSetClassId)
    {
        OpcUa_UadpEncode_Simple(Guid, &a_pValue->DataSetClassId);
    }

    OpcUa_UadpClear_Context;

    OpcUa_ReturnStatusCode;
    OpcUa_BeginErrorHandling;

    OpcUa_UadpClear_Context;

    OpcUa_FinishErrorHandling;
}
示例#20
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;
}
示例#21
0
/*============================================================================
 * OpcUa_P_OpenSSL_X509_GetPublicKey
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetPublicKey(
    OpcUa_CryptoProvider*       a_pProvider,
    OpcUa_ByteString*           a_pCertificate,
    OpcUa_StringA               a_password,             /* this could be optional */
    OpcUa_Key*                  a_pPublicKey)
{
    EVP_PKEY*           pPublicKey      = OpcUa_Null;
    RSA*                pRsaPublicKey   = OpcUa_Null;
    X509*               pCertificate    = OpcUa_Null;
    OpcUa_Byte*         pBuffer         = OpcUa_Null;
    BIO*                bi;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetPublicKey");

    OpcUa_ReferenceParameter(a_password);

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

    bi = BIO_new(BIO_s_mem());
    BIO_write(bi, a_pCertificate->Data, a_pCertificate->Length);

    pCertificate = d2i_X509_bio(bi, NULL);

    BIO_free(bi);

    if(pCertificate == OpcUa_Null)
    {
        return OpcUa_BadCertificateInvalid;
    }

    /* get EVP_PKEY from X509 certificate */
    pPublicKey = X509_get_pubkey(pCertificate);
    if(pPublicKey == OpcUa_Null)
    {
        X509_free(pCertificate);
        return OpcUa_BadCertificateInvalid;
    }

    /* free X509 certificate, since not needed anymore */
    X509_free(pCertificate);

    switch(EVP_PKEY_type(pPublicKey->type))
    {
    case EVP_PKEY_RSA:

        /* allocate memory for RSA key */

        /* get RSA public key from EVP_PKEY */
        pRsaPublicKey = EVP_PKEY_get1_RSA(pPublicKey);

        /* allocate memory for DER encoded bytestring */
        a_pPublicKey->Key.Length = i2d_RSAPublicKey(pRsaPublicKey, OpcUa_Null);

        if(a_pPublicKey->Key.Data == OpcUa_Null)
        {
            RSA_free(pRsaPublicKey);
            pRsaPublicKey = OpcUa_Null;

            EVP_PKEY_free(pPublicKey);
            pPublicKey = OpcUa_Null;

            OpcUa_ReturnStatusCode;
        }

        /* convert RSA key to DER encoded bytestring */
        pBuffer = a_pPublicKey->Key.Data;
        a_pPublicKey->Key.Length = i2d_RSAPublicKey(pRsaPublicKey, &pBuffer);
        a_pPublicKey->Type = OpcUa_Crypto_KeyType_Rsa_Public;

        /* free memory for RSA key */
        RSA_free(pRsaPublicKey);
        pRsaPublicKey = OpcUa_Null;

        break;

    case EVP_PKEY_EC:
    case EVP_PKEY_DSA:
    case EVP_PKEY_DH:
    default:
        OpcUa_GotoErrorWithStatus(OpcUa_BadNotSupported);
    }

    /*** clean up ***/
    EVP_PKEY_free(pPublicKey);
    pPublicKey = OpcUa_Null;

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    EVP_PKEY_free(pPublicKey);
    pPublicKey = OpcUa_Null;

OpcUa_FinishErrorHandling;
}
示例#22
0
/*============================================================================
 * OpcUa_SecureChannel_Renew
 *===========================================================================*/
OpcUa_StatusCode OpcUa_TcpSecureChannel_Renew(  OpcUa_SecureChannel*            a_pSecureChannel,
                                                OpcUa_Handle                    a_hTransportConnection,
                                                OpcUa_ChannelSecurityToken      a_ChannelSecurityToken,
                                                OpcUa_MessageSecurityMode       a_eMessageSecurityMode,
                                                OpcUa_ByteString*               a_pbsClientCertificate,
                                                OpcUa_ByteString*               a_pbsServerCertificate,
                                                OpcUa_SecurityKeyset*           a_pNewReceivingKeyset,
                                                OpcUa_SecurityKeyset*           a_pNewSendingKeyset,
                                                OpcUa_CryptoProvider*           a_pNewCryptoProvider)
{
OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Renew");

    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel);
    OpcUa_ReturnErrorIfArgumentNull(a_hTransportConnection);
    OpcUa_ReturnErrorIfArgumentNull(a_pNewCryptoProvider);

    OPCUA_SECURECHANNEL_LOCK(a_pSecureChannel);

    OpcUa_Trace(OPCUA_TRACE_LEVEL_INFO, "OpcUa_TcpSecureChannel_Renew: New token id for channel %u is %u\n", a_pSecureChannel->SecureChannelId, a_ChannelSecurityToken.TokenId);

    if(a_pSecureChannel->TransportConnection != a_hTransportConnection)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid);
    }

    if(a_pSecureChannel->SecureChannelId != a_ChannelSecurityToken.ChannelId)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadSecureChannelIdInvalid);
    }

    /*** TCP SECURECHANNEL ***/
    /* Previous objects will be overwritten by current objects */
    a_pSecureChannel->bCurrentTokenActive                           = OpcUa_False;

    /* set channelSecurityToken members */
    a_pSecureChannel->PreviousChannelSecurityToken.ChannelId        = a_pSecureChannel->CurrentChannelSecurityToken.ChannelId;
    a_pSecureChannel->PreviousChannelSecurityToken.TokenId          = a_pSecureChannel->CurrentChannelSecurityToken.TokenId;
    a_pSecureChannel->PreviousChannelSecurityToken.CreatedAt        = a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt;
    a_pSecureChannel->PreviousChannelSecurityToken.RevisedLifetime  = a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime;

    /* set current channelSecurityToken */
    a_pSecureChannel->CurrentChannelSecurityToken.ChannelId         = a_ChannelSecurityToken.ChannelId;
    a_pSecureChannel->CurrentChannelSecurityToken.TokenId           = a_ChannelSecurityToken.TokenId;
    a_pSecureChannel->CurrentChannelSecurityToken.CreatedAt         = a_ChannelSecurityToken.CreatedAt;
    a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime   = a_ChannelSecurityToken.RevisedLifetime;

    /*** SECURECHANNEL ***/
    a_pSecureChannel->State                                         = OpcUa_SecureChannelState_Opened;
    a_pSecureChannel->MessageSecurityMode                           = a_eMessageSecurityMode;
    a_pSecureChannel->uExpirationCounter                            = (OpcUa_UInt32)(a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL);
    a_pSecureChannel->uOverlapCounter                               = (OpcUa_UInt32)((a_pSecureChannel->CurrentChannelSecurityToken.RevisedLifetime>>2)/OPCUA_SECURELISTENER_WATCHDOG_INTERVAL);

    /* free old certificate and add new one */
    OpcUa_ByteString_Clear(&a_pSecureChannel->ClientCertificate);

    /* copy client certificate!!! */
    if(a_pbsClientCertificate != OpcUa_Null && a_pbsClientCertificate->Length > 0)
    {
        a_pSecureChannel->ClientCertificate.Data    = (OpcUa_Byte*)OpcUa_Alloc(a_pbsClientCertificate->Length);
        OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ClientCertificate.Data);
        a_pSecureChannel->ClientCertificate.Length  = a_pbsClientCertificate->Length;
        OpcUa_MemCpy(   a_pSecureChannel->ClientCertificate.Data,
                        a_pSecureChannel->ClientCertificate.Length,
                        a_pbsClientCertificate->Data,
                        a_pbsClientCertificate->Length);
    }

    /* free old certificate and add new one */
    OpcUa_ByteString_Clear(&a_pSecureChannel->ServerCertificate);

    if(a_pbsServerCertificate != OpcUa_Null && a_pbsServerCertificate->Length > 0)
    {
        a_pSecureChannel->ServerCertificate.Data    = (OpcUa_Byte*)OpcUa_Alloc(a_pbsServerCertificate->Length);
        OpcUa_GotoErrorIfAllocFailed(a_pSecureChannel->ServerCertificate.Data);
        a_pSecureChannel->ServerCertificate.Length  = a_pbsServerCertificate->Length;
        OpcUa_MemCpy(   a_pSecureChannel->ServerCertificate.Data,
                        a_pSecureChannel->ServerCertificate.Length,
                        a_pbsServerCertificate->Data,
                        a_pbsServerCertificate->Length);
    }

    /* delete previous keysets */
    OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousReceivingKeyset);
    OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousSendingKeyset);
    OpcUa_Free(a_pSecureChannel->pPreviousReceivingKeyset);
    OpcUa_Free(a_pSecureChannel->pPreviousSendingKeyset);
    a_pSecureChannel->pPreviousReceivingKeyset  = OpcUa_Null;
    a_pSecureChannel->pPreviousSendingKeyset    = OpcUa_Null;

    /* assign current to previous */
    a_pSecureChannel->pPreviousReceivingKeyset                      = a_pSecureChannel->pCurrentReceivingKeyset;
    a_pSecureChannel->pPreviousSendingKeyset                        = a_pSecureChannel->pCurrentSendingKeyset;

    /* delete previous cryptoprovider */
    if(     a_pSecureChannel->pPreviousCryptoProvider != OpcUa_Null
        &&  a_pSecureChannel->pPreviousCryptoProvider != a_pSecureChannel->pCurrentCryptoProvider)
    {
        OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pPreviousCryptoProvider);
        OpcUa_Free(a_pSecureChannel->pPreviousCryptoProvider);
        a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
    }
    else
    {
        a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
    }

    /* make current cryptoprovider previous */
    a_pSecureChannel->pPreviousCryptoProvider                       = a_pSecureChannel->pCurrentCryptoProvider;
    a_pSecureChannel->pCurrentCryptoProvider                        = a_pNewCryptoProvider;
    a_pSecureChannel->pCurrentReceivingKeyset                       = a_pNewReceivingKeyset;
    a_pSecureChannel->pCurrentSendingKeyset                         = a_pNewSendingKeyset;

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    OpcUa_SecurityKeyset_Clear(a_pNewReceivingKeyset);
    OpcUa_SecurityKeyset_Clear(a_pNewSendingKeyset);
    OpcUa_Free(a_pNewReceivingKeyset);
    OpcUa_Free(a_pNewSendingKeyset);

    OPCUA_SECURECHANNEL_UNLOCK(a_pSecureChannel);

OpcUa_FinishErrorHandling;
}
/*============================================================================
 * OpcUa_P_OpenSSL_RSA_Private_Decrypt
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Private_Decrypt(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Byte*             a_pCipherText,
    OpcUa_UInt32            a_cipherTextLen,
    OpcUa_Key*              a_privateKey,
    OpcUa_Int16             a_padding,
    OpcUa_Byte*             a_pPlainText,
    OpcUa_UInt32*           a_pPlainTextLen)
{
    EVP_PKEY*       pPrivateKey     = OpcUa_Null;

    OpcUa_UInt32    keySize         = 0;
    OpcUa_Int32     decryptedBytes  = 0;
    OpcUa_UInt32    iCipherText     = 0;
    /* OpcUa_UInt32 iPlainTextLen   = 0; */
    OpcUa_UInt32    decDataSize     = 0;

    const char*     sError          = OpcUa_Null;
    const unsigned char *pData;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Private_Decrypt");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pCipherText);
    OpcUa_ReturnErrorIfArgumentNull(a_privateKey);
    OpcUa_ReturnErrorIfArgumentNull(a_privateKey->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pPlainTextLen);

    *a_pPlainTextLen = 0;

    if(a_privateKey->Type != OpcUa_Crypto_KeyType_Rsa_Private)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pData = a_privateKey->Key.Data;
    pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA,OpcUa_Null, &pData, a_privateKey->Key.Length);

    if (pPrivateKey == OpcUa_Null)
    {
        long lErr = ERR_get_error();
        char *szErr = ERR_error_string(lErr, 0);
        OpcUa_ReferenceParameter(szErr);
        return OpcUa_BadInvalidArgument;
    }

    keySize = RSA_size(pPrivateKey->pkey.rsa);

    if((a_cipherTextLen%keySize) != 0)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoError;
    }

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

    while(iCipherText < a_cipherTextLen)
    {
        if(a_pPlainText != OpcUa_Null)
        {
            decryptedBytes = RSA_private_decrypt(   keySize,                            /* how much to decrypt  */
                                                    a_pCipherText + iCipherText,        /* what to decrypt      */
                                                    a_pPlainText + (*a_pPlainTextLen),  /* where to decrypt     */
                                                    pPrivateKey->pkey.rsa,              /* private key          */
                                                    a_padding);                         /* padding mode         */

            /* goto error block, if decryption fails */
            if(decryptedBytes == -1)
            {
                /* const char* serror = NULL; */
                unsigned long 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
        {
            decryptedBytes = decDataSize;
        }

        *a_pPlainTextLen = *a_pPlainTextLen + decryptedBytes;
        iCipherText = iCipherText + keySize;
    }


    EVP_PKEY_free(pPrivateKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

    *a_pPlainTextLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
示例#24
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;
}
示例#25
0
/*============================================================================
 * OpcUa_P_ParseUrl
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_ParseUrl(  OpcUa_StringA   a_psUrl,
                                    OpcUa_StringA*  a_psIpAddress,
                                    OpcUa_UInt16*   a_puPort)
{
    OpcUa_StringA       sHostName         = OpcUa_Null;
    OpcUa_UInt32        uHostNameLength   = 0;

    OpcUa_CharA*        sPort             = OpcUa_Null;

    OpcUa_CharA*        pcCursor;

    OpcUa_Int           nIndex1           = 0;
    OpcUa_Int           nIpStart;

    struct addrinfo*    pAddrInfo         = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_Utilities, "P_ParseUrl");

    OpcUa_ReturnErrorIfArgumentNull(a_psUrl);
    OpcUa_ReturnErrorIfArgumentNull(a_psIpAddress);
    OpcUa_ReturnErrorIfArgumentNull(a_puPort);


    *a_psIpAddress = OpcUa_Null;

    /* check for // (end of protocol header) */
    pcCursor = strstr(a_psUrl, "//");

    if(pcCursor != OpcUa_Null)
    {
        /* begin of host address */
        pcCursor += 2;
        nIndex1 = (OpcUa_Int)(pcCursor - a_psUrl);
    }

    /* skip protocol prefix and store beginning of ip adress */
    nIpStart = nIndex1;

    /* skip host address (IPv6 address can contain colons!) */
    while(a_psUrl[nIndex1] != '/' && a_psUrl[nIndex1] != 0)
    {
        if(a_psUrl[nIndex1] == ':')
        {
            sPort = &a_psUrl[nIndex1 + 1];
            uHostNameLength = nIndex1 - nIpStart;
        }
        /* handle "opc.tcp://[::1]:4880/" */
        if(a_psUrl[nIndex1] == ']' && sPort != OpcUa_Null && a_psUrl[nIpStart] == '[')
        {
            nIpStart++;
            uHostNameLength = nIndex1 - nIpStart;
            sPort = OpcUa_Null;
            if(a_psUrl[nIndex1 + 1] == ':')
            {
                sPort = &a_psUrl[nIndex1 + 2];
            }
            break;
        }
        nIndex1++;
    }

    if(uHostNameLength == 0)
    {
        uHostNameLength = nIndex1 - nIpStart;
    }

    /* scan port */
    if(sPort != OpcUa_Null)
    {
        /* convert port */
        *a_puPort = (OpcUa_UInt16)OpcUa_P_CharAToInt(sPort);
    }
    else
    {
        /* return default port */
        *a_puPort = OPCUA_TCP_DEFAULT_PORT;
    }

    sHostName = (OpcUa_StringA)OpcUa_P_Memory_Alloc(uHostNameLength + 1);

    if(sHostName == NULL)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadOutOfMemory);
    }

    memcpy(sHostName, &a_psUrl[nIpStart], uHostNameLength);
    sHostName[uHostNameLength] = '\0';

    if(getaddrinfo(sHostName, NULL, NULL, &pAddrInfo))
    {
        /* hostname could not be resolved */
        pAddrInfo = NULL;
        OpcUa_GotoErrorWithStatus(OpcUa_BadHostUnknown);
    }

    if(pAddrInfo->ai_family == AF_INET)
    {
        struct sockaddr_in* pAddr = (struct sockaddr_in*)pAddrInfo->ai_addr;
        OpcUa_P_Memory_Free(sHostName);
        sHostName = OpcUa_P_Memory_Alloc(INET_ADDRSTRLEN);
        OpcUa_GotoErrorIfAllocFailed(sHostName);
        if(inet_ntop(AF_INET, (void*)&pAddr->sin_addr,
                     sHostName, INET_ADDRSTRLEN) == NULL)
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);
        }
    }
    else if(pAddrInfo->ai_family == AF_INET6)
    {
        struct sockaddr_in6* pAddr = (struct sockaddr_in6*)pAddrInfo->ai_addr;
        OpcUa_P_Memory_Free(sHostName);
        sHostName = OpcUa_P_Memory_Alloc(INET6_ADDRSTRLEN);
        OpcUa_GotoErrorIfAllocFailed(sHostName);
        if(inet_ntop(AF_INET6, (void*)&pAddr->sin6_addr,
                     sHostName, INET6_ADDRSTRLEN) == NULL)
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);
        }
        if(pAddr->sin6_scope_id)
        {
            char *pScopeAddress = OpcUa_P_Memory_Alloc(strlen(sHostName) + 12);
            OpcUa_GotoErrorIfAllocFailed(pScopeAddress);
            sprintf(pScopeAddress, "%s%%%u", sHostName, pAddr->sin6_scope_id);
            OpcUa_P_Memory_Free(sHostName);
            sHostName = pScopeAddress;
        }
    }
    else
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInternalError);
    }

    *a_psIpAddress = sHostName;
    freeaddrinfo(pAddrInfo);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

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

    if(pAddrInfo != NULL)
    {
        freeaddrinfo(pAddrInfo);
    }

OpcUa_FinishErrorHandling;
}