mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-28 22:55:49 +08:00
Merge pull request #135 from OPCFoundation/develop_erichb
Added X509 cert store and removed unused code from all stores (not even GDS was using it).
This commit is contained in:
@@ -720,9 +720,6 @@ namespace Opc.Ua.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
// configure access to the executable, the configuration file and the private key.
|
||||
await ConfigureFileAccess(configuration);
|
||||
|
||||
// update configuration file.
|
||||
ConfigUtils.UpdateConfigurationLocation(InstallConfig.ExecutableFile, InstallConfig.ConfigurationFile);
|
||||
|
||||
@@ -1513,124 +1510,6 @@ namespace Opc.Ua.Configuration
|
||||
Utils.Trace(e, "Could not add certificate to trusted peer store. StorePath={0}", storePath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the access rules to use for the application.
|
||||
/// </summary>
|
||||
private List<ApplicationAccessRule> GetAccessRules()
|
||||
{
|
||||
List<ApplicationAccessRule> rules = new List<ApplicationAccessRule>();
|
||||
|
||||
// check for rules specified in the installer configuration.
|
||||
bool hasAdmin = false;
|
||||
|
||||
if (InstallConfig.AccessRules != null)
|
||||
{
|
||||
for (int ii = 0; ii < InstallConfig.AccessRules.Count; ii++)
|
||||
{
|
||||
ApplicationAccessRule rule = InstallConfig.AccessRules[ii];
|
||||
|
||||
if (rule.Right == ApplicationAccessRight.Configure && rule.RuleType == AccessControlType.Allow)
|
||||
{
|
||||
hasAdmin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rules = InstallConfig.AccessRules;
|
||||
}
|
||||
|
||||
// provide some default rules.
|
||||
if (rules.Count == 0)
|
||||
{
|
||||
// give user run access.
|
||||
ApplicationAccessRule rule = new ApplicationAccessRule();
|
||||
rule.RuleType = AccessControlType.Allow;
|
||||
rule.Right = ApplicationAccessRight.Run;
|
||||
rule.IdentityName = WellKnownSids.Users;
|
||||
rules.Add(rule);
|
||||
|
||||
// ensure service can access.
|
||||
if (InstallConfig.InstallAsService)
|
||||
{
|
||||
rule = new ApplicationAccessRule();
|
||||
rule.RuleType = AccessControlType.Allow;
|
||||
rule.Right = ApplicationAccessRight.Run;
|
||||
rule.IdentityName = WellKnownSids.NetworkService;
|
||||
rules.Add(rule);
|
||||
|
||||
rule = new ApplicationAccessRule();
|
||||
rule.RuleType = AccessControlType.Allow;
|
||||
rule.Right = ApplicationAccessRight.Run;
|
||||
rule.IdentityName = WellKnownSids.LocalService;
|
||||
rules.Add(rule);
|
||||
}
|
||||
}
|
||||
|
||||
// ensure someone can change the configuration later.
|
||||
if (!hasAdmin)
|
||||
{
|
||||
ApplicationAccessRule rule = new ApplicationAccessRule();
|
||||
rule.RuleType = AccessControlType.Allow;
|
||||
rule.Right = ApplicationAccessRight.Configure;
|
||||
rule.IdentityName = WellKnownSids.Administrators;
|
||||
rules.Add(rule);
|
||||
}
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures access to the executable, the configuration file and the private key.
|
||||
/// </summary>
|
||||
private async Task ConfigureFileAccess(ApplicationConfiguration configuration)
|
||||
{
|
||||
Utils.Trace(Utils.TraceMasks.Information, "Configuring file access.");
|
||||
|
||||
List<ApplicationAccessRule> rules = GetAccessRules();
|
||||
|
||||
// apply access rules to the excutable file.
|
||||
try
|
||||
{
|
||||
if (InstallConfig.SetExecutableFilePermissions)
|
||||
{
|
||||
ApplicationAccessRule.SetAccessRules(InstallConfig.ExecutableFile, rules, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Trace(e, "Could not set executable file permissions.");
|
||||
}
|
||||
|
||||
// apply access rules to the configuration file.
|
||||
try
|
||||
{
|
||||
if (InstallConfig.SetConfigurationFilePermisions)
|
||||
{
|
||||
ApplicationAccessRule.SetAccessRules(configuration.SourceFilePath, rules, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Trace(e, "Could not set configuration file permissions.");
|
||||
}
|
||||
|
||||
// apply access rules to the private key file.
|
||||
try
|
||||
{
|
||||
X509Certificate2 certificate = await configuration.SecurityConfiguration.ApplicationCertificate.Find(true);
|
||||
|
||||
if (certificate != null)
|
||||
{
|
||||
ICertificateStore store = configuration.SecurityConfiguration.ApplicationCertificate.OpenStore();
|
||||
store.SetAccessRules(certificate.Thumbprint, rules, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Trace(e, "Could not set private key file permissions.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Fields
|
||||
|
||||
@@ -21,18 +21,9 @@
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- The location of the application instance certificate in the Windows certificate store -->
|
||||
<ApplicationCertificate>
|
||||
|
||||
<!-- The type of store. -->
|
||||
<StoreType>Directory</StoreType>
|
||||
|
||||
<!-- The location of the store.
|
||||
Windows store must start with LocalMachine, CurrentUser or CurrentService
|
||||
The name of the store is appended.
|
||||
Note that the names used in code are difference from what appears in the control panel.
|
||||
e.g. My == "Personal", Root == "Trusted Root Certification Authorities" -->
|
||||
<StorePath>%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault</StorePath>
|
||||
|
||||
<ApplicationCertificate>
|
||||
<StoreType>X509Store</StoreType>
|
||||
<StorePath>CurrentUser\UA_MachineDefault</StorePath>
|
||||
|
||||
<!-- The subject for the certificate
|
||||
Note that subject names are complex structures. The text that appears here is the CommonName component.
|
||||
|
||||
@@ -1,438 +1,429 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ApplicationConfiguration
|
||||
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
|
||||
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
|
||||
schemaLocation="./Schema/ApplicationConfiguration.xsd"
|
||||
>
|
||||
<!-- A human readable but not necessarily unique name for the application instance -->
|
||||
<ApplicationName>Opc.Ua.SampleClient</ApplicationName>
|
||||
|
||||
<!-- A globally unique identifier for the application instance.
|
||||
This is overridden with the value contained in the application certificate. -->
|
||||
<ApplicationUri>urn:localhost:OPCFoundation:SampleClient</ApplicationUri>
|
||||
|
||||
<!-- A globally unique URI for the product (usually assigned by the product vendor) -->
|
||||
<ProductUri>http://opcfoundation.org/UA/SampleClient/</ProductUri>
|
||||
|
||||
<!-- Indicates the type of application (Client, Server or ClientServer). -->
|
||||
<ApplicationType>ClientAndServer_2</ApplicationType>
|
||||
|
||||
<!-- Specifies security related configuration information -->
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- The location of the application instance certificate in the Windows certificate store -->
|
||||
<ApplicationCertificate>
|
||||
|
||||
<!-- The type of store. -->
|
||||
<StoreType>Directory</StoreType>
|
||||
|
||||
<!-- The location of the store.
|
||||
Windows store must start with LocalMachine, CurrentUser or CurrentService
|
||||
The name of the store is appended.
|
||||
Note that the names used in code are difference from what appears in the control panel.
|
||||
e.g. My == "Personal", Root == "Trusted Root Certification Authorities" -->
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\MachineDefault</StorePath>
|
||||
|
||||
|
||||
<!-- The subject for the certificate
|
||||
Note that subject names are complex structures. The text that appears here is the CommonName component.
|
||||
A complete distinguished would be something like: 'CN=UA Sample Client, DC=MACHINENAME'
|
||||
The first certificate found is used if multiple certificates with the same CommonName exist.
|
||||
The Thumbprint should be specified if the CommonName does not uniquely identify a certificate. -->
|
||||
<SubjectName>Opc.Ua.SampleClient</SubjectName>
|
||||
|
||||
<!-- The SHA1 thumbprint for the certificate.
|
||||
The thumbprint uniquely identifies a certificate.
|
||||
It should be specified in this file, however, the samples rely on quick and
|
||||
dirty scripts to create new certificate on each machine. A commerical application
|
||||
would generate the initial certificate itself and update the thumbprint accordingly -->
|
||||
<!--<Thumbprint>3a35fb798fc6dee8a7e7e4652b0e28fc14c6ee0f</Thumbprint>-->
|
||||
|
||||
</ApplicationCertificate>
|
||||
|
||||
<!-- The list of certification authorities.
|
||||
|
||||
Typical web browsing applications trust any certificate issued by a CA in the
|
||||
"Trusted Root Certification Authorities" certificate store. However, this approach is
|
||||
not appropriate for UA because Adminstrators have no control over the CAs that get
|
||||
placed in that Root store to facilitate web browsing. This means Adminstrators must
|
||||
specify a different store that is used only for UA related CAs and/or they must explicitly
|
||||
specify the certificate for each trusted certification authority. -->
|
||||
<TrustedIssuerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Certificate Authorities</StorePath>
|
||||
</TrustedIssuerCertificates>
|
||||
|
||||
<!-- The list of trusted certificates.
|
||||
|
||||
Some UA applications will use self-signed certificates (certificates without a CA)
|
||||
which means that every application which communicates with it must be configured to
|
||||
trust it.
|
||||
|
||||
Adminstrators may designate a certificate store that contains trusted UA application
|
||||
instance certificates (this store should not be the same as the store used for CAs
|
||||
certificates). Alternately, Administrators may enter the certificates explicitly in
|
||||
this list.
|
||||
|
||||
Note that entries in this list may either reference a certificate in the store or
|
||||
may contained the entire certificate encoded as base64 data.
|
||||
-->
|
||||
<TrustedPeerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Applications</StorePath>
|
||||
</TrustedPeerCertificates>
|
||||
|
||||
<!-- Applications exchange Nonces during the CreateSession. This value specifies the length. Must be >= 32 -->
|
||||
<NonceLength>32</NonceLength>
|
||||
|
||||
<!-- The directory used to store invalid certficates for later review by the administrator. -->
|
||||
<RejectedCertificateStore>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\RejectedCertificates</StorePath>
|
||||
</RejectedCertificateStore>
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
|
||||
<!-- Specifies quotas used to by the transport layer -->
|
||||
<TransportQuotas>
|
||||
|
||||
<!-- The default timeout in milliseconds for operations (used by clients) -->
|
||||
<OperationTimeout>120000</OperationTimeout>
|
||||
|
||||
<!-- The maximum length for a string value in any message -->
|
||||
<MaxStringLength>1048576</MaxStringLength>
|
||||
|
||||
<!-- The maximum length for a byte string value in any message -->
|
||||
<MaxByteStringLength>4194304</MaxByteStringLength>
|
||||
|
||||
<!-- The maximum length for any array in a message.
|
||||
Note that some protocols do not distinguish between bytes and arrays.
|
||||
In these cases the binding will choose the larger of
|
||||
MaxByteStringLength or MaxArrayLength-->
|
||||
<MaxArrayLength>65535</MaxArrayLength>
|
||||
|
||||
<!-- The maximum size of any message -->
|
||||
<MaxMessageSize>4194304</MaxMessageSize>
|
||||
|
||||
<!-- The maximum buffer size
|
||||
This value controls how big a block of memory the transport layer allocates.
|
||||
Setting this value to a large value will reduce performance and use a lot of RAM -->
|
||||
<MaxBufferSize>65535</MaxBufferSize>
|
||||
|
||||
<!-- The lifetime of a SecureChannel in milliseconds.
|
||||
This specifies how long the server will keep a broken channel around while waiting
|
||||
for a client to reconnect.
|
||||
Not used by HTTP or .NET TCP bindings -->
|
||||
<ChannelLifetime>300000</ChannelLifetime>
|
||||
|
||||
<!-- The lifetime of a SecurityToken in milliseconds.
|
||||
This specifies how long a security token can be used without renewal. -->
|
||||
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
|
||||
|
||||
</TransportQuotas>
|
||||
|
||||
<!-- This element only needs to be specified for Server or ClientServer applications -->
|
||||
<ServerConfiguration>
|
||||
|
||||
<!-- The set of addresses. One for each supported protocol.
|
||||
Note that "localhost" is replace with the hostname when the configuration is loaded.
|
||||
|
||||
Additional URLs are created by appending strings to the base address.
|
||||
For example, a URL used for an endpoint which uses the Basic256 security policy would look like this:
|
||||
http://localhost:61211/UA/SampleClient/Basic256 -->
|
||||
<BaseAddresses>
|
||||
<ua:String>opc.tcp://localhost:61210/UA/SampleClient</ua:String>
|
||||
</BaseAddresses>
|
||||
|
||||
<!--
|
||||
These list the alternate addresses (via firewalls, multiple NICs etc.) that can be
|
||||
used to communicate with the server. The URL used by the client when calling
|
||||
FindServers/GetEndpoints or CreateSession will be used to filter the list of
|
||||
endpoints returned by checking for alternate base addresses that have a domain
|
||||
that matches the domain in the url provided by the client.
|
||||
|
||||
Note that any additional domains should be listed in the server's certificate. If they
|
||||
are left out the client make refuse to connect because it has no way to know if the
|
||||
alternate domain was authorized by the server administrator.
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AlternateBaseAddresses>
|
||||
<ua:String>http://mycompany.com:40000/UA/SampleClient</ua:String>
|
||||
</AlternateBaseAddresses>
|
||||
-->
|
||||
|
||||
<!-- The security policies supported by the server.
|
||||
|
||||
The SDK combines these with the base address to create as many EndpointDescriptions as required.
|
||||
Protocols such as HTTP only allow one SecurityPolicy per endpoint to addition URLs are constructed
|
||||
using the SecurityPolicy and SecurityMode.
|
||||
|
||||
The first policy in the list is assigned to base address. -->
|
||||
<SecurityPolicies>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>4</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>2</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>None_1</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
|
||||
<SecurityLevel>0</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>1</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>5</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>3</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>6</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
</SecurityPolicies>
|
||||
|
||||
<MinRequestThreadCount>5</MinRequestThreadCount>
|
||||
<MaxRequestThreadCount>100</MaxRequestThreadCount>
|
||||
<MaxQueuedRequestCount>2000</MaxQueuedRequestCount>
|
||||
|
||||
<!-- The SDK expects the server to support the same set of user tokens for every endpoint. -->
|
||||
<UserTokenPolicies>
|
||||
<!-- Allows anonymous users -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Anonymous_0</ua:TokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows username/password -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>UserName_1</ua:TokenType>
|
||||
<!-- passwords must be encrypted - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows user certificates -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Certificate_2</ua:TokenType>
|
||||
<!-- certificate possession must be proven with a digital signature - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
<!--
|
||||
Issued tokens are any type of WS-Security compliant token
|
||||
This is a URN assigned by OASIS to SAML Security Tokens
|
||||
tokens must be encrypted - this specifies what algorithm to use
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>IssuedToken_3</ua:TokenType>
|
||||
<ua:IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</ua:IssuedTokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
-->
|
||||
</UserTokenPolicies>
|
||||
|
||||
<!-- Whether the server updates its diagnostic information -->
|
||||
<DiagnosticsEnabled>true</DiagnosticsEnabled>
|
||||
|
||||
<!-- The maximum number of simultaneous sessions -->
|
||||
<MaxSessionCount>100</MaxSessionCount>
|
||||
|
||||
<!-- The minimum session lifetime permitted by the server -->
|
||||
<MinSessionTimeout>10000</MinSessionTimeout>
|
||||
|
||||
<!-- The maximum session lifetime permitted by the server -->
|
||||
<MaxSessionTimeout>3600000</MaxSessionTimeout>
|
||||
|
||||
<!-- The maximum number of browse continuation points per session -->
|
||||
<MaxBrowseContinuationPoints>10</MaxBrowseContinuationPoints>
|
||||
|
||||
<!-- The maximum number of query continuation points per session -->
|
||||
<MaxQueryContinuationPoints>10</MaxQueryContinuationPoints>
|
||||
|
||||
<!-- The maximum number of history continuation points per session -->
|
||||
<MaxHistoryContinuationPoints>100</MaxHistoryContinuationPoints>
|
||||
|
||||
<!-- The maximum age of an incoming request -->
|
||||
<MaxRequestAge>600000</MaxRequestAge>
|
||||
|
||||
<!-- The minimum allowed publishing interval (in milliseconds) -->
|
||||
<MinPublishingInterval>100</MinPublishingInterval>
|
||||
|
||||
<!-- The maximum allowed publishing interval (in milliseconds) -->
|
||||
<MaxPublishingInterval>3600000</MaxPublishingInterval>
|
||||
|
||||
<!-- The publishing resolution. Requested publishing intervals are rounded up to the next multiple of this value.-->
|
||||
<PublishingResolution>100</PublishingResolution>
|
||||
|
||||
<!-- The maximum subscription lifetime.
|
||||
This controls the maximum keep alive count. Smaller publishing intervals will allow large keep alives
|
||||
provided the maximum subscription lifetime is not exceeded -->
|
||||
<MaxSubscriptionLifetime>3600000</MaxSubscriptionLifetime>
|
||||
|
||||
<!-- The maximum number of sent messages kept in the queue for each subscription-->
|
||||
<MaxMessageQueueSize>100</MaxMessageQueueSize>
|
||||
|
||||
<!-- The maximum number of notifications kept in the queue for each monitored item-->
|
||||
<MaxNotificationQueueSize>100</MaxNotificationQueueSize>
|
||||
|
||||
<!-- The maximum number of notifications in a single publish response -->
|
||||
<MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
|
||||
|
||||
<!-- The minimum sampling rate for rarely changing metadata information (such as the server status) -->
|
||||
<MinMetadataSamplingInterval>1000</MinMetadataSamplingInterval>
|
||||
|
||||
<!-- The set of supported sampling rates -->
|
||||
<AvailableSamplingRates />
|
||||
|
||||
<!-- Servers must create a secure channel with the DiscoveryServer
|
||||
This element specifies the connection information.
|
||||
Note that server will use the discovery endpoint to update this information -->
|
||||
|
||||
<RegistrationEndpoint>
|
||||
<ua:EndpointUrl>opc.tcp://localhost:4840</ua:EndpointUrl>
|
||||
<ua:Server>
|
||||
<ua:ApplicationUri>opc.tcp://localhost:4840</ua:ApplicationUri>
|
||||
<ua:ApplicationType>DiscoveryServer_3</ua:ApplicationType>
|
||||
<ua:DiscoveryUrls>
|
||||
<ua:String>opc.tcp://localhost:4840</ua:String>
|
||||
</ua:DiscoveryUrls>
|
||||
</ua:Server>
|
||||
<ua:SecurityMode>SignAndEncrypt_3</ua:SecurityMode>
|
||||
<ua:SecurityPolicyUri />
|
||||
<ua:UserIdentityTokens />
|
||||
<ua:SecurityLevel>1</ua:SecurityLevel>
|
||||
</RegistrationEndpoint>
|
||||
|
||||
<!-- The maximum interval between registration. 0 disables periodic registration -->
|
||||
<MaxRegistrationInterval>0</MaxRegistrationInterval>
|
||||
|
||||
<!-- The file used to save nodes added to the CoreNodeManager. If missing the CoreNodeManger will discard nodes when it stops. -->
|
||||
<NodeManagerSaveFile>Opc.Ua.Server.nodes.xml</NodeManagerSaveFile>
|
||||
|
||||
<!-- The minimum subscription lifetime.
|
||||
This ensures subscriptions are not set to expire too quickly. The revised lifetime count
|
||||
and keep alive count are calculated with this value. -->
|
||||
<MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
|
||||
|
||||
</ServerConfiguration>
|
||||
|
||||
<!-- This element is only required for Client and ClientServer applications -->
|
||||
<ClientConfiguration>
|
||||
<!-- The default timeout for new sessions -->
|
||||
<DefaultSessionTimeout>600000</DefaultSessionTimeout>
|
||||
|
||||
<!-- The well-known URLs for the local discovery servers
|
||||
URLs are tested in the order they appear in this list. -->
|
||||
<WellKnownDiscoveryUrls>
|
||||
<ua:String>opc.tcp://{0}:4840/UADiscovery</ua:String>
|
||||
<ua:String>http://{0}:52601/UADiscovery</ua:String>
|
||||
<ua:String>http://{0}/UADiscovery/Default.svc</ua:String>
|
||||
</WellKnownDiscoveryUrls>
|
||||
|
||||
<!-- EndpointDescriptions for system wide discovery servers -->
|
||||
<DiscoveryServers></DiscoveryServers>
|
||||
|
||||
<!-- The file used to save the EndpointDescriptions for servers known to the Client -->
|
||||
<EndpointCacheFilePath>Opc.Ua.SampleClient.Endpoints.xml</EndpointCacheFilePath>
|
||||
|
||||
<!-- The minimum subscription lifetime.
|
||||
This ensures subscriptions are not set to expire too quickly. The requesed lifetime count
|
||||
and keep alive count are calculated using this value and the request publishing interval -->
|
||||
<MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
|
||||
|
||||
</ClientConfiguration>
|
||||
|
||||
<Extensions>
|
||||
<ua:XmlElement>
|
||||
<MemoryBufferConfiguration xmlns="http://samples.org/UA/memorybuffer">
|
||||
<Buffers>
|
||||
<MemoryBufferInstance>
|
||||
<Name>UInt32</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>UInt32</DataType>
|
||||
</MemoryBufferInstance>
|
||||
<MemoryBufferInstance>
|
||||
<Name>Double</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>Double</DataType>
|
||||
</MemoryBufferInstance>
|
||||
</Buffers>
|
||||
</MemoryBufferConfiguration>
|
||||
</ua:XmlElement>
|
||||
</Extensions>
|
||||
|
||||
<!--
|
||||
Masks supported by the trace feature.
|
||||
Servers will detect changes within 5 seconds.
|
||||
|
||||
Do not output any messages.
|
||||
None = 0x0;
|
||||
|
||||
Output error messages.
|
||||
Error = 0x1;
|
||||
|
||||
Output informational messages.
|
||||
Information = 0x2;
|
||||
|
||||
Output stack traces.
|
||||
StackTrace = 0x4;
|
||||
|
||||
Output basic messages for service calls.
|
||||
Service = 0x8;
|
||||
|
||||
Output detailed messages for service calls.
|
||||
ServiceDetail = 0x10;
|
||||
|
||||
Output basic messages for each operation.
|
||||
Operation = 0x20;
|
||||
|
||||
Output detailed messages for each operation.
|
||||
OperationDetail = 0x40;
|
||||
|
||||
Output messages related to application initialization or shutdown
|
||||
StartStop = 0x80;
|
||||
|
||||
Output messages related to a call to an external system.
|
||||
ExternalSystem = 0x100;
|
||||
|
||||
Output messages related to security
|
||||
Security = 0x200;
|
||||
-->
|
||||
|
||||
<TraceConfiguration>
|
||||
<OutputFilePath>%LocalFolder%\Logs\Opc.Ua.SampleClient.log.txt</OutputFilePath>
|
||||
<DeleteOnLoad>true</DeleteOnLoad>
|
||||
<!-- Show Only Errors -->
|
||||
<!-- <TraceMasks>1</TraceMasks> -->
|
||||
<!-- Show Only Security and Errors -->
|
||||
<TraceMasks>513</TraceMasks>
|
||||
<!-- Show Only Security, Errors and Trace -->
|
||||
<!-- <TraceMasks>515</TraceMasks> -->
|
||||
<!-- Show Only Security, COM Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>771</TraceMasks> -->
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
</TraceConfiguration>
|
||||
|
||||
<!-- Enables the hi-res clock for the process to allows for shorter (<100ms) publishing and sampling intervals. -->
|
||||
<!-- QueryPerformanceCounter does not work on all multi-core machines so enabling the hi-res clock by default is not recommended. -->
|
||||
<DisableHiResClock>true</DisableHiResClock>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ApplicationConfiguration
|
||||
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
|
||||
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
|
||||
schemaLocation="./Schema/ApplicationConfiguration.xsd"
|
||||
>
|
||||
<!-- A human readable but not necessarily unique name for the application instance -->
|
||||
<ApplicationName>Opc.Ua.SampleClient</ApplicationName>
|
||||
|
||||
<!-- A globally unique identifier for the application instance.
|
||||
This is overridden with the value contained in the application certificate. -->
|
||||
<ApplicationUri>urn:localhost:OPCFoundation:SampleClient</ApplicationUri>
|
||||
|
||||
<!-- A globally unique URI for the product (usually assigned by the product vendor) -->
|
||||
<ProductUri>http://opcfoundation.org/UA/SampleClient/</ProductUri>
|
||||
|
||||
<!-- Indicates the type of application (Client, Server or ClientServer). -->
|
||||
<ApplicationType>ClientAndServer_2</ApplicationType>
|
||||
|
||||
<!-- Specifies security related configuration information -->
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- The location of the application instance certificate in the Windows certificate store -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>X509Store</StoreType>
|
||||
<StorePath>CurrentUser\UA_MachineDefault</StorePath>
|
||||
|
||||
<!-- The subject for the certificate
|
||||
Note that subject names are complex structures. The text that appears here is the CommonName component.
|
||||
A complete distinguished would be something like: 'CN=UA Sample Client, DC=MACHINENAME'
|
||||
The first certificate found is used if multiple certificates with the same CommonName exist.
|
||||
The Thumbprint should be specified if the CommonName does not uniquely identify a certificate. -->
|
||||
<SubjectName>Opc.Ua.SampleClient</SubjectName>
|
||||
|
||||
<!-- The SHA1 thumbprint for the certificate.
|
||||
The thumbprint uniquely identifies a certificate.
|
||||
It should be specified in this file, however, the samples rely on quick and
|
||||
dirty scripts to create new certificate on each machine. A commerical application
|
||||
would generate the initial certificate itself and update the thumbprint accordingly -->
|
||||
<!--<Thumbprint>3a35fb798fc6dee8a7e7e4652b0e28fc14c6ee0f</Thumbprint>-->
|
||||
|
||||
</ApplicationCertificate>
|
||||
|
||||
<!-- The list of certification authorities.
|
||||
|
||||
Typical web browsing applications trust any certificate issued by a CA in the
|
||||
"Trusted Root Certification Authorities" certificate store. However, this approach is
|
||||
not appropriate for UA because Adminstrators have no control over the CAs that get
|
||||
placed in that Root store to facilitate web browsing. This means Adminstrators must
|
||||
specify a different store that is used only for UA related CAs and/or they must explicitly
|
||||
specify the certificate for each trusted certification authority. -->
|
||||
<TrustedIssuerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Certificate Authorities</StorePath>
|
||||
</TrustedIssuerCertificates>
|
||||
|
||||
<!-- The list of trusted certificates.
|
||||
|
||||
Some UA applications will use self-signed certificates (certificates without a CA)
|
||||
which means that every application which communicates with it must be configured to
|
||||
trust it.
|
||||
|
||||
Adminstrators may designate a certificate store that contains trusted UA application
|
||||
instance certificates (this store should not be the same as the store used for CAs
|
||||
certificates). Alternately, Administrators may enter the certificates explicitly in
|
||||
this list.
|
||||
|
||||
Note that entries in this list may either reference a certificate in the store or
|
||||
may contained the entire certificate encoded as base64 data.
|
||||
-->
|
||||
<TrustedPeerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Applications</StorePath>
|
||||
</TrustedPeerCertificates>
|
||||
|
||||
<!-- Applications exchange Nonces during the CreateSession. This value specifies the length. Must be >= 32 -->
|
||||
<NonceLength>32</NonceLength>
|
||||
|
||||
<!-- The directory used to store invalid certficates for later review by the administrator. -->
|
||||
<RejectedCertificateStore>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\RejectedCertificates</StorePath>
|
||||
</RejectedCertificateStore>
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
|
||||
<!-- Specifies quotas used to by the transport layer -->
|
||||
<TransportQuotas>
|
||||
|
||||
<!-- The default timeout in milliseconds for operations (used by clients) -->
|
||||
<OperationTimeout>120000</OperationTimeout>
|
||||
|
||||
<!-- The maximum length for a string value in any message -->
|
||||
<MaxStringLength>1048576</MaxStringLength>
|
||||
|
||||
<!-- The maximum length for a byte string value in any message -->
|
||||
<MaxByteStringLength>4194304</MaxByteStringLength>
|
||||
|
||||
<!-- The maximum length for any array in a message.
|
||||
Note that some protocols do not distinguish between bytes and arrays.
|
||||
In these cases the binding will choose the larger of
|
||||
MaxByteStringLength or MaxArrayLength-->
|
||||
<MaxArrayLength>65535</MaxArrayLength>
|
||||
|
||||
<!-- The maximum size of any message -->
|
||||
<MaxMessageSize>4194304</MaxMessageSize>
|
||||
|
||||
<!-- The maximum buffer size
|
||||
This value controls how big a block of memory the transport layer allocates.
|
||||
Setting this value to a large value will reduce performance and use a lot of RAM -->
|
||||
<MaxBufferSize>65535</MaxBufferSize>
|
||||
|
||||
<!-- The lifetime of a SecureChannel in milliseconds.
|
||||
This specifies how long the server will keep a broken channel around while waiting
|
||||
for a client to reconnect.
|
||||
Not used by HTTP or .NET TCP bindings -->
|
||||
<ChannelLifetime>300000</ChannelLifetime>
|
||||
|
||||
<!-- The lifetime of a SecurityToken in milliseconds.
|
||||
This specifies how long a security token can be used without renewal. -->
|
||||
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
|
||||
|
||||
</TransportQuotas>
|
||||
|
||||
<!-- This element only needs to be specified for Server or ClientServer applications -->
|
||||
<ServerConfiguration>
|
||||
|
||||
<!-- The set of addresses. One for each supported protocol.
|
||||
Note that "localhost" is replace with the hostname when the configuration is loaded.
|
||||
|
||||
Additional URLs are created by appending strings to the base address.
|
||||
For example, a URL used for an endpoint which uses the Basic256 security policy would look like this:
|
||||
http://localhost:61211/UA/SampleClient/Basic256 -->
|
||||
<BaseAddresses>
|
||||
<ua:String>opc.tcp://localhost:61210/UA/SampleClient</ua:String>
|
||||
</BaseAddresses>
|
||||
|
||||
<!--
|
||||
These list the alternate addresses (via firewalls, multiple NICs etc.) that can be
|
||||
used to communicate with the server. The URL used by the client when calling
|
||||
FindServers/GetEndpoints or CreateSession will be used to filter the list of
|
||||
endpoints returned by checking for alternate base addresses that have a domain
|
||||
that matches the domain in the url provided by the client.
|
||||
|
||||
Note that any additional domains should be listed in the server's certificate. If they
|
||||
are left out the client make refuse to connect because it has no way to know if the
|
||||
alternate domain was authorized by the server administrator.
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AlternateBaseAddresses>
|
||||
<ua:String>http://mycompany.com:40000/UA/SampleClient</ua:String>
|
||||
</AlternateBaseAddresses>
|
||||
-->
|
||||
|
||||
<!-- The security policies supported by the server.
|
||||
|
||||
The SDK combines these with the base address to create as many EndpointDescriptions as required.
|
||||
Protocols such as HTTP only allow one SecurityPolicy per endpoint to addition URLs are constructed
|
||||
using the SecurityPolicy and SecurityMode.
|
||||
|
||||
The first policy in the list is assigned to base address. -->
|
||||
<SecurityPolicies>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>4</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>2</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>None_1</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
|
||||
<SecurityLevel>0</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>1</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>5</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>3</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>6</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
</SecurityPolicies>
|
||||
|
||||
<MinRequestThreadCount>5</MinRequestThreadCount>
|
||||
<MaxRequestThreadCount>100</MaxRequestThreadCount>
|
||||
<MaxQueuedRequestCount>2000</MaxQueuedRequestCount>
|
||||
|
||||
<!-- The SDK expects the server to support the same set of user tokens for every endpoint. -->
|
||||
<UserTokenPolicies>
|
||||
<!-- Allows anonymous users -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Anonymous_0</ua:TokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows username/password -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>UserName_1</ua:TokenType>
|
||||
<!-- passwords must be encrypted - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows user certificates -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Certificate_2</ua:TokenType>
|
||||
<!-- certificate possession must be proven with a digital signature - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
<!--
|
||||
Issued tokens are any type of WS-Security compliant token
|
||||
This is a URN assigned by OASIS to SAML Security Tokens
|
||||
tokens must be encrypted - this specifies what algorithm to use
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>IssuedToken_3</ua:TokenType>
|
||||
<ua:IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</ua:IssuedTokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
-->
|
||||
</UserTokenPolicies>
|
||||
|
||||
<!-- Whether the server updates its diagnostic information -->
|
||||
<DiagnosticsEnabled>true</DiagnosticsEnabled>
|
||||
|
||||
<!-- The maximum number of simultaneous sessions -->
|
||||
<MaxSessionCount>100</MaxSessionCount>
|
||||
|
||||
<!-- The minimum session lifetime permitted by the server -->
|
||||
<MinSessionTimeout>10000</MinSessionTimeout>
|
||||
|
||||
<!-- The maximum session lifetime permitted by the server -->
|
||||
<MaxSessionTimeout>3600000</MaxSessionTimeout>
|
||||
|
||||
<!-- The maximum number of browse continuation points per session -->
|
||||
<MaxBrowseContinuationPoints>10</MaxBrowseContinuationPoints>
|
||||
|
||||
<!-- The maximum number of query continuation points per session -->
|
||||
<MaxQueryContinuationPoints>10</MaxQueryContinuationPoints>
|
||||
|
||||
<!-- The maximum number of history continuation points per session -->
|
||||
<MaxHistoryContinuationPoints>100</MaxHistoryContinuationPoints>
|
||||
|
||||
<!-- The maximum age of an incoming request -->
|
||||
<MaxRequestAge>600000</MaxRequestAge>
|
||||
|
||||
<!-- The minimum allowed publishing interval (in milliseconds) -->
|
||||
<MinPublishingInterval>100</MinPublishingInterval>
|
||||
|
||||
<!-- The maximum allowed publishing interval (in milliseconds) -->
|
||||
<MaxPublishingInterval>3600000</MaxPublishingInterval>
|
||||
|
||||
<!-- The publishing resolution. Requested publishing intervals are rounded up to the next multiple of this value.-->
|
||||
<PublishingResolution>100</PublishingResolution>
|
||||
|
||||
<!-- The maximum subscription lifetime.
|
||||
This controls the maximum keep alive count. Smaller publishing intervals will allow large keep alives
|
||||
provided the maximum subscription lifetime is not exceeded -->
|
||||
<MaxSubscriptionLifetime>3600000</MaxSubscriptionLifetime>
|
||||
|
||||
<!-- The maximum number of sent messages kept in the queue for each subscription-->
|
||||
<MaxMessageQueueSize>100</MaxMessageQueueSize>
|
||||
|
||||
<!-- The maximum number of notifications kept in the queue for each monitored item-->
|
||||
<MaxNotificationQueueSize>100</MaxNotificationQueueSize>
|
||||
|
||||
<!-- The maximum number of notifications in a single publish response -->
|
||||
<MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
|
||||
|
||||
<!-- The minimum sampling rate for rarely changing metadata information (such as the server status) -->
|
||||
<MinMetadataSamplingInterval>1000</MinMetadataSamplingInterval>
|
||||
|
||||
<!-- The set of supported sampling rates -->
|
||||
<AvailableSamplingRates />
|
||||
|
||||
<!-- Servers must create a secure channel with the DiscoveryServer
|
||||
This element specifies the connection information.
|
||||
Note that server will use the discovery endpoint to update this information -->
|
||||
|
||||
<RegistrationEndpoint>
|
||||
<ua:EndpointUrl>opc.tcp://localhost:4840</ua:EndpointUrl>
|
||||
<ua:Server>
|
||||
<ua:ApplicationUri>opc.tcp://localhost:4840</ua:ApplicationUri>
|
||||
<ua:ApplicationType>DiscoveryServer_3</ua:ApplicationType>
|
||||
<ua:DiscoveryUrls>
|
||||
<ua:String>opc.tcp://localhost:4840</ua:String>
|
||||
</ua:DiscoveryUrls>
|
||||
</ua:Server>
|
||||
<ua:SecurityMode>SignAndEncrypt_3</ua:SecurityMode>
|
||||
<ua:SecurityPolicyUri />
|
||||
<ua:UserIdentityTokens />
|
||||
<ua:SecurityLevel>1</ua:SecurityLevel>
|
||||
</RegistrationEndpoint>
|
||||
|
||||
<!-- The maximum interval between registration. 0 disables periodic registration -->
|
||||
<MaxRegistrationInterval>0</MaxRegistrationInterval>
|
||||
|
||||
<!-- The file used to save nodes added to the CoreNodeManager. If missing the CoreNodeManger will discard nodes when it stops. -->
|
||||
<NodeManagerSaveFile>Opc.Ua.Server.nodes.xml</NodeManagerSaveFile>
|
||||
|
||||
<!-- The minimum subscription lifetime.
|
||||
This ensures subscriptions are not set to expire too quickly. The revised lifetime count
|
||||
and keep alive count are calculated with this value. -->
|
||||
<MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
|
||||
|
||||
</ServerConfiguration>
|
||||
|
||||
<!-- This element is only required for Client and ClientServer applications -->
|
||||
<ClientConfiguration>
|
||||
<!-- The default timeout for new sessions -->
|
||||
<DefaultSessionTimeout>600000</DefaultSessionTimeout>
|
||||
|
||||
<!-- The well-known URLs for the local discovery servers
|
||||
URLs are tested in the order they appear in this list. -->
|
||||
<WellKnownDiscoveryUrls>
|
||||
<ua:String>opc.tcp://{0}:4840/UADiscovery</ua:String>
|
||||
<ua:String>http://{0}:52601/UADiscovery</ua:String>
|
||||
<ua:String>http://{0}/UADiscovery/Default.svc</ua:String>
|
||||
</WellKnownDiscoveryUrls>
|
||||
|
||||
<!-- EndpointDescriptions for system wide discovery servers -->
|
||||
<DiscoveryServers></DiscoveryServers>
|
||||
|
||||
<!-- The file used to save the EndpointDescriptions for servers known to the Client -->
|
||||
<EndpointCacheFilePath>Opc.Ua.SampleClient.Endpoints.xml</EndpointCacheFilePath>
|
||||
|
||||
<!-- The minimum subscription lifetime.
|
||||
This ensures subscriptions are not set to expire too quickly. The requesed lifetime count
|
||||
and keep alive count are calculated using this value and the request publishing interval -->
|
||||
<MinSubscriptionLifetime>10000</MinSubscriptionLifetime>
|
||||
|
||||
</ClientConfiguration>
|
||||
|
||||
<Extensions>
|
||||
<ua:XmlElement>
|
||||
<MemoryBufferConfiguration xmlns="http://samples.org/UA/memorybuffer">
|
||||
<Buffers>
|
||||
<MemoryBufferInstance>
|
||||
<Name>UInt32</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>UInt32</DataType>
|
||||
</MemoryBufferInstance>
|
||||
<MemoryBufferInstance>
|
||||
<Name>Double</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>Double</DataType>
|
||||
</MemoryBufferInstance>
|
||||
</Buffers>
|
||||
</MemoryBufferConfiguration>
|
||||
</ua:XmlElement>
|
||||
</Extensions>
|
||||
|
||||
<!--
|
||||
Masks supported by the trace feature.
|
||||
Servers will detect changes within 5 seconds.
|
||||
|
||||
Do not output any messages.
|
||||
None = 0x0;
|
||||
|
||||
Output error messages.
|
||||
Error = 0x1;
|
||||
|
||||
Output informational messages.
|
||||
Information = 0x2;
|
||||
|
||||
Output stack traces.
|
||||
StackTrace = 0x4;
|
||||
|
||||
Output basic messages for service calls.
|
||||
Service = 0x8;
|
||||
|
||||
Output detailed messages for service calls.
|
||||
ServiceDetail = 0x10;
|
||||
|
||||
Output basic messages for each operation.
|
||||
Operation = 0x20;
|
||||
|
||||
Output detailed messages for each operation.
|
||||
OperationDetail = 0x40;
|
||||
|
||||
Output messages related to application initialization or shutdown
|
||||
StartStop = 0x80;
|
||||
|
||||
Output messages related to a call to an external system.
|
||||
ExternalSystem = 0x100;
|
||||
|
||||
Output messages related to security
|
||||
Security = 0x200;
|
||||
-->
|
||||
|
||||
<TraceConfiguration>
|
||||
<OutputFilePath>%LocalFolder%\Logs\Opc.Ua.SampleClient.log.txt</OutputFilePath>
|
||||
<DeleteOnLoad>true</DeleteOnLoad>
|
||||
<!-- Show Only Errors -->
|
||||
<!-- <TraceMasks>1</TraceMasks> -->
|
||||
<!-- Show Only Security and Errors -->
|
||||
<TraceMasks>513</TraceMasks>
|
||||
<!-- Show Only Security, Errors and Trace -->
|
||||
<!-- <TraceMasks>515</TraceMasks> -->
|
||||
<!-- Show Only Security, COM Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>771</TraceMasks> -->
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
</TraceConfiguration>
|
||||
|
||||
<!-- Enables the hi-res clock for the process to allows for shorter (<100ms) publishing and sampling intervals. -->
|
||||
<!-- QueryPerformanceCounter does not work on all multi-core machines so enabling the hi-res clock by default is not recommended. -->
|
||||
<DisableHiResClock>true</DisableHiResClock>
|
||||
|
||||
</ApplicationConfiguration>
|
||||
@@ -350,27 +350,6 @@ namespace Opc.Ua.Client.Controls
|
||||
else
|
||||
{
|
||||
listItem.SubItems[2].Text = "No";
|
||||
|
||||
if (m_storeId != null)
|
||||
{
|
||||
ICertificateStore store = m_storeId.OpenStore();
|
||||
|
||||
try
|
||||
{
|
||||
if (store.GetPrivateKeyFilePath(certificate.Thumbprint) != null)
|
||||
{
|
||||
listItem.SubItems[2].Text = "Yes (No Access)";
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
listItem.SubItems[2].Text = e.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
store.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// look up domains.
|
||||
|
||||
+3
-3
@@ -56,7 +56,7 @@ namespace Opc.Ua.Client.Controls
|
||||
InitializeComponent();
|
||||
|
||||
StoreTypeCB.Items.Add(CertificateStoreType.Directory);
|
||||
StoreTypeCB.Items.Add(CertificateStoreType.Windows);
|
||||
StoreTypeCB.Items.Add(CertificateStoreType.X509Store);
|
||||
StoreTypeCB.SelectedIndex = 0;
|
||||
}
|
||||
#endregion
|
||||
@@ -170,7 +170,7 @@ namespace Opc.Ua.Client.Controls
|
||||
stores.Add(Path.DirectorySeparatorChar + "OPC Foundation" + Path.DirectorySeparatorChar + "CertificateStores" + Path.DirectorySeparatorChar + "RejectedCertificates");
|
||||
}
|
||||
|
||||
if (CertificateStoreType.Windows == storeType)
|
||||
if (CertificateStoreType.X509Store == storeType)
|
||||
{
|
||||
stores.Add("LocalMachine\\My");
|
||||
stores.Add("LocalMachine\\UA Applications");
|
||||
@@ -244,7 +244,7 @@ namespace Opc.Ua.Client.Controls
|
||||
storePath = dialog.SelectedPath;
|
||||
}
|
||||
|
||||
if (storeType == CertificateStoreType.Windows)
|
||||
if (storeType == CertificateStoreType.X509Store)
|
||||
{
|
||||
CertificateStoreIdentifier store = new CertificateStoreTreeDlg().ShowDialog(null);
|
||||
|
||||
|
||||
-8
@@ -28,8 +28,6 @@
|
||||
* ======================================================================*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
@@ -38,12 +36,6 @@ using System.Xml;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.ServiceProcess;
|
||||
using System.Management;
|
||||
using System.Management.Instrumentation;
|
||||
using System.Runtime.InteropServices;
|
||||
using Opc.Ua.Configuration;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Opc.Ua.Client.Controls
|
||||
{
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace NetCoreConsoleClient
|
||||
{
|
||||
ApplicationCertificate = new CertificateIdentifier
|
||||
{
|
||||
StoreType = "Directory",
|
||||
StorePath = "OPC Foundation/CertificateStores/MachineDefault",
|
||||
StoreType = "X509Store",
|
||||
StorePath = "CurrentUser\\UA_MachineDefault",
|
||||
SubjectName = "UA Core Sample Client"
|
||||
},
|
||||
TrustedPeerCertificates = new CertificateTrustList
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
<!-- Where the application instance certificate is stored (MachineDefault) -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>OPC Foundation/CertificateStores/MachineDefault</StorePath>
|
||||
<StoreType>X509Store</StoreType>
|
||||
<StorePath>CurrentUser\UA_MachineDefault</StorePath>
|
||||
<SubjectName>UA Core Sample Server</SubjectName>
|
||||
</ApplicationCertificate>
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
<TransportConfigurations/>
|
||||
|
||||
<TransportQuotas>
|
||||
<OperationTimeout>600000</OperationTimeout>
|
||||
@@ -193,7 +192,7 @@
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
<TraceMasks>519</TraceMasks>
|
||||
</TraceConfiguration>
|
||||
|
||||
<!-- Disables the hi-res clock if the QueryPerformanceCounter does work on a particular machine. -->
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
<!-- Where the application instance certificate is stored (MachineDefault) -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%CommonApplicationData%\OPC Foundation\CertificateStores\MachineDefault</StorePath>
|
||||
<StoreType>X509Store</StoreType>
|
||||
<StorePath>CurrentUser\UA_MachineDefault</StorePath>
|
||||
<SubjectName>UA Sample Server</SubjectName>
|
||||
</ApplicationCertificate>
|
||||
|
||||
|
||||
@@ -1,208 +1,208 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ApplicationConfiguration
|
||||
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
|
||||
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
|
||||
schemaLocation="./Schema/ApplicationConfiguration.xsd"
|
||||
>
|
||||
<ApplicationName>Opc.Ua.SampleServer</ApplicationName>
|
||||
<ApplicationUri>urn:localhost:OPCFoundation:SampleServer</ApplicationUri>
|
||||
<ProductUri>http://opcfoundation.org/UA/SampleServer</ProductUri>
|
||||
<ApplicationType>Server_0</ApplicationType>
|
||||
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- Where the application instance certificate is stored (MachineDefault) -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\MachineDefault</StorePath>
|
||||
<SubjectName>Opc.Ua.SampleServer</SubjectName>
|
||||
</ApplicationCertificate>
|
||||
|
||||
<!-- Where the issuer certificate are stored (certificate authorities) -->
|
||||
<TrustedIssuerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Certificate Authorities</StorePath>
|
||||
</TrustedIssuerCertificates>
|
||||
|
||||
<!-- Where the trust list is stored (UA Applications) -->
|
||||
<TrustedPeerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Applications</StorePath>
|
||||
</TrustedPeerCertificates>
|
||||
|
||||
<!-- The directory used to store invalid certficates for later review by the administrator. -->
|
||||
<RejectedCertificateStore>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\RejectedCertificates</StorePath>
|
||||
</RejectedCertificateStore>
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
|
||||
<TransportQuotas>
|
||||
<OperationTimeout>600000</OperationTimeout>
|
||||
<MaxStringLength>1048576</MaxStringLength>
|
||||
<MaxByteStringLength>4194304</MaxByteStringLength>
|
||||
<MaxArrayLength>65535</MaxArrayLength>
|
||||
<MaxMessageSize>4194304</MaxMessageSize>
|
||||
<MaxBufferSize>65535</MaxBufferSize>
|
||||
<ChannelLifetime>300000</ChannelLifetime>
|
||||
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
|
||||
</TransportQuotas>
|
||||
|
||||
<ServerConfiguration>
|
||||
<BaseAddresses>
|
||||
<ua:String>opc.tcp://localhost:51210/UA/SampleServer</ua:String>
|
||||
</BaseAddresses>
|
||||
|
||||
<!--
|
||||
These list the alternate addresses (via firewalls, multiple NICs etc.) that can be
|
||||
used to communicate with the server. The URL used by the client when calling
|
||||
FindServers/GetEndpoints or CreateSession will be used to filter the list of
|
||||
endpoints returned by checking for alternate base addresses that have a domain
|
||||
that matches the domain in the url provided by the client.
|
||||
|
||||
Note that any additional domains should be listed in the server's certificate. If they
|
||||
are left out the client make refuse to connect because it has no way to know if the
|
||||
alternate domain was authorized by the server administrator.
|
||||
-->
|
||||
<!--
|
||||
<AlternateBaseAddresses>
|
||||
<ua:String>http://mycompany.com:40000/UA/SampleServer</ua:String>
|
||||
</AlternateBaseAddresses>
|
||||
-->
|
||||
|
||||
<SecurityPolicies>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>4</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>2</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>None_1</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
|
||||
<SecurityLevel>0</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>1</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>5</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>3</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>6</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
</SecurityPolicies>
|
||||
|
||||
<MinRequestThreadCount>5</MinRequestThreadCount>
|
||||
<MaxRequestThreadCount>100</MaxRequestThreadCount>
|
||||
<MaxQueuedRequestCount>2000</MaxQueuedRequestCount>
|
||||
|
||||
<!-- The SDK expects the server to support the same set of user tokens for every endpoint. -->
|
||||
<UserTokenPolicies>
|
||||
<!-- Allows anonymous users -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Anonymous_0</ua:TokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows username/password -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>UserName_1</ua:TokenType>
|
||||
<!-- passwords must be encrypted - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows user certificates -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Certificate_2</ua:TokenType>
|
||||
<!-- certificate possession must be proven with a digital signature - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
<!--
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>IssuedToken_3</ua:TokenType>
|
||||
<ua:IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</ua:IssuedTokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
-->
|
||||
</UserTokenPolicies>
|
||||
<DiagnosticsEnabled>true</DiagnosticsEnabled>
|
||||
<MaxSessionCount>100</MaxSessionCount>
|
||||
<MinSessionTimeout>10000</MinSessionTimeout>
|
||||
<MaxSessionTimeout>3600000</MaxSessionTimeout>
|
||||
<MaxBrowseContinuationPoints>10</MaxBrowseContinuationPoints>
|
||||
<MaxQueryContinuationPoints>10</MaxQueryContinuationPoints>
|
||||
<MaxHistoryContinuationPoints>100</MaxHistoryContinuationPoints>
|
||||
<MaxRequestAge>600000</MaxRequestAge>
|
||||
<MinPublishingInterval>100</MinPublishingInterval>
|
||||
<MaxPublishingInterval>3600000</MaxPublishingInterval>
|
||||
<PublishingResolution>50</PublishingResolution>
|
||||
<MaxSubscriptionLifetime>3600000</MaxSubscriptionLifetime>
|
||||
<MaxMessageQueueSize>100</MaxMessageQueueSize>
|
||||
<MaxNotificationQueueSize>100</MaxNotificationQueueSize>
|
||||
<MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
|
||||
<MinMetadataSamplingInterval>1000</MinMetadataSamplingInterval>
|
||||
<AvailableSamplingRates />
|
||||
<MaxRegistrationInterval>0</MaxRegistrationInterval>
|
||||
<NodeManagerSaveFile>Opc.Ua.Server.nodes.xml</NodeManagerSaveFile>
|
||||
</ServerConfiguration>
|
||||
|
||||
<Extensions>
|
||||
<ua:XmlElement>
|
||||
<MemoryBufferConfiguration xmlns="http://samples.org/UA/memorybuffer">
|
||||
<Buffers>
|
||||
<MemoryBufferInstance>
|
||||
<Name>UInt32</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>UInt32</DataType>
|
||||
</MemoryBufferInstance>
|
||||
<MemoryBufferInstance>
|
||||
<Name>Double</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>Double</DataType>
|
||||
</MemoryBufferInstance>
|
||||
</Buffers>
|
||||
</MemoryBufferConfiguration>
|
||||
</ua:XmlElement>
|
||||
</Extensions>
|
||||
|
||||
<TraceConfiguration>
|
||||
<OutputFilePath>%LocalFolder%\Logs\Opc.Ua.SampleServer.log.txt</OutputFilePath>
|
||||
<DeleteOnLoad>true</DeleteOnLoad>
|
||||
<!-- Show Only Errors -->
|
||||
<!-- <TraceMasks>1</TraceMasks> -->
|
||||
<!-- Show Only Security and Errors -->
|
||||
<TraceMasks>513</TraceMasks>
|
||||
<!-- Show Only Security, Errors and Trace -->
|
||||
<!-- <TraceMasks>515</TraceMasks> -->
|
||||
<!-- Show Only Security, COM Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>771</TraceMasks> -->
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
</TraceConfiguration>
|
||||
|
||||
<!-- Disables the hi-res clock if the QueryPerformanceCounter does work on a particular machine. -->
|
||||
<DisableHiResClock>true</DisableHiResClock>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ApplicationConfiguration
|
||||
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
|
||||
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
|
||||
schemaLocation="./Schema/ApplicationConfiguration.xsd"
|
||||
>
|
||||
<ApplicationName>Opc.Ua.SampleServer</ApplicationName>
|
||||
<ApplicationUri>urn:localhost:OPCFoundation:SampleServer</ApplicationUri>
|
||||
<ProductUri>http://opcfoundation.org/UA/SampleServer</ProductUri>
|
||||
<ApplicationType>Server_0</ApplicationType>
|
||||
|
||||
<SecurityConfiguration>
|
||||
|
||||
<!-- Where the application instance certificate is stored (MachineDefault) -->
|
||||
<ApplicationCertificate>
|
||||
<StoreType>X509Store</StoreType>
|
||||
<StorePath>CurrentUser\UA_MachineDefault</StorePath>
|
||||
<SubjectName>Opc.Ua.SampleServer</SubjectName>
|
||||
</ApplicationCertificate>
|
||||
|
||||
<!-- Where the issuer certificate are stored (certificate authorities) -->
|
||||
<TrustedIssuerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Certificate Authorities</StorePath>
|
||||
</TrustedIssuerCertificates>
|
||||
|
||||
<!-- Where the trust list is stored (UA Applications) -->
|
||||
<TrustedPeerCertificates>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\UA Applications</StorePath>
|
||||
</TrustedPeerCertificates>
|
||||
|
||||
<!-- The directory used to store invalid certficates for later review by the administrator. -->
|
||||
<RejectedCertificateStore>
|
||||
<StoreType>Directory</StoreType>
|
||||
<StorePath>%LocalFolder%\OPC Foundation\CertificateStores\RejectedCertificates</StorePath>
|
||||
</RejectedCertificateStore>
|
||||
|
||||
</SecurityConfiguration>
|
||||
|
||||
|
||||
<TransportConfigurations></TransportConfigurations>
|
||||
|
||||
<TransportQuotas>
|
||||
<OperationTimeout>600000</OperationTimeout>
|
||||
<MaxStringLength>1048576</MaxStringLength>
|
||||
<MaxByteStringLength>4194304</MaxByteStringLength>
|
||||
<MaxArrayLength>65535</MaxArrayLength>
|
||||
<MaxMessageSize>4194304</MaxMessageSize>
|
||||
<MaxBufferSize>65535</MaxBufferSize>
|
||||
<ChannelLifetime>300000</ChannelLifetime>
|
||||
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
|
||||
</TransportQuotas>
|
||||
|
||||
<ServerConfiguration>
|
||||
<BaseAddresses>
|
||||
<ua:String>opc.tcp://localhost:51210/UA/SampleServer</ua:String>
|
||||
</BaseAddresses>
|
||||
|
||||
<!--
|
||||
These list the alternate addresses (via firewalls, multiple NICs etc.) that can be
|
||||
used to communicate with the server. The URL used by the client when calling
|
||||
FindServers/GetEndpoints or CreateSession will be used to filter the list of
|
||||
endpoints returned by checking for alternate base addresses that have a domain
|
||||
that matches the domain in the url provided by the client.
|
||||
|
||||
Note that any additional domains should be listed in the server's certificate. If they
|
||||
are left out the client make refuse to connect because it has no way to know if the
|
||||
alternate domain was authorized by the server administrator.
|
||||
-->
|
||||
<!--
|
||||
<AlternateBaseAddresses>
|
||||
<ua:String>http://mycompany.com:40000/UA/SampleServer</ua:String>
|
||||
</AlternateBaseAddresses>
|
||||
-->
|
||||
|
||||
<SecurityPolicies>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>4</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>2</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>None_1</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
|
||||
<SecurityLevel>0</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
|
||||
<SecurityLevel>1</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
|
||||
<SecurityLevel>5</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>Sign_2</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>3</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
<ServerSecurityPolicy>
|
||||
<SecurityMode>SignAndEncrypt_3</SecurityMode>
|
||||
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
|
||||
<SecurityLevel>6</SecurityLevel>
|
||||
</ServerSecurityPolicy>
|
||||
</SecurityPolicies>
|
||||
|
||||
<MinRequestThreadCount>5</MinRequestThreadCount>
|
||||
<MaxRequestThreadCount>100</MaxRequestThreadCount>
|
||||
<MaxQueuedRequestCount>2000</MaxQueuedRequestCount>
|
||||
|
||||
<!-- The SDK expects the server to support the same set of user tokens for every endpoint. -->
|
||||
<UserTokenPolicies>
|
||||
<!-- Allows anonymous users -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Anonymous_0</ua:TokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows username/password -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>UserName_1</ua:TokenType>
|
||||
<!-- passwords must be encrypted - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
|
||||
<!-- Allows user certificates -->
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>Certificate_2</ua:TokenType>
|
||||
<!-- certificate possession must be proven with a digital signature - this specifies what algorithm to use -->
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
<!--
|
||||
<ua:UserTokenPolicy>
|
||||
<ua:TokenType>IssuedToken_3</ua:TokenType>
|
||||
<ua:IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</ua:IssuedTokenType>
|
||||
<ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</ua:SecurityPolicyUri>
|
||||
</ua:UserTokenPolicy>
|
||||
-->
|
||||
</UserTokenPolicies>
|
||||
<DiagnosticsEnabled>true</DiagnosticsEnabled>
|
||||
<MaxSessionCount>100</MaxSessionCount>
|
||||
<MinSessionTimeout>10000</MinSessionTimeout>
|
||||
<MaxSessionTimeout>3600000</MaxSessionTimeout>
|
||||
<MaxBrowseContinuationPoints>10</MaxBrowseContinuationPoints>
|
||||
<MaxQueryContinuationPoints>10</MaxQueryContinuationPoints>
|
||||
<MaxHistoryContinuationPoints>100</MaxHistoryContinuationPoints>
|
||||
<MaxRequestAge>600000</MaxRequestAge>
|
||||
<MinPublishingInterval>100</MinPublishingInterval>
|
||||
<MaxPublishingInterval>3600000</MaxPublishingInterval>
|
||||
<PublishingResolution>50</PublishingResolution>
|
||||
<MaxSubscriptionLifetime>3600000</MaxSubscriptionLifetime>
|
||||
<MaxMessageQueueSize>100</MaxMessageQueueSize>
|
||||
<MaxNotificationQueueSize>100</MaxNotificationQueueSize>
|
||||
<MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
|
||||
<MinMetadataSamplingInterval>1000</MinMetadataSamplingInterval>
|
||||
<AvailableSamplingRates />
|
||||
<MaxRegistrationInterval>0</MaxRegistrationInterval>
|
||||
<NodeManagerSaveFile>Opc.Ua.Server.nodes.xml</NodeManagerSaveFile>
|
||||
</ServerConfiguration>
|
||||
|
||||
<Extensions>
|
||||
<ua:XmlElement>
|
||||
<MemoryBufferConfiguration xmlns="http://samples.org/UA/memorybuffer">
|
||||
<Buffers>
|
||||
<MemoryBufferInstance>
|
||||
<Name>UInt32</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>UInt32</DataType>
|
||||
</MemoryBufferInstance>
|
||||
<MemoryBufferInstance>
|
||||
<Name>Double</Name>
|
||||
<TagCount>100</TagCount>
|
||||
<DataType>Double</DataType>
|
||||
</MemoryBufferInstance>
|
||||
</Buffers>
|
||||
</MemoryBufferConfiguration>
|
||||
</ua:XmlElement>
|
||||
</Extensions>
|
||||
|
||||
<TraceConfiguration>
|
||||
<OutputFilePath>%LocalFolder%\Logs\Opc.Ua.SampleServer.log.txt</OutputFilePath>
|
||||
<DeleteOnLoad>true</DeleteOnLoad>
|
||||
<!-- Show Only Errors -->
|
||||
<!-- <TraceMasks>1</TraceMasks> -->
|
||||
<!-- Show Only Security and Errors -->
|
||||
<TraceMasks>513</TraceMasks>
|
||||
<!-- Show Only Security, Errors and Trace -->
|
||||
<!-- <TraceMasks>515</TraceMasks> -->
|
||||
<!-- Show Only Security, COM Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>771</TraceMasks> -->
|
||||
<!-- Show Only Security, Service Calls, Errors and Trace -->
|
||||
<!-- <TraceMasks>523</TraceMasks> -->
|
||||
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
|
||||
<!-- <TraceMasks>519</TraceMasks> -->
|
||||
</TraceConfiguration>
|
||||
|
||||
<!-- Disables the hi-res clock if the QueryPerformanceCounter does work on a particular machine. -->
|
||||
<DisableHiResClock>true</DisableHiResClock>
|
||||
|
||||
</ApplicationConfiguration>
|
||||
@@ -1921,7 +1921,7 @@ namespace Opc.Ua
|
||||
/// The type of certificate store.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// If the StoreName is not empty, the CertificateStoreType.Windows is returned, otherwise the StoreType is returned.
|
||||
/// If the StoreName is not empty, the CertificateStoreType.X509Store is returned, otherwise the StoreType is returned.
|
||||
/// </value>
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Order = 0)]
|
||||
public string StoreType
|
||||
@@ -1930,7 +1930,7 @@ namespace Opc.Ua
|
||||
{
|
||||
if (!String.IsNullOrEmpty(m_storeName))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
return m_storeType;
|
||||
@@ -1978,7 +1978,7 @@ namespace Opc.Ua
|
||||
{
|
||||
if (m_storePath.StartsWith("LocalMachine", StringComparison.CurrentCultureIgnoreCase) || m_storePath.StartsWith("CurrentUser", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
m_storeType = CertificateStoreType.Windows;
|
||||
m_storeType = CertificateStoreType.X509Store;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2190,7 +2190,7 @@ namespace Opc.Ua
|
||||
{
|
||||
if (!String.IsNullOrEmpty(m_storeName))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
return m_storeType;
|
||||
@@ -2234,7 +2234,7 @@ namespace Opc.Ua
|
||||
{
|
||||
if (m_storePath.StartsWith("LocalMachine", StringComparison.CurrentCultureIgnoreCase) || m_storePath.StartsWith("CurrentUser", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
m_storeType = CertificateStoreType.Windows;
|
||||
m_storeType = CertificateStoreType.X509Store;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -461,18 +461,8 @@ namespace Opc.Ua.Security
|
||||
Opc.Ua.CertificateIdentifier output = SecuredApplication.FromCertificateIdentifier(this);
|
||||
return output.OpenStore();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the private key file path.
|
||||
/// </summary>
|
||||
public async Task<string> GetPrivateKeyFilePath()
|
||||
{
|
||||
Opc.Ua.CertificateIdentifier output = SecuredApplication.FromCertificateIdentifier(this);
|
||||
return await output.GetPrivateKeyFilePath();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An identifier for a certificate store.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/* Copyright (c) 1996-2016, OPC Foundation. All rights reserved.
|
||||
The source code in this file is covered under a dual-license scenario:
|
||||
- RCL: for OPC Foundation members in good-standing
|
||||
- GPL V2: everybody else
|
||||
RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/
|
||||
GNU General Public License as published by the Free Software Foundation;
|
||||
version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2
|
||||
This source code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Opc.Ua
|
||||
{
|
||||
/// <summary>
|
||||
/// An access rule for an application.
|
||||
/// </summary>
|
||||
public partial class ApplicationAccessRule
|
||||
{
|
||||
/// Gets the application access rules implied by the access rights to the file.
|
||||
/// </summary>
|
||||
public static IList<ApplicationAccessRule> GetAccessRules(String filePath)
|
||||
{
|
||||
// combine the access rules into a set of abstract application rules.
|
||||
List<ApplicationAccessRule> accessRules = new List<ApplicationAccessRule>();
|
||||
|
||||
return accessRules;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the application access rules implied by the access rights to the file.
|
||||
/// </summary>
|
||||
public static void SetAccessRules(String filePath, IList<ApplicationAccessRule> accessRules, bool replaceExisting)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/* Copyright (c) 1996-2016, OPC Foundation. All rights reserved.
|
||||
The source code in this file is covered under a dual-license scenario:
|
||||
- RCL: for OPC Foundation members in good-standing
|
||||
- GPL V2: everybody else
|
||||
RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/
|
||||
GNU General Public License as published by the Free Software Foundation;
|
||||
version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2
|
||||
This source code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Opc.Ua.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// An access rule for an HTTP URL used by a WCF service.
|
||||
/// </summary>
|
||||
[DataContract(Namespace=Namespaces.OpcUaConfig)]
|
||||
public class HttpAccessRule
|
||||
{
|
||||
const Int16 AF_INET = 2;
|
||||
const Int16 AF_INET6 = 23;
|
||||
}
|
||||
|
||||
#region AccessControlEntity Class
|
||||
/// <summary>
|
||||
/// A class that stores the components of ACE within a DACL.
|
||||
/// </summary>
|
||||
public class AccessControlEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// The access type granted by the ACE.
|
||||
/// </summary>
|
||||
public string AccessType
|
||||
{
|
||||
get { return m_accessType; }
|
||||
set { m_accessType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Any flags associated with the ACE.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")]
|
||||
public string Flags
|
||||
{
|
||||
get { return m_flags; }
|
||||
set { m_flags = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The rights allowed/restricted by the ACE.
|
||||
/// </summary>
|
||||
public string Rights
|
||||
{
|
||||
get { return m_rights; }
|
||||
set { m_rights = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object associated with the ACE.
|
||||
/// </summary>
|
||||
public string ObjectGuid
|
||||
{
|
||||
get { return m_objectGuid; }
|
||||
set { m_objectGuid = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The inherited object associated with the ACE.
|
||||
/// </summary>
|
||||
public string InheritObjectGuid
|
||||
{
|
||||
get { return m_inheritObjectGuid; }
|
||||
set { m_inheritObjectGuid = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The SID for the account which is affected by the ACE.
|
||||
/// </summary>
|
||||
public string AccountSid
|
||||
{
|
||||
get { return m_accountSid; }
|
||||
set { m_accountSid = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts a list of ACEs from a SDDL string.
|
||||
/// </summary>
|
||||
public static IList<AccessControlEntity> Parse(string sddl)
|
||||
{
|
||||
List<AccessControlEntity> entities = new List<AccessControlEntity>();
|
||||
|
||||
if (!sddl.StartsWith("D:", StringComparison.Ordinal))
|
||||
{
|
||||
throw new ArgumentException(Utils.Format("Could not parse SDDL string: {0}", sddl));
|
||||
}
|
||||
|
||||
sddl = sddl.Substring(2, sddl.Length-2);
|
||||
|
||||
string[] aces = sddl.Split('(', ')');
|
||||
|
||||
for (int ii = 0; ii < aces.Length; ii++)
|
||||
{
|
||||
if (String.IsNullOrEmpty(aces[ii]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AccessControlEntity entity = new AccessControlEntity();
|
||||
entity.Initialize(aces[ii]);
|
||||
entities.Add(entity);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts a single ACE from a SDDL string fragment.
|
||||
/// </summary>
|
||||
public void Initialize(string sddl)
|
||||
{
|
||||
string[] fields = sddl.Split(';');
|
||||
|
||||
if (fields.Length != 6)
|
||||
{
|
||||
throw new ArgumentException(Utils.Format("Could not parse SDDL ACE string: {0}", sddl));
|
||||
}
|
||||
|
||||
m_accessType = fields[0];
|
||||
m_flags = fields[1];
|
||||
m_rights = fields[2];
|
||||
m_objectGuid = fields[3];
|
||||
m_inheritObjectGuid = fields[4];
|
||||
m_accountSid = fields[5];
|
||||
}
|
||||
|
||||
private string m_accessType;
|
||||
private string m_flags;
|
||||
private string m_rights;
|
||||
private string m_objectGuid;
|
||||
private string m_inheritObjectGuid;
|
||||
private string m_accountSid;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SslCertificateBinding Class
|
||||
/// <summary>
|
||||
/// Stores the details of an SSL certification configuration binding.
|
||||
/// </summary>
|
||||
public class SslCertificateBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// The IP Address.
|
||||
/// </summary>
|
||||
public IPAddress IPAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The port number.
|
||||
/// </summary>
|
||||
public ushort Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The certificate thumbprint.
|
||||
/// </summary>
|
||||
public string Thumbprint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The application id.
|
||||
/// </summary>
|
||||
public Guid ApplicationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The names of the store to use.
|
||||
/// </summary>
|
||||
public string StoreName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default revocation check mode.
|
||||
/// </summary>
|
||||
public uint DefaultCertCheckMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default revocation freshness time.
|
||||
/// </summary>
|
||||
public int DefaultRevocationFreshnessTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default revocation URL timeout.
|
||||
/// </summary>
|
||||
public int DefaultRevocationUrlRetrievalTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default certificate trust list identifier.
|
||||
/// </summary>
|
||||
public string DefaultSslCtlIdentifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default certificate trust list store.
|
||||
/// </summary>
|
||||
public string DefaultSslCtlStoreName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default flags.
|
||||
/// </summary>
|
||||
public uint DefaultFlags { get; set; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -183,12 +183,6 @@ namespace Opc.Ua
|
||||
bool isCA,
|
||||
X509Certificate2 issuerCAKeyCert)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(storeType) &&
|
||||
storeType != CertificateStoreType.Directory)
|
||||
{
|
||||
throw new NotSupportedException("Cannot create a certificate for a non directory store.");
|
||||
}
|
||||
|
||||
if (issuerCAKeyCert != null)
|
||||
{
|
||||
if (!issuerCAKeyCert.HasPrivateKey)
|
||||
@@ -312,15 +306,23 @@ namespace Opc.Ua
|
||||
if (!String.IsNullOrEmpty(storePath))
|
||||
{
|
||||
ICertificateStore store = null;
|
||||
if (storeType == CertificateStoreType.Directory)
|
||||
if (storeType == CertificateStoreType.X509Store)
|
||||
{
|
||||
using (store = new DirectoryCertificateStore())
|
||||
{
|
||||
store.Open(storePath);
|
||||
store.Add(certificate);
|
||||
store.Close();
|
||||
}
|
||||
store = new X509CertificateStore();
|
||||
}
|
||||
else if (storeType == CertificateStoreType.Directory)
|
||||
{
|
||||
store = new DirectoryCertificateStore();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid store type");
|
||||
}
|
||||
|
||||
store.Open(storePath);
|
||||
store.Add(certificate);
|
||||
store.Close();
|
||||
store.Dispose();
|
||||
}
|
||||
|
||||
// note: this cert has a private key!
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
@@ -471,31 +470,6 @@ namespace Opc.Ua
|
||||
store.Open(this.StorePath);
|
||||
return store;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the private key file path.
|
||||
/// </summary>
|
||||
public async Task<string> GetPrivateKeyFilePath()
|
||||
{
|
||||
X509Certificate2 certificate = await Find(false);
|
||||
|
||||
if (certificate == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ICertificateStore store = CertificateStoreIdentifier.CreateStore(this.StoreType);
|
||||
|
||||
try
|
||||
{
|
||||
store.Open(this.StorePath);
|
||||
return store.GetPrivateKeyFilePath(certificate.Thumbprint);
|
||||
}
|
||||
finally
|
||||
{
|
||||
store.Close();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
@@ -737,83 +711,6 @@ namespace Opc.Ua
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store supports access control.
|
||||
/// </summary>
|
||||
public bool SupportsAccessControl
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the access rules that are currently applied to the store.
|
||||
/// </summary>
|
||||
/// <returns>The list of access rules.</returns>
|
||||
public IList<ApplicationAccessRule> GetAccessRules()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the access rules that are currently applied to the store.
|
||||
/// </summary>
|
||||
/// <param name="rules">The rules.</param>
|
||||
/// <param name="replaceExisting">if set to <c>true</c> the existing access rules are replaced.</param>
|
||||
public void SetAccessRules(IList<ApplicationAccessRule> rules, bool replaceExisting)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store supports access control on certificates.
|
||||
/// </summary>
|
||||
public bool SupportsCertificateAccessControl
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether the store supports private keys.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public bool SupportsPrivateKeys
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file containing the private key for the specified certificate.
|
||||
/// </summary>
|
||||
public string GetPrivateKeyFilePath(string thumbprint)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the access rules that are currently applied to the certficate's private key.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The thumbprint.</param>
|
||||
/// <returns>The access rules.</returns>
|
||||
public IList<ApplicationAccessRule> GetAccessRules(string thumbprint)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the access rules that are currently applied to the certficate's private key.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The thumbprint.</param>
|
||||
/// <param name="rules">The rules.</param>
|
||||
/// <param name="replaceExisting">if set to <c>true</c> the existing access rules are replaced.</param>
|
||||
public void SetAccessRules(string thumbprint, IList<ApplicationAccessRule> rules, bool replaceExisting)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store support CRLs.
|
||||
/// </summary>
|
||||
public bool SupportsCRLs { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if issuer has revoked the certificate.
|
||||
/// </summary>
|
||||
@@ -821,13 +718,13 @@ namespace Opc.Ua
|
||||
{
|
||||
return StatusCodes.BadNotSupported;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the CRLs in the store.
|
||||
/// </summary>
|
||||
public List<X509CRL> EnumerateCRLs()
|
||||
{
|
||||
return new List<X509CRL>();
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -835,9 +732,9 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public List<X509CRL> EnumerateCRLs(X509Certificate2 issuer)
|
||||
{
|
||||
return new List<X509CRL>();
|
||||
}
|
||||
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a CRL to the store.
|
||||
/// </summary>
|
||||
|
||||
@@ -98,22 +98,22 @@ namespace Opc.Ua
|
||||
|
||||
if (storePath.StartsWith("LocalMachine\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
if (storePath.StartsWith("CurrentUser\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
if (storePath.StartsWith("User\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
if (storePath.StartsWith("Service\\", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CertificateStoreType.Windows;
|
||||
return CertificateStoreType.X509Store;
|
||||
}
|
||||
|
||||
return CertificateStoreType.Directory;
|
||||
@@ -133,6 +133,11 @@ namespace Opc.Ua
|
||||
|
||||
switch (storeType)
|
||||
{
|
||||
case CertificateStoreType.X509Store:
|
||||
{
|
||||
store = new X509CertificateStore();
|
||||
break;
|
||||
}
|
||||
case CertificateStoreType.Directory:
|
||||
{
|
||||
store = new DirectoryCertificateStore();
|
||||
@@ -175,7 +180,7 @@ namespace Opc.Ua
|
||||
/// <summary>
|
||||
/// A windows certificate store.
|
||||
/// </summary>
|
||||
public const string Windows = "Windows";
|
||||
public const string X509Store = "X509Store";
|
||||
|
||||
/// <summary>
|
||||
/// A directory certificate store.
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Opc.Ua
|
||||
/// <value>
|
||||
/// <c>true</c> if [no private keys]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool NoPrivateKeys { get; set; }
|
||||
private bool NoPrivateKeys { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICertificateStore Members
|
||||
@@ -164,6 +164,7 @@ namespace Opc.Ua
|
||||
|
||||
m_lastDirectoryCheck = DateTime.MinValue;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -224,167 +225,6 @@ namespace Opc.Ua
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.SupportsAccessControl" />
|
||||
public bool SupportsAccessControl
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.GetAccessRules()" />
|
||||
public IList<ApplicationAccessRule> GetAccessRules()
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
return ApplicationAccessRule.GetAccessRules(m_certificateSubdir.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.SetAccessRules(IList{ApplicationAccessRule},bool)" />
|
||||
public void SetAccessRules(IList<ApplicationAccessRule> rules, bool replaceExisting)
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
ApplicationAccessRule.SetAccessRules(m_certificateSubdir.FullName, rules, replaceExisting);
|
||||
|
||||
if (String.Compare(m_certificateSubdir.FullName, m_privateKeySubdir.FullName, StringComparison.OrdinalIgnoreCase) != 0)
|
||||
{
|
||||
ApplicationAccessRule.SetAccessRules(m_privateKeySubdir.FullName, rules, replaceExisting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.SupportsCertificateAccessControl" />
|
||||
public bool SupportsCertificateAccessControl
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.SupportsPrivateKeys" />
|
||||
public bool SupportsPrivateKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.GetPrivateKeyFilePath" />
|
||||
public string GetPublicKeyFilePath(string thumbprint)
|
||||
{
|
||||
Entry entry = Find(thumbprint);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (entry.CertificateFile == null || !entry.CertificateFile.Exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return entry.CertificateFile.FullName;
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.GetPrivateKeyFilePath" />
|
||||
public string GetPrivateKeyFilePath(string thumbprint)
|
||||
{
|
||||
Entry entry = Find(thumbprint);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (entry.PrivateKeyFile == null || !entry.PrivateKeyFile.Exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return entry.PrivateKeyFile.FullName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CRL file paths.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The certificate thumbprint.</param>
|
||||
/// <returns></returns>
|
||||
public string[] GetCrlFilePaths(string thumbprint)
|
||||
{
|
||||
List<string> filePaths = new List<string>();
|
||||
|
||||
Entry entry = Find(thumbprint);
|
||||
|
||||
DirectoryInfo info = new DirectoryInfo(this.Directory.FullName + Path.DirectorySeparatorChar + "crl");
|
||||
|
||||
foreach (FileInfo file in info.GetFiles("*.crl"))
|
||||
{
|
||||
X509CRL crl = null;
|
||||
|
||||
try
|
||||
{
|
||||
crl = new X509CRL(file.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Trace(e, "Could not parse CRL file.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Utils.CompareDistinguishedName(crl.Issuer, entry.Certificate.Subject))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
filePaths.Add(file.FullName);
|
||||
}
|
||||
|
||||
return filePaths.ToArray();
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.GetAccessRules(string)" />
|
||||
public IList<ApplicationAccessRule> GetAccessRules(string thumbprint)
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
Entry entry = Find(thumbprint);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
throw new ArgumentException("Certificate does not exist in store.");
|
||||
}
|
||||
|
||||
if (entry.PrivateKeyFile == null || !entry.PrivateKeyFile.Exists)
|
||||
{
|
||||
throw new ArgumentException("Certificate does not have a private key in the store.");
|
||||
}
|
||||
|
||||
return ApplicationAccessRule.GetAccessRules(entry.PrivateKeyFile.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.SetAccessRules(string, IList{ApplicationAccessRule},bool)" />
|
||||
public void SetAccessRules(string thumbprint, IList<ApplicationAccessRule> rules, bool replaceExisting)
|
||||
{
|
||||
lock (m_lock)
|
||||
{
|
||||
Entry entry = Find(thumbprint);
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
throw new ArgumentException("Certificate does not exist in store.");
|
||||
}
|
||||
|
||||
if (entry.PrivateKeyFile != null && entry.PrivateKeyFile.Exists)
|
||||
{
|
||||
ApplicationAccessRule.SetAccessRules(entry.PrivateKeyFile.FullName, rules, replaceExisting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the private key from a PFX file in the certificate store.
|
||||
/// </summary>
|
||||
@@ -472,11 +312,6 @@ namespace Opc.Ua
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store support CRLs.
|
||||
/// </summary>
|
||||
public bool SupportsCRLs { get { return true; } }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if issuer has revoked the certificate.
|
||||
/// </summary>
|
||||
@@ -640,7 +475,7 @@ namespace Opc.Ua
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.Append(m_directory.FullName);
|
||||
|
||||
|
||||
builder.Append(Path.DirectorySeparatorChar + "crl" + Path.DirectorySeparatorChar);
|
||||
builder.Append(GetFileName(issuer));
|
||||
builder.Append(".crl");
|
||||
@@ -689,9 +524,9 @@ namespace Opc.Ua
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
#region Private Methods
|
||||
/// <summary>
|
||||
/// Reads the current contents of the directory from disk.
|
||||
/// </summary>
|
||||
|
||||
@@ -17,10 +17,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Opc.Ua
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// An abstract interface to certficate stores.
|
||||
/// </summary>
|
||||
public interface ICertificateStore : IDisposable
|
||||
public interface ICertificateStore : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens the store at the specified location.
|
||||
@@ -61,64 +61,11 @@ namespace Opc.Ua
|
||||
/// <returns>The matching certificate</returns>
|
||||
Task<X509Certificate2Collection> FindByThumbprint(string thumbprint);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store supports access control.
|
||||
/// </summary>
|
||||
bool SupportsAccessControl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the access rules that are currently applied to the store.
|
||||
/// </summary>
|
||||
/// <returns>The list of access rules.</returns>
|
||||
IList<ApplicationAccessRule> GetAccessRules();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the access rules that are currently applied to the store.
|
||||
/// </summary>
|
||||
/// <param name="rules">The rules.</param>
|
||||
/// <param name="replaceExisting">if set to <c>true</c> the existing access rules are replaced.</param>
|
||||
void SetAccessRules(IList<ApplicationAccessRule> rules, bool replaceExisting);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store supports access control on certificates.
|
||||
/// </summary>
|
||||
bool SupportsCertificateAccessControl { get; }
|
||||
/// Whether the store supports private keys.
|
||||
/// </summary>
|
||||
bool SupportsPrivateKeys { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file containing the private key for the specified certificate.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The thumbprint.</param>
|
||||
/// <returns>The full file path. Null if the certificate does not exist or the private key does not exist.</returns>
|
||||
string GetPrivateKeyFilePath(string thumbprint);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the access rules that are currently applied to the certficate's private key.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The thumbprint.</param>
|
||||
/// <returns>The access rules.</returns>
|
||||
IList<ApplicationAccessRule> GetAccessRules(string thumbprint);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the access rules that are currently applied to the certficate's private key.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">The thumbprint.</param>
|
||||
/// <param name="rules">The rules.</param>
|
||||
/// <param name="replaceExisting">if set to <c>true</c> the existing access rules are replaced.</param>
|
||||
void SetAccessRules(string thumbprint, IList<ApplicationAccessRule> rules, bool replaceExisting);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the store supports CRLs.
|
||||
/// </summary>
|
||||
bool SupportsCRLs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if issuer has revoked the certificate.
|
||||
/// </summary>
|
||||
StatusCode IsRevoked(X509Certificate2 issuer, X509Certificate2 certificate);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the CRLs in the store.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/* Copyright (c) 1996-2016, OPC Foundation. All rights reserved.
|
||||
|
||||
The source code in this file is covered under a dual-license scenario:
|
||||
- RCL: for OPC Foundation members in good-standing
|
||||
- GPL V2: everybody else
|
||||
|
||||
RCL license terms accompanied with this source code. See http://opcfoundation.org/License/RCL/1.00/
|
||||
|
||||
GNU General Public License as published by the Free Software Foundation;
|
||||
version 2 of the License are accompanied with this source code. See http://opcfoundation.org/License/GPLv2
|
||||
|
||||
This source code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Opc.Ua
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to a simple file based certificate store.
|
||||
/// </summary>
|
||||
public class X509CertificateStore : ICertificateStore
|
||||
{
|
||||
public X509CertificateStore()
|
||||
{
|
||||
m_store = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.Open(string)" />
|
||||
/// <remarks>
|
||||
/// Syntax: StoreLocation\StoreName
|
||||
/// Examples:
|
||||
/// LocalMachine\My
|
||||
/// CurrentUser\Trust
|
||||
/// </remarks>
|
||||
public void Open(string path)
|
||||
{
|
||||
if (path == null) throw new ArgumentNullException("path");
|
||||
|
||||
path = path.Trim();
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadUnexpectedError,
|
||||
"Store Location cannot be empty.");
|
||||
}
|
||||
|
||||
// extract store name.
|
||||
int index = path.IndexOf('\\');
|
||||
if (index == -1)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadUnexpectedError,
|
||||
"Path does not specify a store name. Path={0}",
|
||||
path);
|
||||
}
|
||||
|
||||
// extract store location.
|
||||
string storeLocation = path.Substring(0, index);
|
||||
StoreLocation selectedLocation = StoreLocation.CurrentUser;
|
||||
bool found = false;
|
||||
foreach (StoreLocation availableLocation in (StoreLocation[])Enum.GetValues(typeof(StoreLocation)))
|
||||
{
|
||||
if (availableLocation.ToString() == storeLocation)
|
||||
{
|
||||
selectedLocation = availableLocation;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadUnexpectedError,
|
||||
"Store location specified not available.\r\nStore location={0}",
|
||||
storeLocation);
|
||||
}
|
||||
|
||||
string storeName = path.Substring(index + 1);
|
||||
m_store = new X509Store(storeName, selectedLocation);
|
||||
m_store.Open(OpenFlags.ReadWrite);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (m_store != null)
|
||||
{
|
||||
m_store.Dispose();
|
||||
m_store = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Task<X509Certificate2Collection> Enumerate()
|
||||
{
|
||||
if (m_store == null)
|
||||
{
|
||||
throw new NullReferenceException("Store null. Call Open() on the store first!");
|
||||
}
|
||||
|
||||
X509Certificate2Collection certificates = new X509Certificate2Collection();
|
||||
|
||||
certificates.AddRange(m_store.Certificates);
|
||||
|
||||
return Task.FromResult(certificates);
|
||||
}
|
||||
|
||||
/// <summary cref="ICertificateStore.Add(X509Certificate2)" />
|
||||
public Task Add(X509Certificate2 certificate)
|
||||
{
|
||||
if (m_store == null)
|
||||
{
|
||||
throw new NullReferenceException("Store null. Call Open() on the store first!");
|
||||
}
|
||||
|
||||
if (certificate == null) throw new ArgumentNullException("certificate");
|
||||
|
||||
if (!m_store.Certificates.Contains(certificate))
|
||||
{
|
||||
m_store.Add(certificate);
|
||||
Utils.Trace(Utils.TraceMasks.Information, "Added cert {0} to X509Store {1}.", certificate.ToString(), m_store.Name);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<bool> Delete(string thumbprint)
|
||||
{
|
||||
if (m_store == null)
|
||||
{
|
||||
throw new NullReferenceException("Store null. Call Open() on the store first!");
|
||||
}
|
||||
|
||||
foreach (X509Certificate2 certificate in m_store.Certificates)
|
||||
{
|
||||
if (certificate.Thumbprint == thumbprint)
|
||||
{
|
||||
m_store.Certificates.Remove(certificate);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<X509Certificate2Collection> FindByThumbprint(string thumbprint)
|
||||
{
|
||||
if (m_store == null)
|
||||
{
|
||||
throw new NullReferenceException("Store null. Call Open() on the store first!");
|
||||
}
|
||||
|
||||
X509Certificate2Collection collection = new X509Certificate2Collection();
|
||||
|
||||
foreach (X509Certificate2 certificate in m_store.Certificates)
|
||||
{
|
||||
if (certificate.Thumbprint == thumbprint)
|
||||
{
|
||||
collection.Add(certificate);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(collection);
|
||||
}
|
||||
|
||||
public StatusCode IsRevoked(X509Certificate2 issuer, X509Certificate2 certificate)
|
||||
{
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
public List<X509CRL> EnumerateCRLs()
|
||||
{
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
public List<X509CRL> EnumerateCRLs(X509Certificate2 issuer)
|
||||
{
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
public void AddCRL(X509CRL crl)
|
||||
{
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
public bool DeleteCRL(X509CRL crl)
|
||||
{
|
||||
throw new ServiceResultException(StatusCodes.BadNotSupported);
|
||||
}
|
||||
|
||||
private X509Store m_store;
|
||||
}
|
||||
}
|
||||
@@ -12,48 +12,6 @@
|
||||
|
||||
namespace Opc.Ua
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants that identify certificate store locations.
|
||||
/// </summary>
|
||||
public static class StoreLocations
|
||||
{
|
||||
/// <summary>
|
||||
/// The store assigned to the current user.
|
||||
/// </summary>
|
||||
public const string CurrentUser = "CurrentUser";
|
||||
|
||||
/// <summary>
|
||||
/// The store assigned to the local machine.
|
||||
/// </summary>
|
||||
public const string LocalMachine = "LocalMachine";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants that identify certificate store names.
|
||||
/// </summary>
|
||||
public static class StoreNames
|
||||
{
|
||||
/// <summary>
|
||||
/// The store used for personal certificates.
|
||||
/// </summary>
|
||||
public const string Personal = "My";
|
||||
|
||||
/// <summary>
|
||||
/// The store used for UA application certificates.
|
||||
/// </summary>
|
||||
public const string Applications = "UA Applications";
|
||||
|
||||
/// <summary>
|
||||
/// The store used for UA certificate authorities certificates.
|
||||
/// </summary>
|
||||
public const string CertificateAuthorities = "UA Certificate Authorities";
|
||||
|
||||
/// <summary>
|
||||
/// The store used for trusted root certificate authorities.
|
||||
/// </summary>
|
||||
public const string Root = "Root";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines constants for key security policies.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user