Opc.Ua.Server.Session.ValidateUserIdentityToken C# (CSharp) Method

ValidateUserIdentityToken() private method

Validates the identity token supplied by the client.
private ValidateUserIdentityToken ( ExtensionObject identityToken, SignatureData userTokenSignature, UserTokenPolicy &policy ) : UserIdentityToken
identityToken ExtensionObject
userTokenSignature SignatureData
policy UserTokenPolicy
return UserIdentityToken
        private UserIdentityToken ValidateUserIdentityToken(
            ExtensionObject identityToken,
            SignatureData userTokenSignature,
            out UserTokenPolicy policy )
        {
            policy = null;

            // check for empty token.
            if (identityToken == null || identityToken.Body == null)
            {
                // not changing the token if already activated.
                if (m_activated)
                {
                    return null;
                }

                // check if an anonymous login is permitted.
                if (m_endpoint.UserIdentityTokens != null && m_endpoint.UserIdentityTokens.Count > 0)
                {
                    bool found = false;

                    for (int ii = 0; ii < m_endpoint.UserIdentityTokens.Count; ii++)
                    {
                        if (m_endpoint.UserIdentityTokens[ii].TokenType == UserTokenType.Anonymous)
                        {
                            found = true;
                            policy = m_endpoint.UserIdentityTokens[ii];
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied, "Anonymous user token policy not supported.");
                    }
                }

                // create an anonymous token to use for subsequent validation.
                AnonymousIdentityToken anonymousToken = new AnonymousIdentityToken();
                anonymousToken.PolicyId = policy.PolicyId;
                return anonymousToken;
            }

            UserIdentityToken token = null;
            // check for unrecognized token.
            if (!typeof( UserIdentityToken ).IsInstanceOfType( identityToken.Body ))
            {
                //handle the use case when the UserIdentityToken is binary encoded over xml message encoding
                if (identityToken.Encoding == ExtensionObjectEncoding.Binary && typeof( byte[] ).IsInstanceOfType( identityToken.Body ))
                {
                    UserIdentityToken newToken = BaseVariableState.DecodeExtensionObject( null, typeof( UserIdentityToken ), identityToken, false ) as UserIdentityToken;
                    if (newToken == null)
                    {
                        throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                    }

                    policy = m_endpoint.FindUserTokenPolicy( newToken.PolicyId );
                    if (policy == null)
                    {
                        throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "User token policy not supported.", "Opc.Ua.Server.Session.ValidateUserIdentityToken" );
                    }
                    switch (policy.TokenType)
                    {
                        case UserTokenType.Anonymous:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( AnonymousIdentityToken ), identityToken, true ) as AnonymousIdentityToken;
                            break;
                        case UserTokenType.UserName:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( UserNameIdentityToken ), identityToken, true ) as UserNameIdentityToken;
                            break;
                        case UserTokenType.Certificate:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( X509IdentityToken ), identityToken, true ) as X509IdentityToken;
                            break;
                        case UserTokenType.IssuedToken:
                            token = BaseVariableState.DecodeExtensionObject( null, typeof( IssuedIdentityToken ), identityToken, true ) as IssuedIdentityToken;
                            break;
                        default:
                            throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                    }
                }
                else
                {
                    throw ServiceResultException.Create( StatusCodes.BadUserAccessDenied, "Invalid user identity token provided." );
                }
            }
            else
            {
                // get the token.
                token = (UserIdentityToken) identityToken.Body;
            }

            // find the user token policy.
            policy = m_endpoint.FindUserTokenPolicy( token.PolicyId );

            if (policy == null)
            {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, "User token policy not supported.");
            }

            // determine the security policy uri.
            string securityPolicyUri = policy.SecurityPolicyUri;

            if (String.IsNullOrEmpty( securityPolicyUri ))
            {
                securityPolicyUri = m_endpoint.SecurityPolicyUri;
            }

            if (ServerBase.RequireEncryption(m_endpoint))
            {
                // decrypt the token.
                if (m_serverCertificate == null)
                {
                    m_serverCertificate = CertificateFactory.Create(m_endpoint.ServerCertificate, true);

                    // check for valid certificate.
                    if (m_serverCertificate == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadConfigurationError, "ApplicationCertificate cannot be found.");
                    }
                }

                try
                {
                    token.Decrypt(m_serverCertificate, m_serverNonce, securityPolicyUri);
                }
                catch (Exception e)
                {
                    if (e is ServiceResultException)
                    {
                        throw;
                    }

                    throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid, e, "Could not decrypt identity token.");
                }

                // verify the signature.
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                    {
                        throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid, "Invalid user signature!");
                    }
                }
            }
				
            // validate user identity token.
            return token;
        }