hx509_context_free() must call heim_config_file_free() on
the hx509_context.cf section binding. Otherwise the memory
is leaked.
Change-Id: Ib3350a5be67203904fc1aee727c342c3ed552978
PATH_SEP is declared on Windows to be ";" and not ":"
by include/config.h.w32.
lib/base/context.c and lib/hx509.c must not override an existing
setting. Otherwise, file lists cannot be separated and will be
treated as a single file name.
Change-Id: I5521188faca36e41fbae95fbb8942970eab261c8
Just like krb5.conf, but hx509.conf, with all the same default locations
on Windows, OS X, and elsewhere, and HX509_CONFIG as the environment
variable equivalent of KRB5_CONFIG.
Add two ways to exclude private keys when dealing with an hx509
certificate store. One as a load option (load no private keys, never
add private keys), one as a store option (store no private keys).
This is useful for CA code so it can have a single store with the
issuer's credentials _and_ the chain for it, and copy those to a store
with the issued certificate and _not_ accidentally include the issuer's
private key.
It would be much safer still to flip the default for this flag, but that
could break out-of-tree libhx509 dependents.
This commit adds a few functions for marking KU, EKUs, and SANs as
authorized, and for getting a count of unsupported certificate
extensions requested, and a count of authorized KU/EKUs/SANs.
The intent is to make it easier to build CSR authorization and CA code
that is robust in the face of future support for certificate extensions
and SAN types not currently supported. An application could parse a
CSR, iterate all KU/EKUs/SANs, check a subject's authorization to them,
mark them authorized where authorized, then check if there are any
remaining unauthorized extensions or unsupported extensions requested.
Ultimately, if a CSR's KU/EKUs/SANs are all authorized, then they can
all be copied to a TBS, and a certificate can be issued.
Most consumers of PEM files don't care about the order in which private
keys and certificates are stored. However, Postfix does care when
multiple EE certs (and chains) are stored in a file, in which case it
requires that private keys come before their certificates.
This is necessary in order to add proper support for CSRs in kx509,
where the KDC can examine all requested KUs/EKUs/SANs, check
authorization, and issue a certificate with all those extensions if
authorized.
This is the convention used by OpenSSL, of encoding all the KU, EKUs,
and SANs being requested as Extensions as they would appear in the
TBSCertificate, then putting those in as a single Attribute in the CSR's
Attributes list with attribute OID {id-pkcs-9, 14}.
- expose all hx509_request_*() functions
- finish support in hx509_request_parse*() for KU, EKU, and SAN CSR
attributes
- finish support in hx509_request_to_pkcs10() for encoding all
requested KU, EKU, and SAN extensions as a CSR extReq (extension request)
- add hx509_request_add_*() support for:
- id-pkinit-san and ms-upn-pkinit-san
- XMPP (Jabber) SAN
- registeredID (useless but trivial)
- add hxtool request-create options for all supported SANs
- add hxtool request-create options for KeyUsage
- add hxtool request-create options for ExtKeyUsage
- add hxtool request-print support for all these things
- fix bugs in existing id-pkinit-san handling
Possible future improvements
- add HX509_TRACE env var and support (it would be nice to be able to
observe why some certificate is rejected, or not matched in a query)
- add testing that CSR creating and printing round-trip for all KUs,
EKUs, and SANs
(probably in tests/kdc/check-pkinit.in)
- add testing that OpenSSL can print a CSR made by hxtool and
vice-versa
- hxtool ca: add KU sanity checking (via hx509_ca_sign() and/or friends)
(don't allow encrypt for signing-only algs)
(don't allow encrypt for RSA at all, or for RSA with small e exponents)
- hxtool request-print: warn about all unknown attributes and
extensions
- hxtool ca: MAYBE add support for adding requested extensions from the
--req=CSR
("Maybe" because CA operators should really verify and authorize all
requested attributes, and should acknowledge that they have, and the
simplest way to do this is to make them add all the corresponding
CLI arguments to the hxtool ca command, but too, that is
error-prone, thus it's not clear yet which approach is best.
Perhaps interactively prompt for yes/no for each attribute.)
- add additional SAN types:
- iPAddress (useless?)
- dNSSrv (useful!)
- directoryName (useless, but trivial)
- uniformResourceIdentifier (useful)
- it would be nice if the ASN.1 compiler could generate print
functions..., and/or even better, to-JSON functions
- it would be nice if we had a known-OID db, including the names of the
types they refer to in certificate extensions, otherName SANs and CSR
attributes, then we could generate a CSR and certificate printer for
all known options even when they are not supported by the rest of
Heimdal
- and we could also get friendly names for OIDs, and we could
resolve their arc names
- longer term, we could also stand to add some ASN.1 information
object system functionality, just enough to make
lib/hx509/asn1_print awesome by being able to automatically decode
all heim_any and OCTET STRING content (better than its current
--inner option)
Now we'll use mkostemp() and rename() into place to make
hx509_certs_store() atomic for FILE/DER-FILE/PEM-FILE stores.
This is not ideal, as it can leave temp files in place if a process
crashes in between the mkostemp() and the rename into place.
On Linux we'll eventually make use of O_TMPFILE and linkat(). The idea
will be to first create an anonymous, zero-link file in the directory
that will contain the file at the end, write the file, then linkat() the
file into place as a .new file, then rename() the .new into place. That
will limit the amount of junk that may be left behind to just one file.
(If the linkat() fails, then unlink() the .new and try again. If the
rename() fails that just means the caller raced with another and the
operation is complete.)
We should really make a lib/roken interface that does this.
This will help us generate a directory of OIDs from all the ASN.1
modules in lib/asn1, which will then help us create an hx509 API for
resolving OIDs to/from friendly names, which ultimately will help us
make hxtool more user-friendly.
This is necessary in order to have more control over, e.g., template
certificates for kx509. But also it's good to have this more generally.
Some batteries not included. Specifically: no attempt is made to validate that
given KeyUsage values are compatible with the subjectPublicKey's alrogithm and
parameters.
```
hxtool request-create --subject=... \
--generate-key=... \
--key-bits=... \
--key=STORE \
store
```
wants to generate a key, store it in the location specified by the --key
argument, then read it back, then generate the CSR, and store it in
`store`.
But it didn't work because for generating a key this really wants the
`--key` argument to be a file path into which a raw DER-encoded RSA key
will be written (only RSA is supported, ay!), but for reading the key
back it uses `hx509_certs_init()`, which wants `TYPE:name` keystore
specification. A deadly embrace.
Now that we have improved libhx509 functionality for reading/writing
private keys from/to PEM files we use this functionality and require a
store type in the `--key=STORE` argument.
This commit adds:
- hx509_cert_init_private_key() for creating an hx509_cert object that
has just a private key
- hx509_cert_have_private_key_only() for checking whether an hx509_cert
object has just a private key
This also generalizes the get_key() internal function in hxtool, which
is tasked with reding or generating a private key for use in signing
CSRs. Now hxtool request-create can read/write private keys to/from PEM
files, not just DER files.
This is needed to support key types other than just RSA for CSRs and
certificates.