Skip to content

Commit 0cb20d6

Browse files
authored
Respect configured RSA key size when creating app certificates (#3513)
1 parent 219f0e1 commit 0cb20d6

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

Libraries/Opc.Ua.Configuration/ApplicationInstance.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,12 +462,13 @@ await id.LoadPrivateKeyExAsync(passwordProvider, configuration.ApplicationUri, m
462462
{
463463
if (!DisableCertificateAutoCreation)
464464
{
465-
certificate = await CreateApplicationInstanceCertificateAsync(
466-
configuration,
467-
id,
468-
lifeTimeInMonths,
469-
ct)
470-
.ConfigureAwait(false);
465+
certificate = await CreateApplicationInstanceCertificateAsync(
466+
configuration,
467+
id,
468+
minimumKeySize,
469+
lifeTimeInMonths,
470+
ct)
471+
.ConfigureAwait(false);
471472
}
472473
else
473474
{
@@ -831,13 +832,15 @@ private async Task<bool> CheckDomainsInCertificateAsync(
831832
/// </summary>
832833
/// <param name="configuration">The configuration.</param>
833834
/// <param name="id">The certificate identifier.</param>
835+
/// <param name="minimumKeySize">Minimum RSA key size to use when creating the certificate.</param>
834836
/// <param name="lifeTimeInMonths">The lifetime in months.</param>
835837
/// <param name="ct">Cancellation token to cancel operation with</param>
836838
/// <returns>The new certificate</returns>
837839
/// <exception cref="ServiceResultException"></exception>
838840
private async Task<X509Certificate2> CreateApplicationInstanceCertificateAsync(
839841
ApplicationConfiguration configuration,
840842
CertificateIdentifier id,
843+
ushort minimumKeySize,
841844
ushort lifeTimeInMonths,
842845
CancellationToken ct)
843846
{
@@ -874,10 +877,16 @@ await DeleteApplicationInstanceCertificateAsync(configuration, id, ct).Configure
874877
id.CertificateType == ObjectTypeIds.RsaMinApplicationCertificateType ||
875878
id.CertificateType == ObjectTypeIds.RsaSha256ApplicationCertificateType)
876879
{
877-
id.Certificate = builder.SetRSAKeySize(CertificateFactory.DefaultKeySize)
878-
.CreateForRSA();
880+
ushort keySize = minimumKeySize == 0
881+
? CertificateFactory.DefaultKeySize
882+
: minimumKeySize;
883+
884+
id.Certificate = builder.SetRSAKeySize(keySize).CreateForRSA();
879885

880-
m_logger.LogInformation("Certificate {Certificate} created for RSA.", id.Certificate.AsLogSafeString());
886+
m_logger.LogInformation(
887+
"Certificate {Certificate} created for RSA with key size {KeySize} bits.",
888+
id.Certificate.AsLogSafeString(),
889+
keySize);
881890
}
882891
else
883892
{

Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,48 @@ public async Task TestNoFileConfigAsClientAsync()
142142
Assert.True(certOK);
143143
}
144144

145+
[Test]
146+
public async Task TestNoFileConfigRespectsMinimumKeySizeOnCreationAsync()
147+
{
148+
ITelemetryContext telemetry = NUnitTelemetryContext.Create();
149+
150+
var applicationInstance = new ApplicationInstance(telemetry) { ApplicationName = ApplicationName };
151+
Assert.NotNull(applicationInstance);
152+
153+
CertificateIdentifierCollection applicationCerts =
154+
ApplicationConfigurationBuilder.CreateDefaultApplicationCertificates(
155+
SubjectName,
156+
CertificateStoreType.Directory,
157+
m_pkiRoot);
158+
159+
const ushort minimumKeySize = 4096;
160+
161+
ApplicationConfiguration config = await applicationInstance
162+
.Build(ApplicationUri, ProductUri)
163+
.AsClient()
164+
.AddSecurityConfiguration(applicationCerts, m_pkiRoot)
165+
.SetMinimumCertificateKeySize(minimumKeySize)
166+
.CreateAsync()
167+
.ConfigureAwait(false);
168+
Assert.NotNull(config);
169+
170+
bool certOK = await applicationInstance
171+
.CheckApplicationInstanceCertificatesAsync(true)
172+
.ConfigureAwait(false);
173+
Assert.True(certOK);
174+
175+
CertificateIdentifier certId = config.SecurityConfiguration.ApplicationCertificates[0];
176+
X509Certificate2 certificate = await certId
177+
.FindAsync(
178+
true,
179+
config.ApplicationUri,
180+
telemetry)
181+
.ConfigureAwait(false);
182+
183+
Assert.NotNull(certificate);
184+
Assert.AreEqual(minimumKeySize, X509Utils.GetPublicKeySize(certificate));
185+
}
186+
145187
[Test]
146188
public async Task TestBadApplicationInstanceAsync()
147189
{

0 commit comments

Comments
 (0)