Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ECC profiles #2398

Open
wants to merge 99 commits into
base: master
Choose a base branch
from

Conversation

mrsuciu
Copy link
Contributor

@mrsuciu mrsuciu commented Nov 27, 2023

Proposed changes

  • Port support for ECC NIST/Brainpool profiles from prototyping_ecc branch
  • Implement CertProvider to load certs per connection / profile
  • Backward compatibility of configuration for existing apps
  • SecurityConfiguration specifies app cert types for each profile
  • Autodetect the ECC support for brainpool/nist based on platform (mac OS 10 doesn't support brainpool)
  • ECC supported on net48 / net5.0 / net 6.0 / netstandard2.1
  • ECC supported on windows / linux / macOS (brainpool not < macOS11)
  • Self signed certs for each profile are created on start similar to RSA
  • RSA only profiles are supported on .NET standard 2.0

Types of changes

What types of changes does your code introduce?
Put an x in the boxes that apply. You can also fill these out after creating the PR.

  • Bugfix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change which adds functionality)
  • Test enhancement (non-breaking change to increase test coverage)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected, requires version increase of Nuget packages)
  • Documentation Update (if none of the other choices apply)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • I have read the CONTRIBUTING doc.
  • I have signed the CLA.
  • I ran tests locally with my changes, all passed.
  • I fixed all failing tests in the CI pipelines.
  • I fixed all introduced issues with CodeQL and LGTM.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added necessary documentation (if appropriate).
  • Any dependent changes have been merged and published in downstream modules.

Further comments

mregen and others added 30 commits October 6, 2023 10:11
            CertificateIdentifierCollection applicationCertificates,
            string pkiRoot = null,
            string rejectedRoot = null
            )
@mregen mregen added the ecc label Jul 12, 2024
@ThomasNehring
Copy link
Contributor

I just had a look at the wireshark trace of the handshake between ConsoleReferenceClient and ConsoleReferenceServer.

The good news is that the GetEndpointsResponse shows the ECC profiles. That's nice.

Otoh, it looks as if the server offers all the old and deprecated security policies (Basic128Rsa15, Basic 256). Is this by intention? I think we should try not not expose them by default. (This is probably just a configuration issue).

@mrsuciu
Copy link
Contributor Author

mrsuciu commented Jul 15, 2024

@ThomasNehring The server's Quickstarts.ReferenceServer.Config.xml configuration contains the deprecated security policies below the <!-- deprecated security policies for reference only --> comment. They are there for backward compatibility testing but can be removed anytime.

<RootNamespace>Opc.Ua.Configuration</RootNamespace>
<Description>OPC UA Configuration Class Library</Description>
<IsPackable>true</IsPackable>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove .bak, I must have unintentionally pushed it

@mrsuciu mrsuciu linked an issue Jul 31, 2024 that may be closed by this pull request
5 tasks
@mregen
Copy link
Contributor

mregen commented Aug 29, 2024

code review discussions for follow up

  • check if the serverNonce can be stored as Nonce and unified for ECC and RSA
  • how about key sizes, do they still make sense as they are specified by profile. How do we specify that a nist 384 cert should be used for nist256. But it is not possible to use curve 448 with curve 25519?

Copy link
Contributor

@romanett romanett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments for first 17 changed files

@@ -46,6 +79,7 @@
<RejectSHA1SignedCertificates>true</RejectSHA1SignedCertificates>
<RejectUnknownRevocationStatus>true</RejectUnknownRevocationStatus>
<MinimumCertificateKeySize>2048</MinimumCertificateKeySize>
<MinimumECCertificateKeySize>256</MinimumECCertificateKeySize>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn`t this obosolete?

@@ -122,6 +189,14 @@
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these shall be removed

@@ -5639,7 +5625,14 @@ ITransportChannel transportChannel
EndpointDescription endpoint = m_endpoint.Description;
SignatureData clientSignature = SecurityPolicies.Sign(m_instanceCertificate, endpoint.SecurityPolicyUri, dataToSign);

#if TODO // new code inside, please check if the update is valid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats up with this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romanett I think @mregen suggests a more thorough review of the FindUserTokenPolicy I added to deprecate the one under the TODO ?

/// <param name="responseHeader"></param>
/// <param name="serverCertificate"></param>
/// <exception cref="ServiceResultException"></exception>
protected virtual void ProcessResponseAdditionalHeader(ResponseHeader responseHeader, X509Certificate2 serverCertificate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does a more precise name exist in the spec for this header?

/// </summary>
public async Task DeleteApplicationInstanceCertificate(CancellationToken ct = default)
public async Task DeleteApplicationInstanceCertificate(string[] profileIds = null, CancellationToken ct = default)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I oppose extending the interface before supporting only deleting certain profiles

throw new ServiceResultException(StatusCodes.BadConfigurationError, "The Ecc certificate type is not supported.");
#else
ECCurve curve = default(ECCurve);
if (id.CertificateType == ObjectTypeIds.EccApplicationCertificateType ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code should live in a static function where it is globally accessible

@@ -63,6 +63,28 @@ private static X509KeyUsageFlags GetKeyUsage(X509Certificate2 cert)
return allFlags;
}

/// <summary>
/// Verify RSA key pair of two certificates.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment is misleading, supports both ecc & RSA


/// <summary>
/// TODO: Holds the application certificates but should be generated and the Opc.Ua.Security namespace automatically
/// TODO: Should replace ApplicationCertificateField in the generated Opc.Ua.Security.SecuredApplication class
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed before merging?

/// <summary>
/// Lazy helper for checking ECC eliptic curve support for running OS
/// </summary>
private static readonly Dictionary<string, Lazy<bool>> s_eccCurveSupportCache = new Dictionary<string, Lazy<bool>>{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this used anywhere?

/// </summary>
/// <param name="certificate"></param>
/// <returns></returns>
public static ECDsa GetPublicKey(X509Certificate2 certificate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isnt this function also present as non ecc specific variants in another class, if yes i think we can remove it in EccUtils?

@@ -738,6 +972,12 @@ public Task<X509Certificate2> LoadPrivateKey(string thumbprint, string subjectNa
return Task.FromResult<X509Certificate2>(null);
}

/// <inheritdoc/>
public Task<X509Certificate2> LoadPrivateKey(string thumbprint, string subjectName, NodeId certificateType, string password)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why return always null?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants