diff --git a/genprotimg/man/genprotimg.8 b/genprotimg/man/genprotimg.8 index 81929926..460c1d79 100644 --- a/genprotimg/man/genprotimg.8 +++ b/genprotimg/man/genprotimg.8 @@ -87,7 +87,7 @@ CRLs. Optional. .TP \fB\-\-root\-ca\fR=\fI\,FILE\/\fR Specifies the root CA certificate for the verification. If omitted, -the DigiCert root CA certificate installed on the system is used. Use +the system wide root CAs installed on the system is used. Use this only if you trust the specified certificate. Optional. .TP \fB\-\-no-verify\fR diff --git a/genprotimg/src/include/pv_crypto_def.h b/genprotimg/src/include/pv_crypto_def.h index 53984a3d..3635433c 100644 --- a/genprotimg/src/include/pv_crypto_def.h +++ b/genprotimg/src/include/pv_crypto_def.h @@ -29,9 +29,6 @@ */ #define PV_CERTS_SECURITY_LEVEL 2 -/* SKID for DigiCert Assured ID Root CA */ -#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F" - union ecdh_pub_key { struct { uint8_t x[80]; diff --git a/genprotimg/src/pv/pv_args.c b/genprotimg/src/pv/pv_args.c index 000eb9a0..c67ae99f 100644 --- a/genprotimg/src/pv/pv_args.c +++ b/genprotimg/src/pv/pv_args.c @@ -123,7 +123,7 @@ static gint pv_args_validate_options(PvArgs *args, GError **err) g_strv_length(args->untrusted_cert_paths) == 0)) { g_set_error( err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT, - _("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n" + _("Either specify the IBM Z signing key and intermediate CA certificate\n" "by using the '--cert' option, or use the '--no-verify' flag to disable the\n" "host-key document verification completely (at your own risk).")); return -1; diff --git a/genprotimg/src/pv/pv_image.c b/genprotimg/src/pv/pv_image.c index 1ccb0fce..8399901d 100644 --- a/genprotimg/src/pv/pv_image.c +++ b/genprotimg/src/pv/pv_image.c @@ -311,9 +311,10 @@ static gint pv_img_hostkey_verify(GSList *host_key_certs, } /* Load all untrusted certificates (e.g. IBM Z signing key and - * DigiCert intermediate CA) that are required to establish a chain of - * trust starting from the host-key document up to the root CA (if not - * otherwise specified that's the DigiCert Assured ID Root CA). + * intermediate CA) that are required to establish a chain of trust + * starting from the host-key document up to the root CA (if not + * otherwise specified that can be one of the system wide installed + * root CAs, e.g. DigiCert). */ untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err); if (!untrusted_certs_with_path) @@ -348,9 +349,8 @@ static gint pv_img_hostkey_verify(GSList *host_key_certs, * For this we must check: * * 1. Can a chain of trust be established ending in a root CA - * 2. Is the correct root CA ued? It has either to be the - * 'DigiCert Assured ID Root CA' or the root CA specified via - * command line. + * 2. Is the correct root CA used? It has either to be a system CA + * or the root CA specified via command line. */ for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) { X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i); @@ -371,17 +371,12 @@ static gint pv_img_hostkey_verify(GSList *host_key_certs, if (verify_cert(ibm_signing_cert, ctx, err) < 0) goto error; - /* Verify the build chain of trust chain. If the user passes a - * trusted root CA on the command line then the check for the - * Subject Key Identifier (SKID) is skipped, otherwise let's - * check if the SKID meets our expectation. + /* If there is a chain of trust using either the provided root + * CA on the command line or a system wide trusted root CA. */ - if (!root_ca_path && - check_chain_parameters(X509_STORE_CTX_get0_chain(ctx), - get_digicert_assured_id_root_ca_skid(), - err) < 0) { + if (check_chain_parameters(X509_STORE_CTX_get0_chain(ctx), + err) < 0) goto error; - } ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err); if (!ibm_signing_crls) { @@ -595,7 +590,7 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err) g_warning(_("host-key document verification is disabled. Your workload is not secured.")); if (args->root_ca_path) - g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted.")); + g_warning(_("The root CA is selected through the command line. Ensure that this root CA is trusted.")); ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err); if (!ret->comps) diff --git a/genprotimg/src/utils/crypto.c b/genprotimg/src/utils/crypto.c index 96726095..7745b392 100644 --- a/genprotimg/src/utils/crypto.c +++ b/genprotimg/src/utils/crypto.c @@ -1079,8 +1079,8 @@ int store_set_verify_param(X509_STORE *store, GError **err) g_abort(); /* The maximum depth level of the chain of trust for the verification of - * the IBM Z signing key is 2, i.e. IBM Z signing key -> (DigiCert) - * intermediate CA -> (DigiCert) root CA + * the IBM Z signing key is 2, i.e. IBM Z signing key -> intermediate CA + * -> root CA */ X509_VERIFY_PARAM_set_depth(param, 2); @@ -1267,46 +1267,38 @@ static int security_level_to_bits(int level) return security_bits[level]; } -static ASN1_OCTET_STRING *digicert_assured_id_root_ca; - -const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void) -{ - pv_crypto_init(); - return digicert_assured_id_root_ca; -} - /* Used for the caching of the downloaded CRLs */ static GHashTable *cached_crls; void pv_crypto_init(void) { - if (digicert_assured_id_root_ca) + if (cached_crls) return; - cached_crls = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)X509_CRL_free); - digicert_assured_id_root_ca = s2i_ASN1_OCTET_STRING( - NULL, NULL, DIGICERT_ASSURED_ID_ROOT_CA_SKID); } void pv_crypto_cleanup(void) { - if (!digicert_assured_id_root_ca) + if (!cached_crls) return; g_clear_pointer(&cached_crls, g_hash_table_destroy); - g_clear_pointer(&digicert_assured_id_root_ca, ASN1_OCTET_STRING_free); } gint check_chain_parameters(const STACK_OF_X509 *chain, - const ASN1_OCTET_STRING *skid, GError **err) + GError **err) { - const ASN1_OCTET_STRING *ca_skid = NULL; + const X509_NAME *ca_x509_subject = NULL; + g_autofree gchar *ca_subject = NULL; gint len = sk_X509_num(chain); X509 *ca = NULL; - g_assert(skid); /* at least one root and one leaf certificate must be defined */ - g_assert(len >= 2); + if (len < 2) { + g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + _("there must be at least on root and one leaf certificate in the chain of trust")); + return -1; + } /* get the root certificate of the chain of trust */ ca = sk_X509_value(chain, len - 1); @@ -1316,19 +1308,21 @@ gint check_chain_parameters(const STACK_OF_X509 *chain, return -1; } - ca_skid = X509_get0_subject_key_id(ca); - if (!ca_skid) { - g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_MALFORMED_ROOT_CA, - _("malformed root certificate")); + ca_x509_subject = X509_get_subject_name(ca); + if (!ca_x509_subject) { + g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + _("subject of the root CA cannot be retrieved")); return -1; } - if (ASN1_STRING_cmp(ca_skid, skid) != 0) { - g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_WRONG_CA_USED, - _("expecting DigiCert root CA to be used")); + ca_subject = X509_NAME_oneline(ca_x509_subject, NULL, 0); + if (!ca_subject) { + g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_INTERNAL, + _("subject name of the root CA cannot be retrieved")); return -1; } + g_info("Root CA used: '%s'", ca_subject); return 0; } diff --git a/genprotimg/src/utils/crypto.h b/genprotimg/src/utils/crypto.h index 3cda4507..fdf66de2 100644 --- a/genprotimg/src/utils/crypto.h +++ b/genprotimg/src/utils/crypto.h @@ -125,7 +125,6 @@ int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert, gint verify_flags, GError **err); void pv_crypto_init(void); void pv_crypto_cleanup(void); -const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void); gint verify_host_key(X509 *host_key, GSList *issuer_pairs, gint verify_flags, int level, GError **err); X509 *load_cert_from_file(const char *path, GError **err); @@ -138,8 +137,7 @@ X509_STORE *store_setup(const gchar *root_ca_path, int store_set_verify_param(X509_STORE *store, GError **err); X509_CRL *load_crl_by_cert(X509 *cert, GError **err); STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path); -gint check_chain_parameters(const STACK_OF_X509 *chain, - const ASN1_OCTET_STRING *skid, GError **err); +gint check_chain_parameters(const STACK_OF_X509 *chain, GError **err); X509_NAME *c2b_name(const X509_NAME *name); STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);