https://bugs.openldap.org/show_bug.cgi?id=10321
Issue ID: 10321 Summary: slapd garbles userCertificate hex code Product: OpenLDAP Version: 2.6.7 Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: slapd Assignee: bugs@openldap.org Reporter: jnabasny@gmail.com Target Milestone: ---
I discovered an issue with how slapd handles hex encoded userCertificate;binary values while testing identical setups between FreeIPA and OpenLDAP. It seems to partially decode the hex, causing any search to fail. This was discovered when using SSSD, but is reproducible with ldapsearch. Essentially, you run a query like this using the hex encoded value of the certificate:
ldapsearch -H ldap://10.10.0.94 -D cn=admin,dc=nabasny,dc=com -b "dc=nabasny,dc=com" -W '(&(userCertificate;binary=\30\82\04\85\30\82\02\ed\a0\03\02\01\02\02\01\0d\30\0d\06\09\2a\86\48\86\f7\0d\01\01\0b\05\00\30\37\31\15\30\13\06\03\55\04\0a\0c\0c\46\52\45\45\49\50\41\2e\48\4f\4d\45\31\1e\30\1c\06\03\55\04\03\0c\15\43\65\72\74\69\66\69\63\61\74\65\20\41\75\74\68\6f\72\69\74\79\30\1e\17\0d\32\35\30\33\32\30\31\35\34\35\32\36\5a\17\0d\32\37\30\33\32\31\31\35\34\35\32\36\5a\30\26\31\15\30\13\06\03\55\04\0a\0c\0c\46\52\45\45\49\50\41\2e\48\4f\4d\45\31\0d\30\0b\06\03\55\04\03\0c\04\6a\61\6b\65\30\82\01\22\30\0d\06\09\2a\86\48\86\f7\0d\01\01\01\05\00\03\82\01\0f\00\30\82\01\0a\02\82\01\01\00\b9\b2\3b\be\d1\20\bd\f2\ba\69\e6\b6\e5\2d\13\b0\77\a6\59\69\50\76\4c\07\71\ce\ee\8f\41\ef\04\20\1b\8e\a5\f7\8a\96\0d\f1\89\a5\84\cd\2f\be\ff\9c\2a\b2\bf\99\20\ca\ae\fc\a2\16\df\40\5b\d4\5e\7b\51\a5\b0\dd\bc\e9\c4\b1\e7\89\7c\25\f2\4b\b0\08\09\bd\60\58\c1\8f\af\fb\2a\5e\90\69\37\27\40\61\62\bb\7a\b8\76\18\11\96\2e\45\54\26\b0\c7\ec\92\3c\72\90\52\1a\44\0f\69\5c\b4\f1\98\53\4e\15\86\33\1a\81\ee\70\63\ae\e4\c7\32\7f\92\14\71\9d\58\c0\7d\a1\20\dc\f5\f6\47\29\45\56\bd\a2\dd\eb\4a\17\f2\2a\72\6f\fd\0f\a3\7e\a0\96\de\02\f3\b2\d9\ac\fc\af\38\c9\7a\21\c3\1b\19\4c\bc\d8\11\48\22\cf\18\ec\17\85\51\e9\51\22\49\aa\89\1a\73\2b\8d\40\e9\a9\3a\dd\e8\6e\9b\27\45\09\fd\a4\88\f5\7c\4e\96\b7\82\cd\f6\e2\1e\08\53\38\af\f9\4d\55\9c\79\0f\32\d8\bb\85\83\08\c0\b9\f3\39\7f\b9\7b\a9\02\03\01\00\01\a3\82\01\2b\30\82\01\27\30\1f\06\03\55\1d\23\04\18\30\16\80\14\0d\6b\b6\82\13\0c\a2\9d\91\01\40\e8\59\d6\2b\ec\87\1a\f0\36\30\3e\06\08\2b\06\01\05\05\07\01\01\04\32\30\30\30\2e\06\08\2b\06\01\05\05\07\30\01\86\22\68\74\74\70\3a\2f\2f\69\70\61\2d\63\61\2e\66\72\65\65\69\70\61\2e\68\6f\6d\65\2f\63\61\2f\6f\63\73\70\30\0e\06\03\55\1d\0f\01\01\ff\04\04\03\02\04\f0\30\1c\06\03\55\1d\25\04\15\30\13\06\08\2b\06\01\05\05\07\03\01\06\07\2b\06\01\05\02\03\05\30\77\06\03\55\1d\1f\04\70\30\6e\30\6c\a0\34\a0\32\86\30\68\74\74\70\3a\2f\2f\69\70\61\2d\63\61\2e\66\72\65\65\69\70\61\2e\68\6f\6d\65\2f\69\70\61\2f\63\72\6c\2f\4d\61\73\74\65\72\43\52\4c\2e\62\69\6e\a2\34\a4\32\30\30\31\0e\30\0c\06\03\55\04\0a\0c\05\69\70\61\63\61\31\1e\30\1c\06\03\55\04\03\0c\15\43\65\72\74\69\66\69\63\61\74\65\20\41\75\74\68\6f\72\69\74\79\30\1d\06\03\55\1d\0e\04\16\04\14\e8\11\4b\36\86\c9\7c\a2\d7\4e\ff\7c\13\89\2b\38\8d\c4\ec\32\30\0d\06\09\2a\86\48\86\f7\0d\01\01\0b\05\00\03\82\01\81\00\58\af\2b\7e\fd\05\b9\46\8a\c7\b9\e4\96\42\47\2d\8f\17\01\8e\58\30\95\9c\be\e7\2d\a8\22\64\5e\fd\f5\ec\46\97\2d\88\bc\06\b0\e7\a3\77\a3\d0\b6\da\01\4f\73\f4\3d\c9\47\49\e2\d0\a0\e8\bd\a9\62\fd\6c\de\81\32\9a\33\d5\58\57\d8\c9\47\54\78\fa\69\20\49\11\c9\dc\4f\f4\bc\37\63\28\6a\fd\e2\f7\4b\0f\44\26\90\6c\22\c9\b8\ff\9a\36\05\a3\24\3c\58\73\6f\4b\17\2d\e3\22\30\aa\34\4e\2f\36\24\94\6a\24\9b\bf\ac\e5\23\33\f6\3f\cf\c7\dd\38\91\85\63\c0\61\55\5f\de\2b\e6\3d\13\4f\8c\6a\6a\1e\3b\0e\4a\8c\e9\c3\46\ef\02\bb\63\b7\09\9f\d8\5c\67\4c\c6\40\8f\1e\7e\c8\f0\89\4c\8f\f8\24\63\42\31\f9\5d\5b\2d\cb\78\c3\94\5f\3e\ca\b8\7b\68\9a\6a\09\0c\22\bd\da\39\9f\b7\0f\4f\20\a9\1a\de\d7\8a\31\af\a3\ac\14\d1\ba\90\b8\22\56\31\b1\52\78\73\6f\36\05\88\0b\56\31\fd\55\89\7d\55\8b\01\1d\58\0c\75\03\bd\7c\7b\05\c7\86\15\90\0c\f4\c6\91\d3\f6\73\e9\8f\1f\25\88\32\b2\cb\53\db\91\e4\8b\28\a1\22\7a\38\ac\f5\8b\32\51\d4\9e\d6\e1\15\0d\fb\8f\60\09\e5\0c\dd\d4\19\fe\f7\44\cd\ac\ff\82\94\16\f5\7d\19\57\30\79\96\4b\7b\61\d0\b8\c3\0c\1c\2f\89\7e\01\5e\a0\95\9a\aa\d3\e2\6d\d5\fa\2e\e8\57\5a\b3\45\23\17\40\c9\d3\92\9e\11\cc\c4\31\f2\e5\94\e3\8f\5e\d9\51\92\cd\46\77\33\c8\4b\50\84\73)(objectclass=posixAccount)(uid=*)(&(uidNumber=*)(!(uidNumber=0))))'
And slapd logs the query as:
Mar 20 19:54:01 ldap slapd[457]: conn=1058 op=3 SRCH base="ou=people,dc=nabasny,dc=com" scope=2 deref=0 filter="(&(?userCertificate;binary=0\82\04\850\82\02\ED\A0\03\02\01\02\02\01\0D0\0D\06\09\2A\86H\86\F7\0D\01\01\0B\05\00071\150\13\06\03U\04\0A\0C\0CFREEIPA.HOME1\1E0\1C\06\03U\04\03\0C\15Certificate Authority0\1E\17\0D250320154526Z\17\0D270321154526Z0&1\150\13\06\03U\04\0A\0C\0CFREEIPA.HOME1\0D0\0B\06\03U\04\03\0C\04jake0\82\01"0\0D\06\09\2A\86H\86\F7\0D\01\01\01\05\00\03\82\01\0F\000\82\01\0A\02\82\01\01\00\B9\B2;\BE\D1 \BD\F2\BAi\E6\B6\E5-\13\B0w\A6YiPvL\07q\CE\EE\8FA\EF\04 \1B\8E\A5\F7\8A\96\0D\F1\89\A5\84\CD/\BE\FF\9C\2A\B2\BF\99 \CA\AE\FC\A2\16\DF@[\D4^{Q\A5\B0\DD\BC\E9\C4\B1\E7\89|%\F2K\B0\08\09\BD`X\C1\8F\AF\FB\2A^\90i7'@ab\BBz\B8v\18\11\96.ET&\B0\C7\EC\92<r\90R\1AD\0Fi\5C\B4\F1\98SN\15\863\1A\81\EEpc\AE\E4\C72\7F\92\14q\9DX\C0}\A1 \DC\F5\F6G\29EV\BD\A2\DD\EBJ\17\F2\2Aro\FD\0F\A3~\A0\96\DE\02\F3\B2\D9\AC\FC\AF8\C9z!\C3\1B\19L\BC\D8\11H"\CF\18\EC\17\85Q\E9Q"I\AA\89\1As+\8D@\E9\A9:\DD\E8n\9B'E\09\FD\A4\88\F5|N\96\B7\82\CD\F6\E2\1E\08S8\AF\F9MU\9Cy\0F2\D8\BB\85\83\08\C0\B9\F39\7F\B9{\A9\02\03\01\00\01\A3\82\01+0\82\01'0\1F\06\03U\1D#\04\180\16\80\14\0Dk\B6\82\13\0C\A2\9D\91\01@\E8Y\D6+\EC\87\1A\F060>\06\08+\06\01\05\05\07\01\01\042000.\06\08+\06\01\05\05\070\01\86"http://ipa-ca.freeipa.home/ca/ocsp0%5C0E%5C06%5C03U%5C1D%5C0F%5C01%5C01%5CFF... Authority0\1D\06\03U\1D\0E\04\16\04\14\E8\11K6\86\C9|\A2\D7N\FF|\13\89+8\8D\C4\EC20\0D\06\09\2A\86H\86\F7\0D\01\01\0B\05\00\03\82\01\81\00X\AF+~\FD\05\B9F\8A\C7\B9\E4\96BG-\8F\17\01\8EX0\95\9C\BE\E7-\A8"d^\FD\F5\ECF\97-\88\BC\06\B0\E7\A3w\A3\D0\B6\DA\01Os\F4=\C9GI\E2\D0\A0\E8\BD\A9b\FDl\DE\812\9A3\D5XW\D8\C9GTx\FAi I\11\C9\DCO\F4\BC7c\28j\FD\E2\F7K\0FD&\90l"\C9\B8\FF\9A6\05\A3$<XsoK\17-\E3"0\AA4N/6$\94j$\9B\BF\AC\E5#3\F6?\CF\C7\DD8\91\85c\C0aU_\DE+\E6=\13O\8Cjj\1E;\0EJ\8C\E9\C3F\EF\02\BBc\B7\09\9F\D8\5CgL\C6@\8F\1E~\C8\F0\89L\8F\F8$cB1\F9][-\CBx\C3\94_>\CA\B8{h\9Aj\09\0C"\BD\DA9\9F\B7\0FO \A9\1A\DE\D7\8A1\AF\A3\AC\14\D1\BA\90\B8"V1\B1Rxso6\05\88\0BV1\FDU\89}U\8B\01\1DX\0Cu\03\BD|{\05\C7\86\15\90\0C\F4\C6\91\D3\F6s\E9\8F\1F%\882\B2\CBS\DB\91\E4\8B\28\A1"z8\AC\F5\8B2Q\D4\9E\D6\E1\15\0D\FB\8F`\09\E5\0C\DD\D4\19\FE\F7D\CD\AC\FF\82\94\16\F5}\19W0y\96K{a\D0\B8\C3\0C\1C/\89~\01^\A0\95\9A\AA\D3\E2m\D5\FA.\E8WZ\B3E#\17@\C9\D3\92\9E\11\CC\C41\F2\E5\94\E3\8F^\D9Q\92\CDFw3\C8KP\84s)(objectClass=posixAccount)(uid=*)(&(uidNumber=*)(!(uidNumber=0))))"
Some of the hex has been decoded into readable strings, which causes the search to fail.
Running the same search on FreeIPA with an identical user entry returns the entry correctly.
I'm happy to provide more logs/details if needed.
https://bugs.openldap.org/show_bug.cgi?id=10321
--- Comment #1 from Howard Chu hyc@openldap.org --- The question mark in the logged filter indicates that the filter term was invalid.
Mar 20 19:54:01 ldap slapd[457]: conn=1058 op=3 SRCH base="ou=people,dc=nabasny,dc=com" scope=2 deref=0 filter="(&(?userCertificate;binary=
I.e., it failed to parse, or the requested filter type is not valid for that attributetype. As such nothing else is relevant. The transcription from hex values to decoded characters has no bearing on it.
https://bugs.openldap.org/show_bug.cgi?id=10321
--- Comment #2 from jnabasny@gmail.com --- Thanks for the reply, Howard. When you say "failed to parse", couldn't that be caused by the partial transcription?
Also, I've confirmed the inetOrgPerson schema is loaded, which contains the userCertificate attributetype. As far as I know, this filter doesn't depend on anything else. Are there some other pre-requisites you are aware of?
https://bugs.openldap.org/show_bug.cgi?id=10321
--- Comment #3 from Howard Chu hyc@openldap.org --- To specify a certificate in a search filter you must use certificate assertion syntax, as documented in RFC4523.
There's no bug here, closing this ticket.
https://bugs.openldap.org/show_bug.cgi?id=10321
Howard Chu hyc@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED
https://bugs.openldap.org/show_bug.cgi?id=10321
jnabasny@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|INVALID |--- Status|RESOLVED |UNCONFIRMED
--- Comment #4 from jnabasny@gmail.com --- This is absolutely not a search filter issue unless OpenLDAP is not compliant with the RFC. The exact same ldapsearch query on FreeIPA returns successfully and shows this in the debug log:
[21/Mar/2025:16:40:21.080054196 -0400] conn=22 op=1 SRCH base="dc=freeipa,dc=home" scope=2 filter="(&(usercertificate;binary=0\82\04\850\82\02\ED\A0\03\02\01\02\02\01\0D0\0D\06\09\2A\86H\86\F7\0D\01\01\0B\05)(objectClass=posixAccount)(uid=*)(&(uidNumber=*)(!(uidNumber=0))))" attrs=ALL [21/Mar/2025:16:40:21.081159982 -0400] conn=22 op=1 RESULT err=0 tag=101 nentries=1 wtime=0.000101369 optime=0.001106047 etime=0.001204661
So, the same filter on an identical entry returns different results, and we can see that slapd is mangling the filter.
https://bugs.openldap.org/show_bug.cgi?id=10321
Howard Chu hyc@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED
--- Comment #5 from Howard Chu hyc@openldap.org --- slapd is not mangling the filter.
The filter is invalid, it doesn't conform to RFC4523. Sounds like FreeIPA doesn't implement RFC4523, that's not our concern.
https://bugs.openldap.org/show_bug.cgi?id=10321
--- Comment #6 from Howard Chu hyc@openldap.org --- slapd is only unescaping the bytes in the filter that correspond to printable characters. You can prove that the result is bytewise identical to the original input.
use "xxd -r -p" on the original input to generate the value in its decoded form. it will be an 1161 byte file.
Use this program on the text that slapd logged to generate the value in its decoded form. It will be an identical 1161 byte file.
#include <stdio.h>
int main() { int c; while ((c = fgetc(stdin)) != EOF) { if (c == '\n') continue; if (c == '\') { scanf("%02x", &c); } putchar(c); } }
https://bugs.openldap.org/show_bug.cgi?id=10321
Howard Chu hyc@openldap.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords|needs_review |