I want to query ActiveDirectory using LDAP over TLSv1.2, and .NET Framework 4.5.2 or 4.6.2 (but having trouble with both). The problem is that it keeps trying to use TLSv1.0, even though I'm using "ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12".
Is the "System.DirectoryServices.Protocols" a package I can use to query LDAP over TLSv1.2? If so, what's the proper way to enable that TLS version?
Ultimately, I want to do this from a Web API 2 controller, but as a simple test that reproduces the issue, I have the following console application:
using System;
using System.Diagnostics;
using System.DirectoryServices.Protocols;
using System.Net;
namespace Ldap
{
class Program
{
private const string ldapHost = "169.254.212.120";
private const int ldapPort = 30389; // normally just 389
private const int ldapSslPort = 30636; // normally just 636
private const bool sslEnabled = true;
private const string userBaseDistinguishedName = "dc=example,dc=org";
private const string bindUserCommonName = "admin";
private const string bindUserDistinguishedName = "cn=admin,dc=example,dc=org";
private const string bindUserPassword = "admin";
static void Main(string[] args)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (LdapConnection connection = CreateConnection())
{
try
{
connection.Bind();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
}
private static LdapConnection CreateConnection()
{
var directoryIdentifier = new LdapDirectoryIdentifier(ldapHost,
sslEnabled ? ldapSslPort : ldapPort, true, false);
var credential = new NetworkCredential(bindUserDistinguishedName, bindUserPassword);
var conn = new LdapConnection(directoryIdentifier, credential, AuthType.Basic);
conn.SessionOptions.SecureSocketLayer = sslEnabled;
conn.SessionOptions.ProtocolVersion = 3; // Use LDAPv3 (otherwise it appears to default to LDAPv2)
return conn;
}
}
}
For the server, I'm testing this using an OpenLdap docker container (with ports 30389 and 30636 exposed, rather than the standard ports), although ultimately this code will be used to connect & query ActiveDirectory.
To stand up the test LDAP server, I happen to be using (Docker 17.06 CE):
docker run --name test_ldap -p 0.0.0.0:30636:636 -p 0.0.0.0:30389:389 --env LDAP_TLS_CIPHER_SUITE="SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:-RSA:-DHE-DSS:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC" --env LDAP_TLS_VERIFY_CLIENT="allow" --hostname example.org --detach osixia/openldap:1.1.7
Also running Wireshark: the traffic seen in Wireshark shows that the "Version" within the "Client Hello" packet is "TLS 1.0 (0x0301)".
The logs within the open LDAP server show:
59810624 conn=1002 fd=16 ACCEPT from IP=172.17.0.1:44606 (IP=0.0.0.0:636)
TLS: can't accept: An unknown public key algorithm was encountered..
59810624 conn=1002 fd=16 closed (TLS negotiation failure)