[Freeipa-devel] [RFC] Matching and Mapping Certificates

Jan Cholasta jcholast at redhat.com
Fri Nov 25 13:19:10 UTC 2016


Bump, Sumit, have you seen my comments? I haven't heard back from you.

On 17.10.2016 09:50, Jan Cholasta wrote:
> Hi,
>
> On 13.10.2016 18:52, Sumit Bose wrote:
>> On Tue, Oct 11, 2016 at 01:37:09PM +0200, Sumit Bose wrote:
>>> On Thu, Oct 06, 2016 at 12:49:30PM +0200, Sumit Bose wrote:
>>>> Hi,
>>>>
>>>> I've started to write a SSSD design page about enhancing the current
>>>> mapping of certificates to users and how to select/match a suitable
>>>> certificate if multiple certificates are on a Smartcard.
>>>>
>>>> My currently thoughts and idea and be found at
>>>> https://fedorahosted.org/sssd/wiki/DesignDocs/MatchingAndMappingCertificates
>>>>
>>>> and for your convenience below as well.
>>>>
>>>> Comments and suggestions are welcome. Please let me know about
>>>> concerns,
>>>> alternatives and missing use-cases/user-stories.
>>>>
>>>> bye,
>>>> Sumit
>>>>
>>>
>>> Hi,
>>>
>>> Rob, Fraser, Alexander, thank you for your comments. I think both the
>>> issuer specific matching and the OID in the SUBJECT matching are good
>>> ideas. I updated the design page accordingly. The changes can be shown
>>> with
>>> https://fedorahosted.org/sssd/wiki/DesignDocs/MatchingAndMappingCertificates?action=diff&version=9&old_version=6
>>>
>>>
>>> The updated version can be found below as well. Of course more
>>> comments and
>>> suggestions are still very welcome.
>>>
>>
>> I did another update. A "Compatibility with Active Director" section is
>> added which made me realize that there are use-cases for using the
>> issuer in the mapping as well and the sub-strings in LDAP search filters
>> might be useful as well.
>>
>> The changes can be seen with
>> https://fedorahosted.org/sssd/wiki/DesignDocs/MatchingAndMappingCertificates?action=diff&version=10&old_version=9
>>
>>
>> Please let me know your comments and suggestions.
>>
>> bye,
>> Sumit
>>
>> = Matching and Mapping Certificates =
>>
>> Related ticket(s):
>>  *
>> http://www.freeipa.org/page/V4/User_Certificates#Certificate_Identity_Mapping
>>
>>
>> === Problem statement ===
>> ==== Mapping ====
>> Currently it is required that a certificate used for authentication is
>> either stored in the LDAP user entry or in a matching override. This
>> might not always be applicable and other ways are needed to relate a
>> user with a certificate.
>>
>> ==== Matching ====
>> Even if SSSD will support multiple certificates on a Smartcard in the
>> context of https://fedorahosted.org/sssd/ticket/3050 it might be
>> necessary to restrict (or relax) the current certificate selection in
>> certain environments.
>>
>> === Use cases ===
>> ==== Mapping ====
>> In some environments it might not be possible or would cause unwanted
>> effort to add certificates to the LDAP entry of the users to allow
>> Smartcard based authentication. Reasons might be:
>> * Certificates/Smartcards are issued externally
>> * LDAP schema extension is not possible or not allowed
>>
>> ==== Matching ====
>> A user might have multiple certificate on a Smartcard which are
>> suitable for authentication. But on some host in the environment only
>> certificates from a specific CA (while all other CAs are trusted as
>> well) or with some special extension should be valid for login.
>>
>> === Overview of the solution ===
>> To match a certificate a language/syntax has to be defined which
>> allows to reference items from the certificate and compare the values
>> with the expected data. To map the certificates to a user the
>> language/syntax should allow to relate certificate items with LDAP
>> attributes so that the value(s) from the certificate item can be used
>> in a LDAP search filter.
>
> Note that in some cases it might be possible to map a certificate to a
> user without having to do an extra LDAP search, for example when the
> certificate contains the principal name of the user. Does the design
> allow this? Or is there no extra LDAP search?
>
>>
>>
>> === Implementation details ===
>> ==== Matching ====
>> The pkinit plugin of MIT Kerberos must find a suitable certificate
>> from a Smartcard as well and has defined the following syntax (see the
>> pkinit_cert_match section of the krb5.conf man page or
>> http://web.mit.edu/Kerberos/krb5-1.14/doc/admin/conf_files/krb5_conf.html
>> for details). The main components are
>>
>> * <SUBJECT>regular-expression
>> * <ISSUER>regular-expression
>> * <SAN>regular-expression
>> * <EKU>extended-key-usage-list
>> * <KU>key-usage-list
>>
>> and can be grouped together with a prefixed '&&' (and) or '`||`' (or)
>> operator ('&&' is the default). If multiple rules are given they are
>> iterated with the order in the config file as long as a rule matches
>> exactly one certificate.
>>
>> '''Question: MIT Kerberos use case-sensitive matching and POSIX
>> Extended Regular Expression syntax, shall we do the same?'''
>>
>> While <SUBJECT> and <ISSUER> are (imo) already quite flexible I can
>> see some potential extensions for the other components.
>
> I don't think regular expressions are a particularly good choice for DN
> matching. It is difficult to express assertions which are quite natural
> for DNs (matching multi-attribute RDNs, matching the same attribute type
> by different identifiers, respecting the defined matching rules of
> attribute types) and at the same time it is easy to express assertions
> which do not make much sense for DNs (matching substrings in attribute
> names, matching accross multiple syntactical elements, etc.).
>
> That said, does the design have to be based on the MIT pkinit matching?
> To me it looks like something quickly hacked together rather than
> thoughtfully designed. I would personally base the design on the
> concepts of CertificateMatch, which is the standard way of matching
> certificates, defined in X.509, rather than reinvent the wheel.
>
>>
>> <EKU> and <KU> in MIT Kerberos only accept certain string values
>> related to some allowed values in those field as defined in
>> https://www.ietf.org/rfc/rfc3280.txt . The selection is basically
>> determined by what is supported on server side of the pkinit plugin of
>> MIT Kerberos. Since we plan to extend pkinit and support local
>> authentication without pkinit as well I would suggest to allow OID
>> strings for those components as well (the comparison is done on the
>> OID level nonetheless).
>>
>> The <SAN> component in MIT Kerberos only checks the otherName SAN
>> component for the id-pkinit-san OID as defined in
>> https://www.ietf.org/rfc/rfc4556.txt or the szOID_NT_PRINCIPAL_NAME
>> OID as mentioned in https://support.microsoft.com/en-us/kb/287547.
>> While this is sufficient for the default pkinit user case of MIT
>> Kerberos I would suggest to extend this component by allowing to
>> specific an OID with <SAN:O.I.D>
>>
>> ===== Issuer specific matching =====
>> Although the MIT Kerberos rules allow to select the issuer of a
>> certificate there are use cases where a more specific selection is
>> needed. E.g. if there are some default matching rules for all issuers
>> and some other issuer specific rules where the default rules should
>> not apply. To make this possible with the above scheme the default
>> rules must have an <ISSUER> clause which matches all but the issuer
>> with the specific rules. Writing regular-expressions to not match a
>> specific string or a list of strings is at least error-prone if not
>> impossible.
>>
>> To make it easier to define issuer specific rules and default rules at
>> the same time and optional issuer string can be added to the rule to
>> indicate that for the given issuer only those rules should be
>> considered. Given the use-case I think it is acceptable to require
>> that the full issuer must be specified here in LDAP order (see below)
>> and case-sensitive matching is used.
>
> This could also be solved by adding priority to rules - if two rules
> match, the one with higher priority (the issuer specific rule) is
> preferred over the one with lower priority (the default rule). IMO this
> is better than an optional issuer string as it offers greater flexibility.
>
>>
>> How the issuer string is linked to the matching rules depends on the
>> storage (LDAP or sssd.conf, see below for details).
>> ==== Mapping ====
>> Since different certificates, e.g. issued by different CAs, might have
>> different mapping rule, a matching rule must be added if there are
>> more than 1 mapping rule. A single mapping rule without a matching
>> rule might be used as default/catch-all rule in this case.
>>
>> If multiple rules matches the derived LDAP filter components can be
>> grouped with the or-operator "|".
>>
>> A mapping rule can use a similar syntax like the matching rule where
>> the LDAP attribute can be added with a ':', e.g.
>> * <ISSUER:O.I.D.:ldapAttributeName:*>
>> * <SUBJECT:O.I.D.:ldapAttributeName:*>
>> * <SAN:O.I.D.:ldapAttributeName:*>
>>
>> where O.I.D. is either the OID or name of a RDN type or the OID or
>> some well-known-name of the SAN component respectively. Since the
>> SUBJECT might contain multiple RDNs of the same type always the "most
>> specific" is selected because in general this will be the most suited
>> one to map the certificate to a specific user. "most specific" means
>> the last in X.500 order and the first in LDAP order (see discussion
>> below for details).
>>
>> If the O.I.D. is missing the full SUBJECT/ISSUER is used for mapping.
>> If 'DN' is used as ldapAttributeName SUBJECT is expected to be the DN
>> of the user. If the O.I.D. is missing in the SAN case the same default
>> as with matching (id-pkinit-san and szOID_NT_PRINCIPAL_NAME OID) is
>> used. If both SAN values can be found in the certificate and are
>> different the LDAP search filter will combine both with the or-operator.
>>
>> The optional '*' in the end indicates that a sub-string search
>> (ldapAttributeName=*value*) should be used and not an exact match
>> (ldapAttributeName=value). Please note that it depends on the
>> server-side definition of the LDAP attribute if case-sensitive or
>> case-insensitve matching is used.
>
> This seems like a rather quirky way to write down an LDAP filter. IMHO a
> better way would be to use a single attribute containing a filter
> template, e.g.:
>
>     (&(someAttr={issuer})(someOtherAttr=*{subject:O.I.D}*))
>
>>
>> Currently I see no usage for <KU> and <EKU> in mapping rules because
>> they do not contain any user-specific data. If at some point we will
>> have personal CAs we might consider to add <ISSUER> based mappings.
>>
>> ===== Future consideration =====
>> Most of the interesting values from the SAN should be directly
>> map-able to LDAP attributes. And processing the string representation
>> of <SUBJECT> might be tricky as discussed below. Nevertheless it might
>> be possible to add to following in a future release if more complex
>> operations on the values are needed:
>>
>> * <SUBJECT:ldapAttributeName>/regexp/replacement/
>> * <SAN:O.I.D.:ldapAttributeName>/regexp/replacement/
>>
>> where "/regexp/replacement/" stands for optional sed-like substitution
>> rules. E.g. a rule like
>> {{{
>> <SUBJECT:samAccountName>/^CN=\([^,]*\).*$/\1/
>> }}}
>> would take the subject string 'CN=Certuser,CN=Users,DC=example,DC=com'
>> from the certificate and generate a LDAP search filter component
>> '(samAccountName=Certuser)' which can be included in a LDAP search
>> filter which includes additional components like e.g. an objectClass.
>>
>> The search-and-replace does not has to be sed-like because afaik there
>> is not library which offers this and I would like to avoid
>> implementing it. GLib e.g. has
>> [https://developer.gnome.org/glib/stable/glib-Perl-compatible-regular-expressions.html#g-regex-replace
>> g_regex_replace]. Since we already have a GLib dependency in SSSD due
>> to soem utf8 helper functions using might be acceptable as well.
>> Nevertheless it would be nice to hear if there are alternative
>> libraries available as well.
>>
>> Maybe even search-and-replace are not sufficient for all cases and
>> something like embedded lua scripts are needed. But since certificate
>> mapping is about access control and authorization it should be always
>> considered if adding a new attribute to the users LDAP entry which
>> makes mapping easy and straight-forward wouldn't be the better solution.
>>
>> ===== Some notes about DNs =====
>> The X.500 family of standards define names as "SEQUENCE OF
>> RelativeDistinguishedName" where the sequence is "starting with the
>> root and ending with the object being named" (see X.501 section 9.2
>> for details). On the other hand RFC4514 section 2.1 says "Otherwise,
>> the output consists of the string encoding of each
>> RelativeDistinguishedName in the RDNSequence (according to Section
>> 2.2), starting with the last element of the sequence and moving
>> backwards toward the first." This means that the ASN.1 encoded issuer
>> and subject DN from the X.509 certificate can be either displayed as
>> string in the
>> * X.500 order: DC=com,DC=example,CN=users,CN=Certuser
>> or in the
>> * LDAP order: CN=Certuser,CN=Users,DC=example,DC=com
>>
>> As a consequence different tools will use a different order when
>> printing the issuer and subject DN. While NSS's certutil will use the
>> LDAP order, 'openssl x509' and gnutls's certtool will use the X.500
>> order (the latter might change due to
>> https://gitlab.com/gnutls/gnutls/issues/111).
>>
>> This makes it important to specific the order which is used by SSSD
>> for mapping and matching. I would prefer the LDAP order here. E.g. by
>> default the AD CA uses the DN of the users entry in AD as subject in
>> the issues certificate. So a matching rule like '<SUBJECT:dn>' could
>> tell SSSD to directly search the user based on its DN (which btw is
>> the original intention of the subject field in the certificate, only
>> that the DN should be looked up in a more general DAP as defined by
>> X.500 and not in the lightweight version called LDAP)
>>
>> Another issue is the limited set of attribute names/types required by
>> the RFCs (see section 4.1.2.4 of RFC 3280 and section 3 of RFC 4514).
>> If e.g. the deprecated OID
>> [http://www.oid-info.com/get/1.2.840.113549.1.9.1
>> 1.2.840.113549.1.9.1] is used all tools are able to identify it as an
>> email address but OpenSSL displays it as
>> 'emailAddress=user at example.com', certtool as 'EMAIL=user at example.com'
>> and certutil as 'E=user at example.com'. So matching rules should try to
>> avoid attribute names or only the ones from
>> [https://www.ietf.org/rfc/rfc4514.txt RFC 4514]:
>> * CN      commonName (2.5.4.3)
>> * L       localityName (2.5.4.7)
>> * ST      stateOrProvinceName (2.5.4.8)
>> * O       organizationName (2.5.4.10)
>> * OU      organizationalUnitName (2.5.4.11)
>> * C       countryName (2.5.4.6)
>> * STREET  streetAddress (2.5.4.9)
>> * DC      domainComponent (0.9.2342.19200300.100.1.25)
>> * UID     userId (0.9.2342.19200300.100.1.1)
>>
>> ==== About restricting or enforcing the mapping an matching any
>> further ====
>> The goal of the matching rules in MIT Kerberos is to select a single
>> certificate from a Smartcard which will then be used for PKINIT. Since
>> we already plan to enhance SSSD to support multiple certificates on a
>> Smartcard and if needed prompt the user which one to use for login we
>> should not enforce that the matching rules should return only a single
>> certificate or nothing.
>>
>> Similar we plan to enhance SSSD to use the same certificate to log in
>> with different user identities, e.g. as a user with standard
>> privileges or as a user with administrator privileges. So it can make
>> sense that multiple mapping rules apply to the same certificate and
>> the related LDAP search filter components are or-ed together.
>>
>> In many cases the login program will first ask for a user name which
>> will help to restrict the number of suitable certificates even further
>> and the mapping rules are only needed to check if the certificate
>> belongs to the user trying to log in.
>>
>> But gdm has a feature where gdm will detect when a Smartcard is
>> inserted and call PAM without a user name. In this case SSSD has to
>> determine the user name based on the certificates found on the
>> Smartcard. If in this case multiple valid certificates are on the card
>> and the mapping rules will return multiple users for each certificate
>> gdm has to display a quite long selection of certificate-user pairs
>> the user has to choose from.
>>
>> So it should be underlined in the documentation that the matching and
>> mapping rules should be detailed and specific so that for the given
>> environment they help to avoid cases where the user is prompted to
>> select a certificate (or user name in the gdm case) when trying to log
>> in.
>>
>> ==== Storing matching and mapping configuration ====
>> On the IPA server a new objectclass can be created to store an
>> matching-mapping rule pair together with a specific issuer. All
>> attributes are optional because a missing mapping rule would mean that
>> the user entry will be search with the whole certificate. A missing
>> matching rule will indicate catch-all rule with a default mapping. If
>> only a specific issuer is given certificates from this issuer must be
>> stored in the LDAP entry of the user to make authentication possible.
>>
>> Specifying matching-mapping rules in sssd.conf is a bit more
>> complicated because SSSD does not respect multiple entries with the
>> same keyword, only the last one is used. So all rules have to be added
>> to a single line. To give it a little bit of structure the rules can
>> be enclosed by curly-braces '{}{}{}' and each rule pair is separated
>> by a comma ','. A single rule in curly braces indicates a matching
>> rule and the mapping will be done with the whole certificate. A
>> default/catch-all mapping rule will start with an empty pair of curly
>> braces followed by a pair containing the mapping rule. Issuer specific
>> rules will have three pairs of curly braces where the first pair must
>> contain an issuer string.
>>
>> ===== Future considerations =====
>> If it turns out that this option is used quite often and it gets
>> complicated to manage a larger set of rules with it and storing the
>> rules in LDAP/IPA/AD is not an option we might add support to read the
>> rules from a separate file (certificate_rules =
>> FILE:///etc/sssd/cert_rules) with a more suitable format, e.g. ini
>> where a list can be defined by given the same option multiple times.
>>
>> ===== Examples =====
>> * '''certificate_rules = {<EKU>msScLogin}''': only allow certificates
>> with have the Microsoft OID for Smartcard logon
>> 1.3.6.1.4.1.311.20.2.2 set. use the whole certificate to look-up the
>> user. The same result can be achieved with
>> * '''certificate_rules = {<EKU>1.3.6.1.4.1.311.20.2.2}''': see above
>> * '''certificate_rules =
>> {<ISSUER>*my-company*<SAN:rfc822Name>*@my-company.com$}{<SAN:rfc822Name:mail>}''':
>> only allow certificates form the 'my-company' issuer which have an
>> email address from the 'my-company.com' domain in the rfc882Name SAN
>> attribute. Use the email address in a LDAP search filter
>> '(mail=email-address)' to find the matching user.
>>
>> ==== Compatibility with Active Directory ====
>> Active Directory uses a per-user LDAP attribute
>> [https://msdn.microsoft.com/en-us/library/cc220106.aspx
>> altSecurityIdentities] to allow arbitrary user-certificate mappings is
>> there is no suitable user-principal-name entry in the SAN of the
>> certificate.
>>
>> Unfortunately it is more or less undocumented how AD use the values of
>> this attribute. The best overview I found is in
>> https://blogs.msdn.microsoft.com/spatdsg/2010/06/18/howto-map-a-user-to-a-certificate-via-all-the-methods-available-in-the-altsecurityidentities-attribute/.
>>
>>
>> It looks like the most important variant is the issuer-subject pair.
>> This one is e.g. created when a certificate is added via the 'Name
>> Mappings' context menu entry in AD's 'Users and Computers' utility
>> ('Advanced Features' must be activated in the 'View' menu). The
>> attribute value might look like
>> {{{
>> altSecurityIdentities: X509:<I>O=Red Hat,OU=prod,CN=Certificate
>> Authority<S>DC
>>  =com,DC=redhat,OU=users,OID.0.9.2342.19200300.100.1.1=sbose,E=sbose at redhat.co
>>
>>  m,CN=Sumit Bose Sumit Bose
>> }}}
>> First it can be seen that X.500 ordering is used. Second, if RDN types
>> not explicitly mentioned in the RFCs are used, you are on your own. As
>> can be seen AD can translate the deprecated OID
>> [http://www.oid-info.com/get/1.2.840.113549.1.9.1
>> 1.2.840.113549.1.9.1] and uses 'E' as NSS. But the OID
>> [http://www.oid-info.com/get/0.9.2342.19200300.100.1.1
>> 0.9.2342.19200300.100.1.1] which is explicitly mentioned in RFC4514 is
>> not translated as UID but the plain OID syntax is used (my guess it
>> that Microsoft tries to be compatible with "older" versions because
>> the UID was added in RFC2253 from 1997 but was not present in the
>> RFC1779 from 1995 and RFC1485 from 1993).
>>
>> Nevertheless with the mapping rules described above a rule like
>> {{{
>> <ISSUER:O:altSecurityIdentities:*><SUBJECT:CN:altSecurityIdentities:*>
>> }}}
>> would product a LDAP search filter like
>> {{{
>> (&(altSecurityIdentities=*Red Hat*)(altSecurityIdentities=*Sumit Bose
>> Sumit Bose*))
>> }}}
>> which should quite reliable find the right LDAP entry.
>>
>> As an alternative it would be possible to add special mapping rules
>> like <ALT-SEC-ID-I-S:ldapAttributeName> which would try in a best
>> effort to produce the exact attribute value AD is using. This should
>> work reliable with standard RDN types (see above). I think an optional
>> 'ldapAttributeName' is useful here so that the same mapping rule can
>> be used with different LDAP servers (e.g. IPA) where user-specific
>> mapping attributes are used with the same content but a different
>> attribute name.
>>
>> According to the blob post describing altSecurityIdentities some other
>> additional mapping rules might be useful too. This will give us
>> * <ALT-SEC-ID-I-S:ldapAttributeName>
>> * <ALT-SEC-ID-S:ldapAttributeName>
>> * <ALT-SEC-ID-SKI:ldapAttributeName>
>> * <ALT-SEC-ID-I-SR:ldapAttributeName>
>> * <ALT-SEC-ID-SHA1-PUBKEY:ldapAttributeName>
>> * <ALT-SEC-ID-RFC822:ldapAttributeName>
>>
>> So far I didn't found a AD tool which creates to other mappings, if
>> you know one, please let me know.
>> === Configuration changes ===
>> Does your feature involve changes to configuration, like new options
>> or options changing values? Summarize them here. There's no need to go
>> into too many details, that's what man pages are for.
>>
>> === How To Test ===
>> This section should explain to a person with admin-level of SSSD
>> understanding how this change affects run time behaviour of SSSD and
>> how can an SSSD user test this change. If the feature is
>> internal-only, please list what areas of SSSD are affected so that
>> testers know where to focus.
>>
>> === How To Debug ===
>> Explain how to debug this feature if something goes wrong. This
>> section might include examples of additional commands the user might
>> run (such as keytab or certificate sanity checks) or explain what
>> message to look for.
>>
>> === Authors ===
>> Give credit to authors of the design in this section.
>>
>
> Honza
>


-- 
Jan Cholasta




More information about the Freeipa-devel mailing list