RFC 2559

Internet X.509 Public Key Infrastructure Operational Protocols - LDAPv2

πŸ“… published April 1999, from ietf

RFC 2559: Internet X.509 Public Key Infrastructure Operational Protocols - LDAPv2 πŸŽ€

okay bestie, this one's giving "how PKI repos talk to clients" and it's SO good πŸ’… RFC 2559 came out in April 1999 as a Standards Track doc, written by S. Boeyen (Entrust), T. Howes (Netscape), and P. Richard (Xcert). It updates RFC 1778 πŸ¦‹ and it's part of the bigger IPKI operational stuff. Let's gooo ✨


Status of This Memo πŸ“œ

okay so this doc is a real Internet standards track protocol spec for the whole Internet community, and it's literally asking for discussion and suggestions to make it better 🫢 If you want to know where it stands in the standardization process, check the current edition of "Internet Official Protocol Standards" (STD 1). And yes, you can distribute it freely, no limits 🌸

Copyright (C) The Internet Society (1999). All Rights Reserved.

1. Abstract ✨

so the vibe here is: this protocol handles some of the operational needs of the Internet X.509 Public Key Infrastructure (IPKI) πŸ”₯ Specifically, it's about getting into PKI repositories so you can fetch PKI info and also manage that same info. The mechanism is built on LDAP v2 (from RFC 1777), and it's a profile of that protocol made for IPKI. It also updates the certificate and revocation list encodings from RFC 1778. Other PKIX operational stuff lives in separate docs, so don't look for it here 🧚

The key words 'MUST', 'REQUIRED', 'SHOULD', 'RECOMMENDED', and 'MAY' in this document are to be interpreted as described in RFC 2119. (yes this is the important bit, keep it in mind πŸ‘‘)

2. Introduction 🌈

this spec is one piece of a multi-part standard for building a PKI for the Internet πŸŽ€ It covers two big jobs: retrieving X.509 PKI info (certificates and CRLs included) from a repository, and adding, deleting, and modifying that info in a repository too. To make all that happen, it defines a profile based on LDAP version 2 πŸ’–

3. Model πŸ¦‹

the PKI components involved in PKIX operational protocol interactions (as defined in PKIX Part 1) are:

  • End Entities
  • Certification Authorities (CA)
  • Repository

so end entities and CAs using LDAPv2 pull PKI info from the repository, using a subset of LDAPv2 🧚

CAs fill up the repository with PKI info, also using a subset of LDAPv2 πŸ’…

4. Lightweight Directory Access Protocol (LDAP) πŸ’œ

this section is where the three main jobs get split up: fetching PKI info from a repository, and managing PKI info in a repository. A profile of LDAPv2 is defined for those services 🌸

Section 5 covers retrieving PKI info (a certificate, CRL, or other info of interest) from an entry in the repository, when the retrieving entity (an end entity or a CA) already knows the name of the entry. This is called "repository read" πŸ“–

Section 6 does the same job as Section 5, but for when the entry name is not known, and you only have some other related info, which can optionally be used as a filter against candidate entries in the repository. This is called "repository search" πŸ”

Section 7 handles CAs adding, deleting, and modifying PKI info (a certificate, CRL, or other info of interest) in the repository. This is called "repository modify" πŸ› οΈ

the subset of LDAPv2 needed for each of these functions is described below. Heads up: the repository search service is a superset of the repository read service in terms of the LDAPv2 functionality it needs πŸ‘‘

also, note that all tags are implicit by default in the ASN.1 definitions that follow πŸŽ€

5. LDAP Repository Read πŸ¦‹

so to pull info from an entry that matches the subject or issuer name of a certificate, you need a subset of these three LDAP operations:

  • BindRequest (and BindResponse)
  • SearchRequest (and SearchResponse)
  • UnbindRequest

the subset of each REQUIRED operation is laid out below πŸ’–

5.1. Bind 🌸

5.1.1. Bind Request ✨

the full LDAP v2 Bind Request is defined in RFC 1777.

an app providing an LDAP repository read service MUST implement this subset of the operation:

   BindRequest ::=
     [APPLICATION 0] SEQUENCE {
        version      INTEGER (2),
        name         LDAPDN, -- MUST accept NULL LDAPDN
        simpleauth [0] OCTET STRING  -- MUST accept NULL simple
        }

an app providing an LDAP repository read service MAY implement other aspects of the BindRequest too 🧚

different services can have different security needs πŸ” Some might allow anonymous search, while others need authentication. Services that allow anonymous search can choose to only allow search based on certain criteria, and not others.

an LDAP repository read service SHOULD implement some level of anonymous search access. An LDAP repository read service MAY implement authenticated search access too 🫢

5.1.2. Bind Response πŸ’…

the full LDAPv2 BindResponse is described in RFC 1777.

an app providing an LDAP repository read service MUST implement this entire protocol element. Only these error codes can come back from a Bind operation, though:

    success                      (0),
    operationsError              (1),
    protocolError                (2),
    authMethodNotSupported       (7),
    noSuchObject                 (32),
    invalidDNSyntax              (34),
    inappropriateAuthentication  (48),
    invalidCredentials           (49),
    busy                         (51),
    unavailable                  (52),
    unwillingToPerform           (53),
    other                        (80)

5.2.1. Search Request πŸ¦‹

the full LDAPv2 SearchRequest is defined in RFC 1777.

an app providing an LDAP repository read service MUST implement this subset of the SearchRequest:

   SearchRequest ::=
     [APPLICATION 3] SEQUENCE {
        baseObject     LDAPDN,
        scope             ENUMERATED {
                          baseObject   (0),
                                     },
        derefAliases   ENUMERATED {
                          neverDerefAliases   (0),
                                  },
        sizeLimit      INTEGER (0),
        timeLimit      INTEGER (0),
        attrsOnly      BOOLEAN, -- FALSE only
        filter         Filter,
        attributes     SEQUENCE OF AttributeType
                            }

   Filter ::=
     CHOICE {
       present        [7] AttributeType, -- "objectclass" only
              }

this subset of the LDAPv2 SearchRequest gives you the LDAPv2 "read" operation: a base object search with a filter that checks whether the objectClass attribute exists πŸ’–

an app providing an LDAP repository read service MAY implement other aspects of the SearchRequest too ✨

5.2.2. πŸ’œ

the full LDAPv2 SearchResponse is defined in RFC 1777.

an app providing an LDAP repository read service over LDAPv2 MUST implement the full SearchResponse 🫢

heads up on multivalued attributes like userCertificate: a SearchResponse with this attribute includes all values, as long as the requester has enough access permissions. The application or relying party may need to pick the right value to use 🧐 Also, getting a certificate from a named entry does NOT guarantee the certificate has that same Distinguished Name (DN). In some cases the subject DN in the certificate may be NULL πŸ™ˆ

5.3. Unbind 🌸

the full LDAPv2 UnbindRequest is defined in RFC 1777.

an app providing an LDAP repository read service MUST implement the full UnbindRequest πŸ‘‘

so to search, using arbitrary criteria, for an entry in a repository that holds a certificate, CRL, or other info of interest, you need a subset of these three LDAP operations:

  • BindRequest (and BindResponse)
  • SearchRequest (and SearchResponse)
  • UnbindRequest

the subset of each operation REQUIRED is given below πŸ’…

6.1. Bind 🌸

the BindRequest and BindResponse subsets needed here are the same as the ones described in Section 5.1.

the full LDAP v2 Bind Request is defined in RFC 1777.

6.2.1. Search Request πŸ¦‹

the full LDAPv2 SearchRequest is defined in RFC 1777.

an app providing an LDAP repository search service MUST implement this subset of the SearchRequest protocol unit:

   SearchRequest ::=
     [APPLICATION 3] SEQUENCE {
        baseObject     LDAPDN,
        scope          ENUMERATED {
                            baseObject     (0),
                            singleLevel    (1),
                            wholeSubtree   (2)
                                  },
        derefAliases   ENUMERATED {
                            neverDerefAliases     (0),
                                  },
        sizeLimit      INTEGER (0 .. maxInt),
        timeLimit      INTEGER (0 .. maxInt),
        attrsOnly      BOOLEAN,  -- FALSE only
        filter         Filter,
        attributes     SEQUENCE OF AttributeType
                             }

ok so ALL aspects of the SearchRequest MUST be supported, except for these:

  • Only the neverDerefAliases value of derefAliases needs to be supported
  • Only the FALSE value for attrsOnly needs to be supported

this subset is the more general search capability 🌈 It's a superset of the SearchRequest subset from Section 5.2.1. The extras added for this service are:

  • singleLevel and wholeSubtree scope need to be supported
  • sizeLimit is included
  • timeLimit is included
  • an enhanced filter capability

an app providing an LDAP repository search service MAY implement other aspects of the SearchRequest too πŸ’–

6.2.2. Search Response 🫢

the full LDAPv2 SearchResponse is defined in RFC 1777.

an app providing an LDAP repository search service over LDAPv2 MUST implement the full SearchResponse πŸ‘‘

6.3. Unbind 🌸

an app providing an LDAP repository search service MUST implement the full UnbindRequest ✨

7. LDAP Repository Modify πŸ› οΈ

so to add, delete, and modify PKI info in a repository, you need a subset of these LDAP operations:

  • BindRequest (and BindResponse)
  • ModifyRequest (and ModifyResponse)
  • AddRequest (and AddResponse)
  • DelRequest (and DelResponse
  • UnbindRequest

the subset of each operation REQUIRED is given below πŸ¦‹

7.1. Bind 🌸

the full LDAP v2 Bind Request is defined in RFC 1777.

an app providing an LDAP repository modify service MUST implement this subset of the operation:

   BindRequest ::=
     [APPLICATION 0] SEQUENCE {
        version      INTEGER (2),
        name         LDAPDN,
        simpleauth [0] OCTET STRING
        }

an LDAP repository modify service MUST implement authenticated access πŸ”

the BindResponse subsets needed are the same as the ones described in Section 5.1.2 🧚

7.2. Modify πŸ”₯

7.2.1. Modify Request ✨

okay so the full LDAPv2 ModifyRequest lives in RFC 1777 πŸ’… but if you're building an LDAP repository modify service, you MUST implement this smaller subset of the ModifyRequest protocol unit πŸŽ€

      ModifyRequest ::=
        [APPLICATION 6] SEQUENCE {
       object         LDAPDN,
       modification   SEQUENCE OF SEQUENCE {
                        operation     ENUMERATED {
                                        add     (0),
                                        delete  (1)
                                      },
                        modification  SEQUENCE {
                                      type   AttributeType,
                                      values SET OF
                                             AttributeValue
                                      }
                      }
        }

the whole ModifyRequest MUST be supported, except for this one little thing πŸ‘€

  • only the add and delete values of operation need to be supported 🫢

7.2.2. Modify Response πŸ¦‹

the full LDAPv2 ModifyResponse is defined in RFC 1777 πŸ“– and any app giving an LDAP repository modify service MUST implement the full ModifyResponse. no shortcuts, bestie πŸ’…

7.3. Add 🌸

7.3.1. Add Request 🧚

the full LDAPv2 AddRequest is defined in RFC 1777 ✨ and you MUST implement the full AddRequest if you're doing the LDAP repository modify service πŸ’–

7.3.2. Add Response πŸ“

the full LDAPv2 AddResponse is defined in RFC 1777 πŸŽ€ and the LDAP repository modify service MUST implement the full AddResponse. it's giving completeness πŸ‘‘

7.4. Delete πŸ—‘οΈ

7.4.1. Delete Request πŸ’œ

the full LDAPv2 DelRequest is defined in RFC 1777 πŸ’… and the LDAP repository modify service MUST implement the full DelRequest. periodt πŸ’€

7.4.2. Delete Response 🌈

the full LDAPv2 DelResponse is defined in RFC 1777 ✨ and an app providing the LDAP repository modify service MUST implement the full DelResponse. main character energy πŸ”₯

7.5. Unbind πŸ¦‹

an app providing the LDAP repository modify service MUST implement the full UnbindRequest. no cap, you need the whole thing 🫢

8. Non-standard attribute value encodings πŸŽ€

okay this part is lowkey important 😭 when attributes defined in X.500 get sent in LDAP requests and results, they're supposed to use the string representations from RFC 1778, The String Representation of Standard Attribute Syntaxes ✨ those string encodings were based on the X.500(1988) attribute definitions. so the string representations of the PKI information elements are for version 1 certificates and version 1 revocation lists πŸ™ˆ

but this spec uses version 3 certificates and version 2 revocation lists, as defined in X.509(1997) πŸ’– so the RFC 1778 string encoding is just not it for these attributes. not me getting the wrong format πŸ’€

so these attributes MUST be encoded using a syntax that's similar to the "Undefined" syntax from section 2.1 of RFC 1778 🌸 the values get encoded as if they were "OCTET STRING" values, and the string value of the encoding is the DER-encoding of the value itself 🧚 for example, when a CA writes a userCertificate to the repository, it generates a DER-encoding of the certificate and uses that as the value of the userCertificate attribute in the LDAP Modify request πŸ“ this style matches the encoding scheme proposed for LDAPv3, which is being defined in the IETF right now ✨

heads up 🚨 certificates and revocation lists get transferred with this mechanism instead of the RFC 1778 string encodings. client systems that don't understand this encoding may run into problems with these attributes 😭

9. Transport πŸš—

an app providing an LDAP repository read service, an LDAP repository search service, or an LDAP repository modify service MUST support LDAPv2 transport over TCP, as defined in Section 3.1 of RFC 1777 πŸ’œ that's the baseline, no debate 🫢

an app providing any of those three services MAY also support LDAPv2 transport over other reliable transports 🌈 totally optional, totally up to you ✨

10. Security Considerations πŸ”

okay buckle up bestie, this section is SERIOUS πŸ˜€πŸ’€

certificates and CRLs are the key info for the PKI service, and both of them are digitally signed pieces of information πŸ”₯ so additional integrity service is NOT REQUIRED πŸ¦‹ neither piece of info needs to be kept secret, and anonymous access for retrieval is generally fine, so privacy service is NOT REQUIRED for information retrieval requests 🌸

but CAs have extra requirements, including modifying PKI information 😳 simple authentication alone is not enough for these purposes πŸ™…β€β™€οΈ it is RECOMMENDED to use some stronger means of authentication, and/or (if simple authentication is used) some way of protecting the privacy of the password πŸ”’ for example: only accept modifications over physically secure networks, use IPsec, or use an SSH or TLS or SSL tunnel 🧚 without that kind of authentication, a denial-of-service attack could happen where the attacker swaps valid certificates for bogus ones πŸ’€πŸ˜­

for the LDAP repository modify service (profiled in section 7), there are some specific security considerations about access control πŸ”‘ these controls apply to a repository under the same management control as the CA 🏰 organizations running directories are NOT REQUIRED to give external CAs access permission to their directories πŸ™ˆ

the CA MUST have access control permissions that let it:

  • For CA entries:
    • add, modify and delete all PKI attributes for its own directory entry;
    • add, modify and delete all values of these attributes.
  • For CRL distribution point entries (if used):
    • create, modify and delete entries of object class cRLDistributionPoint immediately subordinate to its own entry;
    • add, modify and delete all attributes, and all values of these attributes for these entries.
  • For subscriber (end-entity) entries:
    • add, modify and delete the attribute userCertificate and all values of that attribute, issued by this CA to/from these entries.

the CA is the ONLY entity with these permissions πŸ‘‘ iykyk 🫢

an app providing LDAP repository read, LDAP repository search, or LDAP repository modify service as defined here is NOT REQUIRED to implement any extra security features beyond the ones described in this document, however an implementation SHOULD do so ✨ it's giving extra protection energy πŸ›‘οΈπŸ’…

11. References πŸ“š

  • [1] Yeong, Y., Howes, T. and S. Kille, "Lightweight Directory Access Protocol", RFC 1777, March 1995.
  • [2] Howes, T., Kille, S., Yeong, W. and C. Robbins, "The String Representation of Standard Attribute Syntaxes", RFC 1778, March 1995.
  • [3] Bradner, S., "Key Words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

12. Authors' Addresses πŸ§‘β€πŸ’»

Sharon Boeyen
Entrust Technologies Limited
750 Heron Road
Ottawa, Ontario
Canada K1V 1A7

EMail: sharon.boeyen@entrust.com


Tim Howes
Netscape Communications Corp.
501 E. Middlefield Rd.
Mountain View, CA 94043
USA

EMail: howes@netscape.com


Patrick Richard
Xcert Software Inc.
Suite 1001, 701 W. Georgia Street
P.O. Box 10145
Pacific Centre
Vancouver, B.C.
Canada V7Y 1C6

EMail: patr@xcert.com

Copyright (C) The Internet Society (1999). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

πŸ“¦ where this page comes from