Example #1
0
        public static LogEntry For(ActivateSessionRequest request)
        {
            LogEntry entry = new LogEntry("ActivateSessionRequest");

            entry.Add("RequestHeader", For(request.RequestHeader));
            entry.Add("LocaleIds", For(request.LocaleIds));
            return(entry);
        }
Example #2
0
        public async Task <ActivateSessionResponse> ActivateSessionAsync(ActivateSessionRequest activateSessionRequest)
        {
            UpdateRequestHeader(activateSessionRequest, true, "ActivateSession");
            ActivateSessionResponse activateSessionResponse = null;

            try
            {
                if (UseTransportChannel)
                {
                    var serviceResponse = await Task <IServiceResponse> .Factory.FromAsync(TransportChannel.BeginSendRequest, TransportChannel.EndSendRequest, activateSessionRequest, null).ConfigureAwait(false);

                    if (serviceResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }
                    ValidateResponse(serviceResponse.ResponseHeader);
                    activateSessionResponse = (ActivateSessionResponse)serviceResponse;
                }
                else
                {
                    var activateSessionResponseMessage = await Task <ActivateSessionResponseMessage> .Factory.FromAsync(InnerChannel.BeginActivateSession, InnerChannel.EndActivateSession, new ActivateSessionMessage(activateSessionRequest), null).ConfigureAwait(false);

                    if (activateSessionResponseMessage == null || activateSessionResponseMessage.ActivateSessionResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }
                    activateSessionResponse = activateSessionResponseMessage.ActivateSessionResponse;
                    ValidateResponse(activateSessionResponse.ResponseHeader);
                }
            }
            finally
            {
                RequestCompleted(activateSessionRequest, activateSessionResponse, "ActivateSession");
            }
            return(activateSessionResponse);
        }
Example #3
0
        /// <inheritdoc/>
        protected override async Task OnOpenAsync(CancellationToken token = default(CancellationToken))
        {
            this.logger?.LogInformation($"Opening session channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'.");
            this.logger?.LogInformation($"SecurityPolicy: '{this.RemoteEndpoint.SecurityPolicyUri}'.");
            this.logger?.LogInformation($"SecurityMode: '{this.RemoteEndpoint.SecurityMode}'.");
            this.logger?.LogInformation($"UserIdentity: '{this.UserIdentity}'.");

            await base.OnOpenAsync(token).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();

            // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession.
            // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce
            if (this.SessionId == null)
            {
                var localNonce           = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce(NonceLength) : null;
                var localCertificate     = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate : null;
                var createSessionRequest = new CreateSessionRequest
                {
                    ClientDescription       = this.LocalDescription,
                    EndpointUrl             = this.RemoteEndpoint.EndpointUrl,
                    SessionName             = this.LocalDescription.ApplicationName,
                    ClientNonce             = localNonce,
                    ClientCertificate       = localCertificate,
                    RequestedSessionTimeout = this.options.SessionTimeout,
                    MaxResponseMessageSize  = this.RemoteMaxMessageSize
                };

                var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false);

                this.SessionId           = createSessionResponse.SessionId;
                this.AuthenticationToken = createSessionResponse.AuthenticationToken;
                this.RemoteNonce         = createSessionResponse.ServerNonce;

                // verify the server's certificate is the same as the certificate from the selected endpoint.
                if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel.");
                }

                // verify the server's signature.
                ISigner verifier = null;
                bool    verified = false;

                switch (this.RemoteEndpoint.SecurityPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    verifier = SignerUtilities.GetSigner("SHA-1withRSA");
                    verifier.Init(false, this.RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature);
                    break;

                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    verifier = SignerUtilities.GetSigner("SHA-256withRSA");
                    verifier.Init(false, this.RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature);
                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    verifier = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                    verifier.Init(false, this.RemotePublicKey);
                    verifier.BlockUpdate(localCertificate, 0, localCertificate.Length);
                    verifier.BlockUpdate(localNonce, 0, localNonce.Length);
                    verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature);
                    break;

                default:
                    verified = true;
                    break;
                }

                verifier = null;
                if (!verified)
                {
                    throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                }
            }

            // create client signature
            SignatureData clientSignature = null;
            ISigner       signer          = null;

            switch (this.RemoteEndpoint.SecurityPolicyUri)
            {
            case SecurityPolicyUris.Basic128Rsa15:
            case SecurityPolicyUris.Basic256:
                signer = SignerUtilities.GetSigner("SHA-1withRSA");
                signer.Init(true, this.LocalPrivateKey);
                signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = RsaSha1Signature,
                };

                break;

            case SecurityPolicyUris.Basic256Sha256:
            case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                signer = SignerUtilities.GetSigner("SHA-256withRSA");
                signer.Init(true, this.LocalPrivateKey);
                signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = RsaSha256Signature,
                };

                break;

            case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                signer.Init(true, this.LocalPrivateKey);
                signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                clientSignature = new SignatureData
                {
                    Signature = signer.GenerateSignature(),
                    Algorithm = RsaPssSha256Signature,
                };

                break;

            default:
                clientSignature = new SignatureData();
                break;
            }

            signer = null;

            // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken
            UserIdentityToken identityToken  = null;
            SignatureData     tokenSignature = null;

            // if UserIdentity type is IssuedIdentity
            if (this.UserIdentity is IssuedIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var             issuedIdentity  = (IssuedIdentity)this.UserIdentity;
                int             plainTextLength = issuedIdentity.TokenData.Length + this.RemoteNonce.Length;
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = cipherText,
                        EncryptionAlgorithm = RsaOaepSha256KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = issuedIdentity.TokenData,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
                encryptor      = null;
                cipherText     = null;
            }

            // if UserIdentity type is X509Identity
            else if (this.UserIdentity is X509Identity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var x509Identity = (X509Identity)this.UserIdentity;
                identityToken = new X509IdentityToken {
                    CertificateData = x509Identity.Certificate?.GetEncoded(), PolicyId = tokenPolicy.PolicyId
                };

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    signer = SignerUtilities.GetSigner("SHA-1withRSA");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                    signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = RsaSha1Signature,
                    };

                    break;

                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    signer = SignerUtilities.GetSigner("SHA-256withRSA");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                    signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = RsaSha256Signature,
                    };
                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1");
                    signer.Init(true, x509Identity.PrivateKey);
                    signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length);
                    signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length);
                    tokenSignature = new SignatureData
                    {
                        Signature = signer.GenerateSignature(),
                        Algorithm = RsaSha256Signature,
                    };
                    break;

                default:
                    tokenSignature = new SignatureData();
                    break;
                }

                signer = null;
            }

            // if UserIdentity type is UserNameIdentity
            else if (this.UserIdentity is UserNameIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var    userNameIdentity = (UserNameIdentity)this.UserIdentity;
                byte[] passwordBytes    = userNameIdentity.Password != null?System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password) : new byte[0];

                int             plainTextLength = passwordBytes.Length + this.RemoteNonce.Length;
                IBufferedCipher encryptor;
                byte[]          cipherText;
                int             pos;

                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                case SecurityPolicyUris.Aes128_Sha256_RsaOaep:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Aes256_Sha256_RsaPss:
                    encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING");
                    encryptor.Init(true, this.RemotePublicKey);
                    cipherText    = new byte[encryptor.GetOutputSize(4 + plainTextLength)];
                    pos           = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0);
                    pos           = encryptor.ProcessBytes(passwordBytes, cipherText, pos);
                    pos           = encryptor.DoFinal(this.RemoteNonce, cipherText, pos);
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = cipherText,
                        EncryptionAlgorithm = RsaOaepSha256KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = passwordBytes,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
                passwordBytes  = null;
                encryptor      = null;
                cipherText     = null;
            }

            // if UserIdentity type is AnonymousIdentity or null
            else
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new AnonymousIdentityToken {
                    PolicyId = tokenPolicy.PolicyId
                };
                tokenSignature = new SignatureData();
            }

            var activateSessionRequest = new ActivateSessionRequest
            {
                ClientSignature    = clientSignature,
                LocaleIds          = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName },
                UserIdentityToken  = identityToken,
                UserTokenSignature = tokenSignature
            };
            var activateSessionResponse = await this.ActivateSessionAsync(activateSessionRequest).ConfigureAwait(false);

            this.RemoteNonce = activateSessionResponse.ServerNonce;

            // fetch namespace array, etc.
            var readValueIds = new ReadValueId[]
            {
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_NamespaceArray),
                    AttributeId = AttributeIds.Value
                },
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_ServerArray),
                    AttributeId = AttributeIds.Value
                }
            };
            var readRequest = new ReadRequest
            {
                NodesToRead = readValueIds
            };

            var readResponse = await this.ReadAsync(readRequest).ConfigureAwait(false);

            if (readResponse.Results.Length == 2)
            {
                if (StatusCode.IsGood(readResponse.Results[0].StatusCode))
                {
                    this.NamespaceUris.Clear();
                    this.NamespaceUris.AddRange(readResponse.Results[0].GetValueOrDefault <string[]>());
                }

                if (StatusCode.IsGood(readResponse.Results[1].StatusCode))
                {
                    this.ServerUris.Clear();
                    this.ServerUris.AddRange(readResponse.Results[1].GetValueOrDefault <string[]>());
                }
            }

            // create the keep alive subscription.
            var subscriptionRequest = new CreateSubscriptionRequest
            {
                RequestedPublishingInterval = DefaultPublishingInterval,
                RequestedMaxKeepAliveCount  = DefaultKeepaliveCount,
                RequestedLifetimeCount      = DefaultKeepaliveCount * 3,
                PublishingEnabled           = true,
            };
            var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false);

            // link up the dataflow blocks
            var id        = subscriptionResponse.SubscriptionId;
            var linkToken = this.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id);

            // start publishing.
            this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token));
        }
        /// <summary>
        /// Activates a session.
        /// </summary>
        /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param>
        /// <param name="request">A <see cref="ActivateSessionRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="ActivateSessionResponse"/>.</returns>
        public static async Task <ActivateSessionResponse> ActivateSessionAsync(this IRequestChannel channel, ActivateSessionRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            return((ActivateSessionResponse)await channel.RequestAsync(request).ConfigureAwait(false));
        }
Example #5
0
        /// <summary>
        /// Activates a session.
        /// </summary>
        /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param>
        /// <param name="request">A <see cref="ActivateSessionRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="ActivateSessionResponse"/>.</returns>
        /// <seealso href="https://reference.opcfoundation.org/v104/Core/docs/Part4/5.6.3/">OPC UA specification Part 4: Services, 5.6.3</seealso>
        internal static async Task <ActivateSessionResponse> ActivateSessionAsync(this IRequestChannel channel, ActivateSessionRequest request, CancellationToken token = default)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return((ActivateSessionResponse)await channel.RequestAsync(request, token).ConfigureAwait(false));
        }
Example #6
0
        /// <summary>
        /// Begins an asynchronous invocation of the ActivateSession service.
        /// </summary>
        public IAsyncResult BeginActivateSession(
            RequestHeader                       requestHeader,
            SignatureData                       clientSignature,
            SignedSoftwareCertificateCollection clientSoftwareCertificates,
            StringCollection                    localeIds,
            ExtensionObject                     userIdentityToken,
            SignatureData                       userTokenSignature,
            AsyncCallback                       callback,
            object                              asyncState)
        {
            ActivateSessionRequest request = new ActivateSessionRequest();

            request.RequestHeader              = requestHeader;
            request.ClientSignature            = clientSignature;
            request.ClientSoftwareCertificates = clientSoftwareCertificates;
            request.LocaleIds                  = localeIds;
            request.UserIdentityToken          = userIdentityToken;
            request.UserTokenSignature         = userTokenSignature;

            UpdateRequestHeader(request, requestHeader == null, "ActivateSession");

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginActivateSession(new ActivateSessionMessage(request), callback, asyncState);
        }
Example #7
0
        /// <summary>
        /// Invokes the ActivateSession service.
        /// </summary>
        public virtual ResponseHeader ActivateSession(
            RequestHeader                       requestHeader,
            SignatureData                       clientSignature,
            SignedSoftwareCertificateCollection clientSoftwareCertificates,
            StringCollection                    localeIds,
            ExtensionObject                     userIdentityToken,
            SignatureData                       userTokenSignature,
            out byte[]                          serverNonce,
            out StatusCodeCollection            results,
            out DiagnosticInfoCollection        diagnosticInfos)
        {
            ActivateSessionRequest request = new ActivateSessionRequest();
            ActivateSessionResponse response = null;

            request.RequestHeader              = requestHeader;
            request.ClientSignature            = clientSignature;
            request.ClientSoftwareCertificates = clientSoftwareCertificates;
            request.LocaleIds                  = localeIds;
            request.UserIdentityToken          = userIdentityToken;
            request.UserTokenSignature         = userTokenSignature;

            UpdateRequestHeader(request, requestHeader == null, "ActivateSession");

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.SendRequest(request);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (ActivateSessionResponse)genericResponse;
                }
                else
                {
                    ActivateSessionResponseMessage responseMessage = InnerChannel.ActivateSession(new ActivateSessionMessage(request));

                    if (responseMessage == null || responseMessage.ActivateSessionResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.ActivateSessionResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                serverNonce     = response.ServerNonce;
                results         = response.Results;
                diagnosticInfos = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(request, response, "ActivateSession");
            }

            return response.ResponseHeader;
        }
Example #8
0
        protected override async Task OnOpenAsync(CancellationToken token)
        {
            await base.OnOpenAsync(token).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();

            // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession.
            // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce
            if (this.SessionId == null)
            {
                var localNonce           = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce() : null;
                var localCertificateBlob = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate.RawData : null;
                var createSessionRequest = new CreateSessionRequest
                {
                    ClientDescription       = this.LocalDescription,
                    EndpointUrl             = this.RemoteEndpoint.EndpointUrl,
                    SessionName             = this.LocalDescription.ApplicationName,
                    ClientNonce             = localNonce,
                    ClientCertificate       = localCertificateBlob,
                    RequestedSessionTimeout = this.SessionTimeout,
                    MaxResponseMessageSize  = this.RemoteMaxMessageSize
                };

                var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false);

                this.SessionId           = createSessionResponse.SessionId;
                this.AuthenticationToken = createSessionResponse.AuthenticationToken;
                this.RemoteNonce         = createSessionResponse.ServerNonce;

                // verify the server's certificate is the same as the certificate from the selected endpoint.
                if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel.");
                }

                // verify the server's signature.
                switch (this.RemoteEndpoint.SecurityPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    byte[] dataToVerify = Concat(localCertificateBlob, localNonce);
                    if (!this.RemotePublicKey.VerifyData(dataToVerify, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                    }

                    break;

                case SecurityPolicyUris.Basic256Sha256:
                    byte[] dataToVerify256 = Concat(localCertificateBlob, localNonce);
                    if (!this.RemotePublicKey.VerifyData(dataToVerify256, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                    }

                    break;

                default:
                    break;
                }
            }

            // create client signature
            SignatureData clientSignature = null;

            switch (this.RemoteEndpoint.SecurityPolicyUri)
            {
            case SecurityPolicyUris.Basic128Rsa15:
            case SecurityPolicyUris.Basic256:
                byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                clientSignature = new SignatureData
                {
                    Signature = this.LocalPrivateKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1),
                    Algorithm = RsaSha1Signature,
                };

                break;

            case SecurityPolicyUris.Basic256Sha256:
                byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                clientSignature = new SignatureData
                {
                    Signature = this.LocalPrivateKey.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
                    Algorithm = RsaSha256Signature,
                };

                break;

            default:
                clientSignature = new SignatureData();
                break;
            }

            // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken
            UserIdentityToken identityToken  = null;
            SignatureData     tokenSignature = null;

            // if UserIdentity type is IssuedIdentity
            if (this.UserIdentity is IssuedIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var    issuedIdentity = (IssuedIdentity)this.UserIdentity;
                byte[] plainText      = Concat(issuedIdentity.TokenData, this.RemoteNonce);
                var    secPolicyUri   = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                RSA    asymRemoteEncryptionKey;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                    identityToken           = new IssuedIdentityToken
                    {
                        TokenData           = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                    asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                    identityToken           = new IssuedIdentityToken
                    {
                        TokenData           = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new IssuedIdentityToken
                    {
                        TokenData           = issuedIdentity.TokenData,
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is X509Identity
            else if (this.UserIdentity is X509Identity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var x509Identity = (X509Identity)this.UserIdentity;
                identityToken = new X509IdentityToken {
                    CertificateData = x509Identity.Certificate?.RawData, PolicyId = tokenPolicy.PolicyId
                };
                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    var asymSigningKey = x509Identity.Certificate?.GetRSAPrivateKey();
                    if (asymSigningKey != null)
                    {
                        byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                        tokenSignature = new SignatureData
                        {
                            Signature = asymSigningKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1),
                            Algorithm = RsaSha1Signature,
                        };
                        break;
                    }

                    tokenSignature = new SignatureData();
                    break;

                case SecurityPolicyUris.Basic256Sha256:
                    var asymSigningKey256 = x509Identity.Certificate?.GetRSAPrivateKey();
                    if (asymSigningKey256 != null)
                    {
                        byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                        tokenSignature = new SignatureData
                        {
                            Signature = asymSigningKey256.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
                            Algorithm = RsaSha256Signature,
                        };
                        break;
                    }

                    tokenSignature = new SignatureData();
                    break;

                default:
                    tokenSignature = new SignatureData();
                    break;
                }
            }

            // if UserIdentity type is UserNameIdentity
            else if (this.UserIdentity is UserNameIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var    userNameIdentity = (UserNameIdentity)this.UserIdentity;
                byte[] plainText        = Concat(System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), this.RemoteNonce);
                var    secPolicyUri     = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                RSA    asymRemoteEncryptionKey;
                switch (secPolicyUri)
                {
                case SecurityPolicyUris.Basic128Rsa15:
                    asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                    identityToken           = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                        EncryptionAlgorithm = RsaV15KeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                case SecurityPolicyUris.Basic256:
                case SecurityPolicyUris.Basic256Sha256:
                    asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                    identityToken           = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                        EncryptionAlgorithm = RsaOaepKeyWrap,
                        PolicyId            = tokenPolicy.PolicyId
                    };

                    break;

                default:
                    identityToken = new UserNameIdentityToken
                    {
                        UserName            = userNameIdentity.UserName,
                        Password            = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password),
                        EncryptionAlgorithm = null,
                        PolicyId            = tokenPolicy.PolicyId
                    };
                    break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is AnonymousIdentity or null
            else
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new AnonymousIdentityToken {
                    PolicyId = tokenPolicy.PolicyId
                };
                tokenSignature = new SignatureData();
            }

            var activateSessionRequest = new ActivateSessionRequest
            {
                ClientSignature    = clientSignature,
                LocaleIds          = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName },
                UserIdentityToken  = identityToken,
                UserTokenSignature = tokenSignature
            };
            var activateSessionResponse = await this.ActivateSessionAsync(activateSessionRequest).ConfigureAwait(false);

            this.RemoteNonce = activateSessionResponse.ServerNonce;

            // fetch namespace array, etc.
            var readValueIds = new ReadValueId[]
            {
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_NamespaceArray),
                    AttributeId = AttributeIds.Value
                },
                new ReadValueId
                {
                    NodeId      = NodeId.Parse(VariableIds.Server_ServerArray),
                    AttributeId = AttributeIds.Value
                }
            };
            var readRequest = new ReadRequest
            {
                NodesToRead = readValueIds
            };

            var readResponse = await this.ReadAsync(readRequest).ConfigureAwait(false);

            if (readResponse.Results.Length == 2)
            {
                if (StatusCode.IsGood(readResponse.Results[0].StatusCode))
                {
                    this.NamespaceUris.Clear();
                    this.NamespaceUris.AddRange(readResponse.Results[0].GetValueOrDefault <string[]>());
                }

                if (StatusCode.IsGood(readResponse.Results[1].StatusCode))
                {
                    this.ServerUris.Clear();
                    this.ServerUris.AddRange(readResponse.Results[1].GetValueOrDefault <string[]>());
                }
            }
        }
Example #9
0
 /// <summary>
 /// Initializes the message with the body.
 /// </summary>
 public ActivateSessionMessage(ActivateSessionRequest ActivateSessionRequest)
 {
     this.ActivateSessionRequest = ActivateSessionRequest;
 }
        protected override async Task OnOpenAsync(CancellationToken token)
        {
            await base.OnOpenAsync(token).ConfigureAwait(false);
            token.ThrowIfCancellationRequested();

            // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession.
            // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce
            if (this.SessionId == null)
            {
                var localNonce = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce() : null;
                var localCertificateBlob = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate.RawData : null;
                var createSessionRequest = new CreateSessionRequest
                {
                    RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow },
                    ClientDescription = this.LocalDescription,
                    EndpointUrl = this.RemoteEndpoint.EndpointUrl,
                    SessionName = this.LocalDescription.ApplicationName,
                    ClientNonce = localNonce,
                    ClientCertificate = localCertificateBlob,
                    RequestedSessionTimeout = this.SessionTimeout,
                    MaxResponseMessageSize = this.RemoteMaxMessageSize
                };
                var createSessionResponse = (CreateSessionResponse)await this.RequestAsync(createSessionRequest).ConfigureAwait(false);
                this.SessionId = createSessionResponse.SessionId;
                this.AuthenticationToken = createSessionResponse.AuthenticationToken;
                this.RemoteNonce = createSessionResponse.ServerNonce;

                // verify the server's certificate is the same as the certificate from the selected endpoint.
                if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate))
                {
                    throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel.");
                }

                // verify the server's signature.
                switch (this.RemoteEndpoint.SecurityPolicyUri)
                {
                    case SecurityPolicyUris.Basic128Rsa15:
                    case SecurityPolicyUris.Basic256:
                        byte[] dataToVerify = Concat(localCertificateBlob, localNonce);
                        if (!this.RemotePublicKey.VerifyData(dataToVerify, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1))
                        {
                            throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                        }

                        break;

                    case SecurityPolicyUris.Basic256Sha256:
                        byte[] dataToVerify256 = Concat(localCertificateBlob, localNonce);
                        if (!this.RemotePublicKey.VerifyData(dataToVerify256, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
                        {
                            throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client.");
                        }

                        break;

                    default:
                        break;
                }
            }

            // create client signature
            SignatureData clientSignature = null;
            switch (this.RemoteEndpoint.SecurityPolicyUri)
            {
                case SecurityPolicyUris.Basic128Rsa15:
                case SecurityPolicyUris.Basic256:
                    byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                    clientSignature = new SignatureData
                    {
                        Signature = this.LocalPrivateKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1),
                        Algorithm = RsaSha1Signature,
                    };

                    break;

                case SecurityPolicyUris.Basic256Sha256:
                    byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                    clientSignature = new SignatureData
                    {
                        Signature = this.LocalPrivateKey.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
                        Algorithm = RsaSha256Signature,
                    };

                    break;

                default:
                    clientSignature = new SignatureData();
                    break;
            }

            // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken
            UserIdentityToken identityToken = null;
            SignatureData tokenSignature = null;

            // if UserIdentity type is IssuedIdentity
            if (this.UserIdentity is IssuedIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var issuedIdentity = (IssuedIdentity)this.UserIdentity;
                byte[] plainText = Concat(issuedIdentity.TokenData, this.RemoteNonce);
                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                RSA asymRemoteEncryptionKey;
                switch (secPolicyUri)
                {
                    case SecurityPolicyUris.Basic128Rsa15:
                        asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                        identityToken = new IssuedIdentityToken
                        {
                            TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                            EncryptionAlgorithm = RsaV15KeyWrap,
                            PolicyId = tokenPolicy.PolicyId
                        };

                        break;

                    case SecurityPolicyUris.Basic256:
                    case SecurityPolicyUris.Basic256Sha256:
                        asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                        identityToken = new IssuedIdentityToken
                        {
                            TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                            EncryptionAlgorithm = RsaOaepKeyWrap,
                            PolicyId = tokenPolicy.PolicyId
                        };

                        break;

                    default:
                        identityToken = new IssuedIdentityToken
                        {
                            TokenData = issuedIdentity.TokenData,
                            EncryptionAlgorithm = null,
                            PolicyId = tokenPolicy.PolicyId
                        };
                        break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is X509Identity
            else if (this.UserIdentity is X509Identity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var x509Identity = (X509Identity)this.UserIdentity;
                identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.RawData, PolicyId = tokenPolicy.PolicyId };
                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                switch (secPolicyUri)
                {
                    case SecurityPolicyUris.Basic128Rsa15:
                    case SecurityPolicyUris.Basic256:
                        var asymSigningKey = x509Identity.Certificate?.GetRSAPrivateKey();
                        if (asymSigningKey != null)
                        {
                            byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                            tokenSignature = new SignatureData
                            {
                                Signature = asymSigningKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1),
                                Algorithm = RsaSha1Signature,
                            };
                            break;
                        }

                        tokenSignature = new SignatureData();
                        break;

                    case SecurityPolicyUris.Basic256Sha256:
                        var asymSigningKey256 = x509Identity.Certificate?.GetRSAPrivateKey();
                        if (asymSigningKey256 != null)
                        {
                            byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce);
                            tokenSignature = new SignatureData
                            {
                                Signature = asymSigningKey256.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1),
                                Algorithm = RsaSha256Signature,
                            };
                            break;
                        }

                        tokenSignature = new SignatureData();
                        break;

                    default:
                        tokenSignature = new SignatureData();
                        break;
                }
            }

            // if UserIdentity type is UserNameIdentity
            else if (this.UserIdentity is UserNameIdentity)
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                var userNameIdentity = (UserNameIdentity)this.UserIdentity;
                byte[] plainText = Concat(System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), this.RemoteNonce);
                var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri;
                RSA asymRemoteEncryptionKey;
                switch (secPolicyUri)
                {
                    case SecurityPolicyUris.Basic128Rsa15:
                        asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                        identityToken = new UserNameIdentityToken
                        {
                            UserName = userNameIdentity.UserName,
                            Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                            EncryptionAlgorithm = RsaV15KeyWrap,
                            PolicyId = tokenPolicy.PolicyId
                        };

                        break;

                    case SecurityPolicyUris.Basic256:
                    case SecurityPolicyUris.Basic256Sha256:
                        asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey();
                        identityToken = new UserNameIdentityToken
                        {
                            UserName = userNameIdentity.UserName,
                            Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri),
                            EncryptionAlgorithm = RsaOaepKeyWrap,
                            PolicyId = tokenPolicy.PolicyId
                        };

                        break;

                    default:
                        identityToken = new UserNameIdentityToken
                        {
                            UserName = userNameIdentity.UserName,
                            Password = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password),
                            EncryptionAlgorithm = null,
                            PolicyId = tokenPolicy.PolicyId
                        };
                        break;
                }

                tokenSignature = new SignatureData();
            }

            // if UserIdentity type is AnonymousIdentity or null
            else
            {
                var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                if (tokenPolicy == null)
                {
                    throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected);
                }

                identityToken = new AnonymousIdentityToken { PolicyId = tokenPolicy.PolicyId };
                tokenSignature = new SignatureData();
            }

            var activateSessionRequest = new ActivateSessionRequest
            {
                RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow },
                ClientSignature = clientSignature,
                LocaleIds = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName },
                UserIdentityToken = identityToken,
                UserTokenSignature = tokenSignature
            };
            var activateSessionResponse = (ActivateSessionResponse)await this.RequestAsync(activateSessionRequest).ConfigureAwait(false);
            this.RemoteNonce = activateSessionResponse.ServerNonce;
            await this.FetchNamespaceTablesAsync().ConfigureAwait(false);
        }