https://bugs.openldap.org/show_bug.cgi?id=10216
Issue ID: 10216 Summary: Channel binding enforced on AD with AD cert using EDCSA-SHA384 fails Product: OpenLDAP Version: 2.6.7 Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: libraries Assignee: bugs@openldap.org Reporter: simon.pichugin@gmail.com Target Milestone: ---
Secure LDAP connections to the target Windows server 2019 DC began failing after the Windows Server DC certificate was updated to an Elliptic Curve Public Key (384 bits) with the sha384ECDSA signature algorithm and sha384 signature hash algorithm specified.
The connections were previously successful when the Windows server DC certificate specified an RSA Public Key certificate with signature algorithm sha256RSA and signature hash algorithm sha256 specified.
Once the Windows server domain controller certificate is upgraded to the ECC public key, subsequent secure ldap connection attempts fail.
If channel binding is turned off on the Windows AD target server, secure ldap connections will succeed using starttls.
If Windows server domain controller certificate is upgraded to ECC public key and ldap channel binding is enforced, subsequent secure ldap connection attempts fail with this error message:
ldap_sasl_interactive_bind_s: Invalid credentials (49) additional info: 80090346: LdapErr: DSID-0C09070F, comment: AcceptSecurityContext error, data 80090346, v4563
Expected results: Kerberos SASL should work with STARTTLS even when AD certificate is ECC and SASL_CBINDING is set to "tls-endpoint"
Actual results: Kerberos SASL only works with STARTTLS even when AD certificate is RSA and SASL_CBINDING is set to "tls-endpoint"; it fails when AD certificate is ECC
Additional information: According to the OpenSSL maintainer, there might be a bug in the OpenLDAP code: it uses EVP_get_digestbynid() to find a digest algorithm based on the signature algorithm, but there might be no such mapping in EC compared to the RSA case. OpenLDAP needs to use OBJ_find_sigid_algs() to find the right algorithm.
Possibly, this is the failing code: https://git.openldap.org/openldap/openldap/-/blob/master/libraries/libldap/t...
Instead of X509_get_signature_nid() OpenLDAP code probably should call something like OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_nid, &pk_nid). The former only supports mapping for a few known signature algorithms, but everything did work, most likely due to a fallback to sha256 in case the digest wasn't really found.
Judging by https://github.com/openssl/openssl/issues/14278 and https://github.com/openssl/openssl/issues/14467, a better API is coming but not currently available (and as it was in the state for a few years, it probably won't be coming soon)