/// <summary>
            /// Verify user token signature
            /// </summary>
            /// <param name="userTokenSignature"></param>
            /// <param name="token"></param>
            /// <param name="securityPolicyUri"></param>
            private void VerifyUserTokenSignature(SignatureData userTokenSignature,
                                                  UserIdentityToken token, string securityPolicyUri)
            {
                // Verify with leaf certificate
                var dataToSign = Utils.Append(_serverCertificate.RawData, _serverNonce);

                if (token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                {
                    return;
                }
                // Validate the signature with complete chain
                var serverCertificateChain = Utils.ParseCertificateChainBlob(
                    Endpoint.ServerCertificate);

                if (serverCertificateChain.Count <= 1)
                {
                    throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid,
                                                     "Invalid user signature!");
                }
                var serverCertificateChainList = new List <byte>();

                for (var i = 0; i < serverCertificateChain.Count; i++)
                {
                    serverCertificateChainList.AddRange(
                        serverCertificateChain[i].RawData);
                }
                var serverCertificateChainData = serverCertificateChainList.ToArray();

                dataToSign = Utils.Append(serverCertificateChainData, _serverNonce);
                if (!token.Verify(dataToSign, userTokenSignature, securityPolicyUri))
                {
                    throw new ServiceResultException(StatusCodes.BadUserSignatureInvalid,
                                                     "Invalid user signature!");
                }
            }
        /// <summary>
        /// Convert user identity token to service model
        /// </summary>
        /// <param name="token"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public static CredentialModel ToServiceModel(this UserIdentityToken token,
                                                     IJsonSerializer serializer)
        {
            if (token == null)
            {
                return(null);  // Treat as anonymous
            }
            switch (token)
            {
            case IssuedIdentityToken it:
                switch (it.IssuedTokenType)
                {
                case IssuedTokenType.JWT:
                    return(new CredentialModel {
                        Type = CredentialType.JwtToken,
                        Value = serializer.FromObject(it.DecryptedTokenData)
                    });

                case IssuedTokenType.SAML:
                // TODO?
                default:
                    throw new ServiceResultException(
                              StatusCodes.BadNotSupported,
                              $"Token type {it.IssuedTokenType} is not supported");
                }

            case AnonymousIdentityToken ai:
                return(null);

            case UserNameIdentityToken un:
                return(new CredentialModel {
                    Type = CredentialType.UserName,
                    Value = serializer.FromObject(new {
                        user = un.UserName,
                        password = un.DecryptedPassword
                    })
                });

            case X509IdentityToken x5:
                return(new CredentialModel {
                    Type = CredentialType.X509Certificate,
                    Value = serializer.FromObject(x5.CertificateData)
                });

            default:
                throw new ServiceResultException(StatusCodes.BadNotSupported,
                                                 $"User identity token type {token.GetType()} is unsupported");
            }
        }
Example #3
0
        private async void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                var token         = txtToken.Text;
                var applicationId = new Guid(txtApplicationId.Text);

                var uit = await UserIdentityToken.ParseAsync(token, applicationId);

                MessageBox.Show("The token was valid, UserId = " + uit.UserId);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"An error occurred while validating the user identity token:  {ex.Message}");
            }
        }
        /// <summary>
        /// Validate user identity
        /// </summary>
        /// <param name="newIdentity"></param>
        /// <param name="userTokenPolicy"></param>
        /// <returns></returns>
        private static IUserIdentity ValidateUserIdentity(UserIdentityToken newIdentity,
                                                          UserTokenPolicy userTokenPolicy)
        {
            System.Diagnostics.Contracts.Contract.Ensures(userTokenPolicy != null);
            try {
                IUserIdentity identity          = null;
                IUserIdentity effectiveIdentity = null;

                // Validate the identity token and impersonate user.

                // TODO

                // lock (_eventLock) {
                // if (_impersonateUser != null) {
                //
                //     var args = new ImpersonateEventArgs(newIdentity, userTokenPolicy);
                //     _impersonateUser(session, args);
                //
                //     if (ServiceResult.IsBad(args.IdentityValidationError)) {
                //         error = args.IdentityValidationError;
                // if (ServiceResult.IsBad(error)) {
                //     throw new ServiceResultException(error);
                // }
                //     }
                //     else {
                //         identity = args.Identity;
                //         return args.EffectiveIdentity;
                //     }
                // }
                // }

                // check for validation error.
                if (identity == null)
                {
                    identity = new UserIdentity(newIdentity);
                }
                // use the identity as the effectiveIdentity if not provided.
                return(effectiveIdentity ?? identity);
            }
            catch (ServiceResultException) {
                throw;
            }
            catch (Exception e) {
                throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                    e, "Could not validate user identity token: {0}", newIdentity);
            }
        }
Example #5
0
        protected override OperationContext ValidateRequest(RequestHeader requestHeader, RequestType requestType)
        {
            OperationContext context = new OperationContext(requestHeader, requestType);

            try
            {
                context = base.ValidateRequest(requestHeader, requestType);
                if (requestType != RequestType.Write)
                {
                    return(context);
                }
                // reject all writes if no user provided.
                if (context.UserIdentity.TokenType == UserTokenType.Anonymous)
                {
                    // construct translation object with default text.
                    TranslationInfo info = new TranslationInfo(
                        "NoWriteAllowed",
                        "en-US",
                        "Must provide a valid user before calling write.");
                    // create an exception with a vendor defined sub-code.
                    throw new ServiceResultException(new ServiceResult(
                                                         StatusCodes.BadUserAccessDenied,
                                                         "NoWriteAllowed",
                                                         Namespaces.OpcUa,
                                                         new LocalizedText(info)));
                }
                UserIdentityToken securityToken = context.UserIdentity.GetIdentityToken();
                // check for a user name token.
                if (!(securityToken is UserNameIdentityToken))
                {
                    return(context);
                }
                lock (_requestLock)
                {
                    _contexts.Add(context.RequestId, new ImpersonationContext());
                }
                return(context);
            }
            catch (Exception e)
            {
                Utils.Trace($"Session Manager Impersonate Exception:\r\n{e.StackTrace}");
            }
            return(context);
        }
Example #6
0
        /// <summary>
        /// This method is called at the being of the thread that processes a request.
        /// </summary>
        protected override OperationContext ValidateRequest(RequestHeader requestHeader, RequestType requestType)
        {
            OperationContext context = base.ValidateRequest(requestHeader, requestType);

            if (requestType == RequestType.Write)
            {
                // reject all writes if no user provided.
                if (context.UserIdentity.TokenType == UserTokenType.Anonymous)
                {
                    // construct translation object with default text.
                    TranslationInfo info = new TranslationInfo(
                        "NoWriteAllowed",
                        "en-US",
                        "Must provide a valid user before calling write.");

                    // create an exception with a vendor defined sub-code.
                    throw new ServiceResultException(new ServiceResult(
                                                         StatusCodes.BadUserAccessDenied,
                                                         "NoWriteAllowed",
                                                         Opc.Ua.Gds.Namespaces.OpcUaGds,
                                                         new LocalizedText(info)));
                }

                UserIdentityToken securityToken = context.UserIdentity.GetIdentityToken();

                // check for a user name token.
                UserNameIdentityToken userNameToken = securityToken as UserNameIdentityToken;
                if (userNameToken != null)
                {
                    lock (m_lock)
                    {
                        m_contexts.Add(context.RequestId, new ImpersonationContext());
                    }
                }
            }

            return(context);
        }
Example #7
0
        public static BASEAuthenticationResult AuthenticateUserAndSetToken(string username, string password, int?siteUID)
        {
            UserIdentityToken token = null;

            try
            {
                token = UserIdentityToken.CreateToken(username, password, siteUID);

                if (token == null)
                {
                    return(BASEAuthenticationResult.InvalidUsernameOrPassword);
                }
                else if (token.IsExpired)
                {
                    return(BASEAuthenticationResult.Expired);
                }
                else if (token.IsDisabled)
                {
                    return(BASEAuthenticationResult.Disabled);
                }
                else if (!token.IsValidToken)
                {
                    return(BASEAuthenticationResult.NotValid);
                }

                BASE.Web.SessionState.SessionManager.AddUserToken(token);

                return(BASEAuthenticationResult.Success);
            }
            catch (Exception ex)
            {
#if DEBUG
                throw;
#else
                return(BASEAuthenticationResult.ExceptionCaught);
#endif
            }
        }
Example #8
0
        public static UserIdentityToken GetUserToken()
        {
            //Get context ready
            HttpContext context = HttpContext.Current;

            //Try first gettoing token from session state. May not exist if user logged in in a previous session.
            UserIdentityToken token = (UserIdentityToken)Get(SessionKeys.UserToken);

            if (token == null)
            {
                //get again from DB
                BASE.Logging.Logger.Log("Getting UserToken from DB at SessionManager.GetUserToken()", BASE.Logging.LogPriority.Debug, "SESSIONSTATE");
                if (context.User == null || !context.User.Identity.IsAuthenticated)
                {
                    //Anonymous user, so load anonymous usertoken.
                    token = UserIdentityToken.CreateAnonymousToken(SystemManager.Current.AnonymousGuid);
                }
                else
                {
                    //Authenticated user, load the token.
                    token = UserIdentityToken.CreateTokenNoSecCheck(new Guid(context.User.Identity.Name));
                }

                if (token.IsValidToken)
                {
                    AddUserToken(token);
                }
                else
                {
                    throw new BASEGenericException("Invalid Token");
                }
            }

            //TODO: Add extra checking/security
            return(token);
        }
Example #9
0
        /// <summary>
        /// Updates the user identity.
        /// </summary>
        /// <returns>true if the new identity is different from the old identity.</returns>
        private bool UpdateUserIdentity(
            UserIdentityToken identityToken,
            IUserIdentity identity,
            IUserIdentity effectiveIdentity)
        {
            if (identityToken == null)
            {
                throw new ArgumentNullException("identityToken");
            }

            lock (m_lock)
            {
                bool changed = m_effectiveIdentity == null && effectiveIdentity != null;

                if (m_effectiveIdentity != null)
                {
                    changed = !m_effectiveIdentity.Equals(effectiveIdentity);
                }

                // always save the new identity since it may have additional information that does not affect equality.
                m_identityToken     = identityToken;
                m_identity          = identity;
                m_effectiveIdentity = effectiveIdentity;

                // update diagnostics.
                lock (m_diagnostics)
                {
                    m_securityDiagnostics.ClientUserIdOfSession   = identity.DisplayName;
                    m_securityDiagnostics.AuthenticationMechanism = identity.TokenType.ToString();

                    m_securityDiagnostics.ClientUserIdHistory.Add(identity.DisplayName);
                }

                return(changed);
            }
        }
Example #10
0
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext context,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            byte[]                    serverNonce,
            out UserIdentityToken identityToken,
            out UserTokenPolicy userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);
                    //byte[] dataToSign = Utils.Append(m_serverCertificateChain, m_serverNonce);

                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }
                }

                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext          context,
            SignatureData             clientSignature,
            List<SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject           userIdentityToken,
            SignatureData             userTokenSignature,
            StringCollection          localeIds,
            byte[]                    serverNonce,
            out UserIdentityToken     identityToken,
            out UserTokenPolicy       userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);
                    
                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }
                }
                   
                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }    
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public bool Activate(
            OperationContext          context,
            List<SoftwareCertificate> clientSoftwareCertificates,
            UserIdentityToken         identityToken,
            IUserIdentity             identity,
            IUserIdentity             effectiveIdentity,
            StringCollection          localeIds,
            byte[]                    serverNonce)
        {
            lock (m_lock)
            {
                // update user identity.
                bool changed = false;

                if (identityToken != null)
                {
                    if (UpdateUserIdentity(identityToken, identity, effectiveIdentity))
                    {
                        changed = true;
                    }
                }
                
                // update local ids.
                if (UpdateLocaleIds( localeIds ))
                {
                    changed = true;
                }

                if (!m_activated)
                {
                    // toggle the activated flag.
                    m_activated = true;

                    // save the software certificates.
                    m_softwareCertificates = clientSoftwareCertificates;

                    TraceState("FIRST ACTIVATION");
                }
                else
                {
                    // bind to the new secure channel.
                    m_secureChannelId = context.ChannelContext.SecureChannelId;      

                    TraceState("RE-ACTIVATION");  
                }

                // update server nonce.
                m_serverNonce = serverNonce;
                    
                // build list of signed certificates for audit event.
                List<SignedSoftwareCertificate> signedSoftwareCertificates = new List<SignedSoftwareCertificate>();

                if (clientSoftwareCertificates != null)
                {
                    foreach (SoftwareCertificate softwareCertificate in clientSoftwareCertificates)
                    {
                        SignedSoftwareCertificate item = new SignedSoftwareCertificate();
                        item.CertificateData = softwareCertificate.SignedCertificate.RawData;
                        signedSoftwareCertificates.Add(item);
                    }
                }

                // raise an audit event.
                ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(context);
                ReportAuditActivateSessionEvent(systemContext);

                // update the contact time.
                lock (m_diagnostics)
                {
                    m_diagnostics.ClientLastContactTime = DateTime.UtcNow;
                }

                // indicate whether the user context has changed.
                return changed;
            }
        }
Example #13
0
 public async Task UserIdentityToken_EmptyGuidApplication()
 {
     var token = await UserIdentityToken.ParseAsync("valid token", Guid.Empty);
 }
        /// <summary>
        /// Updates the user identity.
        /// </summary>
        /// <returns>true if the new identity is different from the old identity.</returns>
        private bool UpdateUserIdentity(
            UserIdentityToken identityToken, 
            IUserIdentity     identity, 
            IUserIdentity     effectiveIdentity)
        {
            if (identityToken == null) throw new ArgumentNullException("identityToken");
                        
            lock (m_lock)
            {
                bool changed = m_effectiveIdentity == null && effectiveIdentity != null;
                
                if (m_effectiveIdentity != null)
                {
                    changed = !m_effectiveIdentity.Equals(effectiveIdentity);
                }
                
                // always save the new identity since it may have additional information that does not affect equality.
                m_identityToken = identityToken;
                m_identity = identity;
                m_effectiveIdentity = effectiveIdentity;
                                                                
                // update diagnostics.
                lock (m_diagnostics)
                {
                    m_securityDiagnostics.ClientUserIdOfSession   = identity.DisplayName;
                    m_securityDiagnostics.AuthenticationMechanism = identity.TokenType.ToString();

                    m_securityDiagnostics.ClientUserIdHistory.Add(identity.DisplayName);
                }

                return changed;
            }
        }
Example #15
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy, EndpointDescription endpointDescription = null)
 {
     m_newIdentity         = newIdentity;
     m_userTokenPolicy     = userTokenPolicy;
     m_endpointDescription = endpointDescription;
 }
Example #16
0
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public void ValidateBeforeActivate(
            OperationContext context,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            byte[] serverNonce,
            out UserIdentityToken identityToken,
            out UserTokenPolicy userTokenPolicy)
        {
            lock (m_lock)
            {
                // verify that a secure channel was specified.
                if (context.ChannelContext == null)
                {
                    throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                }

                // verify that the same security policy has been used.
                EndpointDescription endpoint = context.ChannelContext.EndpointDescription;

                if (endpoint.SecurityPolicyUri != m_endpoint.SecurityPolicyUri || endpoint.SecurityMode != m_endpoint.SecurityMode)
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityPolicyRejected);
                }

                // verify the client signature.
                if (m_clientCertificate != null)
                {
                    if (m_endpoint.SecurityPolicyUri != SecurityPolicies.None && clientSignature != null && clientSignature.Signature == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                    }

                    byte[] dataToSign = Utils.Append(m_serverCertificate.RawData, m_serverNonce);

                    if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                    {
                        // verify for certificate chain in endpoint.
                        // validate the signature with complete chain if the check with leaf certificate failed.
                        X509Certificate2Collection serverCertificateChain = Utils.ParseCertificateChainBlob(m_endpoint.ServerCertificate);

                        if (serverCertificateChain.Count > 1)
                        {
                            List <byte> serverCertificateChainList = new List <byte>();

                            for (int i = 0; i < serverCertificateChain.Count; i++)
                            {
                                serverCertificateChainList.AddRange(serverCertificateChain[i].RawData);
                            }

                            byte[] serverCertificateChainData = serverCertificateChainList.ToArray();
                            dataToSign = Utils.Append(serverCertificateChainData, m_serverNonce);

                            if (!SecurityPolicies.Verify(m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, clientSignature))
                            {
                                throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                            }
                        }
                        else
                        {
                            throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid);
                        }
                    }
                }

                if (!m_activated)
                {
                    // must active the session on the channel that was used to create it.
                    if (m_secureChannelId != context.ChannelContext.SecureChannelId)
                    {
                        throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid);
                    }
                }
                else
                {
                    // cannot change the certificates after activation.
                    if (clientSoftwareCertificates != null && clientSoftwareCertificates.Count > 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidArgument);
                    }
                }

                // validate the user identity token.
                identityToken = ValidateUserIdentityToken(userIdentityToken, userTokenSignature, out userTokenPolicy);

                TraceState("VALIDATED");
            }
        }
Example #17
0
 public void UserIdentityToken_Constructor_Success()
 {
     var token = new UserIdentityToken(new SigningKeysCache());
 }
        /// <summary>
        /// Activates an existing session
        /// </summary>
        public virtual bool ActivateSession(
            OperationContext context,
            NodeId authenticationToken,
            SignatureData clientSignature,
            List <SoftwareCertificate> clientSoftwareCertificates,
            ExtensionObject userIdentityToken,
            SignatureData userTokenSignature,
            StringCollection localeIds,
            out byte[] serverNonce)
        {
            serverNonce = null;

            Session           session         = null;
            UserIdentityToken newIdentity     = null;
            UserTokenPolicy   userTokenPolicy = null;

            lock (m_lock)
            {
                // find session.
                if (!m_sessions.TryGetValue(authenticationToken, out session))
                {
                    throw new ServiceResultException(StatusCodes.BadSessionClosed);
                }

                // check if session timeout has expired.
                if (session.HasExpired)
                {
                    m_server.CloseSession(null, session.Id, false);
                    throw new ServiceResultException(StatusCodes.BadSessionClosed);
                }

                // create new server nonce.
                serverNonce = Utils.Nonce.CreateNonce((uint)m_minNonceLength);

                // validate before activation.
                session.ValidateBeforeActivate(
                    context,
                    clientSignature,
                    clientSoftwareCertificates,
                    userIdentityToken,
                    userTokenSignature,
                    localeIds,
                    serverNonce,
                    out newIdentity,
                    out userTokenPolicy);
            }

            IUserIdentity identity          = null;
            IUserIdentity effectiveIdentity = null;
            ServiceResult error             = null;

            try
            {
                // check if the application has a callback which validates the identity tokens.
                lock (m_eventLock)
                {
                    if (m_ImpersonateUser != null)
                    {
                        ImpersonateEventArgs args = new ImpersonateEventArgs(newIdentity, userTokenPolicy);
                        m_ImpersonateUser(session, args);

                        if (ServiceResult.IsBad(args.IdentityValidationError))
                        {
                            error = args.IdentityValidationError;
                        }
                        else
                        {
                            identity          = args.Identity;
                            effectiveIdentity = args.EffectiveIdentity;
                        }
                    }
                }

                // parse the token manually if the identity is not provided.
                if (identity == null)
                {
                    identity = new UserIdentity(newIdentity);
                }

                // use the identity as the effectiveIdentity if not provided.
                if (effectiveIdentity == null)
                {
                    effectiveIdentity = identity;
                }
            }
            catch (Exception e)
            {
                if (e is ServiceResultException)
                {
                    throw e;
                }

                throw ServiceResultException.Create(
                          StatusCodes.BadIdentityTokenInvalid,
                          e,
                          "Could not validate user identity token: {0}",
                          newIdentity);
            }

            // check for validation error.
            if (ServiceResult.IsBad(error))
            {
                throw new ServiceResultException(error);
            }

            // activate session.
            bool contextChanged = session.Activate(
                context,
                clientSoftwareCertificates,
                newIdentity,
                identity,
                effectiveIdentity,
                localeIds,
                serverNonce);

            // raise session related event.
            if (contextChanged)
            {
                RaiseSessionEvent(session, SessionEventReason.Activated);
            }

            // indicates that the identity context for the session has changed.
            return(contextChanged);
        }
Example #19
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[]>());
                }
            }
        }
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                // check that discover has completed.
                if (!m_discoverySucceeded)
                {
                    DialogResult result = MessageBox.Show(
                        "Endpoint information may be out of date because the discovery process has not completed. Continue anyways?",
                        this.Text,
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Warning);

                    if (result != DialogResult.Yes)
                    {
                        return;
                    }
                }

                EndpointConfiguration configuration = m_endpointConfiguration;

                if (configuration == null)
                {
                    configuration = EndpointConfiguration.Create(m_configuration);
                }

                if (m_currentDescription == null)
                {
                    m_currentDescription = CreateDescriptionFromSelections();
                }

                // the discovery endpoint should always be on the same machine as the server.
                // if there is a mismatch it is likely because the server has multiple addresses
                // and was not configured to return the current address to the client.
                // The code automatically updates the domain in the url.
                Uri endpointUrl = Utils.ParseUri(m_currentDescription.EndpointUrl);

                if (m_discoverySucceeded)
                {
                    if (!Utils.AreDomainsEqual(endpointUrl, m_discoveryUrl))
                    {
                        UriBuilder url = new UriBuilder(endpointUrl);

                        url.Host = m_discoveryUrl.DnsSafeHost;

                        if (url.Scheme == m_discoveryUrl.Scheme)
                        {
                            url.Port = m_discoveryUrl.Port;
                        }

                        endpointUrl = url.Uri;

                        m_currentDescription.EndpointUrl = endpointUrl.ToString();
                    }
                }

                // set the encoding.
                Encoding encoding = (Encoding)EncodingCB.SelectedItem;
                configuration.UseBinaryEncoding = encoding != Encoding.Xml;

                if (m_endpoint == null)
                {
                    m_endpoint = new ConfiguredEndpoint(null, m_currentDescription, configuration);
                }
                else
                {
                    m_endpoint.Update(m_currentDescription);
                    m_endpoint.Update(configuration);
                }

                // set the user token policy.
                m_endpoint.SelectedUserTokenPolicyIndex = FindBestUserTokenPolicy(m_currentDescription);

                // update the user identity.
                UserTokenType userTokenType = (UserTokenType)UserTokenTypeCB.SelectedItem;

                UserIdentityToken userIdentity = null;

                if (!m_userIdentities.TryGetValue(userTokenType, out userIdentity))
                {
                    userIdentity = null;
                }

                m_endpoint.UserIdentity = userIdentity;

                DialogResult = DialogResult.OK;
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Example #21
0
 public async Task UserIdentityToken_NullToken()
 {
     var token = await UserIdentityToken.ParseAsync(null, Guid.NewGuid());
 }
Example #22
0
        /// <summary>
        /// Activates the session and binds it to the current secure channel.
        /// </summary>
        public bool Activate(
            OperationContext context,
            List <SoftwareCertificate> clientSoftwareCertificates,
            UserIdentityToken identityToken,
            IUserIdentity identity,
            IUserIdentity effectiveIdentity,
            StringCollection localeIds,
            byte[]                    serverNonce)
        {
            lock (m_lock)
            {
                // update user identity.
                bool changed = false;

                if (identityToken != null)
                {
                    if (UpdateUserIdentity(identityToken, identity, effectiveIdentity))
                    {
                        changed = true;
                    }
                }

                // update local ids.
                if (UpdateLocaleIds(localeIds))
                {
                    changed = true;
                }

                if (!m_activated)
                {
                    // toggle the activated flag.
                    m_activated = true;

                    // save the software certificates.
                    m_softwareCertificates = clientSoftwareCertificates;

                    TraceState("FIRST ACTIVATION");
                }
                else
                {
                    // bind to the new secure channel.
                    m_secureChannelId = context.ChannelContext.SecureChannelId;

                    TraceState("RE-ACTIVATION");
                }

                // update server nonce.
                m_serverNonce = serverNonce;

                // build list of signed certificates for audit event.
                List <SignedSoftwareCertificate> signedSoftwareCertificates = new List <SignedSoftwareCertificate>();

                if (clientSoftwareCertificates != null)
                {
                    foreach (SoftwareCertificate softwareCertificate in clientSoftwareCertificates)
                    {
                        SignedSoftwareCertificate item = new SignedSoftwareCertificate();
                        item.CertificateData = softwareCertificate.SignedCertificate.GetRawCertData();
                        signedSoftwareCertificates.Add(item);
                    }
                }

                // raise an audit event.
                ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(context);
                ReportAuditActivateSessionEvent(systemContext);

                // update the contact time.
                lock (m_diagnostics)
                {
                    m_diagnostics.ClientLastContactTime = DateTime.UtcNow;
                }

                // indicate whether the user context has changed.
                return(changed);
            }
        }
Example #23
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));
        }
Example #24
0
        /// <summary>
        /// Validates the identity token supplied by the client.
        /// </summary>
        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);
        }
Example #25
0
 public async Task UserIdentityToken_WhitespaceToken()
 {
     var token = await UserIdentityToken.ParseAsync(string.Empty, Guid.NewGuid());
 }
Example #26
0
        /// <summary>
        /// Create and Activate a session without security.
        /// </summary>
        /// <remarks>
        /// The request header is used to call services directly,
        /// without establishing a session with a client.
        /// </remarks>
        /// <param name="server">The server to connect to.</param>
        /// <param name="sessionName">A session name.</param>
        /// <returns>The request header for the session.</returns>
        public static RequestHeader CreateAndActivateSession(
            this SessionServerBase server,
            string sessionName,
            bool useSecurity = false,
            UserIdentityToken identityToken = null,
            double sessionTimeout           = DefaultSessionTimeout,
            uint maxResponseMessageSize     = DefaultMaxResponseMessageSize)
        {
            // Find TCP endpoint
            var endpoints = server.GetEndpoints();
            var endpoint  = endpoints.FirstOrDefault(e =>
                                                     e.TransportProfileUri.Equals(Profiles.UaTcpTransport, StringComparison.Ordinal) ||
                                                     e.TransportProfileUri.Equals(Profiles.HttpsBinaryTransport, StringComparison.Ordinal));

            if (endpoint == null)
            {
                throw new Exception("Unsupported transport profile.");
            }

            // fake profiles
            if (useSecurity)
            {
                endpoint.SecurityMode      = MessageSecurityMode.Sign;
                endpoint.SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
            }
            else
            {
                endpoint.SecurityMode      = MessageSecurityMode.None;
                endpoint.SecurityPolicyUri = SecurityPolicies.None;
            }

            var context = new SecureChannelContext(
                sessionName,
                endpoint,
                RequestEncoding.Binary);

            // set security context
            SecureChannelContext.Current = context;
            var requestHeader = new RequestHeader();

            // Create session
            var response = server.CreateSession(
                requestHeader,
                null, null, null,
                sessionName,
                null, null, sessionTimeout, maxResponseMessageSize,
                out var sessionId, out var authenticationToken, out sessionTimeout,
                out var serverNonce, out var serverCertificate, out var endpointDescriptions,
                out var serverSoftwareCertificates, out var signatureData, out var maxRequestMessageSize);

            ValidateResponse(response);

            // Activate session
            requestHeader.AuthenticationToken = authenticationToken;
            response = server.ActivateSession(requestHeader, signatureData,
                                              new SignedSoftwareCertificateCollection(), new StringCollection(),
                                              (identityToken != null) ? new ExtensionObject(identityToken) : null, null,
                                              out serverNonce, out var results, out var diagnosticInfos);
            ValidateResponse(response);

            return(requestHeader);
        }
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy)
 {
     m_newIdentity = newIdentity;
     m_userTokenPolicy = userTokenPolicy;
 }
            /// <summary>
            /// Validates the identity token supplied by the client.
            /// </summary>
            /// <param name="identityToken"></param>
            /// <param name="userTokenSignature"></param>
            /// <returns></returns>
            private bool ValidateUserIdentityToken(ExtensionObject identityToken,
                                                   SignatureData userTokenSignature)
            {
                UserIdentityToken token = null;
                UserTokenPolicy   policy;

                if (identityToken == null || identityToken.Body == null)
                {
                    if (_activated)
                    {
                        // not changing the token if already activated.
                        return(false);
                    }
                    policy = Endpoint.UserIdentityTokens?
                             .FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadUserAccessDenied,
                                                            "Anonymous user token policy not supported.");
                    }
                    // create an anonymous token to use for subsequent validation.
                    token = new AnonymousIdentityToken {
                        PolicyId = policy.PolicyId
                    };
                }
                else if (!typeof(UserIdentityToken).IsInstanceOfType(identityToken.Body))
                {
                    // Decode identity token from binary.
                    token = DecodeUserIdentityToken(identityToken, out policy);
                }
                else
                {
                    token = (UserIdentityToken)identityToken.Body;
                    // find the user token policy.
                    policy = Endpoint.FindUserTokenPolicy(token.PolicyId);
                    if (policy == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                            "User token policy not supported.");
                    }
                }

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

                if (string.IsNullOrEmpty(securityPolicyUri))
                {
                    securityPolicyUri = Endpoint.SecurityPolicyUri;
                }

                if (securityPolicyUri != SecurityPolicies.None)
                {
                    // decrypt the user identity token.
                    if (_serverCertificate == null)
                    {
                        _serverCertificate = CertificateFactory.Create(
                            Endpoint.ServerCertificate, true);
                        // check for valid certificate.
                        if (_serverCertificate == null)
                        {
                            throw ServiceResultException.Create(StatusCodes.BadConfigurationError,
                                                                "ApplicationCertificate cannot be found.");
                        }
                    }
                    try {
                        token.Decrypt(_serverCertificate, _serverNonce, securityPolicyUri);
                    }
                    catch (ServiceResultException) {
                        throw;
                    }
                    catch (Exception e) {
                        throw ServiceResultException.Create(StatusCodes.BadIdentityTokenInvalid,
                                                            e, "Could not decrypt identity token.");
                    }
                    // ... and verify the signature if any.
                    VerifyUserTokenSignature(userTokenSignature, token, securityPolicyUri);
                }

                // We have a valid token - validate it through the handler chain.
                var arg = new UserIdentityHandlerArgs {
                    CurrentIdentities = Identities,
                    Token             = token
                };

                _validator?.Invoke(this, arg);
                if (arg.ValidationException != null)
                {
                    throw arg.ValidationException;
                }
                if (arg.NewIdentities != null)
                {
                    Identities = arg.NewIdentities;
                    return(true);
                }
                return(false); // No new identities
            }
Example #29
0
 public async Task UserIdentityToken_MalformedToken()
 {
     var token = await UserIdentityToken.ParseAsync("malformed_token", Guid.NewGuid());
 }
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 public ImpersonateEventArgs(UserIdentityToken newIdentity, UserTokenPolicy userTokenPolicy)
 {
     m_newIdentity     = newIdentity;
     m_userTokenPolicy = userTokenPolicy;
 }
Example #31
0
 internal static void AddUserToken(UserIdentityToken usertoken)
 {
     Add(SessionKeys.UserToken, usertoken);
 }