Repository navigation
[API Proposal]: LdapSessionOptions.CertificateDirectory Property #104260
Description
Background and motivation
This is to provide a way for those who may not have the privilege to administer the system CA certificates store or those who do not want to add entries to the system CA stores permanently but still want to verify the server certificate.
The new APIs are only for Linux and MacOS since the LdapSessionOptions.VerifyServerCertificates property is not supported there.
API Proposal
Adds to https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.protocols.ldapsessionoptions
Assembly: System.DirectoryServices.Protocols.dll
namespace System.DirectoryServices.Protocols;
public class LdapSessionOptions
{
+ // Throws `PlatformNotSupportedException` on non-Windows.
+ public string CertificateDirectory { get; set; }
+ public void StartNewTlsSessionContext();
}Internally the CertificateDirectory setter calls
LdapPal.SetStringOption(_connection._ldapHandle, LdapOption.LDAPTLS_CACERTDIR \ 0x6003, value);and simililarily StartNewTLSSessionContext sets
LDAP_OPT_X_TLS_NEWCTXAPI Usage
connection.SessionOptions.CertificateDirectory = "~/console/mycerts";
// This is necessary if the connection's context was already created.
connection.SessionOptions.StartNewTLSSessionContext();Longer example:
// This is an alternative for specifying the directory.
// Environment.SetEnvironmentVariable("LDAPTLS_CACERTDIR", Path.Combine(AppContext.BaseDirectory, "certs"));
LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier("ldap.local", 1636, fullyQualifiedDnsHostName: true, connectionless: false);
NetworkCredential credential = new NetworkCredential("cn=admin,dc=example,dc=org", "password");
using LdapConnection connection = new LdapConnection(directoryIdentifier, credential)
{
AuthType = AuthType.Basic
};
connection.SessionOptions.ProtocolVersion = 3;
connection.SessionOptions.SecureSocketLayer = true;
Debug.Assert(OperatingSystem.IsLinux());
connection.SessionOptions.CertificateDirectory = "~/console/mycerts";
connection.SessionOptions.StartNewTLSSessionContext();
connection.Bind();
var searchRequest = new SearchRequest("DC=example,DC=org", "(objectClass=*)", SearchScope.Subtree);
_ = (SearchResponse)connection.SendRequest(searchRequest);
Console.WriteLine("Success!");Backup of original proposal
API Proposal
Namespace:
System.DirectoryServices.Protocols
Assembly:
System.DirectoryServices.Protocols.dll
The property CaCertificate contains a X509CertificateCollection object with one or more CA certificates to use to verify server certificates when an SSL connection is established.
public System.Security.Cryptography.X509Certificates.X509CertificateCollection CaCertificates { set; }Property value
CaCertficates
CA certificates to verify server certificate.
API Usage
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier("192.168.10.100", 3060, false, false);
using (LdapConnection ldapConnection = new LdapConnection(identifier))
{
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.Credential = new NetworkCredential("admin", "SomePassword");
ldapConnection.ClientCertificates.AddRange(myCert);
ldapConnection.SessionOptions.CaCertificates.AddRange(CaCerts);
ldapConnection.Bind();
}Alternative Designs
Have LdapSessionOptions.VerifyServerCertificates be functional.
Risks
The risk is minimal because no current application is using this property.
Activity
dotnet-policy-service commentedon Jul 1, 2024
Tagging subscribers to this area: @dotnet/area-system-directoryservices, @jay98014
See info in area-owners.md if you want to be subscribed.
filipnavara commentedon Jul 1, 2024
I think this is misguided. There's an existing API for certificate validation (
LdapSessionOptions.VerifyServerCertificates) that follows established pattern used by other classes likeSslStreamorHttpClientHandler. The reason it's not implemented on non-Windows system is the lack or corresponding API in the native system LDAP library (*). The API proposed above would still suffer from the same underlying issue which is lack of certificate control at the lower level system API.(*) See #60972 for details.
steveharter commentedon Jul 3, 2024
Per offline discussion with @buyaa-n, moving to future. Please close if there is a valid alternative.
buyaa-n commentedon Jul 5, 2024
@onmp could you collaborate more on how you imagine this
SessionOption.CaCertificateswould work further to replaceLdapSessionOptions.VerifyServerCertificateson Linux?dotnet-policy-service commentedon Jul 5, 2024
This issue has been marked
needs-author-actionand may be missing some important information.buyaa-n commentedon Jul 8, 2024
@onmp as a work around, could you set the env variable
LDAPTLS_CACERTDIRwith the path where your CA certificates are located and run your client app? Please check https://www.openldap.org/doc/admin24/tls.html#TLS%20Configuration for more info about the directory requirements (like might need to runc_rehashutility).Could try with a ldapsearch commant:
env LDAPTLS_CACERTDIR=/path/to/CACerts ldapsearch -H ldaps://ldap.local:1636 -b dc=example,dc=org -x -D cn=admin,dc=example,dc=org -w passwordOr run
export LDAPTLS_CACERTDIR="/path/to/CACerts"before running you app.11 remaining items
steveharter commentedon Dec 30, 2024
Re-opened. We have external validation that that adding
namespace System.DirectoryServices.Protocols; public class LdapSessionOptions { + public string CertificateDirectory { get; set; } + public void StartNewTlsSessionContext(); }addresses this. Internally the
CertificateDirectorysetter callsThis will throw
PlatformNotSupportedExceptionon non-Windows.Usage along the lines of:
steveharter commentedon Dec 30, 2024
I will update the original API suggestion and mark it ready for reviewing pending internal discussion.
[-][API Proposal]: LdapSessionOptions.CaCertificates Property[/-][+][API Proposal]: LdapSessionOptions.CertificateDirectory Property[/+]bartonjs commentedon Jan 28, 2025
Video
CertificateDirectory=>TrustedCertificatesDirectory