From de7f537b899f46f64938fa0401977c51e7e1f52c Mon Sep 17 00:00:00 2001 From: Toshihisa-Fujii Date: Mon, 10 Feb 2025 15:33:29 +0900 Subject: [PATCH 1/2] Enable request to specify UTC DateTime. Unify the time zone of DateTime handled in requests and responses to UTC. --- Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs b/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs index 91e0a81f4..5de62794a 100644 --- a/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs +++ b/Stack/Opc.Ua.Core/Types/Encoders/BinaryEncoder.cs @@ -509,7 +509,8 @@ public void WriteString(string fieldName, string value) /// public void WriteDateTime(string fieldName, DateTime value) { - value = Utils.ToOpcUaUniversalTime(value); + // Azbil: Comment out the line below to unify the time zone of DateTime handled in requests and responses to UTC. + //value = Utils.ToOpcUaUniversalTime(value); long ticks = value.Ticks; From ec9687efbc1ed2cb747674daf98e4ef47deabb23 Mon Sep 17 00:00:00 2001 From: Toshihisa-Fujii Date: Mon, 10 Feb 2025 15:49:55 +0900 Subject: [PATCH 2/2] Find a certificate within the validity period. Add a new method 'Find' to find a certificate within the validity period. --- .../Certificates/CertificateIdentifier.cs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateIdentifier.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateIdentifier.cs index 539f95ae3..f219a685a 100644 --- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateIdentifier.cs +++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateIdentifier.cs @@ -256,6 +256,61 @@ public async Task Find(bool needPrivateKey, string application return certificate; } + /// + /// Azbil: Finds a certificate within the validity period in a store. + /// + /// The certificate type is used to match the signature and public key type. And check also validity period. + /// if set to true the returned certificate must contain the private key. + /// The time to check the validity period. + /// An instance of the that is embedded by this instance or find it in + /// the selected store pointed out by the using selected or if specified applicationUri. + public async Task Find(bool needPrivateKey, DateTime dateTime) + { + X509Certificate2 certificate = null; + + // check if the entire certificate has been specified. + if (m_certificate != null && (!needPrivateKey || m_certificate.HasPrivateKey)) + { + certificate = m_certificate; + } + else + { + // open store. + using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(StoreType)) + { + store.Open(StorePath); + + X509Certificate2Collection collection = await store.Enumerate().ConfigureAwait(false); + + certificate = Find(collection, m_thumbprint, m_subjectName, needPrivateKey); + + if (certificate != null) + { + if (certificate.NotBefore <= dateTime + && dateTime <= certificate.NotAfter) + { + m_certificate = certificate; + + if (needPrivateKey && this.StoreType == CertificateStoreType.Directory) + { + var message = new StringBuilder(); + message.AppendLine("Loaded a certificate with private key from the directory store."); + Utils.Trace(Utils.TraceMasks.Information, message.ToString()); + } + } + } + } + } + + // use the single instance in the certificate cache. + if (needPrivateKey) + { + certificate = m_certificate = CertificateFactory.Load(certificate, true); + } + + return certificate; + } + /// /// Returns a display name for a certificate. ///