Re: Adding support for optimistic preauth to kinit
Greg Hudson <[email protected]> Sun, 4 Apr 2021 01:18:05 -0400
| Newsgroups | gmane.comp.encryption.kerberos.devel |
|---|---|
| Message-ID | <[email protected]> |
On 4/3/21 8:09 PM, Ken Hornstein wrote: >>From an architectural standpoint, the hard work is already done; the > library supports this via an already-exposed API in the get_init_creds > interface (krb5_get_init_creds_opt_set_preauth_list()). It's just > that kinit has no way to set this list. I think the problem is both harder and easier than this. Each preauth mechanism works differently, and some lend themselves to optimistic preauth better than others: * For encrypted timestamp and its FAST variant encrypted challenge, the KDC's initial method-data is empty, but is accompanied by etype-info containing the enctype, salt, and s2kparams. The client can cache those (but we don't any current mechanism for that) or try to guess them (default salt, no s2kparams, the client's preferred enctype), but it should be prepared to retry after getting the proper etype-info, and if the KDC is doing account lockout for the user principal, the optimistic failure will count as a strike. * For PKINIT the KDC's initial method-data is empty and the etype-info is not needed. The client needs some configuration and possibly a local password to unlock its private key, but there's no difference between optimistic PKINIT preauth and regular PKINIT preauth aside from the decision to do it. If optimistic PKINIT fails, it should not be retried as the method-data won't contain any new information. (There is a flow where PKINIT continues on a KDC error containing TD_DH_PARAMETERS or similar, but that's not the same as trying again using the KDC initial method-data.) * SPAKE is even simpler than PKINIT; the client needs no information or configuration to send an initial negotiation message. I had actually planned to make optimistic SPAKE happen by default until I realized it would prioritize SPAKE over PKINIT when the KDC thinks both are options. * For SAM-2, the KDC's initial method-data contains a challenge (including a checksum that can be dictionary-attacked to determine the password). The challenge cannot be guessed, so optimistic SAM-2 simply can't happen. * For FAST OTP, the KDC's initial method-data contains some challenge information which is mostly unused as we implemented it (and I don't think anyone else has implemented it). So it might be reasonable to do optimistic FAST OTP with no challenge data if asked for by the user, although the spec contains no guidance for doing so. On the flip side, the problem you stated isn't about reducing the number of round trips, so we don't necessarily need optimistic preauth. Giving kinit a way to choose between multiple credentials could be done in other ways, although we don't have any current gic_opt machinery for them. A path of lower resistance is to add an option to force a particular preauth mech (single choice, hard-failing if it isn't available or doesn't work). clpreauth modules already declare names like "pkinit" and "sam2" which could be matched against. This approach has the notable failing of requiring users to know something about preauth mechs--in particular, if the user wants to authenticate with just their password as registered with kpasswd, they need to know which of three different preauth mechs to use (encrypted_timestamp, encrypted_challenge, and spake) based on specific knowledge of their realm and client capabilities. A path of higher resistance is to invent names for credential types like "password", and add a way to query preauth mechs for whether they use the selected credential type. Although this might seem more user-friendly at first, I think it would unfortunately get muddled fairly quickly. For instance, "token" could describe a PKCS11 token to be used with PKINIT, but also a device displaying a second factor for use with SAM-2 or FAST OTP or (in the possible future) SPAKE. "password" could describe a password to be used via one of the three s2k-based mechanisms, or a password that decrypts a PKCS12 private key or logs into a PKCS11 token for PKINIT. There is also the option of just having specific kinit options for specific preauth scenarios; that is, this problem's solution doesn't have to be runtime-extensible just because we have a runtime-extensible clpreauth framework (which as far as I know has only ever been used to replace the PKINIT module with another implementation). As a point of reference, Heimdal has specific kinit options and GIC options for PKINIT, although they don't necessarily seem to fit your problem statement. _______________________________________________ krbdev mailing list [email protected] https://mailman.mit.edu/mailman/listinfo/krbdev