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
= 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.
=== 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.
<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>
==== 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.
* <SUBJECT:ldapAttributeName>
* <SAN:O.I.D.:ldapAttributeName>
Currently I see no usage for <ISSUER>, <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.
'''Question, do we need search-and-replace at all (or at this stage)? 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 the following might be possible:
* <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.
'''
===== 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=u...@example.com', certtool as
'EMAIL=u...@example.com' and certutil as 'E=u...@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. Both 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.
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.
===== 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.
=== 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.
Wow, this is really great.
I think I'd pre-plan to support different configuration per issuer
subject, with one named default. It shouldn't be a lot more work and
will future-proof things for you, particularly in how the rules are
stored in LDAP.
I worry a bit about matching without comparing the certificate for the
case where you don't examine issuer.
You may want to have an option to require that the presented cert match
the one stored in LDAP (off by default). I realize that you specifically
mention this can be problematic, but it can also be quite useful. It can
be used, for example, to disable a login by removing the certificate
from the user's entry. It also ensures that some carefully crafted
certificate doesn't allow a bad actor to map to a user account.
rob
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org