This commit adds support for proof of posession to the kx509 protocol by
using PKCS#10 CSRs.
This allows conveyance of extReq CSR attributes requesting desired
Certificate Extensions.
This commit adds support for kx509 in libkrb5, and revamps the KDC's
kx509 service (fixing bugs, adding features).
Of note is that kx509 is attempted optimistically by the client, with
the certificate and private key stored in the ccache, and optionally in
an external PEM or DER file.
NOTE: We do not optimistically use kx509 in krb5_cc_store_cred() if the
ccache is a MEMORY ccache so we don't generate a key when
accepting a GSS context with a delegated credential.
kx509 protocol issues to be fixed in an upcoming commit:
- no proof of possession (this is mostly not too bad, but we'll want to
fix it by using CSRs)
- no algorithm agility (only plain RSA is supported)
- very limited (no way to request any options in regards to the
requested cert)
- error codes are not very useful
Things we're adding in this commit:
- libkrb5 kx509 client
- automatic kx509 usage hooked in via krb5_cc_store_cred() of start TGT
- per-realm templates on the KDC side
- per-realm issuer certificates
- send error messages on the KDC side
(this is essential to avoid client-side timeouts on error)
- authenticate as many error messages
- add a protocol probe feature so we can avoid generating a
keypair if the service is not enabled
(once we add support for ECC algorithms we won't need this
anymore; the issue is that RSA keygen is slow)
- support for different types of client principals, not just username:
- host-based service and domain-based service, each with its own
template set per-{realm, service} or per-service
(the idea is to support issuance of server certificates too, not
just client/user certs)
- more complete support for SAN types
- tests (including that PKINIT->kx509->PKINIT works, which makes it
possible to have "delegation" of PKIX credentials by just delegating
Kerberos credentials)
- document the protocol in lib/krb5/kx509.c
Future work:
- add option for longer-ticket-lifetime service certs
- add support for ECDSA, and some day for ed25519 and ed448
- reuse private key when running kinit
(this will require rethinking how we trigger optimistic kx509
usage)
- HDB lookup for:
- optional revocation check (not strictly necessary)
- adding to certificates those SANs listed in HDB
- hostname aliases (dNSName SANs)
- rfc822Name (email)
- XMPP SANs
- id-pkinit-san (a user could have aliases too)
- support username wild-card A RRs, ala OSKT/krb5_admin
i.e., if a host/f.q.d.n principal asks for a certificate for
some service at some-label.f.q.d.n, then issue it
(this is not needed at OSKT sites because OSKT already
supports keying such service principals, which means kx509
will issue certificates for them, however, it would be nice
to be able to have this independent of OSKT)
(a better way to do this would be to integrate more of OSKT
into Heimdal proper)
- a kx509 command, or heimtools kx509 subcommand for explicitly
attempting use of the kx509 protocol (as opposed to implicit, as is
done in kinit via krb5_cc_store_cred() magic right now)
Issues:
- optimistically trying kx509 on start realm TGT store -> timeout issues!
- newer KDCs will return errors because of this commit; older ones
will not, which causes timouts
- need a separate timeout setting for kx509 for optimistic case
- need a [realm] config item and DNS SRV RR lookup for whether a
realm is expected to support kx509 service
Refactor krb5_cc_set_default_name() by splitting out the part that looks
for a configured default ccache name. This will allow one to check if a
given ccache is a default ccache for a process ignoring KRB5CCNAME,
which might prove useful in the kx509 client.
Move init/copy/destroy fallback sequence from fcc_move() to
krb5_cc_move().
Make sure all backends's move() method calls krb5_cc_destroy() on the
source on success (and only on success).
In text_cc make sure that we can find in the destination the cred
stored into the source.
The header file was not installed, and the manpage had the wrong
name for the plugin load function, it is "krb5_plugin_kuserok_plugin_load",
not "kuserok_plugin_load".
%{loginname} is for getlogin_r().
Now %{username} uses only the $USER and $LOGNAME environment variables
(if the caller is not set-uid), or if absent or the caller is set-uid,
then getpwuid_r().
The intent is to allow kadmin(1) to use the loginname instead of the
username for the construction of the kadmin client principal name. This
is helpful when the user runs kadmin as root via sudo and/or su.
* Anonymous pkinit responses from the KDC where the name
type is not well-known (as issued by 7.5 KDCs and earlier)
are accepted by the client. There is no need for the client
to strictly enforce the name type.
* With historical_anon_pkinit = true, the kinit(1) client's
"--anonymous" option only performs anon pkinit, and does
not require an '@' prefix for the realm argument.
* With historical_anon_realm = true, the KDC issues anon
pkinit tickets with the legacy pre-7.0 "real" realm.
The Microsoft compiler cannot handle multiple const modifiers
for the same type. It is also unhappy with the output pointer
parameter being declared const.
This change introduces new typedefs and cast of the dlsym() return
type to prevent warnings.
Change-Id: Ia92645efab8d2ec6745339a6f47c690782ae730a
Rename common_plugin_ftable to krb5_plugin_common_ftable.
Create lib/krb5/common_plugin.h to include the structure and typedef.
The common_plugin.h header is now included by ccache_plugin.h
along with a prototype for the required ccache_ops_plugin_load()
function.
Change-Id: I2b27d6d0f5cf0544482c3f01784fef945e12e8d8
As with the krb5plugin_an2ln_ftable_desc, krb5plugin_db_ftable_desc,
and krb5plugin_kuserok_ftable_desc the function pointers in
common_plugin_ftable_desc must be annotated with KRB5_LIB_CALL.
Change-Id: Ia7ea78743ee9eb8c7f6b648063852ca91a360d2c
Only fallback to loading the plugin function table directly if
if the initialization function is not exported. Failing a
consistency check should not permit falling back to a potentially
incompatible function table.
Change-Id: Ic753ed9a090aef6073853f7309f0f8f0f29d0aa9
even if tgt used an enctype with a different checksum.
Per [MS-SFU] 2.2.1 PA-FOR-USER the checksum is always
HMAC_MD5, and that's what Windows and MIT clients send.
In heimdal both the client and kdc use instead the
checksum of the tgt, and therefore work with each other
but windows and MIT clients fail against heimdal KDC.
Both Windows and MIT KDC would allow any keyed checksum
to be used so Heimdal client work fine against it.
Change Heimdal KDC to allow HMAC_MD5 even for non RC4
based tgt in order to support per-spec clients.
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Commit bdcd7d2f moved the KRB5_ANON_MATCH_xxx preprocessor symbols to krb5.h,
but did not remove the originals from krb5_locl.h. This commit removes them.
The combination of 8740528b24
("Windows-compatible sentinel socket type and value") and
d497d7e4a7 ("krb5_sendto_kdc:
failover for multiple AAAA/A RRs on one domain") broke
all the send to kdc loop on Windows. rk_socket_t is
a HANDLE and rk_INVALID_SOCKET is the max value. Therefore,
no valid socket will be larger and all communications
will fail.
Change-Id: I3464f78d67b19f14050ad7a01738fb32bac99385
_krb5_principal_is_anonymous() is used outside lib/krb5 and
therefore it needs to be properly exported and its flag macros
need to be in a public header: krb5.h not krb5_locl.h.
Including krb5_locl.h from within kuser_locl.h for instance
results in build failures on Solaris.
This change renames the function and makes it part of the public
api.
Change-Id: I130d1698b10bdbd150b95e8c7d32dfc362889ce6
RFC8062 Section 7 requires verification of the PA-PKINIT-KX key excahnge
when anonymous PKINIT is used. Failure to do so can permit an active
attacker to become a man-in-the-middle.
Introduced by a1ef548600. First tagged
release Heimdal 1.4.0.
CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N (4.8)
Change-Id: I6cc1c0c24985936468af08693839ac6c3edda133
Signed-off-by: Jeffrey Altman <jaltman@auristor.com>
Approved-by: Jeffrey Altman <jaltman@auritor.com>
We found that the libraries behaviour when dealing with domains with
more than one entry in them is slightly suboptimal. The situation
was
kdc1 IN A 1.2.3.4
kdc1 IN AAAA ff02::1
I.e. a single hostmame with both IPv6 and IPv4 addresses. When we
run krb5_sendto_kdc on a box with only IPv4 addresses, there is a
3s delay before it fails back to the IPv4 address. This is because
the library sets the 2nd address on each hostname to be 3s in the
future and each additional one another 3s.
We change wait_response() s.t. if one is able to make progress, we
iterate over the list of hosts and move them all 1s forward. We
also modify submit_request() to skip hosts if host_connect() fails.
Add macros to give symbolic names to the flags which can be passed to
krb5_get_init_creds_opt_set_pkinit(). Reserve flags for BTMM and not validating
KDC anchors.
Add _krb5_principal_is_anonymous() private API for checking if a principal is
anonymous or not. The third argument determines whether to match authenticated
anonymous, unauthenticated anonymous, or both types of principal.