/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns> /// Result of authentication process. /// </returns> public override AuthenticationResult Authenticate(Session session) { session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyFile in KeyFiles) { _authenticationCompleted.Reset(); _isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data); if (KeyFiles.Count < 2) { // If only one key file provided then send signature for very first request var signatureData = new SignatureData(message, session.SessionId).GetBytes(); message.Signature = keyFile.HostKey.Sign(signatureData); } // Send public key authentication request session.SendMessage(message); session.WaitOnHandle(_authenticationCompleted); if (_isSignatureRequired) { _authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = keyFile.HostKey.Sign(signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitOnHandle(_authenticationCompleted); if (_authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return _authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.Protocol == null) return AuthenticationResult.Failure; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var identity in this.Protocol.GetIdentities()) { this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, identity.Type, identity.Blob); // Send public key authentication request session.SendMessage(message); session.WaitOnHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, identity.Type, identity.Blob); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = this.Protocol.SignData(identity, signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitOnHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return this._authenticationResult; }
/// <summary> /// Called when connection needs to be authenticated. /// </summary> protected override void OnAuthenticate() { if (this.KeyFiles == null) return; this.Session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyFile in this.KeyFiles) { this._publicKeyRequestMessageResponseWaitHandle.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, keyFile.HostKey.Name, keyFile.HostKey.Data); if (this.KeyFiles.Count < 2) { // If only one key file provided then send signature for very first request var signatureData = new SignatureData(message, this.Session.SessionId).GetBytes(); message.Signature = keyFile.HostKey.Sign(signatureData); } // Send public key authentication request this.SendMessage(message); this.WaitHandle(this._publicKeyRequestMessageResponseWaitHandle); if (this._isSignatureRequired) { this._publicKeyRequestMessageResponseWaitHandle.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, keyFile.HostKey.Name, keyFile.HostKey.Data); var signatureData = new SignatureData(message, this.Session.SessionId).GetBytes(); signatureMessage.Signature = keyFile.HostKey.Sign(signatureData); // Send public key authentication request with signature this.SendMessage(signatureMessage); } this.WaitHandle(this._publicKeyRequestMessageResponseWaitHandle); if (this.IsAuthenticated) { break; } } this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); }
/// <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; }
private void LoadSignature() { var moduleSymbol = this.containingType.ContainingPEModule; byte callingConvention; BadImageFormatException mrEx; MetadataDecoder.ParamInfo[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(this.handle, out callingConvention, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!SignatureHeader.IsGeneric(callingConvention) && lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange(ref lazyTypeParameters, ImmutableArray <TypeParameterSymbol> .Empty, default(ImmutableArray <TypeParameterSymbol>)); } int count = paramInfo.Length - 1; ImmutableArray <ParameterSymbol> @params; bool isBadParameter; if (count > 0) { ParameterSymbol[] parameterCreation = new ParameterSymbol[count]; for (int i = 0; i < count; i++) { parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter); if (isBadParameter) { makeBad = true; } } @params = parameterCreation.AsImmutableOrNull(); } else { @params = ImmutableArray <ParameterSymbol> .Empty; } // paramInfo[0] contains information about return "parameter" Debug.Assert(!paramInfo[0].IsByRef); // Dynamify object type if necessary paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(this.containingType); var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { var old = Interlocked.CompareExchange(ref lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo || ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this)); } var signature = new SignatureData(callingConvention, @params, returnParam); Interlocked.CompareExchange(ref lazySignature, signature, null); }
/// <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: 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; 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: 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; 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; byte[] plainText = Concat(issuedIdentity.TokenData, this.RemoteNonce); 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 + plainText.Length)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainText.Length), cipherText, 0); pos = encryptor.DoFinal(plainText, cipherText, pos); identityToken = new IssuedIdentityToken { TokenData = cipherText, EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainText.Length)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainText.Length), cipherText, 0); pos = encryptor.DoFinal(plainText, cipherText, pos); identityToken = new IssuedIdentityToken { TokenData = cipherText, EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new IssuedIdentityToken { TokenData = issuedIdentity.TokenData, EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); plainText = null; encryptor = null; cipherText = null; } // if UserIdentity type is X509Identity else if (this.UserIdentity is X509Identity) { throw new NotImplementedException("A user identity of X509Identity is not implemented."); /* * 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) * { * 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) * { * dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); * tokenSignature = new SignatureData * { * Signature = asymSigningKey256.SignData(dataToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), * Algorithm = RsaSha256Signature, * }; * break; * } * * tokenSignature = new SignatureData(); * break; * * default: * tokenSignature = new SignatureData(); * break; * } * * dataToSign = 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 = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password); 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: 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; 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(true); // link up the dataflow blocks var id = subscriptionResponse.SubscriptionId; var linkToken = this.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id); // start publishing. this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token)); }
/// <summary> /// Invokes the CreateSession service. /// </summary> public virtual ResponseHeader CreateSession( RequestHeader requestHeader, ApplicationDescription clientDescription, string serverUri, string endpointUrl, string sessionName, byte[] clientNonce, byte[] clientCertificate, double requestedSessionTimeout, uint maxResponseMessageSize, out NodeId sessionId, out NodeId authenticationToken, out double revisedSessionTimeout, out byte[] serverNonce, out byte[] serverCertificate, out EndpointDescriptionCollection serverEndpoints, out SignedSoftwareCertificateCollection serverSoftwareCertificates, out SignatureData serverSignature, out uint maxRequestMessageSize) { CreateSessionRequest request = new CreateSessionRequest(); CreateSessionResponse response = null; request.RequestHeader = requestHeader; request.ClientDescription = clientDescription; request.ServerUri = serverUri; request.EndpointUrl = endpointUrl; request.SessionName = sessionName; request.ClientNonce = clientNonce; request.ClientCertificate = clientCertificate; request.RequestedSessionTimeout = requestedSessionTimeout; request.MaxResponseMessageSize = maxResponseMessageSize; UpdateRequestHeader(request, requestHeader == null, "CreateSession"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (CreateSessionResponse)genericResponse; } else { CreateSessionResponseMessage responseMessage = InnerChannel.CreateSession(new CreateSessionMessage(request)); if (responseMessage == null || responseMessage.CreateSessionResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.CreateSessionResponse; ValidateResponse(response.ResponseHeader); } sessionId = response.SessionId; authenticationToken = response.AuthenticationToken; revisedSessionTimeout = response.RevisedSessionTimeout; serverNonce = response.ServerNonce; serverCertificate = response.ServerCertificate; serverEndpoints = response.ServerEndpoints; serverSoftwareCertificates = response.ServerSoftwareCertificates; serverSignature = response.ServerSignature; maxRequestMessageSize = response.MaxRequestMessageSize; } finally { RequestCompleted(request, response, "CreateSession"); } return response.ResponseHeader; }
/// <summary> /// Verifies a signature created with the token. /// </summary> public override bool Verify(byte[] dataToVerify, SignatureData signatureData, string securityPolicyUri) { X509Certificate2 certificate = m_certificate; if (certificate == null) { certificate = CertificateFactory.Create(m_certificateData, true); } bool valid = SecurityPolicies.Verify( certificate, securityPolicyUri, dataToVerify, signatureData); m_certificateData = certificate.RawData; return valid; }
/// <summary> /// Invokes the ActivateSession service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="clientSignature">The client signature.</param> /// <param name="clientSoftwareCertificates">The client software certificates.</param> /// <param name="localeIds">The locale ids.</param> /// <param name="userIdentityToken">The user identity token.</param> /// <param name="userTokenSignature">The user token signature.</param> /// <param name="serverNonce">The server nonce.</param> /// <param name="results">The results.</param> /// <param name="diagnosticInfos">The diagnostic infos.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader ActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, out byte[] serverNonce, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { serverNonce = null; results = null; diagnosticInfos = null; OperationContext context = ValidateRequest(requestHeader, RequestType.ActivateSession); try { // validate client's software certificates. List<SoftwareCertificate> softwareCertificates = new List<SoftwareCertificate>(); if (context.SecurityPolicyUri != SecurityPolicies.None) { bool diagnosticsExist = false; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos = new DiagnosticInfoCollection(); } results = new StatusCodeCollection(); diagnosticInfos = new DiagnosticInfoCollection(); foreach (SignedSoftwareCertificate signedCertificate in clientSoftwareCertificates) { SoftwareCertificate softwareCertificate = null; ServiceResult result = SoftwareCertificate.Validate( new CertificateValidator(), signedCertificate.CertificateData, out softwareCertificate); if (ServiceResult.IsBad(result)) { results.Add(result.Code); // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(ServerInternal, context, result); diagnosticInfos.Add(diagnosticInfo); diagnosticsExist = true; } } else { softwareCertificates.Add(softwareCertificate); results.Add(StatusCodes.Good); // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(null); } } } if (!diagnosticsExist && diagnosticInfos != null) { diagnosticInfos.Clear(); } } // check if certificates meet the server's requirements. ValidateSoftwareCertificates(softwareCertificates); // activate the session. bool identityChanged = ServerInternal.SessionManager.ActivateSession( context, requestHeader.AuthenticationToken, clientSignature, softwareCertificates, userIdentityToken, userTokenSignature, localeIds, out serverNonce); if (identityChanged) { // TBD - call Node Manager and Subscription Manager. } Utils.Trace("Server - SESSION ACTIVATED."); return CreateResponse(requestHeader, StatusCodes.Good); } catch (ServiceResultException e) { Utils.Trace("Server - SESSION ACTIVATE failed. {0}", e.Message); lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException((DiagnosticsMasks)requestHeader.ReturnDiagnostics, localeIds, e); } finally { OnRequestComplete(context); } }
/// <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> /// Creates a session with the server. /// </summary> public void CreateSession() { ApplicationDescription description = new ApplicationDescription(); description.ApplicationName = new LocalizedText("UA Sample Client"); description.ApplicationType = ApplicationType.Client_1; description.ApplicationUri = "http://localhost/UASampleClient"; byte[] serverCertificateData; ListOfEndpointDescription serverEndpoints; ListOfSignedSoftwareCertificate serverSoftwareCertificates; SignatureData serverSignature; // create a client nonce. byte[] clientNonce = new byte[32]; RNGCryptoServiceProvider random = new RNGCryptoServiceProvider(); random.GetBytes(clientNonce); string endpointUrl = this.Endpoint.Address.Uri.ToString(); // create the session. CreateSession( CreateRequestHeader(), description, null, this.Endpoint.Address.Uri.ToString(), "My Session", clientNonce, m_clientCertificate.RawData, 600000, 0, out m_sessionId, out m_authenticationToken, out m_sessionTimeout, out m_serverNonce, out serverCertificateData, out serverEndpoints, out serverSoftwareCertificates, out serverSignature, out m_maxRequestMessageSize); // find the endpoint description being used. string securityPolicyUri = ""; Uri url = new Uri(endpointUrl); foreach (EndpointDescription serverEndpoint in serverEndpoints) { Uri url2 = new Uri(serverEndpoint.EndpointUrl); if (url2.Scheme == url.Scheme && url2.Port == url.Port && url2.PathAndQuery == url.PathAndQuery) { securityPolicyUri = serverEndpoint.SecurityPolicyUri; break; } } // validate the server's signature. byte[] dataToSign = SecurityUtils.Append(m_clientCertificate.RawData, clientNonce); bool valid = SecurityUtils.Verify( new X509Certificate2(serverCertificateData), securityPolicyUri, dataToSign, serverSignature); if (!valid) { throw new StatusCodeException( StatusCodes.BadSecurityChecksFailed, "Server did not provide a correct signature for the nonce data provided by the client."); } // create the client signature. dataToSign = SecurityUtils.Append(serverCertificateData, m_serverNonce); SignatureData clientSignature = SecurityUtils.Sign( m_clientCertificate, securityPolicyUri, dataToSign); // use an anonymous user identity token. ExtensionObject userIdentityToken = new ExtensionObject( new ExpandedNodeId(Objects.AnonymousIdentityToken_Encoding_DefaultXml), new AnonymousIdentityToken()); ListOfStatusCode results; ListOfDiagnosticInfo diagnosticInfos; // activate the session. ActivateSession( CreateRequestHeader(), clientSignature, new ListOfSignedSoftwareCertificate(), new ListOfString(), null, null, out m_serverNonce, out results, out diagnosticInfos); }
/// <summary> /// Activates the session. /// </summary> public byte[] Activate( SignatureData signature, ListOfString localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature) { lock (m_lock) { if (m_clientCertificate != null) { // validate the client's signature. byte[] dataToSign = SecurityUtils.Append(m_endpoint.ServerCertificate, m_serverNonce); bool valid = SecurityUtils.Verify( m_clientCertificate, m_endpoint.SecurityPolicyUri, dataToSign, signature); if (!valid) { throw new StatusCodeException( StatusCodes.BadSecurityChecksFailed, "Client did not provide a correct signature for the nonce data provided by the server."); } } m_activated = true; m_localeIds = localeIds; // TBD - validate the user identity token. // return a new nonce. RNGCryptoServiceProvider random = new RNGCryptoServiceProvider(); random.GetBytes(m_serverNonce); return m_serverNonce; } }
public void TestSignatureDataOkWithNoUri() { SignatureData signatureData = GetSignatureDataFromFile(Resources.SignatureData_Ok_No_Uri); Assert.AreEqual(3, signatureData.Count, "Invalid amount of child TLV objects"); }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.PrivateKeyAgent.Value == null) return AuthenticationResult.Failure; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyInfo in this.PrivateKeyAgent.Value.ListSsh2()) { var key = keyInfo.Key; this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); // Send public key authentication request session.SendMessage(message); session.WaitHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); var signature = this.PrivateKeyAgent.Value.SignSsh2(key.Data, signatureData); if (signature != null) { signatureMessage.Signature = signature; // Send public key authentication request with signature session.SendMessage(signatureMessage); } else { this._authenticationResult = AuthenticationResult.Failure; this._authenticationCompleted.Set(); } } session.WaitHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return this._authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.PrivateKeyAgent.Value == null) { return(AuthenticationResult.Failure); } session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyInfo in this.PrivateKeyAgent.Value.ListSsh2()) { var key = keyInfo.Key; this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); // Send public key authentication request session.SendMessage(message); session.WaitHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); var signature = this.PrivateKeyAgent.Value.SignSsh2(key.Data, signatureData); if (signature != null) { signatureMessage.Signature = signature; // Send public key authentication request with signature session.SendMessage(signatureMessage); } else { this._authenticationResult = AuthenticationResult.Failure; this._authenticationCompleted.Set(); } } session.WaitHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return(this._authenticationResult); }
/// <summary> /// Verifies the signature using the SecurityPolicyUri and return true if valid. /// </summary> public static bool Verify(X509Certificate2 certificate, string securityPolicyUri, byte[] dataToVerify, SignatureData signature) { // check if nothing to do. if (signature == null) { return(true); } // nothing more to do if no encryption. if (String.IsNullOrEmpty(securityPolicyUri)) { return(true); } // decrypt data. switch (securityPolicyUri) { case SecurityPolicies.Basic256: case SecurityPolicies.Basic128Rsa15: { if (signature.Algorithm == SecurityAlgorithms.RsaSha1) { return(RsaUtils.RsaPkcs15Sha1_Verify(new ArraySegment <byte>(dataToVerify), signature.Signature, certificate)); } break; } case SecurityPolicies.Basic256Sha256: { if (signature.Algorithm == SecurityAlgorithms.RsaSha256) { return(RsaUtils.RsaPkcs15Sha256_Verify(new ArraySegment <byte>(dataToVerify), signature.Signature, certificate)); } break; } // always accept signatures if security is not used. case SecurityPolicies.None: { return(true); } default: { throw ServiceResultException.Create( StatusCodes.BadSecurityPolicyRejected, "Unsupported security policy: {0}", securityPolicyUri); } } throw ServiceResultException.Create( StatusCodes.BadSecurityChecksFailed, "Unexpected signature algorithm : {0}", signature.Algorithm); }
private void LoadSignature() { var moduleSymbol = this.containingType.ContainingPEModule; byte callingConvention; BadImageFormatException mrEx; MetadataDecoder.ParamInfo[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(this.handle, out callingConvention, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!SignatureHeader.IsGeneric(callingConvention) && lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedCompareExchange(ref lazyTypeParameters, ImmutableArray<TypeParameterSymbol>.Empty, default(ImmutableArray<TypeParameterSymbol>)); } int count = paramInfo.Length - 1; ImmutableArray<ParameterSymbol> @params; bool isBadParameter; if (count > 0) { ParameterSymbol[] parameterCreation = new ParameterSymbol[count]; for (int i = 0; i < count; i++) { parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter); if (isBadParameter) { makeBad = true; } } @params = parameterCreation.AsImmutableOrNull(); } else { @params = ImmutableArray<ParameterSymbol>.Empty; } // paramInfo[0] contains information about return "parameter" Debug.Assert(!paramInfo[0].IsByRef); // Dynamify object type if necessary paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(this.containingType); var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { var old = Interlocked.CompareExchange(ref lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo); Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo || ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this)); } var signature = new SignatureData(callingConvention, @params, returnParam); Interlocked.CompareExchange(ref lazySignature, signature, null); }
/// <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); } // create new server nonce. serverNonce = Utils.Nonce.CreateNonce("ActivateSession", (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); }
/// <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"); } }
/// <summary> /// Invokes the ActivateSession service. /// </summary> public virtual ResponseHeader ActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, out byte[] serverNonce, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { serverNonce = null; results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
public ManualStackingInfo(string title, IDictionary <string, string> signatureData) : this(title) { if (signatureData != null && signatureData.Count > 0) { SignatureData.AddRange(signatureData); } }
protected override async Task OnOpenAsync(CancellationToken token) { await base.OnOpenAsync(token).ConfigureAwait(false); token.ThrowIfCancellationRequested(); // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession. // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce if (this.SessionId == null) { var localNonce = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce() : null; var localCertificateBlob = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate.RawData : null; var createSessionRequest = new CreateSessionRequest { RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow }, ClientDescription = this.LocalDescription, EndpointUrl = this.RemoteEndpoint.EndpointUrl, SessionName = this.LocalDescription.ApplicationName, ClientNonce = localNonce, ClientCertificate = localCertificateBlob, RequestedSessionTimeout = this.SessionTimeout, MaxResponseMessageSize = this.RemoteMaxMessageSize }; var createSessionResponse = (CreateSessionResponse)await this.RequestAsync(createSessionRequest).ConfigureAwait(false); this.SessionId = createSessionResponse.SessionId; this.AuthenticationToken = createSessionResponse.AuthenticationToken; this.RemoteNonce = createSessionResponse.ServerNonce; // verify the server's certificate is the same as the certificate from the selected endpoint. if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate)) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel."); } // verify the server's signature. switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: byte[] dataToVerify = Concat(localCertificateBlob, localNonce); if (!this.RemotePublicKey.VerifyData(dataToVerify, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client."); } break; case SecurityPolicyUris.Basic256Sha256: byte[] dataToVerify256 = Concat(localCertificateBlob, localNonce); if (!this.RemotePublicKey.VerifyData(dataToVerify256, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client."); } break; default: break; } } // create client signature SignatureData clientSignature = null; switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); clientSignature = new SignatureData { Signature = this.LocalPrivateKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1), Algorithm = RsaSha1Signature, }; break; case SecurityPolicyUris.Basic256Sha256: byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); clientSignature = new SignatureData { Signature = this.LocalPrivateKey.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), Algorithm = RsaSha256Signature, }; break; default: clientSignature = new SignatureData(); break; } // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken UserIdentityToken identityToken = null; SignatureData tokenSignature = null; // if UserIdentity type is IssuedIdentity if (this.UserIdentity is IssuedIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var issuedIdentity = (IssuedIdentity)this.UserIdentity; byte[] plainText = Concat(issuedIdentity.TokenData, this.RemoteNonce); var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; RSA asymRemoteEncryptionKey; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new IssuedIdentityToken { TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new IssuedIdentityToken { TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new IssuedIdentityToken { TokenData = issuedIdentity.TokenData, EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); } // if UserIdentity type is X509Identity else if (this.UserIdentity is X509Identity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var x509Identity = (X509Identity)this.UserIdentity; identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.RawData, PolicyId = tokenPolicy.PolicyId }; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: var asymSigningKey = x509Identity.Certificate?.GetRSAPrivateKey(); if (asymSigningKey != null) { byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); tokenSignature = new SignatureData { Signature = asymSigningKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1), Algorithm = RsaSha1Signature, }; break; } tokenSignature = new SignatureData(); break; case SecurityPolicyUris.Basic256Sha256: var asymSigningKey256 = x509Identity.Certificate?.GetRSAPrivateKey(); if (asymSigningKey256 != null) { byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); tokenSignature = new SignatureData { Signature = asymSigningKey256.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), Algorithm = RsaSha256Signature, }; break; } tokenSignature = new SignatureData(); break; default: tokenSignature = new SignatureData(); break; } } // if UserIdentity type is UserNameIdentity else if (this.UserIdentity is UserNameIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var userNameIdentity = (UserNameIdentity)this.UserIdentity; byte[] plainText = Concat(System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), this.RemoteNonce); var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; RSA asymRemoteEncryptionKey; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); } // if UserIdentity type is AnonymousIdentity or null else { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } identityToken = new AnonymousIdentityToken { PolicyId = tokenPolicy.PolicyId }; tokenSignature = new SignatureData(); } var activateSessionRequest = new ActivateSessionRequest { RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow }, ClientSignature = clientSignature, LocaleIds = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName }, UserIdentityToken = identityToken, UserTokenSignature = tokenSignature }; var activateSessionResponse = (ActivateSessionResponse)await this.RequestAsync(activateSessionRequest).ConfigureAwait(false); this.RemoteNonce = activateSessionResponse.ServerNonce; await this.FetchNamespaceTablesAsync().ConfigureAwait(false); }
/// <summary> /// Compares two Signature objects. /// </summary> /// <param name="original">The original recorded signature.</param> /// <param name="attempt">The attempt to compare.</param> /// <returns>The result of the comparison.</returns> static public SignatureComparisonResult Compare(Signature original, Signature attempt) { SignatureComparisonFailureCollection result = new SignatureComparisonFailureCollection(); if (original._c == attempt._c) { for (int i = 0; i < original._c; ++i) { SignatureData o = original._[i], a = attempt._[i]; double time = o.TimeOffset / a.TimeOffset; if (time <1 / Config.tt | time> Config.tt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.Timing, i)); } if (Math.Max(o.Length, a.Length) < Config.dst) { goto skip; } double length = o.Length / a.Length; if (length <1 / Config.lt | length> Config.lt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.Length, i)); } if (Math.Max(o.AngleChange, a.AngleChange) >= Config.mact) { double angleChange = o.AngleChange / a.AngleChange; if (angleChange <1 / Config.act | angleChange> Config.act) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.AngleChange, i)); } double angleWobble = o.AngleWobble / a.AngleWobble; if (angleWobble <1 / Config.adt | angleWobble> Config.adt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.AngleWobble, i)); } } double startingAngle = Math.Abs(o.StartingAngle - a.StartingAngle); if (startingAngle > Config.sat) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.StartingAngle, i)); } skip: if (Math.Max(o.PressureChange, a.PressureChange) >= Config.mpct) { double pressureChange = o.PressureChange / a.PressureChange; if (pressureChange <1 / Config.pct | pressureChange> Config.pct) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.PressureChange, i)); } double pressureWobble = o.PressureWobble / a.PressureWobble; if (pressureWobble <1 / Config.pdt | pressureWobble> Config.pdt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.PressureWobble, i)); } } double startingPressure = Math.Abs(o.StartingPressure - a.StartingPressure); if (startingPressure > Config.spt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.StartingPressure, i)); } double startPoint = Math.Sqrt(Math.Pow(Math.Abs(o.Start.X - a.Start.X), 2) + Math.Pow(Math.Abs(o.Start.Y - a.Start.Y), 2)); if (startPoint > Config.set) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.StartPoint, i)); } double endPoint = Math.Sqrt(Math.Pow(Math.Abs(o.End.X - a.End.X), 2) + Math.Pow(Math.Abs(o.End.Y - a.End.Y), 2)); if (endPoint > Config.set) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.EndPoint, i)); } double directLinearSize = Math.Sqrt(Math.Pow(Math.Abs(o.Start.X - o.End.X), 2) + Math.Pow(Math.Abs(o.Start.Y - o.End.Y), 2)) / Math.Sqrt(Math.Pow(Math.Abs(a.Start.X - a.End.X), 2) + Math.Pow(Math.Abs(a.Start.Y - a.End.Y), 2)); if (directLinearSize <1 / Config.edt | directLinearSize> Config.edt) { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.DirectLinearSize, i)); } } } else { result.Add(new SignatureComparisonFailure(SignatureComparisonFailureCode.SegmentCount)); } return(new SignatureComparisonResult(result)); }
/// <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); } // create new server nonce. serverNonce = new byte[m_minNonceLength]; IBuffer buffer = CryptographicBuffer.GenerateRandom((uint) m_minNonceLength); CryptographicBuffer.CopyToByteArray(buffer, out serverNonce); // 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; } 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; }
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[]>()); } } }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.KeyFiles == null) { return(AuthenticationResult.Failure); } session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyFile in this.KeyFiles) { this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, keyFile.HostKey.Name, keyFile.HostKey.Data); if (this.KeyFiles.Count < 2) { // If only one key file provided then send signature for very first request var signatureData = new SignatureData(message, session.SessionId).GetBytes(); message.Signature = keyFile.HostKey.Sign(signatureData); } // Send public key authentication request session.SendMessage(message); session.WaitHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, keyFile.HostKey.Name, keyFile.HostKey.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = keyFile.HostKey.Sign(signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return(this._authenticationResult); }
/// <summary> /// Signs the data using the SecurityPolicyUri and returns the signature. /// </summary> public static SignatureData Sign(X509Certificate2 certificate, string securityPolicyUri, byte[] dataToSign) { SignatureData signatureData = new SignatureData(); // check if nothing to do. if (dataToSign == null) { return signatureData; } // nothing more to do if no encryption. if (String.IsNullOrEmpty(securityPolicyUri)) { return signatureData; } // sign data. switch (securityPolicyUri) { case SecurityPolicies.Basic256: case SecurityPolicies.Basic128Rsa15: { signatureData.Algorithm = SecurityAlgorithms.RsaSha1; signatureData.Signature = RsaUtils.RsaPkcs15Sha1_Sign(new ArraySegment<byte>(dataToSign), certificate); break; } case SecurityPolicies.None: { signatureData.Algorithm = null; signatureData.Signature = null; break; } default: { throw ServiceResultException.Create( StatusCodes.BadSecurityPolicyRejected, "Unsupported security policy: {0}", securityPolicyUri); } } return signatureData; }
/// <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> /// Verifies the signature using the SecurityPolicyUri and return true if valid. /// </summary> public static bool Verify(X509Certificate2 certificate, string securityPolicyUri, byte[] dataToVerify, SignatureData signature) { // check if nothing to do. if (signature == null) { return true; } // nothing more to do if no encryption. if (String.IsNullOrEmpty(securityPolicyUri)) { return true; } // decrypt data. switch (securityPolicyUri) { case SecurityPolicies.Basic256: case SecurityPolicies.Basic128Rsa15: { if (signature.Algorithm == SecurityAlgorithms.RsaSha1) { return RsaUtils.RsaPkcs15Sha1_Verify(new ArraySegment<byte>(dataToVerify), signature.Signature, certificate); } break; } // always accept signatures if security is not used. case SecurityPolicies.None: { return true; } default: { throw ServiceResultException.Create( StatusCodes.BadSecurityPolicyRejected, "Unsupported security policy: {0}", securityPolicyUri); } } throw ServiceResultException.Create( StatusCodes.BadSecurityChecksFailed, "Unexpected signature algorithm : {0}", signature.Algorithm); }
/// <summary> /// Creates a session with the server that is independent of the network connection. /// </summary> public CreateSessionResponseMessage CreateSession(CreateSessionMessage request) { try { lock (m_lock) { InitializeApplicationDescription(); // create a new session object. Session session = new Session(); NodeId sessionId; NodeId authenticationToken; byte[] serverNonce; double revisedSessionTimeout; EndpointDescription endpoint = m_endpoints[0]; // the session object validates the incoming parameters and produces faults on error. session.Create( endpoint, request.ClientDescription, request.ClientCertificate, request.SessionName, request.RequestedSessionTimeout, out sessionId, out authenticationToken, out serverNonce, out revisedSessionTimeout); // save the session. m_sessions.Add(authenticationToken.Identifier, session); // the server application must authenticate itself to the client by providing a signature. // this process is redundant for applications using WS-SecureConversation with mutual certificate // exchange, however, the UA specification requires this step to ensure that secure channel // technologies such as machine-to-machine VPNs can be used instead without sacrificing the // ability to identify the remote applications. byte[] dataToSign = SecurityUtils.Append(request.ClientCertificate, request.ClientNonce); SignatureData serverSignature = SecurityUtils.Sign( m_serverCertificate, endpoint.SecurityPolicyUri, dataToSign); // contruct the response. CreateSessionResponseMessage response = new CreateSessionResponseMessage(); response.ResponseHeader = CreateResponseHeader(request.RequestHeader); response.SessionId = sessionId; response.AuthenticationToken = authenticationToken; response.MaxRequestMessageSize = request.MaxResponseMessageSize; response.RevisedSessionTimeout = revisedSessionTimeout; response.ServerNonce = serverNonce; response.ServerCertificate = m_serverCertificate.GetRawCertData(); response.ServerSignature = serverSignature; response.ServerEndpoints = m_endpoints; response.ServerSoftwareCertificates = new ListOfSignedSoftwareCertificate(); return(response); } } catch (Exception e) { throw CreateSoapFault(request.RequestHeader, e); } }
/// <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 }
/// <summary> /// Verifies a signature created with the token (implemented by the subclass). /// </summary> public virtual bool Verify(byte[] dataToVerify, SignatureData signatureData, string securityPolicyUri) { return(true); }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (Protocol == null) { return(AuthenticationResult.Failure); } session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.UserAuthenticationPublicKeyReceived += Session_UserAuthenticationPublicKeyReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); try { foreach (var identity in Protocol.GetIdentities()) { _authenticationCompleted.Reset(); _isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, Username, identity.Type, identity.Blob); // Send public key authentication request session.SendMessage(message); session.WaitOnHandle(_authenticationCompleted, new TimeSpan(-1)); if (_isSignatureRequired) { _authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, Username, identity.Type, identity.Blob); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = this.Protocol.SignData(identity, signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitOnHandle(_authenticationCompleted, new TimeSpan(-1)); if (_authenticationResult == AuthenticationResult.Success) { break; } } return(_authenticationResult); } finally { session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.UserAuthenticationPublicKeyReceived -= Session_UserAuthenticationPublicKeyReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); } }
private SignatureData LoadSignature() { var moduleSymbol = _containingType.ContainingPEModule; SignatureHeader signatureHeader; BadImageFormatException mrEx; ParamInfo <TypeSymbol>[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(_handle, out signatureHeader, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!signatureHeader.IsGeneric && _lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameters, ImmutableArray <TypeParameterSymbol> .Empty); } int count = paramInfo.Length - 1; ImmutableArray <ParameterSymbol> @params; bool isBadParameter; if (count > 0) { var builder = ImmutableArray.CreateBuilder <ParameterSymbol>(count); for (int i = 0; i < count; i++) { builder.Add(PEParameterSymbol.Create(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter)); if (isBadParameter) { makeBad = true; } } @params = builder.ToImmutable(); } else { @params = ImmutableArray <ParameterSymbol> .Empty; } // workaround for CodeAnalysis 0.6.0 // remove after we use 0.9.0+ if (paramInfo[0].Type is ByRefReturnErrorTypeSymbol rtype) { // fix paramInfo paramInfo[0].IsByRef = true; paramInfo[0].Type = rtype.TheReturnType; } //// Dynamify object type if necessary //paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(_containingType); var returnParam = PEParameterSymbol.Create(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { //InitializeUseSiteDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)); } var signature = new SignatureData(signatureHeader, @params, returnParam); return(InterlockedOperations.Initialize(ref _lazySignature, signature)); }
////public ReplacementSignature(SignatureHelpSource source, ISignatureHelpSession session, ITextBuffer subjectBuffer, ITrackingSpan applicableToSpan, string replacementSignature, string documentation) public ReplacementSignature(SignatureHelpSource source, ISignatureHelpSession session, ITextBuffer subjectBuffer, ITrackingSpan applicableToSpan, SignatureData data) { this.source = source; this.session = session; this.subjectBuffer = subjectBuffer; this.ApplicableToSpan = applicableToSpan; this.Content = data.Name; this.Documentation = data.Documentation; this.SignatureKey = data.SignatureKey; List <IParameter> parameters = new List <IParameter>(); foreach (var parameter in data.Parameters) { parameters.Add(new ReplacementParameter(parameter.Documentation, parameter.Locus, parameter.Name, this, parameter.SignatureKey)); } this.Parameters = new ReadOnlyCollection <IParameter>(parameters); this.ComputeCurrentParameter(); this.subjectBuffer.Changed += SubjectBuffer_Changed; this.session.Dismissed += Session_Dismissed; }
/// <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); }
/// <inheritdoc/> protected override async Task OnOpenAsync(CancellationToken token = default) { _logger?.LogInformation($"Opening session channel with endpoint '{RemoteEndpoint.EndpointUrl}'."); _logger?.LogInformation($"SecurityPolicy: '{RemoteEndpoint.SecurityPolicyUri}'."); _logger?.LogInformation($"SecurityMode: '{RemoteEndpoint.SecurityMode}'."); _logger?.LogInformation($"UserIdentity: '{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 (SessionId == null) { var localNonce = GetNextNonce(_nonceLength); var localCertificate = LocalCertificate; var createSessionRequest = new CreateSessionRequest { ClientDescription = LocalDescription, EndpointUrl = RemoteEndpoint.EndpointUrl, SessionName = LocalDescription.ApplicationName, ClientNonce = localNonce, ClientCertificate = localCertificate, RequestedSessionTimeout = _options.SessionTimeout, MaxResponseMessageSize = RemoteMaxMessageSize }; var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false); SessionId = createSessionResponse.SessionId; AuthenticationToken = createSessionResponse.AuthenticationToken; RemoteNonce = createSessionResponse.ServerNonce; // verify the server's certificate is the same as the certificate from the selected endpoint. ThrowOnInvalidSessionServerCertificate(createSessionResponse.ServerCertificate); // verify the server's signature. ISigner?verifier = null; bool verified = false; switch (RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: verifier = SignerUtilities.GetSigner("SHA-1withRSA"); verifier.Init(false, 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, 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, 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 (RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: signer = SignerUtilities.GetSigner("SHA-1withRSA"); signer.Init(true, LocalPrivateKey); signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, 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, LocalPrivateKey); signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, RemoteNonce !.Length); clientSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = _rsaSha256Signature, }; break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1"); signer.Init(true, LocalPrivateKey); signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, 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 (UserIdentity is IssuedIdentity issuedIdentity) { var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.IssuedToken); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } int plainTextLength = issuedIdentity.TokenData.Length + RemoteNonce !.Length; IBufferedCipher encryptor; byte[] cipherText; int pos; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding"); encryptor.Init(true, 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(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, 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(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, 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(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(); } // if UserIdentity type is X509Identity else if (UserIdentity is X509Identity x509Identity) { var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.Certificate); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.GetEncoded(), PolicyId = tokenPolicy.PolicyId }; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: signer = SignerUtilities.GetSigner("SHA-1withRSA"); signer.Init(true, x509Identity.PrivateKey); signer.BlockUpdate(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, 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(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, 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(RemoteEndpoint.ServerCertificate, 0, RemoteEndpoint.ServerCertificate !.Length); signer.BlockUpdate(RemoteNonce, 0, 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 (UserIdentity is UserNameIdentity userNameIdentity) { var tokenPolicy = RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t?.TokenType == UserTokenType.UserName); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } byte[] passwordBytes = userNameIdentity.Password != null?System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password) : new byte[0]; int plainTextLength = passwordBytes.Length + RemoteNonce !.Length; IBufferedCipher encryptor; byte[] cipherText; int pos; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding"); encryptor.Init(true, 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(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, 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(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, 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(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(); } // if UserIdentity type is AnonymousIdentity or null else { var tokenPolicy = 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); 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 (readResponse.Results[0] is { } res0&& StatusCode.IsGood(res0.StatusCode)) { if (res0.GetValueOrDefault <string[]>() is { } namespaceUris) { NamespaceUris = namespaceUris; } } if (readResponse.Results[1] is { } res1&& StatusCode.IsGood(res1.StatusCode)) { if (res1.GetValueOrDefault <string[]>() is { } serverUris) { ServerUris = serverUris; } } } // create the keep alive subscription. var subscriptionRequest = new CreateSubscriptionRequest { RequestedPublishingInterval = 1000f, RequestedMaxKeepAliveCount = 5, RequestedLifetimeCount = 120, PublishingEnabled = true, }; var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false); // link up the dataflow blocks var id = subscriptionResponse.SubscriptionId; var linkToken = this.LinkTo(_actionBlock, pr => pr.SubscriptionId == id); // start publishing. _stateMachineTask = Task.Run(() => StateMachineAsync(_stateMachineCts.Token)); }
/// <summary> /// Invokes the CreateSession service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="clientDescription">Application description for the client application.</param> /// <param name="serverUri">The server URI.</param> /// <param name="endpointUrl">The endpoint URL.</param> /// <param name="sessionName">Name for the Session assigned by the client.</param> /// <param name="clientNonce">The client nonce.</param> /// <param name="clientCertificate">The client certificate.</param> /// <param name="requestedSessionTimeout">The requested session timeout.</param> /// <param name="maxResponseMessageSize">Size of the max response message.</param> /// <param name="sessionId">The unique public identifier assigned by the Server to the Session.</param> /// <param name="authenticationToken">The unique private identifier assigned by the Server to the Session.</param> /// <param name="revisedSessionTimeout">The revised session timeout.</param> /// <param name="serverNonce">The server nonce.</param> /// <param name="serverCertificate">The server certificate.</param> /// <param name="serverEndpoints">The server endpoints.</param> /// <param name="serverSoftwareCertificates">The server software certificates.</param> /// <param name="serverSignature">The server signature.</param> /// <param name="maxRequestMessageSize">Size of the max request message.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader CreateSession( RequestHeader requestHeader, ApplicationDescription clientDescription, string serverUri, string endpointUrl, string sessionName, byte[] clientNonce, byte[] clientCertificate, double requestedSessionTimeout, uint maxResponseMessageSize, out NodeId sessionId, out NodeId authenticationToken, out double revisedSessionTimeout, out byte[] serverNonce, out byte[] serverCertificate, out EndpointDescriptionCollection serverEndpoints, out SignedSoftwareCertificateCollection serverSoftwareCertificates, out SignatureData serverSignature, out uint maxRequestMessageSize) { sessionId = 0; revisedSessionTimeout = 0; serverNonce = null; serverCertificate = null; serverSoftwareCertificates = null; serverSignature = null; maxRequestMessageSize = (uint)MessageContext.MaxMessageSize; OperationContext context = ValidateRequest(requestHeader, RequestType.CreateSession); try { // check the server uri. if (!String.IsNullOrEmpty(serverUri)) { if (serverUri != this.Configuration.ApplicationUri) { throw new ServiceResultException(StatusCodes.BadServerUriInvalid); } } bool requireEncryption = ServerBase.RequireEncryption(context.ChannelContext.EndpointDescription); if (!requireEncryption && clientCertificate != null) { requireEncryption = true; } // validate client application instance certificate. X509Certificate2 parsedClientCertificate = null; if (requireEncryption && clientCertificate != null && clientCertificate.Length > 0) { try { parsedClientCertificate = CertificateFactory.Create(clientCertificate, true); if (context.SecurityPolicyUri != SecurityPolicies.None) { string certificateApplicationUri = Utils.GetApplicationUriFromCertficate(parsedClientCertificate); // verify if applicationUri from ApplicationDescription matches the applicationUri in the client certificate. if (!String.IsNullOrEmpty(certificateApplicationUri) && !String.IsNullOrEmpty(clientDescription.ApplicationUri) && certificateApplicationUri != clientDescription.ApplicationUri) { throw ServiceResultException.Create( StatusCodes.BadCertificateUriInvalid, "The URI specified in the ApplicationDescription does not match the URI in the Certificate."); } CertificateValidator.Validate(parsedClientCertificate); } } catch (Exception e) { OnApplicationCertificateError(clientCertificate, new ServiceResult(e)); } } // verify the nonce provided by the client. if (clientNonce != null) { if (clientNonce.Length < m_minNonceLength) { throw new ServiceResultException(StatusCodes.BadNonceInvalid); } } // create the session. Session session = ServerInternal.SessionManager.CreateSession( context, requireEncryption ? InstanceCertificate : null, sessionName, clientNonce, clientDescription, endpointUrl, parsedClientCertificate, requestedSessionTimeout, maxResponseMessageSize, out sessionId, out authenticationToken, out serverNonce, out revisedSessionTimeout); lock (m_lock) { // return the application instance certificate for the server. if (requireEncryption) { serverCertificate = InstanceCertificate.RawData; } // return the endpoints supported by the server. serverEndpoints = GetEndpointDescriptions(endpointUrl, BaseAddresses, null); // return the software certificates assigned to the server. serverSoftwareCertificates = new SignedSoftwareCertificateCollection(ServerProperties.SoftwareCertificates); // sign the nonce provided by the client. serverSignature = null; // sign the client nonce (if provided). if (parsedClientCertificate != null && clientNonce != null) { byte[] dataToSign = Utils.Append(clientCertificate, clientNonce); serverSignature = SecurityPolicies.Sign(InstanceCertificate, context.SecurityPolicyUri, dataToSign); } } lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.CurrentSessionCount++; ServerInternal.ServerDiagnostics.CumulatedSessionCount++; } Utils.Trace("Server - SESSION CREATED. SessionId={0}", sessionId); return CreateResponse(requestHeader, StatusCodes.Good); } catch (ServiceResultException e) { Utils.Trace("Server - SESSION CREATE failed. {0}", e.Message); lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedSessionCount++; ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedSessionCount++; ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException((DiagnosticsMasks)requestHeader.ReturnDiagnostics, new StringCollection(), e); } finally { OnRequestComplete(context); } }
/// <summary> /// Finishes an asynchronous invocation of the CreateSession service. /// </summary> public ResponseHeader EndCreateSession( IAsyncResult result, out NodeId sessionId, out NodeId authenticationToken, out double revisedSessionTimeout, out byte[] serverNonce, out byte[] serverCertificate, out EndpointDescriptionCollection serverEndpoints, out SignedSoftwareCertificateCollection serverSoftwareCertificates, out SignatureData serverSignature, out uint maxRequestMessageSize) { CreateSessionResponse response = null; try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.EndSendRequest(result); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (CreateSessionResponse)genericResponse; } else { CreateSessionResponseMessage responseMessage = InnerChannel.EndCreateSession(result); if (responseMessage == null || responseMessage.CreateSessionResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.CreateSessionResponse; ValidateResponse(response.ResponseHeader); } sessionId = response.SessionId; authenticationToken = response.AuthenticationToken; revisedSessionTimeout = response.RevisedSessionTimeout; serverNonce = response.ServerNonce; serverCertificate = response.ServerCertificate; serverEndpoints = response.ServerEndpoints; serverSoftwareCertificates = response.ServerSoftwareCertificates; serverSignature = response.ServerSignature; maxRequestMessageSize = response.MaxRequestMessageSize; } finally { RequestCompleted(null, response, "CreateSession"); } return response.ResponseHeader; }
/// <summary> /// Invokes the CreateSession service. /// </summary> public virtual ResponseHeader CreateSession( RequestHeader requestHeader, ApplicationDescription clientDescription, string serverUri, string endpointUrl, string sessionName, byte[] clientNonce, byte[] clientCertificate, double requestedSessionTimeout, uint maxResponseMessageSize, out NodeId sessionId, out NodeId authenticationToken, out double revisedSessionTimeout, out byte[] serverNonce, out byte[] serverCertificate, out EndpointDescriptionCollection serverEndpoints, out SignedSoftwareCertificateCollection serverSoftwareCertificates, out SignatureData serverSignature, out uint maxRequestMessageSize) { sessionId = null; authenticationToken = null; revisedSessionTimeout = 0; serverNonce = null; serverCertificate = null; serverEndpoints = null; serverSoftwareCertificates = null; serverSignature = null; maxRequestMessageSize = 0; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the ActivateSession service. /// </summary> public virtual ResponseHeader ActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, out byte[] serverNonce, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { ActivateSessionRequest request = new ActivateSessionRequest(); ActivateSessionResponse response = null; request.RequestHeader = requestHeader; request.ClientSignature = clientSignature; request.ClientSoftwareCertificates = clientSoftwareCertificates; request.LocaleIds = localeIds; request.UserIdentityToken = userIdentityToken; request.UserTokenSignature = userTokenSignature; UpdateRequestHeader(request, requestHeader == null, "ActivateSession"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (ActivateSessionResponse)genericResponse; } else { ActivateSessionResponseMessage responseMessage = InnerChannel.ActivateSession(new ActivateSessionMessage(request)); if (responseMessage == null || responseMessage.ActivateSessionResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.ActivateSessionResponse; ValidateResponse(response.ResponseHeader); } serverNonce = response.ServerNonce; results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "ActivateSession"); } return response.ResponseHeader; }
private SignatureData LoadSignature() { var moduleSymbol = _containingType.ContainingPEModule; SignatureHeader signatureHeader; BadImageFormatException mrEx; ParamInfo<TypeSymbol>[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(_handle, out signatureHeader, out mrEx); bool makeBad = (mrEx != null); // If method is not generic, let's assign empty list for type parameters if (!signatureHeader.IsGeneric && _lazyTypeParameters.IsDefault) { ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameters, ImmutableArray<TypeParameterSymbol>.Empty); } int count = paramInfo.Length - 1; ImmutableArray<ParameterSymbol> @params; bool isBadParameter; if (count > 0) { var builder = ImmutableArray.CreateBuilder<ParameterSymbol>(count); for (int i = 0; i < count; i++) { builder.Add(PEParameterSymbol.Create(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter)); if (isBadParameter) { makeBad = true; } } @params = builder.ToImmutable(); } else { @params = ImmutableArray<ParameterSymbol>.Empty; } // Dynamify object type if necessary var returnType = paramInfo[0].Type.AsDynamicIfNoPia(_containingType); // Check for tuple type returnType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(returnType, paramInfo[0].Handle, moduleSymbol); paramInfo[0].Type = returnType; var returnParam = PEParameterSymbol.Create(moduleSymbol, this, 0, paramInfo[0], out isBadParameter); if (makeBad || isBadParameter) { InitializeUseSiteDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)); } var signature = new SignatureData(signatureHeader, @params, returnParam); return InterlockedOperations.Initialize(ref _lazySignature, signature); }
/// <summary> /// Begins an asynchronous invocation of the ActivateSession service. /// </summary> public IAsyncResult BeginActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, AsyncCallback callback, object asyncState) { ActivateSessionRequest request = new ActivateSessionRequest(); request.RequestHeader = requestHeader; request.ClientSignature = clientSignature; request.ClientSoftwareCertificates = clientSoftwareCertificates; request.LocaleIds = localeIds; request.UserIdentityToken = userIdentityToken; request.UserTokenSignature = userTokenSignature; UpdateRequestHeader(request, requestHeader == null, "ActivateSession"); if (UseTransportChannel) { return TransportChannel.BeginSendRequest(request, callback, asyncState); } return InnerChannel.BeginActivateSession(new ActivateSessionMessage(request), callback, asyncState); }
/// <summary> /// Verifies a signature created with the token (implemented by the subclass). /// </summary> public virtual bool Verify(byte[] dataToVerify, SignatureData signatureData, string securityPolicyUri) { return true; }
/// <summary> /// Verifies a signature created with the token. /// </summary> public override bool Verify(byte[] dataToVerify, SignatureData signatureData, string securityPolicyUri) { return true; }