The CA submission internal API uses child processes to do the heavy lifting. Self-signing is handled internally, but interaction with most CAs is done through external helpers. This is how it looks from the application's standpoint. Transmitting enrollment request: 1. Call submit_start(). 2. Wait/poll until submit_sent() returns 0. Checking initial submission results: 3. If submit_issued() returns non-0: * If submit_save_ca_cookie() returns 0, jump to step 5. 4. If submit_issued() returned 0, the CA has issued a certificate. * If submit_needs_retrieval() returns 0, wait/poll until submit_status_ready() returns 0. * Done; move on to saving the certificate. Polling submission results. 5. * Wait/poll until submit_status_ready() returns 0. 6. If submit_issued() returned 0, the CA has issued a certificate. * If submit_needs_retrieval() returns 0, wait/poll until submit_status_ready() returns 0. * Done; move on to saving the certificate. An external helper has a few jobs, then: * Invoked either with "SUBMIT" or "POLL" as the value of the $CERTMONGER_OPERATION environment value, with command-line arguments as specified in certmaster's configuration. Some of the data from the request is also provided in the environment. * $CERTMONGER_REQ_SUBJECT -> requested subject name * $CERTMONGER_REQ_EMAIL -> email address subjectAltName values * $CERTMONGER_REQ_HOSTNAME -> DNS name subjectAltName values * $CERTMONGER_REQ_PRINCIPAL -> Kerberos principal name subjectAltName values * If in "submit" mode, $CERTMONGER_CSR has as its value a PEM-formatted CSR. * Submit request to CA. * Issued -> output PEM-formatted cert on stdout, exit with status 0. * Wait a bit -> output CA cookie value on stdout, exit with status 1. * Rejected -> output error message on stdout, exit with status 2. * Connect error -> output error message on stdout, exit with status 3. * Underconfigured-> output error message on stdout, exit with status 4. * If in "poll" mode, $CERTMONGER_COOKIE has as its value a CA cookie value. * Poll CA for result of previously-started enrollment operation. * Issued -> output PEM-formatted cert on stdout, exit with status 0. * Wait some more -> output CA cookie value on stdout, exit with status 1. * Rejected -> output error message on stdout, exit with status 2. * Connect error -> output error message on stdout, exit with status 3. * Underconfigured-> output error message on stdout, exit with status 4. For testing purposes, a helper can be added by creating a file in the CAs directory (usually /var/lib/certmonger/cas) with these contents: id=Test ca_type=EXTERNAL ca_is_default=0 ca_external_helper=/usr/libexec/certmonger/test-submit-helper Passing the "-c Test" flag to the "getcert request" command will then use the helper to attempt enrollment. This, with some built-in defaults that provide the same result when no existing CAs file defines a CA named "IPA", is how the daemon knows about IPA. The ipa-getcert client, meanwhile, just assumes that clients want to use the CA nicknamed "IPA".