Discussion:
Stateless PKINIT?
(too old to reply)
Yoann Gini
2024-03-13 19:10:22 UTC
Permalink
Hello,

I'm trying to achieve a deployment of Kerberos and PKINIT as some sort of authentication proxy. I'm working for an IDP startup.

Is there a way when using PKINIT to not need any internal list of principals but to rely on the validity of the certificate to proxy the certificate identity into the Kerberos ticket?

Here is the schema:
— the PKI issue a certificate for someone and maintain a CRL
— the IDP require SP NEGO for some route
— the KDC need to issue the needed TGT then TGS based on the identity in the certificate if CRL is OK
— IDP will then check information collected during SP NEGO to get the identity of the user and continue its work

In that context, the Kerberos realm is used only as some kind of protocolar authentication proxy that just need to convert an authenticated identity coming from a certificate intro a Kerberos ticket.

Is there a way to configure a KDC to behave like that?

Best regards
Yoann
Ken Hornstein
2024-03-14 19:27:45 UTC
Permalink
Post by Yoann Gini
Is there a way when using PKINIT to not need any internal list of
principals but to rely on the validity of the certificate to proxy the
certificate identity into the Kerberos ticket?
I know what all of those words are, but I'm unclear what they mean all
Post by Yoann Gini
— the KDC need to issue the needed TGT then TGS based on the identity
in the certificate if CRL is OK
To get a TGT issued you need to send an AS-REQ, that's going to have
a client principal in it, so normally that's already done. However,
you are allowed to set the canonicalization flag as part of the AS-REQ
message and the KDC can change the client principal.

Note: this is where we reach the limits of my experience, so other may
correct me on the following points. Also, I'm limiting my speaking to
the MIT Kerberos implementation.

It looks like there is some code in the MIT KDC to perform such
a lookup; the database plugin API contains a function called
krb5_db_get_s4u_x509_principal(), which takes a client certificate. But
neither of the current database implementations (db2 or LDAP) use that
plugin API today. Note that third-party code may already exist that
uses that API, but I am unfamiliar with it.

It looks like if you go that route you have to add that certificate
to the client request outside of PKINIT. In either case I do not
believe you can actually just stick the SPNEGO API as that PKINIT
would require initial ticket acquisition.

It feels like a large number of the pieces are there, but I am not
sure it's going to be turnkey.

--Ken
Greg Hudson
2024-03-14 20:56:37 UTC
Permalink
Post by Ken Hornstein
Post by Yoann Gini
Is there a way when using PKINIT to not need any internal list of
principals but to rely on the validity of the certificate to proxy the
certificate identity into the Kerberos ticket?
I know what all of those words are, but I'm unclear what they mean all
I believe Yoann is asking for a KDC configuration where the KDB contains
server principal entries (including a krbtgt entry) but no client
principal entries. PKINIT does not require client long-term keys, and
other client principal fields (except for the name) could be taken from
a template entry.

MIT krb5 does not currently have this ability with the built-in KDB
modules. It could be done with a custom KDB module, but that module
would also have to provide all of the regular KDB functionality for the
server principal entries, and the KDB interface isn't designed to be
stackable (meaning it isn't trivial to implement an overlay).

Alternatively, I think it would be a relatively simple change to the
core KDC code to support this: do_as_req.c:lookup_client() could look up
a template at a fixed name (WELLKNOWN/CLIENT-TEMPLATE or something) if
the regular client lookup fails, and substitute in the requested name.
Post by Ken Hornstein
It looks like there is some code in the MIT KDC to perform such
a lookup; the database plugin API contains a function called
krb5_db_get_s4u_x509_principal(), which takes a client certificate.
This KDB method is there to support S4U2Self requests where the
requesting server presents an X.509 certificate instead of a cient
principal name. It
Yoann Gini
2024-03-15 10:15:14 UTC
Permalink
Hi
Post by Ken Hornstein
Post by Yoann Gini
Is there a way when using PKINIT to not need any internal list of
principals but to rely on the validity of the certificate to proxy the
certificate identity into the Kerberos ticket?
I know what all of those words are, but I'm unclear what they mean all
I believe Yoann is asking for a KDC configuration where the KDB contains server principal entries (including a krbtgt entry) but no client principal entries. PKINIT does not require client long-term keys, and other client principal fields (except for the name) could be taken from a template entry.
Exactly

Informations about the principal (name and everything) could be extracted from the certificate. Principal and certificate contains the same informations.
MIT krb5 does not currently have this ability with the built-in KDB modules. It could be done with a custom KDB module, but that module would also have to provide all of the regular KDB functionality for the server principal entries, and the KDB interface isn't designed to be stackable (meaning it isn't trivial to implement an overlay).
OK, no overlay is a limitation here indeed, it would have been the best option to mix template based response and internal DB.
Alternatively, I think it would be a relatively simple change to the core KDC code to support this: do_as_req.c:lookup_client() could look up a template at a fixed name (WELLKNOWN/CLIENT-TEMPLATE or something) if the regular client lookup fails, and substitute in the requested name.
That's an idea. Branching core product is always a impactful option for the future when it's time to follow main branch evolution, but that could be an option.

Other option I wonder is using the LDAP backend to answer dynamic content (we have an LDAP gateway in our codebase, so we can use it as a backend API between MIT Kerberos and our identity store).

Doing so the main issue would be to know what Kerberos need to write, to handle it. LDAP Gateway for read only is easy, supporting write operation however requires more work to ensure we handle all supported scenarios by the requesters.

I guess here also, it's not possible to use normal DB for R/W and LDAP in RO?

Best regards
Yoann
Greg Hudson
2024-03-15 16:17:44 UTC
Permalink
Post by Yoann Gini
Informations about the principal (name and everything) could be
extracted from the certificate. Principal and certificate contains the
same informations.
To issue a ticket, the KDC doesn't need to know directory-type
information such as real names, but it does need to know
Kerberos-specific policy information like "how long can the ticket
expiration time be". That information could presumably be standardized
across clients, which is why I suggested a template principal.
Post by Yoann Gini
Other option I wonder is using the LDAP backend to answer dynamic
content (we have an LDAP gateway in our codebase, so we can use it as a
backend API between MIT Kerberos and our identity store).
Doing so the main issue would be to know what Kerberos need to write, to
handle it.
The KDC does not need to write to the KDB, although it will attempt to
do writes to maintain account lockout state (which is irrelevant to the
configuration at hand). Attempts to write can be disabled via the
settings documented here:

https://web.mit.edu/kerberos/krb5-latest/doc/admin/lockout.html#disable-lockout

When synthesizing a client principal entry (or creating a template), be
sure to include the KRB5_KDB_REQUIRES_PRE_AUTH and KRB5_KDB_DISALLOW_SVR
principal flags.
Yoann Gini
2024-03-15 16:19:08 UTC
Permalink
Post by Yoann Gini
Informations about the principal (name and everything) could be extracted from the certificate. Principal and certificate contains the same informations.
To issue a ticket, the KDC doesn't need to know directory-type information such as real names, but it does need to know Kerberos-specific policy information like "how long can the ticket expiration time be". That information could presumably be standardized across clients, which is why I suggested a template principal.
Understood!

That's and interesting lead here.
Post by Yoann Gini
Other option I wonder is using the LDAP backend to answer dynamic content (we have an LDAP gateway in our codebase, so we can use it as a backend API between MIT Kerberos and our identity store).
Doing so the main issue would be to know what Kerberos need to write, to handle it.
https://web.mit.edu/kerberos/krb5-latest/doc/admin/lockout.html#disable-lockout
When synthesizing a client principal entry (or creating a template), be sure to include the KRB5_KDB_REQUIRES_PRE_AUTH and KRB5_KDB_DISALLOW_SVR principal flags.
OK, thanks!

Loading...