Directory ApacheDS
  1. Directory ApacheDS
  2. DIRSERVER-1198

Requests of usercertificate;binary are not supported

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0.0-M1
    • Component/s: None
    • Labels:
      None

      Description

      ApacheDS only supports the retrieval of certificates without the ;binary transfer suffix.

      RFC4523 states certificates must be transferred using the ;binary transfer option.

      In practice we have clients in the field that are making requests both with and without the option so we'd need support for both methods to be able to consider deploying ApacheDS.

        Issue Links

          Activity

          Hide
          Dominik Heine added a comment -

          No I am not using the JNDI API, I am using the default "Apache Directory LDAP Client API".

          Show
          Dominik Heine added a comment - No I am not using the JNDI API, I am using the default "Apache Directory LDAP Client API".
          Hide
          Emmanuel Lecharny added a comment -

          A question : are you using the JNDI API in Studio ? If so, can you test with the LDAP API ? (this is an option in the preferences : Apache Directory Studio > Connections > Default Network Provider )

          Thanks

          Show
          Emmanuel Lecharny added a comment - A question : are you using the JNDI API in Studio ? If so, can you test with the LDAP API ? (this is an option in the preferences : Apache Directory Studio > Connections > Default Network Provider ) Thanks
          Hide
          Dominik Heine added a comment -

          Thanks for the quick reply. There is definitely something odd. It might actually be that the problem is a combination of ApacheDS and Apache Directory Studio.

          If I use Apache Directory Studio to add the Attribute "userCertificate;binary" to ApacheDS it converts it immediately after adding a value to the attribute (only after adding/editing value) to just "userCertificate" and the ";binary" disappears. If I then run a query for "userCertificate;binary" the result is empty.

          But if I use the Apache Directory Studio to do the same with an OpenLDAP server the "userCertificate;binary" stays and also the query for it works.

          But then if I take your test and modify it to an LDIF file (with my test-DN):
          dn: cn=Kate Bush,o=test
          objectclass: top
          objectclass: person
          objectclass: inetOrgPerson
          userCertificate;binary:: PEhlbGxvIHdvcmxkICE+
          sn: Bush
          cn: Kate Bush

          and Import this with Apache Directory Studio then the userCertificate;binary stays but only until I edit the value, then it also disappears again.
          The modify looks like this (making it <Hello world2 !>):
          dn: cn=Kate Bush,o=test
          changetype: modify
          replace: userCertificate;binary
          userCertificate;binary:: PEhlbGxvIHdvcmxkMiAhPg==

          This is strange because I am using the same editor (Apache Directory Studio) with OpenLDAP and with OpenLDAP I don't have that issue.

          You moved this issue to Studio once before but it was moved back, I think you were on the right track. I guess it needs to be looked at again from both perspectives.

          Show
          Dominik Heine added a comment - Thanks for the quick reply. There is definitely something odd. It might actually be that the problem is a combination of ApacheDS and Apache Directory Studio. If I use Apache Directory Studio to add the Attribute "userCertificate;binary" to ApacheDS it converts it immediately after adding a value to the attribute (only after adding/editing value) to just "userCertificate" and the ";binary" disappears. If I then run a query for "userCertificate;binary" the result is empty. But if I use the Apache Directory Studio to do the same with an OpenLDAP server the "userCertificate;binary" stays and also the query for it works. But then if I take your test and modify it to an LDIF file (with my test-DN): dn: cn=Kate Bush,o=test objectclass: top objectclass: person objectclass: inetOrgPerson userCertificate;binary:: PEhlbGxvIHdvcmxkICE+ sn: Bush cn: Kate Bush and Import this with Apache Directory Studio then the userCertificate;binary stays but only until I edit the value, then it also disappears again. The modify looks like this (making it <Hello world2 !>): dn: cn=Kate Bush,o=test changetype: modify replace: userCertificate;binary userCertificate;binary:: PEhlbGxvIHdvcmxkMiAhPg== This is strange because I am using the same editor (Apache Directory Studio) with OpenLDAP and with OpenLDAP I don't have that issue. You moved this issue to Studio once before but it was moved back, I think you were on the right track. I guess it needs to be looked at again from both perspectives.
          Hide
          Emmanuel Lecharny added a comment -

          This is not an ApacheDS issue. The server correctly returns the userCertificate;binary value when requested with an API that supports it. There is a test that checks this specific use case :

              @Test
              public void testAddWithCertificateBinary() throws Exception
              {
                  LdapConnection con = getAdminConnection( getLdapServer() );
                  con.loadSchema();
          
                  String dn = "cn=Kate Bush," + BASE;
                  Entry kate = new DefaultEntry( dn,
                      "objectclass: top",
                      "objectclass: person",
                      "objectclass: inetOrgPerson",
                      "userCertificate;binary:: PEhlbGxvIHdvcmxkICE+", // This is "<hello world !>"
                      "sn: Bush",
                      "cn: Kate Bush" );
          
                  con.add( kate );
          
                  // Analyze entry and description attribute
                  Entry kateReloaded = con.lookup( dn );
                  assertNotNull( kateReloaded );
                  Attribute certificate = kateReloaded.get( "userCertificate;binary" );
                  assertNotNull( certificate );
                  assertEquals( 1, certificate.size() );
                  assertTrue( certificate.contains( Strings.getBytesUtf8( "<Hello world !>" ) ) );
          
          Show
          Emmanuel Lecharny added a comment - This is not an ApacheDS issue. The server correctly returns the userCertificate;binary value when requested with an API that supports it. There is a test that checks this specific use case : @Test public void testAddWithCertificateBinary() throws Exception { LdapConnection con = getAdminConnection( getLdapServer() ); con.loadSchema(); String dn = "cn=Kate Bush," + BASE; Entry kate = new DefaultEntry( dn, "objectclass: top" , "objectclass: person" , "objectclass: inetOrgPerson" , "userCertificate;binary:: PEhlbGxvIHdvcmxkICE+" , // This is "<hello world !>" "sn: Bush" , "cn: Kate Bush" ); con.add( kate ); // Analyze entry and description attribute Entry kateReloaded = con.lookup( dn ); assertNotNull( kateReloaded ); Attribute certificate = kateReloaded.get( "userCertificate;binary" ); assertNotNull( certificate ); assertEquals( 1, certificate.size() ); assertTrue( certificate.contains( Strings.getBytesUtf8( "<Hello world !>" ) ) );
          Hide
          Dominik Heine added a comment -

          I understand that this is an old issue that seems to be caused by JNDI if the last post is correct but nevertheless this issue is the reason why I needed to go back to OpenLDAP since for example Outlook 2011 (the Apple Mac OS X-Version of Office) cannot retrieve S/MIME certificates from ApacheDS due to the fact the userCertificate;binary-request is not answered correctly by ApacheDS. Mozilla Thunderbird seems to be affected as well, only to name a few: https://bugzilla.mozilla.org/show_bug.cgi?id=488127.

          So I am pretty sure there are many people affected by this issue. Therefore I recommend to reopen this issue.

          Show
          Dominik Heine added a comment - I understand that this is an old issue that seems to be caused by JNDI if the last post is correct but nevertheless this issue is the reason why I needed to go back to OpenLDAP since for example Outlook 2011 (the Apple Mac OS X-Version of Office) cannot retrieve S/MIME certificates from ApacheDS due to the fact the userCertificate;binary-request is not answered correctly by ApacheDS. Mozilla Thunderbird seems to be affected as well, only to name a few: https://bugzilla.mozilla.org/show_bug.cgi?id=488127 . So I am pretty sure there are many people affected by this issue. Therefore I recommend to reopen this issue.
          Hide
          Emmanuel Lecharny added a comment -

          The fact that attrs.get( "userCertificate;binary" ) does not work is not a server issue : its a problem with JNDI.

          Show
          Emmanuel Lecharny added a comment - The fact that attrs.get( "userCertificate;binary" ) does not work is not a server issue : its a problem with JNDI.
          Hide
          gunter zeilinger added a comment -

          attrs.get("userCertificate;binary") still (2.0.0-M3) returns null!

          Show
          gunter zeilinger added a comment - attrs.get("userCertificate;binary") still (2.0.0-M3) returns null!
          Hide
          Pierre-Arnaud Marcelot added a comment -

          Version 2.0.0-M1 has been release.
          Closing all related resolved issues.

          Show
          Pierre-Arnaud Marcelot added a comment - Version 2.0.0-M1 has been release. Closing all related resolved issues.
          Hide
          Emmanuel Lecharny added a comment -

          Both tests has been added and now work.

          However, I have modified the test in order to have it working : when checking for the userCertificate in the returned entry, I have removed the ';binary' postfix as JNDI isn't able to handle this option.

          This is not perfect, but at least, one can search for "userCertificate;binary" and get back the attribute value.

          Show
          Emmanuel Lecharny added a comment - Both tests has been added and now work. However, I have modified the test in order to have it working : when checking for the userCertificate in the returned entry, I have removed the ';binary' postfix as JNDI isn't able to handle this option. This is not perfect, but at least, one can search for "userCertificate;binary" and get back the attribute value.
          Hide
          Emmanuel Lecharny added a comment -

          Postponed to 2.0.0-RC1

          Show
          Emmanuel Lecharny added a comment - Postponed to 2.0.0-RC1
          Hide
          Emmanuel Lecharny added a comment -

          Partial fix :
          http://svn.apache.org/viewvc?rev=774815&view=rev

          It solves the first case (values > 0x7F in the attribute)

          Show
          Emmanuel Lecharny added a comment - Partial fix : http://svn.apache.org/viewvc?rev=774815&view=rev It solves the first case (values > 0x7F in the attribute)
          Hide
          Emmanuel Lecharny added a comment -

          Almost impossible to fix without reviewing the whole Entry manipulation system. The first case can be fix (allowing values above 0x80), as it's a simple check in the decoder, but the second case impact the changeLog system, as we need to manipulate ClientEntry in the LDIF revertor. ClientEntry don't have any knowledge currently about options or AttributeType, so it's very difficult to fix it.

          We will have to postpone this to a later version, I'm afraid ...

          Show
          Emmanuel Lecharny added a comment - Almost impossible to fix without reviewing the whole Entry manipulation system. The first case can be fix (allowing values above 0x80), as it's a simple check in the decoder, but the second case impact the changeLog system, as we need to manipulate ClientEntry in the LDIF revertor. ClientEntry don't have any knowledge currently about options or AttributeType, so it's very difficult to fix it. We will have to postpone this to a later version, I'm afraid ...
          Hide
          Emmanuel Lecharny added a comment -

          Let's see if we can fix that before 1.5.5, as we have missed the opportunity to release last week.

          Show
          Emmanuel Lecharny added a comment - Let's see if we can fix that before 1.5.5, as we have missed the opportunity to release last week.
          Hide
          Rihards Gailums added a comment -

          This issue seems to affect all versions of Mozilla Thunderbird like 2.0.0.21 till latest nightly build 3.0
          When trying to send S/MIME encrypted e-mail, it send usercertificate;binary request ,but get usercertificate=., as result fail to find certificate.
          I would say this is major and urgent problem to resolve.

          Show
          Rihards Gailums added a comment - This issue seems to affect all versions of Mozilla Thunderbird like 2.0.0.21 till latest nightly build 3.0 When trying to send S/MIME encrypted e-mail, it send usercertificate;binary request ,but get usercertificate=., as result fail to find certificate. I would say this is major and urgent problem to resolve.
          Hide
          Alex Karasulu added a comment -

          Handle this in 1.5.7 where we confront issue of tags.

          Show
          Alex Karasulu added a comment - Handle this in 1.5.7 where we confront issue of tags.
          Hide
          Emmanuel Lecharny added a comment -

          Postponed to 1.5.4.

          A fix has been applied to allow certificates with bytes above 0x7F, so the initial problem (DIRSERVER-1197) should now be fixed

          Show
          Emmanuel Lecharny added a comment - Postponed to 1.5.4. A fix has been applied to allow certificates with bytes above 0x7F, so the initial problem ( DIRSERVER-1197 ) should now be fixed
          Hide
          Emmanuel Lecharny added a comment -

          In order to correctly handle these cases, we have to support attributeType options, like binary.

          All what have done until now is to hack the code. Let' fix this in 1.5.4.

          Show
          Emmanuel Lecharny added a comment - In order to correctly handle these cases, we have to support attributeType options, like binary. All what have done until now is to hack the code. Let' fix this in 1.5.4.
          Hide
          Emmanuel Lecharny added a comment -

          I can make the first test working easily, but not the second.

          In fact, I can get the entry to be found, and returned, but the Attribute attr = attrs.get("userCertificate;binary") call won't work,
          as the entry come back with "userCertificate" without the ";binary" string into it.

          I don't see easy ay to fix it, unless we decide to support attribute options, which will be a huge modification.

          How urgent is this ?

          Show
          Emmanuel Lecharny added a comment - I can make the first test working easily, but not the second. In fact, I can get the entry to be found, and returned, but the Attribute attr = attrs.get("userCertificate;binary") call won't work, as the entry come back with "userCertificate" without the ";binary" string into it. I don't see easy ay to fix it, unless we decide to support attribute options, which will be a huge modification. How urgent is this ?
          Hide
          Stefan Seelmann added a comment -

          Moved back to Server. I found two more bugs:

          1st)
          There is a problem when writing ;binary values greater than 0x80. The following test write four bytes 0x80, 0x81, 0x82, 0x83 when reading it from the server I get 12 bytes.

          /**

          • Add a new ;binary attribute with bytes greater than 0x80
          • to a person entry.
          • Test for DIRSERVER-1146
          • @throws NamingException
            */
            public void testAddNewBinaryAttributeValue0x80() throws NamingException
            {
            // Add a ;binary attribute with high-bytes
            byte[] newValue = new byte[] {(byte)0x80, (byte)0x81, (byte)0x82, (byte)0x83}

            ;
            Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue );
            ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );

          // Verify, that attribute value is added
          attrs = ctx.getAttributes( RDN_TORI_AMOS );
          Attribute attr = attrs.get( "userCertificate" );
          assertNotNull( attr );
          assertTrue( attr.contains( newValue ) );
          byte[] certificate = (byte[])attr.get();
          assertTrue( Arrays.equals( newValue, certificate ) );
          assertEquals( 1, attr.size() );
          }

          2nd)
          Reading the entry and requesting userCertificate;binary (including the ;binary) doesn't work

          /**

          • Retrieve a ;binary attribute from a person entry.
          • Test for DIRSERVER-1146
          • @throws NamingException
            */
            public void testRetrieveEntryWithBinaryAttributeValue() throws NamingException
            {
            // Add a ;binary attribute
            byte[] newValue = new byte[] {0x00, 0x01, 0x02, 0x03}

            ;
            Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue );
            ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );

          // Search entry an request ;binary attribute
          SearchControls sctls = new SearchControls();
          sctls.setSearchScope(SearchControls.OBJECT_SCOPE);
          sctls.setReturningAttributes( new String[]

          { "userCertificate;binary" }

          );
          String filter = "(objectClass=*)";
          String base = RDN_TORI_AMOS;

          // Test that ;binary attribute is present
          NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls);
          assertTrue(enm.hasMore());
          while (enm.hasMore())

          { SearchResult sr = enm.next(); attrs = sr.getAttributes(); Attribute attr = attrs.get("userCertificate;binary"); assertNotNull(attr); assertTrue( attr.contains( newValue ) ); byte[] certificate = (byte[])attr.get(); assertTrue( Arrays.equals( newValue, certificate ) ); assertEquals( 1, attr.size() ); }

          }

          Show
          Stefan Seelmann added a comment - Moved back to Server. I found two more bugs: 1st) There is a problem when writing ;binary values greater than 0x80. The following test write four bytes 0x80, 0x81, 0x82, 0x83 when reading it from the server I get 12 bytes. /** Add a new ;binary attribute with bytes greater than 0x80 to a person entry. Test for DIRSERVER-1146 @throws NamingException */ public void testAddNewBinaryAttributeValue0x80() throws NamingException { // Add a ;binary attribute with high-bytes byte[] newValue = new byte[] {(byte)0x80, (byte)0x81, (byte)0x82, (byte)0x83} ; Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue ); ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); // Verify, that attribute value is added attrs = ctx.getAttributes( RDN_TORI_AMOS ); Attribute attr = attrs.get( "userCertificate" ); assertNotNull( attr ); assertTrue( attr.contains( newValue ) ); byte[] certificate = (byte[])attr.get(); assertTrue( Arrays.equals( newValue, certificate ) ); assertEquals( 1, attr.size() ); } 2nd) Reading the entry and requesting userCertificate;binary (including the ;binary) doesn't work /** Retrieve a ;binary attribute from a person entry. Test for DIRSERVER-1146 @throws NamingException */ public void testRetrieveEntryWithBinaryAttributeValue() throws NamingException { // Add a ;binary attribute byte[] newValue = new byte[] {0x00, 0x01, 0x02, 0x03} ; Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue ); ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); // Search entry an request ;binary attribute SearchControls sctls = new SearchControls(); sctls.setSearchScope(SearchControls.OBJECT_SCOPE); sctls.setReturningAttributes( new String[] { "userCertificate;binary" } ); String filter = "(objectClass=*)"; String base = RDN_TORI_AMOS; // Test that ;binary attribute is present NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls); assertTrue(enm.hasMore()); while (enm.hasMore()) { SearchResult sr = enm.next(); attrs = sr.getAttributes(); Attribute attr = attrs.get("userCertificate;binary"); assertNotNull(attr); assertTrue( attr.contains( newValue ) ); byte[] certificate = (byte[])attr.get(); assertTrue( Arrays.equals( newValue, certificate ) ); assertEquals( 1, attr.size() ); } }
          Hide
          Emmanuel Lecharny added a comment -

          Moved to Studio to check that it's not an issue with the way Studio handles ;binary values

          Show
          Emmanuel Lecharny added a comment - Moved to Studio to check that it's not an issue with the way Studio handles ;binary values
          Hide
          Emmanuel Lecharny added a comment -

          The following test demonstrates that the userCertificate;binary attribute is working on the server, and that the certificate is not modified.

          There may be a bug in Studio, however.

          public void testAddNewBinaryAttributeValue() throws NamingException
          {
          // Add a binary attribute
          byte[] newValue = new byte[]

          {0x00, 0x01, 0x02, 0x03}

          ;
          Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue );
          ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs );

          // Verify, that attribute value is added
          attrs = ctx.getAttributes( RDN_TORI_AMOS );
          Attribute attr = attrs.get( "userCertificate" );
          assertNotNull( attr );
          assertTrue( attr.contains( newValue ) );
          byte[] certificate = (byte[])attr.get();
          assertTrue( Arrays.equals( newValue, certificate ) );
          assertEquals( 1, attr.size() );
          }

          Show
          Emmanuel Lecharny added a comment - The following test demonstrates that the userCertificate;binary attribute is working on the server, and that the certificate is not modified. There may be a bug in Studio, however. public void testAddNewBinaryAttributeValue() throws NamingException { // Add a binary attribute byte[] newValue = new byte[] {0x00, 0x01, 0x02, 0x03} ; Attributes attrs = new AttributesImpl( "userCertificate;binary", newValue ); ctx.modifyAttributes( RDN_TORI_AMOS, DirContext.ADD_ATTRIBUTE, attrs ); // Verify, that attribute value is added attrs = ctx.getAttributes( RDN_TORI_AMOS ); Attribute attr = attrs.get( "userCertificate" ); assertNotNull( attr ); assertTrue( attr.contains( newValue ) ); byte[] certificate = (byte[])attr.get(); assertTrue( Arrays.equals( newValue, certificate ) ); assertEquals( 1, attr.size() ); }
          Hide
          Emmanuel Lecharny added a comment -

          Do you mean that if you store a valid certificate, and get it back, it has been modified ?

          Can you attach a valid certificate that we can test the procedure ?

          Another possibility s that Studio messes wit the certificate. We have to check that.

          I will check if we have a unit test for certificate storing, and if not, I will add one.

          Show
          Emmanuel Lecharny added a comment - Do you mean that if you store a valid certificate, and get it back, it has been modified ? Can you attach a valid certificate that we can test the procedure ? Another possibility s that Studio messes wit the certificate. We have to check that. I will check if we have a unit test for certificate storing, and if not, I will add one.
          Hide
          Chris Trobridge added a comment -

          My initial testing suggests that I can use Apache Directory Studio to import ldif files with attributes named with the ";binary" suffix but I haven't managed to retrieve the attributes correctly. The retrieved attributes aren't valid certificates.

          Browsing in studio looks it like they're corrupt, eg all my certificates start with repears of "30 ef bf bd" and there are way more "ef bf bd" sequences in the data than I'd expect. However, the data is the expected length.

          Show
          Chris Trobridge added a comment - My initial testing suggests that I can use Apache Directory Studio to import ldif files with attributes named with the ";binary" suffix but I haven't managed to retrieve the attributes correctly. The retrieved attributes aren't valid certificates. Browsing in studio looks it like they're corrupt, eg all my certificates start with repears of "30 ef bf bd" and there are way more "ef bf bd" sequences in the data than I'd expect. However, the data is the expected length.
          Hide
          Alex Karasulu added a comment -

          Did we fix this? I thought we had something in already. Can I get a status on this?

          Show
          Alex Karasulu added a comment - Did we fix this? I thought we had something in already. Can I get a status on this?
          Hide
          Emmanuel Lecharny added a comment -

          Will be partially available in 1.5.2, but the definitive fix is due for the next version.

          Show
          Emmanuel Lecharny added a comment - Will be partially available in 1.5.2, but the definitive fix is due for the next version.
          Hide
          Emmanuel Lecharny added a comment -

          We have added some partial support of ';binary' option for attributes, it will be available in 1.5.2 (expected in march)

          Show
          Emmanuel Lecharny added a comment - We have added some partial support of ';binary' option for attributes, it will be available in 1.5.2 (expected in march)

            People

            • Assignee:
              Emmanuel Lecharny
              Reporter:
              Chris Trobridge
            • Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development