public static LogEntry For(ActivateSessionRequest request) { LogEntry entry = new LogEntry("ActivateSessionRequest"); entry.Add("RequestHeader", For(request.RequestHeader)); entry.Add("LocaleIds", For(request.LocaleIds)); return(entry); }
public async Task <ActivateSessionResponse> ActivateSessionAsync(ActivateSessionRequest activateSessionRequest) { UpdateRequestHeader(activateSessionRequest, true, "ActivateSession"); ActivateSessionResponse activateSessionResponse = null; try { if (UseTransportChannel) { var serviceResponse = await Task <IServiceResponse> .Factory.FromAsync(TransportChannel.BeginSendRequest, TransportChannel.EndSendRequest, activateSessionRequest, null).ConfigureAwait(false); if (serviceResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(serviceResponse.ResponseHeader); activateSessionResponse = (ActivateSessionResponse)serviceResponse; } else { var activateSessionResponseMessage = await Task <ActivateSessionResponseMessage> .Factory.FromAsync(InnerChannel.BeginActivateSession, InnerChannel.EndActivateSession, new ActivateSessionMessage(activateSessionRequest), null).ConfigureAwait(false); if (activateSessionResponseMessage == null || activateSessionResponseMessage.ActivateSessionResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } activateSessionResponse = activateSessionResponseMessage.ActivateSessionResponse; ValidateResponse(activateSessionResponse.ResponseHeader); } } finally { RequestCompleted(activateSessionRequest, activateSessionResponse, "ActivateSession"); } return(activateSessionResponse); }
/// <inheritdoc/> protected override async Task OnOpenAsync(CancellationToken token = default(CancellationToken)) { this.logger?.LogInformation($"Opening session channel with endpoint '{this.RemoteEndpoint.EndpointUrl}'."); this.logger?.LogInformation($"SecurityPolicy: '{this.RemoteEndpoint.SecurityPolicyUri}'."); this.logger?.LogInformation($"SecurityMode: '{this.RemoteEndpoint.SecurityMode}'."); this.logger?.LogInformation($"UserIdentity: '{this.UserIdentity}'."); await base.OnOpenAsync(token).ConfigureAwait(false); token.ThrowIfCancellationRequested(); // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession. // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce if (this.SessionId == null) { var localNonce = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce(NonceLength) : null; var localCertificate = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate : null; var createSessionRequest = new CreateSessionRequest { ClientDescription = this.LocalDescription, EndpointUrl = this.RemoteEndpoint.EndpointUrl, SessionName = this.LocalDescription.ApplicationName, ClientNonce = localNonce, ClientCertificate = localCertificate, RequestedSessionTimeout = this.options.SessionTimeout, MaxResponseMessageSize = this.RemoteMaxMessageSize }; var createSessionResponse = await this.CreateSessionAsync(createSessionRequest).ConfigureAwait(false); this.SessionId = createSessionResponse.SessionId; this.AuthenticationToken = createSessionResponse.AuthenticationToken; this.RemoteNonce = createSessionResponse.ServerNonce; // verify the server's certificate is the same as the certificate from the selected endpoint. if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate)) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel."); } // verify the server's signature. ISigner verifier = null; bool verified = false; switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: verifier = SignerUtilities.GetSigner("SHA-1withRSA"); verifier.Init(false, this.RemotePublicKey); verifier.BlockUpdate(localCertificate, 0, localCertificate.Length); verifier.BlockUpdate(localNonce, 0, localNonce.Length); verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature); break; case SecurityPolicyUris.Basic256Sha256: case SecurityPolicyUris.Aes128_Sha256_RsaOaep: verifier = SignerUtilities.GetSigner("SHA-256withRSA"); verifier.Init(false, this.RemotePublicKey); verifier.BlockUpdate(localCertificate, 0, localCertificate.Length); verifier.BlockUpdate(localNonce, 0, localNonce.Length); verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature); break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: verifier = SignerUtilities.GetSigner("SHA-256withRSAandMGF1"); verifier.Init(false, this.RemotePublicKey); verifier.BlockUpdate(localCertificate, 0, localCertificate.Length); verifier.BlockUpdate(localNonce, 0, localNonce.Length); verified = verifier.VerifySignature(createSessionResponse.ServerSignature.Signature); break; default: verified = true; break; } verifier = null; if (!verified) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client."); } } // create client signature SignatureData clientSignature = null; ISigner signer = null; switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: signer = SignerUtilities.GetSigner("SHA-1withRSA"); signer.Init(true, this.LocalPrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); clientSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaSha1Signature, }; break; case SecurityPolicyUris.Basic256Sha256: case SecurityPolicyUris.Aes128_Sha256_RsaOaep: signer = SignerUtilities.GetSigner("SHA-256withRSA"); signer.Init(true, this.LocalPrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); clientSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaSha256Signature, }; break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1"); signer.Init(true, this.LocalPrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); clientSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaPssSha256Signature, }; break; default: clientSignature = new SignatureData(); break; } signer = null; // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken UserIdentityToken identityToken = null; SignatureData tokenSignature = null; // if UserIdentity type is IssuedIdentity if (this.UserIdentity is IssuedIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var issuedIdentity = (IssuedIdentity)this.UserIdentity; int plainTextLength = issuedIdentity.TokenData.Length + this.RemoteNonce.Length; IBufferedCipher encryptor; byte[] cipherText; int pos; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new IssuedIdentityToken { TokenData = cipherText, EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: case SecurityPolicyUris.Aes128_Sha256_RsaOaep: encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new IssuedIdentityToken { TokenData = cipherText, EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(issuedIdentity.TokenData, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new IssuedIdentityToken { TokenData = cipherText, EncryptionAlgorithm = RsaOaepSha256KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new IssuedIdentityToken { TokenData = issuedIdentity.TokenData, EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); encryptor = null; cipherText = null; } // if UserIdentity type is X509Identity else if (this.UserIdentity is X509Identity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var x509Identity = (X509Identity)this.UserIdentity; identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.GetEncoded(), PolicyId = tokenPolicy.PolicyId }; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: signer = SignerUtilities.GetSigner("SHA-1withRSA"); signer.Init(true, x509Identity.PrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); tokenSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaSha1Signature, }; break; case SecurityPolicyUris.Basic256Sha256: case SecurityPolicyUris.Aes128_Sha256_RsaOaep: signer = SignerUtilities.GetSigner("SHA-256withRSA"); signer.Init(true, x509Identity.PrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); tokenSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaSha256Signature, }; break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: signer = SignerUtilities.GetSigner("SHA-256withRSAandMGF1"); signer.Init(true, x509Identity.PrivateKey); signer.BlockUpdate(this.RemoteEndpoint.ServerCertificate, 0, this.RemoteEndpoint.ServerCertificate.Length); signer.BlockUpdate(this.RemoteNonce, 0, this.RemoteNonce.Length); tokenSignature = new SignatureData { Signature = signer.GenerateSignature(), Algorithm = RsaSha256Signature, }; break; default: tokenSignature = new SignatureData(); break; } signer = null; } // if UserIdentity type is UserNameIdentity else if (this.UserIdentity is UserNameIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var userNameIdentity = (UserNameIdentity)this.UserIdentity; byte[] passwordBytes = userNameIdentity.Password != null?System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password) : new byte[0]; int plainTextLength = passwordBytes.Length + this.RemoteNonce.Length; IBufferedCipher encryptor; byte[] cipherText; int pos; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: encryptor = CipherUtilities.GetCipher("RSA//PKCS1Padding"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(passwordBytes, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = cipherText, EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: case SecurityPolicyUris.Aes128_Sha256_RsaOaep: encryptor = CipherUtilities.GetCipher("RSA//OAEPPADDING"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(passwordBytes, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = cipherText, EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Aes256_Sha256_RsaPss: encryptor = CipherUtilities.GetCipher("RSA//OAEPWITHSHA256ANDMGF1PADDING"); encryptor.Init(true, this.RemotePublicKey); cipherText = new byte[encryptor.GetOutputSize(4 + plainTextLength)]; pos = encryptor.ProcessBytes(BitConverter.GetBytes(plainTextLength), cipherText, 0); pos = encryptor.ProcessBytes(passwordBytes, cipherText, pos); pos = encryptor.DoFinal(this.RemoteNonce, cipherText, pos); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = cipherText, EncryptionAlgorithm = RsaOaepSha256KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = passwordBytes, EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); passwordBytes = null; encryptor = null; cipherText = null; } // if UserIdentity type is AnonymousIdentity or null else { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } identityToken = new AnonymousIdentityToken { PolicyId = tokenPolicy.PolicyId }; tokenSignature = new SignatureData(); } var activateSessionRequest = new ActivateSessionRequest { ClientSignature = clientSignature, LocaleIds = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName }, UserIdentityToken = identityToken, UserTokenSignature = tokenSignature }; var activateSessionResponse = await this.ActivateSessionAsync(activateSessionRequest).ConfigureAwait(false); this.RemoteNonce = activateSessionResponse.ServerNonce; // fetch namespace array, etc. var readValueIds = new ReadValueId[] { new ReadValueId { NodeId = NodeId.Parse(VariableIds.Server_NamespaceArray), AttributeId = AttributeIds.Value }, new ReadValueId { NodeId = NodeId.Parse(VariableIds.Server_ServerArray), AttributeId = AttributeIds.Value } }; var readRequest = new ReadRequest { NodesToRead = readValueIds }; var readResponse = await this.ReadAsync(readRequest).ConfigureAwait(false); if (readResponse.Results.Length == 2) { if (StatusCode.IsGood(readResponse.Results[0].StatusCode)) { this.NamespaceUris.Clear(); this.NamespaceUris.AddRange(readResponse.Results[0].GetValueOrDefault <string[]>()); } if (StatusCode.IsGood(readResponse.Results[1].StatusCode)) { this.ServerUris.Clear(); this.ServerUris.AddRange(readResponse.Results[1].GetValueOrDefault <string[]>()); } } // create the keep alive subscription. var subscriptionRequest = new CreateSubscriptionRequest { RequestedPublishingInterval = DefaultPublishingInterval, RequestedMaxKeepAliveCount = DefaultKeepaliveCount, RequestedLifetimeCount = DefaultKeepaliveCount * 3, PublishingEnabled = true, }; var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest).ConfigureAwait(false); // link up the dataflow blocks var id = subscriptionResponse.SubscriptionId; var linkToken = this.LinkTo(this.actionBlock, pr => pr.SubscriptionId == id); // start publishing. this.stateMachineTask = Task.Run(() => this.StateMachineAsync(this.stateMachineCts.Token)); }
/// <summary> /// Activates a session. /// </summary> /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param> /// <param name="request">A <see cref="ActivateSessionRequest"/>.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="ActivateSessionResponse"/>.</returns> public static async Task <ActivateSessionResponse> ActivateSessionAsync(this IRequestChannel channel, ActivateSessionRequest request) { if (request == null) { throw new ArgumentNullException("request"); } return((ActivateSessionResponse)await channel.RequestAsync(request).ConfigureAwait(false)); }
/// <summary> /// Activates a session. /// </summary> /// <param name="channel">A instance of <see cref="IRequestChannel"/>.</param> /// <param name="request">A <see cref="ActivateSessionRequest"/>.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="ActivateSessionResponse"/>.</returns> /// <seealso href="https://reference.opcfoundation.org/v104/Core/docs/Part4/5.6.3/">OPC UA specification Part 4: Services, 5.6.3</seealso> internal static async Task <ActivateSessionResponse> ActivateSessionAsync(this IRequestChannel channel, ActivateSessionRequest request, CancellationToken token = default) { if (request == null) { throw new ArgumentNullException(nameof(request)); } return((ActivateSessionResponse)await channel.RequestAsync(request, token).ConfigureAwait(false)); }
/// <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> /// 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; }
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> /// Initializes the message with the body. /// </summary> public ActivateSessionMessage(ActivateSessionRequest ActivateSessionRequest) { this.ActivateSessionRequest = ActivateSessionRequest; }
protected override async Task OnOpenAsync(CancellationToken token) { await base.OnOpenAsync(token).ConfigureAwait(false); token.ThrowIfCancellationRequested(); // if SessionId is provided then we skip the CreateSessionRequest and go directly to (re)ActivateSession. // requires from previous Session: SessionId, AuthenticationToken, RemoteNonce if (this.SessionId == null) { var localNonce = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.GetNextNonce() : null; var localCertificateBlob = this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None ? this.LocalCertificate.RawData : null; var createSessionRequest = new CreateSessionRequest { RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow }, ClientDescription = this.LocalDescription, EndpointUrl = this.RemoteEndpoint.EndpointUrl, SessionName = this.LocalDescription.ApplicationName, ClientNonce = localNonce, ClientCertificate = localCertificateBlob, RequestedSessionTimeout = this.SessionTimeout, MaxResponseMessageSize = this.RemoteMaxMessageSize }; var createSessionResponse = (CreateSessionResponse)await this.RequestAsync(createSessionRequest).ConfigureAwait(false); this.SessionId = createSessionResponse.SessionId; this.AuthenticationToken = createSessionResponse.AuthenticationToken; this.RemoteNonce = createSessionResponse.ServerNonce; // verify the server's certificate is the same as the certificate from the selected endpoint. if (this.RemoteEndpoint.ServerCertificate != null && !this.RemoteEndpoint.ServerCertificate.SequenceEqual(createSessionResponse.ServerCertificate)) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Server did not return the same certificate used to create the channel."); } // verify the server's signature. switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: byte[] dataToVerify = Concat(localCertificateBlob, localNonce); if (!this.RemotePublicKey.VerifyData(dataToVerify, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client."); } break; case SecurityPolicyUris.Basic256Sha256: byte[] dataToVerify256 = Concat(localCertificateBlob, localNonce); if (!this.RemotePublicKey.VerifyData(dataToVerify256, createSessionResponse.ServerSignature.Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)) { throw new ServiceResultException(StatusCodes.BadApplicationSignatureInvalid, "Server did not provide a correct signature for the nonce data provided by the client."); } break; default: break; } } // create client signature SignatureData clientSignature = null; switch (this.RemoteEndpoint.SecurityPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); clientSignature = new SignatureData { Signature = this.LocalPrivateKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1), Algorithm = RsaSha1Signature, }; break; case SecurityPolicyUris.Basic256Sha256: byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); clientSignature = new SignatureData { Signature = this.LocalPrivateKey.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), Algorithm = RsaSha256Signature, }; break; default: clientSignature = new SignatureData(); break; } // supported UserIdentityToken types are AnonymousIdentityToken, UserNameIdentityToken, IssuedIdentityToken, X509IdentityToken UserIdentityToken identityToken = null; SignatureData tokenSignature = null; // if UserIdentity type is IssuedIdentity if (this.UserIdentity is IssuedIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.IssuedToken); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var issuedIdentity = (IssuedIdentity)this.UserIdentity; byte[] plainText = Concat(issuedIdentity.TokenData, this.RemoteNonce); var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; RSA asymRemoteEncryptionKey; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new IssuedIdentityToken { TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new IssuedIdentityToken { TokenData = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new IssuedIdentityToken { TokenData = issuedIdentity.TokenData, EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); } // if UserIdentity type is X509Identity else if (this.UserIdentity is X509Identity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Certificate); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var x509Identity = (X509Identity)this.UserIdentity; identityToken = new X509IdentityToken { CertificateData = x509Identity.Certificate?.RawData, PolicyId = tokenPolicy.PolicyId }; var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: case SecurityPolicyUris.Basic256: var asymSigningKey = x509Identity.Certificate?.GetRSAPrivateKey(); if (asymSigningKey != null) { byte[] dataToSign = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); tokenSignature = new SignatureData { Signature = asymSigningKey.SignData(dataToSign, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1), Algorithm = RsaSha1Signature, }; break; } tokenSignature = new SignatureData(); break; case SecurityPolicyUris.Basic256Sha256: var asymSigningKey256 = x509Identity.Certificate?.GetRSAPrivateKey(); if (asymSigningKey256 != null) { byte[] dataToSign256 = Concat(this.RemoteEndpoint.ServerCertificate, this.RemoteNonce); tokenSignature = new SignatureData { Signature = asymSigningKey256.SignData(dataToSign256, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1), Algorithm = RsaSha256Signature, }; break; } tokenSignature = new SignatureData(); break; default: tokenSignature = new SignatureData(); break; } } // if UserIdentity type is UserNameIdentity else if (this.UserIdentity is UserNameIdentity) { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.UserName); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } var userNameIdentity = (UserNameIdentity)this.UserIdentity; byte[] plainText = Concat(System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), this.RemoteNonce); var secPolicyUri = tokenPolicy.SecurityPolicyUri ?? this.RemoteEndpoint.SecurityPolicyUri; RSA asymRemoteEncryptionKey; switch (secPolicyUri) { case SecurityPolicyUris.Basic128Rsa15: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaV15KeyWrap, PolicyId = tokenPolicy.PolicyId }; break; case SecurityPolicyUris.Basic256: case SecurityPolicyUris.Basic256Sha256: asymRemoteEncryptionKey = this.RemoteCertificate.GetRSAPublicKey(); identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = asymRemoteEncryptionKey.EncryptTokenData(plainText, secPolicyUri), EncryptionAlgorithm = RsaOaepKeyWrap, PolicyId = tokenPolicy.PolicyId }; break; default: identityToken = new UserNameIdentityToken { UserName = userNameIdentity.UserName, Password = System.Text.Encoding.UTF8.GetBytes(userNameIdentity.Password), EncryptionAlgorithm = null, PolicyId = tokenPolicy.PolicyId }; break; } tokenSignature = new SignatureData(); } // if UserIdentity type is AnonymousIdentity or null else { var tokenPolicy = this.RemoteEndpoint.UserIdentityTokens.FirstOrDefault(t => t.TokenType == UserTokenType.Anonymous); if (tokenPolicy == null) { throw new ServiceResultException(StatusCodes.BadIdentityTokenRejected); } identityToken = new AnonymousIdentityToken { PolicyId = tokenPolicy.PolicyId }; tokenSignature = new SignatureData(); } var activateSessionRequest = new ActivateSessionRequest { RequestHeader = new RequestHeader { TimeoutHint = this.TimeoutHint, ReturnDiagnostics = this.DiagnosticsHint, Timestamp = DateTime.UtcNow }, ClientSignature = clientSignature, LocaleIds = new[] { CultureInfo.CurrentUICulture.TwoLetterISOLanguageName }, UserIdentityToken = identityToken, UserTokenSignature = tokenSignature }; var activateSessionResponse = (ActivateSessionResponse)await this.RequestAsync(activateSessionRequest).ConfigureAwait(false); this.RemoteNonce = activateSessionResponse.ServerNonce; await this.FetchNamespaceTablesAsync().ConfigureAwait(false); }