/// <summary> /// Updates an endpoint with information from the server's discovery endpoint. /// </summary> public void UpdateFromServer( Uri endpointUrl, MessageSecurityMode securityMode, string securityPolicyUri) { UpdateFromServer(endpointUrl, null, securityMode, securityPolicyUri); }
/// <summary> /// Displays the dialog. /// </summary> public bool ShowDialog(ref MessageSecurityMode securityMode, ref string securityPolicyUri, ref bool useNativeStack) { // set security mode. SecurityModeCB.SelectedItem = securityMode; // set security policy uri SecurityPolicyUriCB.SelectedIndex = -1; // set native stack flag. UseNativeStackCK.Checked = useNativeStack; if (!String.IsNullOrEmpty(securityPolicyUri)) { SecurityPolicyUriCB.SelectedItem = SecurityPolicies.GetDisplayName(securityPolicyUri); } // show dialog. if (ShowDialog() != DialogResult.OK) { return false; } securityMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; securityPolicyUri = SecurityPolicies.GetUri((string)SecurityPolicyUriCB.SelectedItem); useNativeStack = UseNativeStackCK.Checked; return true; }
/// <summary> /// Checks if it is possible to revise the security mode. /// </summary> protected void ReviseSecurityMode(bool firstCall, MessageSecurityMode requestedMode) { bool supported = false; // server may support multiple security modes - check if the one the client used is supported. if (firstCall && !m_discoveryOnly) { foreach (EndpointDescription endpoint in m_endpoints) { if (endpoint.SecurityMode == requestedMode) { if (requestedMode == MessageSecurityMode.None || endpoint.SecurityPolicyUri == m_securityPolicyUri) { m_securityMode = endpoint.SecurityMode; m_selectedEndpoint = endpoint; supported = true; break; } } } } if (!supported) { throw ServiceResultException.Create(StatusCodes.BadSecurityModeRejected, "Security mode is not acceptable to the server."); } }
/// <summary> /// Displays the dialog. /// </summary> public bool ShowDialog(ref MessageSecurityMode securityMode, ref string securityPolicyUri, ref bool useNativeStack) { // set security mode. SecurityModeCB.SelectedItem = securityMode; // set security policy uri SecurityPolicyUriCB.SelectedIndex = -1; // set native stack flag. UseNativeStackCK.Checked = useNativeStack; if (!String.IsNullOrEmpty(securityPolicyUri)) { SecurityPolicyUriCB.SelectedItem = SecurityPolicies.GetDisplayName(securityPolicyUri); } // show dialog. if (ShowDialog() != DialogResult.OK) { return(false); } securityMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; securityPolicyUri = SecurityPolicies.GetUri((string)SecurityPolicyUriCB.SelectedItem); useNativeStack = UseNativeStackCK.Checked; return(true); }
public async Task SendClosingMessage(string securityPolicyUri, MessageSecurityMode mode, byte[] openRequest, byte[] openResponse, byte[] request, byte[] response, byte[] closingRequest) { const uint channelId = 3; uint handle = 10; // create client and server var client = await CreateClientConversationAsync(securityPolicyUri, mode); var server = CreateServerConversation(channelId, mode); await SendAndReceiveAsync(client, server, MessageTypes.OPNF, handle, openRequest); server.SecurityMode = mode; await SendAndReceiveAsync(server, client, MessageTypes.OPNF, handle, openResponse); client.TokenId = TokenId; handle++; await SendAndReceiveAsync(client, server, MessageTypes.MSGA, handle, request); await SendAndReceiveAsync(server, client, MessageTypes.MSGA, handle, response); handle++; var result = await SendAndReceiveAsync(client, server, MessageTypes.CLOF, handle, closingRequest); result.requestHandle .Should().Be(handle); result.messageType .Should().Be(MessageTypes.CLOF); result.content .Should().Equal(closingRequest); client.ChannelId .Should().Be(channelId); }
public virtual bool SessionActivateClient( object session, SecurityPolicy securityPolicy, MessageSecurityMode messageSecurityMode, X509Certificate2 remoteCertificate) { return(true); }
/// <summary> /// Establishes the connection to the OPC Server /// </summary> /// <param name="serverUrl">URL to the server, ocp.tcp://server:port </param> /// <param name="securityMode"> None, Sign or SignAndEncrypt </param> /// <returns></returns> public async Task Connect(string serverUrl, MessageSecurityMode securityMode) { ConfiguredEndpoint endpoint = null; EndpointDescription endpointDescription = null; EndpointConfiguration endpointConfiguration = null; UserIdentity userIdentity = null; string[] preferredLocales = null; try { if (m_configuration == null) { throw new ArgumentNullException("m_configuration"); } if (session != null && !session.Disposed) { //remove existing subscriptions (not implemented yet) this.Disconnect(); //close the session } //List the server endpoints List <EndpointDescription> endpointsList = ListEndpoints(serverUrl); //Get the endpoint that matches the securityMode (like None, Sign or SignAndEncrypt) endpointDescription = endpointsList.Find(ep => ep.SecurityMode == securityMode); if (endpointDescription != null) { //Hook up a validator function for a CertificateValidation event m_configuration.CertificateValidator.CertificateValidation += CertificateValidator_CertificateValidation; //creates the endpointConfiguration object endpointConfiguration = EndpointConfiguration.Create(m_configuration); //creates the endpoint object endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration); //establishes the connection and creates the session this.session = await Session.Create( m_configuration, endpoint, updateBeforeConnect : false, checkDomain : true, sessionName : m_configuration.ApplicationName, sessionTimeout : 60000, identity : userIdentity, preferredLocales : preferredLocales); this.session.KeepAlive += Session_KeepAlive; } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(String.Format("Exception OpcUaClient::Connect: " + ex.ToString())); } }
private void AddTcpEndpoint(ushort port, MessageSecurityMode securityMode, string securityPolicyUri, ushort keySize, bool useAnsiCStack) { ConfiguredEndpoint endpoint = m_endpoints.Create(Utils.Format("opc.tcp://localhost:{0}/StackTestServer/{1}/{2}", port, (useAnsiCStack)?"AnsiC":"DotNet", keySize)); endpoint.Description.SecurityMode = securityMode; endpoint.Description.SecurityPolicyUri = securityPolicyUri; m_endpoints.Add(endpoint); }
private void AddHttpEndpoint(ushort port, MessageSecurityMode securityMode, string securityPolicyUri, bool useBinaryEncoding, ushort keySize) { ConfiguredEndpoint endpoint = m_endpoints.Create(Utils.Format("http://localhost:{0}/StackTestServer/{1}", port, keySize)); endpoint.Description.SecurityMode = securityMode; endpoint.Description.SecurityPolicyUri = securityPolicyUri; endpoint.Configuration.UseBinaryEncoding = useBinaryEncoding; m_endpoints.Add(endpoint); }
public static StatusCode SecureSymmetric( MemoryBuffer respBuf, int messageEncodedBlockStart, SLChannel.Keyset localKeyset, SLChannel.Keyset remoteKeyset, SecurityPolicy policy, MessageSecurityMode securityMode) { if (securityMode == MessageSecurityMode.None) { return(StatusCode.Good); } int num1 = UASecurity.SignatureSizeForSecurityPolicy(policy); if (securityMode >= MessageSecurityMode.SignAndEncrypt) { int symmetricPaddingSize = UASecurity.CalculateSymmetricPaddingSize(localKeyset.SymEncKey.Length, num1 + respBuf.Position - messageEncodedBlockStart); byte num2 = (byte)(symmetricPaddingSize - 1 & byte.MaxValue); byte[] Add = new byte[symmetricPaddingSize]; for (int index = 0; index < symmetricPaddingSize; ++index) { Add[index] = num2; } respBuf.Append(Add); } int num3 = respBuf.Position + num1; if (securityMode >= MessageSecurityMode.SignAndEncrypt) { num3 = messageEncodedBlockStart + UASecurity.CalculateSymmetricEncryptedSize(localKeyset.SymEncKey.Length, num3 - messageEncodedBlockStart); } if (num3 >= respBuf.Capacity) { return(StatusCode.BadEncodingLimitsExceeded); } UASecurity.MarkUAMessageSize(respBuf, (uint)num3); byte[] Add1 = UASecurity.SymmetricSign(localKeyset.SymSignKey, new ArraySegment <byte>(respBuf.Buffer, 0, respBuf.Position), policy); respBuf.Append(Add1); if (num3 != respBuf.Position) { throw new Exception(); } if (securityMode >= MessageSecurityMode.SignAndEncrypt) { UASecurity.RijndaelEncryptInplace(new ArraySegment <byte>(respBuf.Buffer, messageEncodedBlockStart, num3 - messageEncodedBlockStart), localKeyset.SymEncKey, localKeyset.SymIV); } return(StatusCode.Good); }
private static UaSecureConversation CreateServerConversation(uint channelId, MessageSecurityMode mode) { var store = mode == MessageSecurityMode.None ? ThrowingStore : Store; return(new UaSecureConversation(channelId, ServerDescription, new TransportConnectionOptions(), store, null) { TokenId = TokenId, }); }
private static bool IsValidCombination(string uri, MessageSecurityMode mode) { if (uri == SecurityPolicyUris.None) { return(mode == MessageSecurityMode.None); } else { return(mode != MessageSecurityMode.None); } }
/// <summary> /// Attaches the object to an existing socket. /// </summary> public UaSCUaBinaryChannel( string contextId, BufferManager bufferManager, ChannelQuotas quotas, X509Certificate2 serverCertificate, EndpointDescriptionCollection endpoints, MessageSecurityMode securityMode, string securityPolicyUri) : this(contextId, bufferManager, quotas, serverCertificate, null, endpoints, securityMode, securityPolicyUri) { }
/// <inheritdoc/> public IApplicationConfigurationBuilderServerSelected AddPolicy(MessageSecurityMode securityMode, string securityPolicy) { if (SecurityPolicies.GetDisplayName(securityPolicy) == null) { throw new ArgumentException("Unknown security policy", nameof(securityPolicy)); } if (securityMode == MessageSecurityMode.None || securityPolicy.Equals(SecurityPolicies.None)) { throw new ArgumentException("Use AddUnsecurePolicyNone to add no security policy."); } InternalAddPolicy(ApplicationConfiguration.ServerConfiguration.SecurityPolicies, securityMode, securityPolicy); return(this); }
/// <summary> /// Initializes a new instance of the <see cref="ClientSecurityConfiguration"/> class. /// </summary> /// <param name="mode">The message security mode</param> /// <param name="policyUri">The Uri to the security policy</param> /// <param name="username">The username, leave blank to use ananoymous access</param> /// <param name="password">The password, leave blank to use anonymous access</param> /// <param name="userTokenPolicies">A collection of user token policies that may be used, to identify is anonymous login is allowed</param> public ClientSecurityConfiguration(MessageSecurityMode mode, string policyUri = "", string username = "", string password = "", UserTokenPolicyCollection userTokenPolicies = null) { this.securityMode = mode; this.securityPolicyUri = policyUri; this.username = username; this.password = password; if (userTokenPolicies != null) { foreach (var token in userTokenPolicies) { if (token.TokenType == UserTokenType.Anonymous) { this.anonymousAccessAllowed = true; break; } } } }
public async Task SendOpeningMessage(string securityPolicyUri, MessageSecurityMode mode, byte[] request) { const uint channelId = 3; uint handle = 10; // create client and server var client = await CreateClientConversationAsync(securityPolicyUri, mode); var server = CreateServerConversation(channelId, mode); var result = await SendAndReceiveAsync(client, server, MessageTypes.OPNF, handle, request); result.requestHandle .Should().Be(handle); result.messageType .Should().Be(MessageTypes.OPNF); result.content .Should().Equal(request); }
public EndpointDescription( string EndpointUrl, ApplicationDescription Server, byte[] ServerCertificate, MessageSecurityMode SecurityMode, string SecurityPolicyUri, UserTokenPolicy[] UserIdentityTokens, string TransportProfileUri, byte SecurityLevel) { this.EndpointUrl = EndpointUrl; this.Server = Server; this.ServerCertificate = ServerCertificate; this.SecurityMode = SecurityMode; this.SecurityPolicyUri = SecurityPolicyUri; this.UserIdentityTokens = UserIdentityTokens; this.TransportProfileUri = TransportProfileUri; this.SecurityLevel = SecurityLevel; }
/// <summary> /// Add security policy if it doesn't exist yet. /// </summary> /// <param name="policies">The collection to which the policies are added.</param> /// <param name="securityMode">The message security mode.</param> /// <param name="policyUri">The security policy Uri.</param> private bool InternalAddPolicy(ServerSecurityPolicyCollection policies, MessageSecurityMode securityMode, string policyUri) { if (securityMode == MessageSecurityMode.Invalid) { throw new ArgumentException("Invalid security mode selected", nameof(securityMode)); } var newPolicy = new ServerSecurityPolicy() { SecurityMode = securityMode, SecurityPolicyUri = policyUri }; if (policies.Find(s => s.SecurityMode == newPolicy.SecurityMode && string.Equals(s.SecurityPolicyUri, newPolicy.SecurityPolicyUri, StringComparison.Ordinal) ) == null) { policies.Add(newPolicy); return(true); } return(false); }
public static Entry For(MessageSecurityMode securityMode) { string msmText = null; switch (securityMode) { case MessageSecurityMode.Invalid: msmText = "Invalid"; break; case MessageSecurityMode.None: msmText = "None"; break; case MessageSecurityMode.Sign: msmText = "Sign"; break; case MessageSecurityMode.SignAndEncrypt: msmText = "SignAndEncrypt"; break; } return(new StringEntry(msmText)); }
private static async Task <UaSecureConversation> CreateClientConversationAsync(string securityPolicyUri, MessageSecurityMode mode) { var store = mode == MessageSecurityMode.None ? ThrowingStore : Store; var client = new UaSecureConversation(ClientDescription, new TransportConnectionOptions(), store, null) { SecurityMode = mode, }; await client.SetRemoteCertificateAsync(securityPolicyUri, store.ServerCertificate, default); return(client); }
public void InitializeSinglePolicy( Type contractType, ApplicationConfiguration configuration, BindingFactory bindingFactory, EndpointConfiguration endpointConfiguration, List<EndpointDescription> endpoints, MessageSecurityMode securityMode, string securityPolicyUri) { // allow any url to match. System.ServiceModel.ServiceBehaviorAttribute behavoir = this.Description.Behaviors.Find<System.ServiceModel.ServiceBehaviorAttribute>(); behavoir.AddressFilterMode = System.ServiceModel.AddressFilterMode.Any; // specify service credentials ServiceCredentials credentials = new ServiceCredentials(); credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom; credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine; credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; credentials.ClientCertificate.Authentication.CustomCertificateValidator = configuration.CertificateValidator.GetChannelValidator(); if (configuration.SecurityConfiguration.ApplicationCertificate != null) { X509Certificate2 certificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true); if (certificate != null) { credentials.ServiceCertificate.Certificate = CertificateFactory.Load(certificate, true); } } this.Description.Behaviors.Add(credentials); // check if explicitly specified. ServiceThrottlingBehavior throttle = this.Description.Behaviors.Find<ServiceThrottlingBehavior>(); if (throttle == null) { throttle = new ServiceThrottlingBehavior(); throttle.MaxConcurrentCalls = 1000; throttle.MaxConcurrentInstances = 100; throttle.MaxConcurrentSessions = 100; this.Description.Behaviors.Add(throttle); } // add the endpoints for each base address. foreach (Uri baseAddress in this.BaseAddresses) { ServiceEndpoint endpoint = null; // find endpoint configuration. EndpointDescription description = null; foreach (EndpointDescription current in endpoints) { if (new Uri(current.EndpointUrl) == baseAddress) { description = current; break; } } // skip endpoints without a matching base address. if (description == null) { continue; } // set the supported profiles. description.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport; // create the SOAP XML binding Binding binding = bindingFactory.Create(baseAddress.Scheme, description, endpointConfiguration); // add the session endpoint. endpoint = this.AddServiceEndpoint(contractType, binding, baseAddress, baseAddress); // set the protection level if (securityMode == MessageSecurityMode.Sign) { endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign; } // update the max items in graph (set to an low value by default). foreach (OperationDescription operation in endpoint.Contract.Operations) { operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = Int32.MaxValue; } } }
/// <summary> /// Creates a new endpoint from a url that is not part of the collection. /// </summary> /// <remarks> /// Call the Add() method to add it to the collection. /// </remarks> public ConfiguredEndpoint Create(string url) { // check for security parameters appended to the URL string parameters = null; int index = url.IndexOf("- [", StringComparison.Ordinal); if (index != -1) { parameters = url.Substring(index + 3); url = url.Substring(0, index).Trim(); } MessageSecurityMode securityMode = MessageSecurityMode.SignAndEncrypt; string securityPolicyUri = SecurityPolicies.Basic128Rsa15; bool useBinaryEncoding = true; if (!String.IsNullOrEmpty(parameters)) { string[] fields = parameters.Split(new char[] { '-', '[', ':', ']' }, StringSplitOptions.RemoveEmptyEntries); try { if (fields.Length > 0) { securityMode = (MessageSecurityMode)Enum.Parse(typeof(MessageSecurityMode), fields[0], false); } else { securityMode = MessageSecurityMode.None; } } catch { securityMode = MessageSecurityMode.None; } try { if (fields.Length > 1) { securityPolicyUri = SecurityPolicies.GetUri(fields[1]); } else { securityPolicyUri = SecurityPolicies.None; } } catch { securityPolicyUri = SecurityPolicies.None; } try { if (fields.Length > 2) { useBinaryEncoding = fields[2] == "Binary"; } else { useBinaryEncoding = false; } } catch { useBinaryEncoding = false; } } Uri uri = new Uri(url); EndpointDescription description = new EndpointDescription(); description.EndpointUrl = uri.ToString(); description.SecurityMode = securityMode; description.SecurityPolicyUri = securityPolicyUri; description.Server.ApplicationUri = Utils.UpdateInstanceUri(uri.ToString()); description.Server.ApplicationName = uri.AbsolutePath; if (description.EndpointUrl.StartsWith(Utils.UriSchemeOpcTcp, StringComparison.Ordinal)) { description.TransportProfileUri = Profiles.UaTcpTransport; description.Server.DiscoveryUrls.Add(description.EndpointUrl); } else if (description.EndpointUrl.StartsWith(Utils.UriSchemeHttps, StringComparison.Ordinal)) { description.TransportProfileUri = Profiles.HttpsBinaryTransport; description.Server.DiscoveryUrls.Add(description.EndpointUrl); } ConfiguredEndpoint endpoint = new ConfiguredEndpoint(this, description, null); endpoint.Configuration.UseBinaryEncoding = useBinaryEncoding; endpoint.UpdateBeforeConnect = true; return(endpoint); }
/// <summary> /// Updates an endpoint with information from the server's discovery endpoint. /// </summary> public void UpdateFromServer( Uri endpointUrl, MessageSecurityMode securityMode, string securityPolicyUri) { // get the a discovery url. Uri discoveryUrl = GetDiscoveryUrl(endpointUrl); // create the discovery client. DiscoveryClient client = DiscoveryClient.Create(discoveryUrl, m_configuration); try { // get the endpoints. EndpointDescriptionCollection collection = client.GetEndpoints(null); if (collection == null || collection.Count == 0) { throw ServiceResultException.Create( StatusCodes.BadUnknownResponse, "Server does not have any endpoints defined."); } // find list of matching endpoints. EndpointDescriptionCollection matches = new EndpointDescriptionCollection(); // first pass - match on the requested security parameters. foreach (EndpointDescription description in collection) { // check for match on security policy. if (!String.IsNullOrEmpty(securityPolicyUri)) { if (securityPolicyUri != description.SecurityPolicyUri) { continue; } } // check for match on security mode. if (securityMode != MessageSecurityMode.Invalid) { if (securityMode != description.SecurityMode) { continue; } } // add to list of matches. matches.Add(description); } // no matches (security parameters may have changed). if (matches.Count == 0) { matches = collection; } // check if list has to be narrowed down further. if (matches.Count > 1) { collection = matches; matches = new EndpointDescriptionCollection(); // second pass - match on the url scheme. foreach (EndpointDescription description in collection) { // parse the endpoint url. Uri sessionUrl = Utils.ParseUri(description.EndpointUrl); if (sessionUrl == null) { continue; } // check for matching protocol. if (sessionUrl.Scheme != endpointUrl.Scheme) { continue; } matches.Add(description); } } // no matches (protocol may not be supported). if (matches.Count == 0) { matches = collection; } // choose first in list by default. EndpointDescription match = matches[0]; // check if list has to be narrowed down further. if (matches.Count > 1) { // third pass - match based on security level. foreach (EndpointDescription description in matches) { if (description.SecurityMode > match.SecurityMode) { match = description; } } } // check if the endpoint url matches the endpoint used in the request. Uri matchUrl = Utils.ParseUri(match.EndpointUrl); if (matchUrl == null || String.Compare(discoveryUrl.DnsSafeHost, matchUrl.DnsSafeHost, StringComparison.OrdinalIgnoreCase) != 0) { UriBuilder uri = new UriBuilder(matchUrl); uri.Host = discoveryUrl.DnsSafeHost; uri.Port = discoveryUrl.Port; match.EndpointUrl = uri.ToString(); // need to update the discovery urls. match.Server.DiscoveryUrls.Clear(); match.Server.DiscoveryUrls.Add(discoveryUrl.ToString()); } // update the endpoint. Update(match); } finally { client.Close(); } }
public ConnectionProfile(string securityProfileUri, MessageSecurityMode messageSecurityMode) { SecurityProfileUri = securityProfileUri; MessageSecurityMode = messageSecurityMode; }
/// <summary> /// Finds the best match for the current protocol and security selections. /// </summary> private EndpointDescription FindBestEndpointDescription(EndpointDescriptionCollection endpoints) { // filter by the current protocol. string currentProtocol = (string)ProtocolCB.SelectedItem; // filter by the current security mode. MessageSecurityMode currentMode = MessageSecurityMode.None; if (SecurityModeCB.SelectedIndex != -1) { currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; } // filter by the current security policy. string currentPolicy = (string)SecurityPolicyCB.SelectedItem; // find all matching descriptions. EndpointDescriptionCollection matches = new EndpointDescriptionCollection(); if (endpoints != null) { foreach (EndpointDescription endpoint in endpoints) { Uri url = Utils.ParseUri(endpoint.EndpointUrl); if (url == null) { continue; } if (currentProtocol != url.Scheme) { continue; } if (currentMode != endpoint.SecurityMode) { continue; } if (currentPolicy != SecurityPolicies.GetDisplayName(endpoint.SecurityPolicyUri)) { continue; } matches.Add(endpoint); } } // check for no matches. if (matches.Count == 0) { return(null); } // check for single match. if (matches.Count == 1) { return(matches[0]); } // choose highest priority. EndpointDescription bestMatch = matches[0]; for (int ii = 1; ii < matches.Count; ii++) { if (bestMatch.SecurityLevel < matches[ii].SecurityLevel) { bestMatch = matches[ii]; } } return(bestMatch); }
public static StatusCode SecureSymmetric(MemoryBuffer respBuf, int messageEncodedBlockStart, SLChannel.Keyset localKeyset, SLChannel.Keyset remoteKeyset, SecurityPolicy policy, MessageSecurityMode securityMode) { if (securityMode == MessageSecurityMode.None) { return(StatusCode.Good); } int sigSize = SignatureSizeForSecurityPolicy(policy); if (securityMode >= MessageSecurityMode.SignAndEncrypt) { //int padSize2 = CalculateSymmetricPaddingSize(remoteKeyset.SymEncKey.Length, sigSize + respBuf.Position - messageEncodedBlockStart); int padSize = CalculateSymmetricPaddingSize(localKeyset.SymEncKey.Length, sigSize + respBuf.Position - messageEncodedBlockStart); byte paddingValue = (byte)((padSize - 1) & 0xFF); var appendPadding = new byte[padSize]; for (int i = 0; i < padSize; i++) { appendPadding[i] = paddingValue; } respBuf.Append(appendPadding); } int msgSize = respBuf.Position + sigSize; if (securityMode >= MessageSecurityMode.SignAndEncrypt) { msgSize = messageEncodedBlockStart + CalculateSymmetricEncryptedSize(localKeyset.SymEncKey.Length, msgSize - messageEncodedBlockStart); } if (msgSize >= respBuf.Capacity) { return(StatusCode.BadEncodingLimitsExceeded); } MarkUAMessageSize(respBuf, (UInt32)msgSize); var sig = UASecurity.SymmetricSign(localKeyset.SymSignKey, new ArraySegment <byte>(respBuf.Buffer, 0, respBuf.Position), policy); respBuf.Append(sig); if (msgSize != respBuf.Position) { throw new Exception(); return(StatusCode.BadInternalError); } if (securityMode >= MessageSecurityMode.SignAndEncrypt) { int encrLen = UASecurity.RijndaelEncryptInplace( new ArraySegment <byte>(respBuf.Buffer, messageEncodedBlockStart, msgSize - messageEncodedBlockStart), localKeyset.SymEncKey, localKeyset.SymIV); } return(StatusCode.Good); }
/// <summary> /// Initializes the security modes dropdown. /// </summary> private void InitializeSecurityModes(EndpointDescriptionCollection endpoints) { // filter by the current protocol. string currentProtocol = (string)ProtocolCB.SelectedItem; // preserve the existing value. MessageSecurityMode currentMode = MessageSecurityMode.None; if (SecurityModeCB.SelectedIndex != -1) { currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; } SecurityModeCB.Items.Clear(); // set all available security modes. if (m_showAllOptions) { SecurityModeCB.Items.Add(MessageSecurityMode.None); SecurityModeCB.Items.Add(MessageSecurityMode.Sign); SecurityModeCB.Items.Add(MessageSecurityMode.SignAndEncrypt); } // find all unique security modes. else { if (endpoints != null) { foreach (EndpointDescription endpoint in endpoints) { Uri url = Utils.ParseUri(endpoint.EndpointUrl); if (url != null) { if (currentProtocol != url.Scheme) { continue; } if (!SecurityModeCB.Items.Contains(endpoint.SecurityMode)) { SecurityModeCB.Items.Add(endpoint.SecurityMode); } } } } // add at least one policy. if (SecurityModeCB.Items.Count == 0) { SecurityModeCB.Items.Add(MessageSecurityMode.None); } } // set the current value. int index = SecurityModeCB.Items.IndexOf(currentMode); if (index == -1) { index = 0; } SecurityModeCB.SelectedIndex = index; }
/// <summary> /// Initializes the security policies dropdown. /// </summary> private void InitializeSecurityPolicies(EndpointDescriptionCollection endpoints) { // filter by the current protocol. string currentProtocol = (string)ProtocolCB.SelectedItem; // filter by the current security mode. MessageSecurityMode currentMode = MessageSecurityMode.None; if (SecurityModeCB.SelectedIndex != -1) { currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem; } // preserve the existing value. string currentPolicy = (string)SecurityPolicyCB.SelectedItem; SecurityPolicyCB.Items.Clear(); // set all available security policies. if (m_showAllOptions) { SecurityPolicyCB.Items.Add(SecurityPolicies.GetDisplayName(SecurityPolicies.None)); SecurityPolicyCB.Items.Add(SecurityPolicies.GetDisplayName(SecurityPolicies.Basic128Rsa15)); SecurityPolicyCB.Items.Add(SecurityPolicies.GetDisplayName(SecurityPolicies.Basic256)); } // find all unique security policies. else { if (endpoints != null) { foreach (EndpointDescription endpoint in endpoints) { Uri url = Utils.ParseUri(endpoint.EndpointUrl); if (url != null) { if (currentProtocol != url.Scheme) { continue; } if (currentMode != endpoint.SecurityMode) { continue; } string policyName = SecurityPolicies.GetDisplayName(endpoint.SecurityPolicyUri); int existingIndex = SecurityPolicyCB.FindStringExact(policyName); if (existingIndex == -1) { SecurityPolicyCB.Items.Add(policyName); } } } } } // add at least one policy. if (SecurityPolicyCB.Items.Count == 0) { SecurityPolicyCB.Items.Add(SecurityPolicies.GetDisplayName(SecurityPolicies.None)); } // set the current value. int index = 0; if (!String.IsNullOrEmpty(currentPolicy)) { index = SecurityPolicyCB.FindStringExact(currentPolicy); if (index == -1) { index = 0; } } SecurityPolicyCB.SelectedIndex = index; }
public void InitializeSinglePolicy( Type contractType, ApplicationConfiguration configuration, BindingFactory bindingFactory, EndpointConfiguration endpointConfiguration, List <EndpointDescription> endpoints, MessageSecurityMode securityMode, string securityPolicyUri) { // allow any url to match. System.ServiceModel.ServiceBehaviorAttribute behavoir = this.Description.Behaviors.Find <System.ServiceModel.ServiceBehaviorAttribute>(); behavoir.AddressFilterMode = System.ServiceModel.AddressFilterMode.Any; // specify service credentials ServiceCredentials credentials = new ServiceCredentials(); credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom; credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine; credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; credentials.ClientCertificate.Authentication.CustomCertificateValidator = configuration.CertificateValidator.GetChannelValidator(); if (configuration.SecurityConfiguration.ApplicationCertificate != null) { X509Certificate2 certificate = configuration.SecurityConfiguration.ApplicationCertificate.Find(true); if (certificate != null) { credentials.ServiceCertificate.Certificate = CertificateFactory.Load(certificate, true); } } this.Description.Behaviors.Add(credentials); // check if explicitly specified. ServiceThrottlingBehavior throttle = this.Description.Behaviors.Find <ServiceThrottlingBehavior>(); if (throttle == null) { throttle = new ServiceThrottlingBehavior(); throttle.MaxConcurrentCalls = 1000; throttle.MaxConcurrentInstances = 100; throttle.MaxConcurrentSessions = 100; this.Description.Behaviors.Add(throttle); } // add the endpoints for each base address. foreach (Uri baseAddress in this.BaseAddresses) { ServiceEndpoint endpoint = null; // find endpoint configuration. EndpointDescription description = null; foreach (EndpointDescription current in endpoints) { if (new Uri(current.EndpointUrl) == baseAddress) { description = current; break; } } // skip endpoints without a matching base address. if (description == null) { continue; } // set the supported profiles. description.TransportProfileUri = Profiles.WsHttpXmlOrBinaryTransport; // create the SOAP XML binding Binding binding = bindingFactory.Create(baseAddress.Scheme, description, endpointConfiguration); // add the session endpoint. endpoint = this.AddServiceEndpoint(contractType, binding, baseAddress, baseAddress); // set the protection level if (securityMode == MessageSecurityMode.Sign) { endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.Sign; } // update the max items in graph (set to an low value by default). foreach (OperationDescription operation in endpoint.Contract.Operations) { operation.Behaviors.Find <DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = Int32.MaxValue; } } }
/// <summary> /// Create a new service host for protocols that support only one policy per host. /// </summary> /// <param name="hosts">The hosts.</param> /// <param name="configuration">The configuration.</param> /// <param name="bindingFactory">The binding factory.</param> /// <param name="baseAddresses">The base addresses.</param> /// <param name="serverDescription">The server description.</param> /// <param name="securityMode">The security mode.</param> /// <param name="securityPolicyUri">The security policy URI.</param> /// <param name="basePath">The base path to use when constructing the hosts.</param> /// <returns>Returns list of descriptions for the EndpointDescription DataType, return type is list of <seealso cref="EndpointDescription"/>.</returns> protected List<EndpointDescription> CreateSinglePolicyServiceHost( IDictionary<string, ServiceHost> hosts, ApplicationConfiguration configuration, BindingFactory bindingFactory, IList<string> baseAddresses, ApplicationDescription serverDescription, MessageSecurityMode securityMode, string securityPolicyUri, string basePath) { // generate a unique host name. string hostName = basePath; if (hosts.ContainsKey(hostName)) { hostName += Utils.Format("/{0}", SecurityPolicies.GetDisplayName(securityPolicyUri)); } if (hosts.ContainsKey(hostName)) { hostName += Utils.Format("/{0}", securityMode); } if (hosts.ContainsKey(hostName)) { hostName += Utils.Format("/{0}", hosts.Count); } // build list of uris. List<Uri> uris = new List<Uri>(); List<EndpointDescription> endpoints = new List<EndpointDescription>(); string computerName = System.Net.Dns.GetHostName(); for (int ii = 0; ii < baseAddresses.Count; ii++) { // UA TCP and HTTPS endpoints have their own host. if (baseAddresses[ii].StartsWith(Utils.UriSchemeOpcTcp, StringComparison.Ordinal) || baseAddresses[ii].StartsWith(Utils.UriSchemeHttps, StringComparison.Ordinal) || baseAddresses[ii].StartsWith(Utils.UriSchemeNoSecurityHttp, StringComparison.Ordinal)) { continue; } UriBuilder uri = new UriBuilder(baseAddresses[ii]); if (String.Compare(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase) == 0) { uri.Host = computerName; } uri.Path += hostName; uris.Add(uri.Uri); // create the endpoint description. EndpointDescription description = new EndpointDescription(); description.EndpointUrl = uri.ToString(); description.Server = serverDescription; description.SecurityMode = securityMode; description.SecurityPolicyUri = securityPolicyUri; description.TransportProfileUri = Profiles.WsHttpXmlTransport; description.UserIdentityTokens = GetUserTokenPolicies(configuration, description); bool requireEncryption = RequireEncryption(description); if (!requireEncryption) { foreach (UserTokenPolicy userTokenPolicy in description.UserIdentityTokens) { if (userTokenPolicy.SecurityPolicyUri != SecurityPolicies.None) { requireEncryption = true; break; } } } if (requireEncryption) { if (InstanceCertificate == null) { throw new ServiceResultException( StatusCodes.BadConfigurationError, "Server does not have an instance certificate assigned." ); } description.ServerCertificate = InstanceCertificate.RawData; //if (InstanceCertificateChain != null) //{ // List<byte> certificateChainList = new List<byte>(); // for (int i = 0; i < InstanceCertificateChain.Count; i++) // { // certificateChainList.AddRange(InstanceCertificateChain[i].RawData); // } // description.ServerCertificate = certificateChainList.ToArray(); //} } endpoints.Add(description); } // check if nothing to do. if (uris.Count == 0) { return endpoints; } // create the host. ServiceHost serviceHost = CreateServiceHost(this, uris.ToArray()); // create the endpoint configuration to use. EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(configuration); // initialize the host. serviceHost.InitializeSinglePolicy( GetServiceContract(), configuration, bindingFactory, endpointConfiguration, endpoints, securityMode, securityPolicyUri); if (String.IsNullOrEmpty(hostName)) { serviceHost.InitializeDiscovery(configuration, serverDescription.DiscoveryUrls); } // save in server list. hosts[hostName] = serviceHost; return endpoints; }
/// <summary> /// Updates the list of servers displayed in the control. /// </summary> private void OnUpdateEndpoints(object state) { if (this.InvokeRequired) { this.BeginInvoke(new WaitCallback(OnUpdateEndpoints), state); return; } // get the updated descriptions. EndpointDescriptionCollection endpoints = state as EndpointDescriptionCollection; if (endpoints == null) { m_showAllOptions = true; InitializeProtocols(m_availableEndpoints); } else { m_showAllOptions = false; m_availableEndpoints = endpoints; if (endpoints.Count > 0) { m_currentDescription = endpoints[0]; } // initializing the protocol will trigger an update to all other controls. InitializeProtocols(m_availableEndpoints); // select the best security mode. MessageSecurityMode bestMode = MessageSecurityMode.Invalid; foreach (MessageSecurityMode securityMode in SecurityModeCB.Items) { if (securityMode > bestMode) { bestMode = securityMode; } } SecurityModeCB.SelectedItem = bestMode; // select the best encoding. Encoding bestEncoding = Encoding.Default; foreach (Encoding encoding in EncodingCB.Items) { if (encoding > bestEncoding) { bestEncoding = encoding; } } EncodingCB.SelectedItem = bestEncoding; } if (m_endpoint != null) { Uri url = m_endpoint.EndpointUrl; foreach (string protocol in ProtocolCB.Items) { if (protocol == url.Scheme) { ProtocolCB.SelectedItem = url.Scheme; break; } } foreach (MessageSecurityMode securityMode in SecurityModeCB.Items) { if (securityMode == m_endpoint.Description.SecurityMode) { SecurityModeCB.SelectedItem = securityMode; break; } } foreach (string securityPolicy in SecurityPolicyCB.Items) { if (securityPolicy == m_endpoint.Description.SecurityPolicyUri) { SecurityPolicyCB.SelectedItem = securityPolicy; break; } } foreach (Encoding encoding in EncodingCB.Items) { if (encoding == Encoding.Binary && m_endpoint.Configuration.UseBinaryEncoding) { EncodingCB.SelectedItem = encoding; break; } if (encoding == Encoding.Xml && !m_endpoint.Configuration.UseBinaryEncoding) { EncodingCB.SelectedItem = encoding; break; } } } }
/*protected void ReadAsymmetricMessageHeader( BinaryDecoder decoder, X509Certificate2 receiverCertificate, out uint secureChannelId, out X509Certificate2Collection senderCertificate, out string securityPolicyUri) { senderCertificate = null; uint messageType = decoder.ReadUInt32(null); uint messageSize = decoder.ReadUInt32(null); // decode security header. byte[] certificateData = null; byte[] thumbprintData = null; try { secureChannelId = decoder.ReadUInt32(null); securityPolicyUri = decoder.ReadString(null, TcpMessageLimits.MaxSecurityPolicyUriSize); certificateData = decoder.ReadByteString(null, TcpMessageLimits.MaxCertificateSize); thumbprintData = decoder.ReadByteString(null, TcpMessageLimits.CertificateThumbprintSize); } catch (Exception e) { throw ServiceResultException.Create( StatusCodes.BadSecurityChecksFailed, e, "The asymmetric security header could not be parsed."); } // verify sender certificate. if (certificateData != null && certificateData.Length > 0) { senderCertificate = Utils.ParseCertificateChainBlob(certificateData); try { string thumbprint = senderCertificate[0].Thumbprint; if (thumbprint == null) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Invalid certificate thumbprint."); } } catch (Exception e) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, e, "The sender's certificate could not be parsed."); } } else { if (securityPolicyUri != SecurityPolicies.None) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The sender's certificate was not specified."); } } // verify receiver thumbprint. if (thumbprintData != null && thumbprintData.Length > 0) { if (receiverCertificate.Thumbprint.ToUpperInvariant() != GetThumbprintString(thumbprintData)) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint is not valid."); } } else { if (securityPolicyUri != SecurityPolicies.None) { throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint was not specified."); } } } */ /// <summary> /// Checks if it is possible to revise the security mode. /// </summary> protected void ReviseSecurityMode(bool firstCall, MessageSecurityMode requestedMode) { bool supported = false; // server may support multiple security modes - check if the one the client used is supported. if (firstCall && !m_discoveryOnly) { foreach (EndpointDescription endpoint in m_endpoints) { if (endpoint.SecurityMode == requestedMode) { if (requestedMode == MessageSecurityMode.None || endpoint.SecurityPolicyUri == m_securityPolicyUri) { m_securityMode = endpoint.SecurityMode; m_selectedEndpoint = endpoint; supported = true; break; } } } } if (!supported) { throw ServiceResultException.Create(StatusCodes.BadSecurityModeRejected, "Security mode is not acceptable to the server."); } }
/// <summary> /// Attaches the object to an existing socket. /// </summary> public TcpChannel( string contextId, BufferManager bufferManager, TcpChannelQuotas quotas, X509Certificate2 serverCertificate, EndpointDescriptionCollection endpoints, MessageSecurityMode securityMode, string securityPolicyUri) { if (bufferManager == null) { throw new ArgumentNullException("bufferManager"); } if (quotas == null) { throw new ArgumentNullException("quotas"); } // create a unique contex if none provided. m_contextId = contextId; if (String.IsNullOrEmpty(m_contextId)) { m_contextId = Guid.NewGuid().ToString(); } // secuirty turned off if message security mode is set to none. if (securityMode == MessageSecurityMode.None) { securityPolicyUri = SecurityPolicies.None; } if (securityMode != MessageSecurityMode.None) { if (serverCertificate == null) { throw new ArgumentNullException("serverCertificate"); } if (serverCertificate.RawData.Length > TcpMessageLimits.MaxCertificateSize) { throw new ArgumentException( Utils.Format("The DER encoded certificate may not be more than {0} bytes.", TcpMessageLimits.MaxCertificateSize), "serverCertificate"); } } if (new UTF8Encoding().GetByteCount(securityPolicyUri) > TcpMessageLimits.MaxSecurityPolicyUriSize) { throw new ArgumentException( Utils.Format("UTF-8 form of the security policy URI may not be more than {0} bytes.", TcpMessageLimits.MaxSecurityPolicyUriSize), "securityPolicyUri"); } m_bufferManager = bufferManager; m_quotas = quotas; m_serverCertificate = serverCertificate; m_endpoints = endpoints; m_securityMode = securityMode; m_securityPolicyUri = securityPolicyUri; m_discoveryOnly = false; m_uninitialized = true; m_state = TcpChannelState.Closed; m_receiveBufferSize = quotas.MaxBufferSize; m_sendBufferSize = quotas.MaxBufferSize; if (m_receiveBufferSize < TcpMessageLimits.MinBufferSize) { m_receiveBufferSize = TcpMessageLimits.MinBufferSize; } if (m_receiveBufferSize > TcpMessageLimits.MaxBufferSize) { m_receiveBufferSize = TcpMessageLimits.MaxBufferSize; } if (m_sendBufferSize < TcpMessageLimits.MinBufferSize) { m_sendBufferSize = TcpMessageLimits.MinBufferSize; } if (m_sendBufferSize > TcpMessageLimits.MaxBufferSize) { m_sendBufferSize = TcpMessageLimits.MaxBufferSize; } m_maxRequestMessageSize = quotas.MaxMessageSize; m_maxResponseMessageSize = quotas.MaxMessageSize; CalculateSymmetricKeySizes(); }
public static StatusCode UnsecureSymmetric(MemoryBuffer recvBuf, uint tokenID, uint?prevTokenID, int messageEncodedBlockStart, SLChannel.Keyset localKeyset, SLChannel.Keyset[] remoteKeysets, SecurityPolicy policy, MessageSecurityMode securityMode, out int decrSize) { decrSize = -1; int restorePos = recvBuf.Position; byte type = 0; uint messageSize = 0; UInt32 secureChannelId, securityTokenId, securitySeqNum, securityReqId; if (!recvBuf.Decode(out type)) { return(StatusCode.BadDecodingError); } if (!recvBuf.Decode(out messageSize)) { return(StatusCode.BadDecodingError); } if (!recvBuf.Decode(out secureChannelId)) { return(StatusCode.BadDecodingError); } if (!recvBuf.Decode(out securityTokenId)) { return(StatusCode.BadDecodingError); } int keysetIdx = -1; if (tokenID == securityTokenId) { keysetIdx = 0; } else if (prevTokenID.HasValue && prevTokenID.Value == securityTokenId) { keysetIdx = 1; } else { return(StatusCode.BadSecureChannelTokenUnknown); } //UInt32 respDecodeSize = messageSize; if (securityMode == MessageSecurityMode.SignAndEncrypt) { try { decrSize = UASecurity.RijndaelDecryptInplace( new ArraySegment <byte>(recvBuf.Buffer, messageEncodedBlockStart, (int)messageSize - messageEncodedBlockStart), remoteKeysets[keysetIdx].SymEncKey, remoteKeysets[keysetIdx].SymIV) + messageEncodedBlockStart; //respDecodeSize = (UInt32)(messageEncodedBlockStart + decrSize); } catch { return(StatusCode.BadSecurityChecksFailed); } } if (securityMode >= MessageSecurityMode.Sign) { try { int sigSize = SignatureSizeForSecurityPolicy(policy); var sigData = new ArraySegment <byte>(recvBuf.Buffer, 0, (int)messageSize - sigSize); var sig = new ArraySegment <byte>(recvBuf.Buffer, (int)messageSize - sigSize, sigSize).ToArray(); var sigExpect = UASecurity.SymmetricSign(remoteKeysets[keysetIdx].SymSignKey, sigData, policy); if (sig.Length != sigExpect.Length) { return(StatusCode.BadSecurityChecksFailed); } for (int i = 0; i < sig.Length; i++) { if (sig[i] != sigExpect[i]) { return(StatusCode.BadSecurityChecksFailed); } } byte padValue = (byte)(recvBuf.Buffer[messageSize - sigSize - 1] + 1); if (decrSize > 0) { decrSize -= sigSize; decrSize -= (int)padValue; if (decrSize <= 0) { return(StatusCode.BadSecurityChecksFailed); } } } catch { return(StatusCode.BadSecurityChecksFailed); } } if (!recvBuf.Decode(out securitySeqNum)) { return(StatusCode.BadDecodingError); } if (!recvBuf.Decode(out securityReqId)) { return(StatusCode.BadDecodingError); } recvBuf.Position = restorePos; return(StatusCode.Good); }