Secure passwordless logins with FIDO2 and LDAP
Access Granted
Recently, FIDO2 and the passwordless authentication that goes with it have been in focus. As long as you base your login on a flexible database system, you can simply add the required fields for one or more public keys. To store the required information in Lightweight Directory Access Protocol (LDAP), as well, you need to extend the schema and define your own object and attribute types.
FIDO2 is a milestone of passwordless authentication. When logging in, the user's browser receives a challenge and has to sign it with the user's private key so that the service provider can validate the signature against the stored public keys. If validation is successful, the login is considered complete.
One advantage of public key procedures such as FIDO2 is that service providers and users no longer have to share a secret, including secrets that are used for two-factor authentication. Therefore, these secrets can no longer be lost on either side. In case of an attack, all the attacker gets is a user's public key, and as the name suggests, this key can be widely known. Logging in to the service itself or to other services in which the user has deposited the same key remains impossible. To make sure a user is not left without access if a private key is lost, most FIDO2 implementations allow the direct storage of several public keys or different security tokens.
Extending the LDAP Schema
The LDAP schemas normally available (e.g., from the OpenLDAP distribution) do not provide the objects needed to store the information required for FIDO2 authentication directly within the directory. Like other database systems, LDAP lets you extend the set of storable objects by adding an appropriate schema. Once you have successfully loaded a schema, you can create the objects to match directly afterward. To prevent confusion, each schema is assigned an individual identification number. Globally unique object identifiers (OIDs) have become established for this purpose.
If you have ever worked with the Simple Network Management Protocol (SNMP), you are probably familiar with OIDs. In SNMP, they are used intensively for the queries and responses of the network management protocol. However, OIDs are also used elsewhere, such as, in technical standardization or in requests for comments (RFCs). In particular, Abstract Syntax Notation One (ASN.1), which is often used in such documents, also uses OIDs. To define your own objects and attributes in an LDAP schema, you can now request a personal OID range from the Internet Assigned Numbers Authority (IANA) [1]. The allocation of a subtree for your own OIDs is very convenient and can be accomplished within a matter of days.
For the FIDO2 schema in this article, I have already assigned OIDs from my assigned namespace. You can use these, of course, as long as you do not have to adapt the schema again, which is the only way to ensure global uniqueness.
FIDO2 Schema Structure
To map FIDO2 to an LDAP directory, you need different objects and attributes. First, you need to define the public key as an attribute:
attributetype ( 1.3.6.1.4.1.56227.1.1.1 NAME 'fido2pubkey' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )
The OID in the first line is the unique ID of this attribute type. The name of the attribute is arbitrary; in this scenario, I am prefixing all assigned names with fido2
for ease of recognition. The syntax specification defines the type of data that will be stored in this object. The value specified is from the namespace belonging to Mark Wahl [2], one of the authors of the LDAPv3 standard, and indicates that binary data is stored in this attribute. The SINGLE-VALUE
specification means that this attribute can be contained only once in the parent object.
The SINGLE-VALUE
in the definition is then used to define the identifier of the public key that the security tokens specifically use when selecting the private key:
attributetype ( 1.3.6.1.4.1.56227.1.1.2 NAME 'fido2credentialId' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
This identifier identifies the entire key pair. The specified syntax OID defines an IA5 string, an ASCII-compatible character set, as required by the FIDO2 specification. This attribute can also only exist once in the parent object.
Now you need to combine the public key with the identifier in the resulting object type to define this object for FIDO2 authentication and specify a parent object type, in the sense of an inheritance hierarchy, with SUP top
:
objectclass ( 1.3.6.1.4.1.56227.1.1.4 NAME 'fido2credential' SUP top STRUCTURAL MUST ( fido2credentialId $ fido2pubkey) MAY ( fido2credentialDescription ))
Objects defined as STRUCTURAL
are combined from other object and attribute types. The specifications of MUST
and MAY
define the mandatory and optional attributes of your object. The finished fido2credential
object thus has to consist of the two attributes fido2credentialId
and fido2pubkey
that were defined earlier.
Optionally, an attribute of the type fido2credentialDescription
is specified, which can be used to distinguish the different public keys:
attributetype ( 1.3.6.1.4.1.56227.1.1.1.3 NAME 'fido2credentialDescription' EQUALITY caseExactMatch ORDERING caseExactOrderingMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
This method lets users manage different key pairs themselves. The user can freely choose the names and use them to remove lost or unused key pairs from their account.
The schema attributes EQUALITY
, ORDERING
, and SUBSTR
describe rules for finding, comparing, and sorting the values of this type. In this example, to distinguish between upper- and lowercase descriptions. The specified OID syntax defines a UTF-8-encoded string.
To use the types developed here, you need to group them in a schema file and import them to your LDAP server with ldapadd
; then, you can assign objects of type fido2credential
to your users. Remember to adapt the access authorizations of your LDAP server. In particular, you need to make sure that users can only write their own public keys, whereas read access to them may be less restrictive and may even have to be, depending on the implementation of the login process.
Conclusions
FIDO2 lets users log in to their accounts securely without a password. If you use LDAP for authentication in your environment and want to use FIDO2, you can use the schema created in this article to establish the objects and attributes required for FIDO2 authentication in your directory. If you need additional elements in your schema, just apply for a separate section in the IANA OID tree and create additional unique object IDs there.
Infos
- Request OID area: https://pen.iana.org/pen/PenApplication.page
- Mark Wahl namespace: https://www.alvestrand.no/objectid/1.3.6.1.4.1.1466.115.121.1.html
Buy this article as PDF
(incl. VAT)