/*============================================================================
 * 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_TcpSecureChannel_Clear
 *===========================================================================*/
OpcUa_StatusCode OpcUa_TcpSecureChannel_Clear(OpcUa_SecureChannel* a_pSecureChannel)
{
OpcUa_InitializeStatus(OpcUa_Module_SecureChannel, "Clear");

    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel);
    OpcUa_ReturnErrorIfArgumentNull(a_pSecureChannel->Handle);

    OpcUa_String_Clear(&a_pSecureChannel->SecurityPolicyUri);
    OpcUa_String_Clear(&a_pSecureChannel->sPeerInfo);

    OpcUa_Free(a_pSecureChannel->Handle);
    a_pSecureChannel->Handle = OpcUa_Null;

    OpcUa_ByteString_Clear(&a_pSecureChannel->ClientCertificate);

    OpcUa_ByteString_Clear(&a_pSecureChannel->ServerCertificate);

    if(a_pSecureChannel->pCurrentReceivingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pCurrentReceivingKeyset);
        OpcUa_Free(a_pSecureChannel->pCurrentReceivingKeyset);
        a_pSecureChannel->pCurrentReceivingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pCurrentSendingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pCurrentSendingKeyset);
        OpcUa_Free(a_pSecureChannel->pCurrentSendingKeyset);
        a_pSecureChannel->pCurrentSendingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousReceivingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousReceivingKeyset);
        OpcUa_Free(a_pSecureChannel->pPreviousReceivingKeyset);
        a_pSecureChannel->pPreviousReceivingKeyset = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousSendingKeyset != OpcUa_Null)
    {
        OpcUa_SecurityKeyset_Clear(a_pSecureChannel->pPreviousSendingKeyset);
        OpcUa_Free(a_pSecureChannel->pPreviousSendingKeyset);
        a_pSecureChannel->pPreviousSendingKeyset = OpcUa_Null;
    }

    /* delete both crypto providers */
    if(a_pSecureChannel->pCurrentCryptoProvider != OpcUa_Null)
    {
        if(a_pSecureChannel->pPreviousCryptoProvider == a_pSecureChannel->pCurrentCryptoProvider)
        {
            /* prevent double deletion */
            a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
        }

        OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pCurrentCryptoProvider);
        OpcUa_Free(a_pSecureChannel->pCurrentCryptoProvider);
        a_pSecureChannel->pCurrentCryptoProvider = OpcUa_Null;
    }

    if(a_pSecureChannel->pPreviousCryptoProvider != OpcUa_Null)
    {
        OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(a_pSecureChannel->pPreviousCryptoProvider);
        OpcUa_Free(a_pSecureChannel->pPreviousCryptoProvider);
        a_pSecureChannel->pPreviousCryptoProvider = OpcUa_Null;
    }

    if(a_pSecureChannel->pPendingSecureIStream != OpcUa_Null)
    {
        OpcUa_Stream_Close((OpcUa_Stream*)(a_pSecureChannel->pPendingSecureIStream));
        OpcUa_Stream_Delete((OpcUa_Stream**)&(a_pSecureChannel->pPendingSecureIStream));
    }

    while(a_pSecureChannel->pPendingSendBuffers != OpcUa_Null)
    {
        OpcUa_BufferList* pCurrentBuffer = a_pSecureChannel->pPendingSendBuffers;
        a_pSecureChannel->pPendingSendBuffers = pCurrentBuffer->pNext;
        OpcUa_Buffer_Clear(&pCurrentBuffer->Buffer);
        OpcUa_Free(pCurrentBuffer);
    }

    if(a_pSecureChannel->hSyncAccess != OpcUa_Null)
    {
        OPCUA_P_MUTEX_DELETE(&(a_pSecureChannel->hSyncAccess));
        a_pSecureChannel->hSyncAccess = OpcUa_Null;
    }

    if(a_pSecureChannel->hWriteMutex != OpcUa_Null)
    {
        OPCUA_P_MUTEX_DELETE(&(a_pSecureChannel->hWriteMutex));
        a_pSecureChannel->hWriteMutex = OpcUa_Null;
    }

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_FinishErrorHandling;
}
Beispiel #3
0
OpcUa_StatusCode OPCUA_DLLCALL OpcUa_CryptoProvider_Delete(OpcUa_CryptoProvider*   a_pProvider)
{
    return OPCUA_P_CRYPTOFACTORY_DELETECRYPTOPROVIDER(  a_pProvider);
}