Discussion:
[Freeipa-devel] [RFC] Matching and Mapping Certificates
Sumit Bose
2016-10-06 10:49:30 UTC
Permalink
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=***@example.com', certtool as 'EMAIL=***@example.com' and certutil as 'E=***@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.
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Rob Crittenden
2016-10-06 14:33:48 UTC
Permalink
Post by Sumit Bose
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 =
* 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 ====
* 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.
* <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)
* 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
=== 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
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2016-10-06 15:57:13 UTC
Permalink
Post by Rob Crittenden
Hi,
Wow, this is really great.
Hi Rob,

thank you for the feedback.
Post by Rob Crittenden
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.
Do I understand it correctly that you are looking for rules which will
always and only match for certificate from a given issuer? E.g. if all
matching rules will have the <ISSUER> set like

<ISSUER>CN=ca,DC=abd,DC=com<EKU>clientAuth
<ISSUER>CN=ca,DC=def,DC=com<EKU>msScLogin

certificates from the abc issue must have clientAuth set to be valid for
authentication and certificates from issuer def must have msScLogin set.
But you are right, if one rule does not have issuer set like

<ISSUER>CN=ca,DC=abd,DC=com<EKU>clientAuth
<EKU>msScLogin

then a certificate from issuer abc which does not have clientAuth set
but msScLogin would be accepted as well.

Do you think it would help to make <ISSUER> a required field but allow
that the lazy admin can just enter a '*' to match any issuer?
Post by Rob Crittenden
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.
This happens when no mapping rule is given. Then SSSD will fall
back to search/map the user with the whole certificate. And if the
certificate is removed from the LDAP entry of the user Smartcard
authentication will fail as soon as the user entry in the cache of SSSD
is expired.

bye,
Sumit
Post by Rob Crittenden
rob
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Rob Crittenden
2016-10-06 17:48:02 UTC
Permalink
Post by Sumit Bose
Post by Rob Crittenden
Hi,
Wow, this is really great.
Hi Rob,
thank you for the feedback.
Post by Rob Crittenden
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.
Do I understand it correctly that you are looking for rules which will
always and only match for certificate from a given issuer? E.g. if all
matching rules will have the <ISSUER> set like
<ISSUER>CN=ca,DC=abd,DC=com<EKU>clientAuth
<ISSUER>CN=ca,DC=def,DC=com<EKU>msScLogin
certificates from the abc issue must have clientAuth set to be valid for
authentication and certificates from issuer def must have msScLogin set.
But you are right, if one rule does not have issuer set like
<ISSUER>CN=ca,DC=abd,DC=com<EKU>clientAuth
<EKU>msScLogin
then a certificate from issuer abc which does not have clientAuth set
but msScLogin would be accepted as well.
Do you think it would help to make <ISSUER> a required field but allow
that the lazy admin can just enter a '*' to match any issuer?
Yes, that is basically what I was proposing, and mostly to ensure that
the data is stored in such away that adding rules per issuer would be
easy/possible in the future. It probably hits 80/20 by supporting only a
single set of rules for the 1.0 release.
Post by Sumit Bose
Post by Rob Crittenden
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.
This happens when no mapping rule is given. Then SSSD will fall
back to search/map the user with the whole certificate. And if the
certificate is removed from the LDAP entry of the user Smartcard
authentication will fail as soon as the user entry in the cache of SSSD
is expired.
I wonder if some might want both at the same time. Match using rules and
then also confirm the certificate matches, if it is available in the
entry, with a require/optional setting to decide what to do in case the
cert isn't in LDAP.

rob
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Fraser Tweedale
2016-10-06 23:53:04 UTC
Permalink
Post by Sumit Bose
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.
* <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.
A counter-proposal w.r.t. DN mapping:

<SUBJECT:OID:ldapAttributeName>

Where OID is either an actual OID or the corresponding string i.e.
"CN", "O", etc. This would extract the "most specific" (leftmost in
the LDAP sense, rightmost in the X.500 sense) attribute value of the
specified type from the Subject DN.

IMO this would cover most DN mapping use cases whilst avoiding regex
or confusion about RDN order. Therefore your original example of:

<SUBJECT:samAccountName>/^CN=\([^,]*\).*$/\1/

can be accomplished with:

<SUBJECT:CN:samAccountName>

In the spirit of "make the simple things simple, and the hard things
possible" it is probably necessary to retain the regex variant to
handle more complex DN mapping use cases, e.g. where there are
multiple occurrences of a single attribute type, a particular fixed
RDN must be matched, etc.

w.r.t. SAN mapping, I concur that search/replace is probably not
needed.

Cheers,
Fraser
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Alexander Bokovoy
2016-10-07 06:35:00 UTC
Permalink
Post by Fraser Tweedale
Post by Sumit Bose
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.
* <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.
<SUBJECT:OID:ldapAttributeName>
Where OID is either an actual OID or the corresponding string i.e.
"CN", "O", etc. This would extract the "most specific" (leftmost in
the LDAP sense, rightmost in the X.500 sense) attribute value of the
specified type from the Subject DN.
IMO this would cover most DN mapping use cases whilst avoiding regex
<SUBJECT:samAccountName>/^CN=\([^,]*\).*$/\1/
<SUBJECT:CN:samAccountName>
In the spirit of "make the simple things simple, and the hard things
possible" it is probably necessary to retain the regex variant to
handle more complex DN mapping use cases, e.g. where there are
multiple occurrences of a single attribute type, a particular fixed
RDN must be matched, etc.
w.r.t. SAN mapping, I concur that search/replace is probably not
needed.
How all these syntax extensions are going to handle multi-valued RDN?
--
/ Alexander Bokovoy
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Fraser Tweedale
2016-10-10 00:41:14 UTC
Permalink
Post by Alexander Bokovoy
Post by Fraser Tweedale
Post by Sumit Bose
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.
* <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.
<SUBJECT:OID:ldapAttributeName>
Where OID is either an actual OID or the corresponding string i.e.
"CN", "O", etc. This would extract the "most specific" (leftmost in
the LDAP sense, rightmost in the X.500 sense) attribute value of the
specified type from the Subject DN.
IMO this would cover most DN mapping use cases whilst avoiding regex
<SUBJECT:samAccountName>/^CN=\([^,]*\).*$/\1/
<SUBJECT:CN:samAccountName>
In the spirit of "make the simple things simple, and the hard things
possible" it is probably necessary to retain the regex variant to
handle more complex DN mapping use cases, e.g. where there are
multiple occurrences of a single attribute type, a particular fixed
RDN must be matched, etc.
w.r.t. SAN mapping, I concur that search/replace is probably not
needed.
How all these syntax extensions are going to handle multi-valued RDN?
In the variant I proposed, it is handled fine because it selects the
"most specific" occurrence of that attribute type. An attribute
type cannot appear twice in the same RDN so this is unambiguous.

For the regex variant, because `RDN ::= SET OF AVA' we would have to
ensure that the stringified DN uses a deterministic order for
attribute types (probably lexicographic order on corresponding LDAP
attribute name) within a multi-valued RDN and clearly document this.
It will be up to admins to define the correct regex based on naming
of the certificates they use.

Cheers,
Fraser
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2016-10-11 11:37:09 UTC
Permalink
Post by Sumit Bose
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.

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>

===== 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.

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.
* <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 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.

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.

===== 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=***@example.com', certtool as 'EMAIL=***@example.com' and certutil as 'E=***@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.


=== 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.
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2016-10-13 16:52:35 UTC
Permalink
Post by Sumit Bose
Post by Sumit Bose
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.


=== 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>

===== 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.

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.

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=***@example.com', certtool as 'EMAIL=***@example.com' and certutil as 'E=***@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=***@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.
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2016-10-17 07:50:57 UTC
Permalink
Hi,
Post by Sumit Bose
Post by Sumit Bose
Post by Sumit Bose
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 =
* 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 ====
* 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?
Post by Sumit Bose
=== 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.
Post by Sumit Bose
<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.
Post by Sumit Bose
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}*))
Post by Sumit Bose
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 =====
* <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)
* 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
==== 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
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
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Rob Crittenden
2016-10-17 14:50:54 UTC
Permalink
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.

rob
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2016-10-18 05:34:48 UTC
Permalink
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2017-01-02 08:18:47 UTC
Permalink
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2017-01-05 09:39:34 UTC
Permalink
Post by Jan Cholasta
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
I'm fine with an optional(?) priority as well. Since priorities are
already used in the pwpolicies this should be already known to the
experienced admin. I guess we just have stick with "A lower value
indicates a higher priority" to not confuse users. That's why I think
that the priority should be optional here and a missing value indicates
the lowest priority (default rules).

Are you thinking of using the CoS scheme here as well would a priority
attribute be sufficient because we do not want to reference internal
objects in the mapping rules?

bye,
Sumit
Post by Jan Cholasta
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2017-01-06 07:50:14 UTC
Permalink
Post by Sumit Bose
Post by Jan Cholasta
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
I'm fine with an optional(?) priority as well. Since priorities are
already used in the pwpolicies this should be already known to the
experienced admin. I guess we just have stick with "A lower value
indicates a higher priority" to not confuse users. That's why I think
that the priority should be optional here and a missing value indicates
the lowest priority (default rules).
In pwpolicy and sudorule, the priority is required and has to be unique.
Maybe we should do this for certificate mapping rules as well?
Post by Sumit Bose
Are you thinking of using the CoS scheme here as well would a priority
attribute be sufficient because we do not want to reference internal
objects in the mapping rules?
I'm not sure how CoS would be helpful here, I think a simple interger
attribute would be perfectly sufficient.
Post by Sumit Bose
bye,
Sumit
Post by Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2017-01-06 09:30:37 UTC
Permalink
Post by Jan Cholasta
Post by Sumit Bose
Post by Jan Cholasta
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
I'm fine with an optional(?) priority as well. Since priorities are
already used in the pwpolicies this should be already known to the
experienced admin. I guess we just have stick with "A lower value
indicates a higher priority" to not confuse users. That's why I think
that the priority should be optional here and a missing value indicates
the lowest priority (default rules).
In pwpolicy and sudorule, the priority is required and has to be unique.
Maybe we should do this for certificate mapping rules as well?
I think there is no requirement that only a single rule should match
hence I think the priority here must not be unique.
Post by Jan Cholasta
Post by Sumit Bose
Are you thinking of using the CoS scheme here as well would a priority
attribute be sufficient because we do not want to reference internal
objects in the mapping rules?
I'm not sure how CoS would be helpful here, I think a simple interger
attribute would be perfectly sufficient.
I agree.

bye,
Sumit
Post by Jan Cholasta
Post by Sumit Bose
bye,
Sumit
Post by Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2017-01-09 07:46:22 UTC
Permalink
Post by Sumit Bose
Post by Jan Cholasta
Post by Sumit Bose
Post by Jan Cholasta
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
I'm fine with an optional(?) priority as well. Since priorities are
already used in the pwpolicies this should be already known to the
experienced admin. I guess we just have stick with "A lower value
indicates a higher priority" to not confuse users. That's why I think
that the priority should be optional here and a missing value indicates
the lowest priority (default rules).
In pwpolicy and sudorule, the priority is required and has to be unique.
Maybe we should do this for certificate mapping rules as well?
I think there is no requirement that only a single rule should match
hence I think the priority here must not be unique.
Is there a requirement that it must be possible for multiple rules to
match? If not, we could begin with a simpler (for admin) solution with
unique priorities and lift the restriction later when/if it becomes
necessary. But I don't have a strong opinion on this.
Post by Sumit Bose
Post by Jan Cholasta
Post by Sumit Bose
Are you thinking of using the CoS scheme here as well would a priority
attribute be sufficient because we do not want to reference internal
objects in the mapping rules?
I'm not sure how CoS would be helpful here, I think a simple interger
attribute would be perfectly sufficient.
I agree.
bye,
Sumit
Post by Jan Cholasta
Post by Sumit Bose
bye,
Sumit
Post by Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2017-01-20 09:34:46 UTC
Permalink
Post by Sumit Bose
Post by Jan Cholasta
Post by Sumit Bose
Post by Jan Cholasta
Post by Jan Cholasta
Post by Rob Crittenden
Post by Jan Cholasta
Hi,
Post by Sumit Bose
===== 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.
The use cases I've seen haven't had to do with priority, though that
would be a nice enhancement, but with only allowing certificates issued
by a specific CA to be allowed (this is pretty common in web servers).
Being able to say "only do the matching on certificates issued by foo"
is valuable.
Sure, I'm not suggesting that matching by issuer should be removed, only
that rule precedence should not be determined by the issuer field setting.
Bump. Sumit, what is your opinion on this?
I'm fine with an optional(?) priority as well. Since priorities are
already used in the pwpolicies this should be already known to the
experienced admin. I guess we just have stick with "A lower value
indicates a higher priority" to not confuse users. That's why I think
that the priority should be optional here and a missing value indicates
the lowest priority (default rules).
In pwpolicy and sudorule, the priority is required and has to be unique.
Maybe we should do this for certificate mapping rules as well?
I think there is no requirement that only a single rule should match
hence I think the priority here must not be unique.
Is there a requirement that it must be possible for multiple rules to match?
If not, we could begin with a simpler (for admin) solution with unique
priorities and lift the restriction later when/if it becomes necessary. But
I don't have a strong opinion on this.
me neither (I was hoping other people might chime in as well)

My reasoning just was that not requiring uniqueness is more flexible
(but of course it is easier to lift the restriction later than enforce
it later). Additionally imo it would be simpler for the admin because
the admin does not have to think about how to order a list of rules
which are logically on the same level (e.g. rules for different
issuers). But as said I do not have a strong opinion here either.

bye,
Sumit
Post by Sumit Bose
Post by Jan Cholasta
Post by Sumit Bose
Are you thinking of using the CoS scheme here as well would a priority
attribute be sufficient because we do not want to reference internal
objects in the mapping rules?
I'm not sure how CoS would be helpful here, I think a simple interger
attribute would be perfectly sufficient.
I agree.
bye,
Sumit
Post by Jan Cholasta
Post by Sumit Bose
bye,
Sumit
Post by Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2016-11-25 13:19:10 UTC
Permalink
Bump, Sumit, have you seen my comments? I haven't heard back from you.
Post by Jan Cholasta
Hi,
Post by Sumit Bose
Post by Sumit Bose
Post by Sumit Bose
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 =
*
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
* 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?
Post by Sumit Bose
=== 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.
Post by Sumit Bose
<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.
Post by Sumit Bose
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
(&(someAttr={issuer})(someOtherAttr=*{subject:O.I.D}*))
Post by Sumit Bose
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
* <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
avoid attribute names or only the ones from
* 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 =
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
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
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2016-11-25 14:55:43 UTC
Permalink
Post by Jan Cholasta
Bump, Sumit, have you seen my comments? I haven't heard back from you.
Yes, I've seen it and added a comment about it on the page
https://fedorahosted.org/sssd/wiki/DesignDocs/MatchingAndMappingCertificates#Matching-alternativeRFC4523syntax
To cut it short I would prefer to use a standard, but I think RFC4523
currently does nit meet out needs. But I would be happy if there are
ways to mitigate my concerns.

I'm working on updating and changing other sections as well and planned
to reply when I'm done with the other sections as well.

bye,
Sumit
Post by Jan Cholasta
Post by Jan Cholasta
Hi,
Post by Sumit Bose
Post by Sumit Bose
Post by Sumit Bose
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 =
*
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
* 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?
Post by Sumit Bose
=== 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.
Post by Sumit Bose
<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.
Post by Sumit Bose
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
(&(someAttr={issuer})(someOtherAttr=*{subject:O.I.D}*))
Post by Sumit Bose
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
* <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
avoid attribute names or only the ones from
* 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 =
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
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
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jan Cholasta
2016-12-05 13:05:51 UTC
Permalink
Post by Sumit Bose
Post by Jan Cholasta
Bump, Sumit, have you seen my comments? I haven't heard back from you.
Yes, I've seen it and added a comment about it on the page
https://fedorahosted.org/sssd/wiki/DesignDocs/MatchingAndMappingCertificates#Matching-alternativeRFC4523syntax
To cut it short I would prefer to use a standard, but I think RFC4523
currently does nit meet out needs. But I would be happy if there are
ways to mitigate my concerns.
What I actually had in mind was not to use the full RFC 4523 syntax, but
rather re-use the concepts used in it - for example, instead of using
regular expressions to match subject names, we could use a scheme based
on name constraints, where the subject name is matched using base +
minimum distance + maximum distance, which could look like this, written
down using glob-like syntax:

directoryName=CN=a,O=b
(base = CN=a,O=b, minimum distance = 0, maximum distance = 0)

directoryName=*,O=b
(base = O=b, minimum distance = 1, maximum distance = 1)

directoryName=*,*,O=b
(base = O=b, minimum distance = 2, maximum distance = 2)

directoryName=**,*,O=b
(base = O=b, minimum distance = 1, maximum distance unspecified)
Post by Sumit Bose
I'm working on updating and changing other sections as well and planned
to reply when I'm done with the other sections as well.
OK, thanks for the heads up.
Post by Sumit Bose
bye,
Sumit
Post by Jan Cholasta
Post by Jan Cholasta
Hi,
Post by Sumit Bose
Post by Sumit Bose
Post by Sumit Bose
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 =
*
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
* 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?
Post by Sumit Bose
=== 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.
Post by Sumit Bose
<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.
Post by Sumit Bose
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
(&(someAttr={issuer})(someOtherAttr=*{subject:O.I.D}*))
Post by Sumit Bose
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
* <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
avoid attribute names or only the ones from
* 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 =
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
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
--
Jan Cholasta
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Simo Sorce
2016-10-17 15:50:32 UTC
Permalink
Post by Sumit Bose
==== 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/.
A few more pointers Sumit:
- This describes what is allowed for users:
https://msdn.microsoft.com/en-us/library/ms677943%28v=vs.85%29.aspx

- This describes a use for devices:
https://msdn.microsoft.com/en-us/library/dn408946.aspx

- additional description specific for PKINIT:
https://msdn.microsoft.com/en-us/library/hh536384.aspx

- This is a good detailed overview of the Smart Card logon workflow in
windows, it describes Vista but I do not think it changed in fundamental
ways in following releases:
https://msdn.microsoft.com/en-us/library/bb905527.aspx

NOTE: Please look at the small paragraph named "Smart card logon across
forests", we definitely want to think about this problem as well from
the get-go and not try to retrofit something later on.


HTH,
Simo.
--
Simo Sorce * Red Hat, Inc * New York
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Jakub Hrozek
2017-04-07 08:38:55 UTC
Permalink
Post by Sumit Bose
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
I converted the page to pagure markdown:
https://docs.pagure.org/SSSD.sssd/design_pages/matching_and_mapping_certificates.html

There are no changes to the content except for fixing typos.
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Sumit Bose
2017-04-07 08:58:30 UTC
Permalink
Post by Jakub Hrozek
Post by Sumit Bose
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
https://docs.pagure.org/SSSD.sssd/design_pages/matching_and_mapping_certificates.html
There are no changes to the content except for fixing typos.
Thank you for doing the conversion and fixing the typos. I will now
update the page to reflect the current state of the code.

bye,
Sumit
Post by Jakub Hrozek
--
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
Loading...