mirror of https://github.com/openssl/openssl.git
				
				
				
			Merge fd6662cf75 into 7fb9163586
				
					
				
			This commit is contained in:
		
						commit
						94aac371a2
					
				
							
								
								
									
										29
									
								
								apps/cmp.c
								
								
								
								
							
							
						
						
									
										29
									
								
								apps/cmp.c
								
								
								
								
							|  | @ -87,6 +87,9 @@ static char *opt_srvcert = NULL; | ||||||
| static char *opt_expect_sender = NULL; | static char *opt_expect_sender = NULL; | ||||||
| static int opt_ignore_keyusage = 0; | static int opt_ignore_keyusage = 0; | ||||||
| static int opt_unprotected_errors = 0; | static int opt_unprotected_errors = 0; | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  | static int opt_ta_in_ip_extracerts = 0; | ||||||
|  | #endif | ||||||
| static int opt_no_cache_extracerts = 0; | static int opt_no_cache_extracerts = 0; | ||||||
| static char *opt_srvcertout = NULL; | static char *opt_srvcertout = NULL; | ||||||
| static char *opt_extracertsout = NULL; | static char *opt_extracertsout = NULL; | ||||||
|  | @ -253,7 +256,11 @@ typedef enum OPTION_choice { | ||||||
| 
 | 
 | ||||||
|     OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT, |     OPT_TRUSTED, OPT_UNTRUSTED, OPT_SRVCERT, | ||||||
|     OPT_EXPECT_SENDER, |     OPT_EXPECT_SENDER, | ||||||
|     OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_NO_CACHE_EXTRACERTS, |     OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  |     OPT_TA_IN_IP_EXTRACERTS, | ||||||
|  | #endif | ||||||
|  |     OPT_NO_CACHE_EXTRACERTS, | ||||||
|     OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, |     OPT_SRVCERTOUT, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, | ||||||
|     OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, |     OPT_OLDWITHOLD, OPT_NEWWITHNEW, OPT_NEWWITHOLD, OPT_OLDWITHNEW, | ||||||
|     OPT_CRLCERT, OPT_OLDCRL, OPT_CRLOUT, |     OPT_CRLCERT, OPT_OLDCRL, OPT_CRLOUT, | ||||||
|  | @ -441,6 +448,14 @@ const OPTIONS cmp_options[] = { | ||||||
|      "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"}, |      "certificate responses (ip/cp/kup), revocation responses (rp), and PKIConf"}, | ||||||
|     {OPT_MORE_STR, 0, 0, |     {OPT_MORE_STR, 0, 0, | ||||||
|      "WARNING: This setting leads to behavior allowing violation of RFC 4210"}, |      "WARNING: This setting leads to behavior allowing violation of RFC 4210"}, | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  |     {"ta_in_ip_extracerts", OPT_TA_IN_IP_EXTRACERTS, '-', | ||||||
|  |      "Permit using self-issued certificates from the extraCerts in an IP message"}, | ||||||
|  |     {OPT_MORE_STR, 0, 0, | ||||||
|  |      "as trust anchors under conditions defined by 3GPP TS 33.310"}, | ||||||
|  |     {OPT_MORE_STR, 0, 0, | ||||||
|  |      "WARNING: This setting leads to behavior allowing violation of RFC 9810"}, | ||||||
|  | #endif | ||||||
|     {"no_cache_extracerts", OPT_NO_CACHE_EXTRACERTS, '-', |     {"no_cache_extracerts", OPT_NO_CACHE_EXTRACERTS, '-', | ||||||
|      "Do not keep certificates received in the extraCerts CMP message field"}, |      "Do not keep certificates received in the extraCerts CMP message field"}, | ||||||
|     { "srvcertout", OPT_SRVCERTOUT, 's', |     { "srvcertout", OPT_SRVCERTOUT, 's', | ||||||
|  | @ -666,6 +681,9 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ | ||||||
|     {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert}, |     {&opt_trusted}, {&opt_untrusted}, {&opt_srvcert}, | ||||||
|     {&opt_expect_sender}, |     {&opt_expect_sender}, | ||||||
|     {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, |     {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  |     {(char **)&opt_ta_in_ip_extracerts}, | ||||||
|  | #endif | ||||||
|     {(char **)&opt_no_cache_extracerts}, |     {(char **)&opt_no_cache_extracerts}, | ||||||
|     {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, |     {&opt_srvcertout}, {&opt_extracertsout}, {&opt_cacertsout}, | ||||||
|     {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, |     {&opt_oldwithold}, {&opt_newwithnew}, {&opt_newwithold}, {&opt_oldwithnew}, | ||||||
|  | @ -1340,6 +1358,10 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) | ||||||
| 
 | 
 | ||||||
|     if (opt_unprotected_errors) |     if (opt_unprotected_errors) | ||||||
|         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1); |         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS, 1); | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  |     if (opt_ta_in_ip_extracerts) | ||||||
|  |         (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR, 1); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     if (opt_out_trusted != NULL) { /* for use in OSSL_CMP_certConf_cb() */ |     if (opt_out_trusted != NULL) { /* for use in OSSL_CMP_certConf_cb() */ | ||||||
|         X509_VERIFY_PARAM *out_vpm = NULL; |         X509_VERIFY_PARAM *out_vpm = NULL; | ||||||
|  | @ -2921,6 +2943,11 @@ static int get_opts(int argc, char **argv) | ||||||
|         case OPT_UNPROTECTED_ERRORS: |         case OPT_UNPROTECTED_ERRORS: | ||||||
|             opt_unprotected_errors = 1; |             opt_unprotected_errors = 1; | ||||||
|             break; |             break; | ||||||
|  | #ifdef OPENSSL_CMP_APP_ALLOW_UNSAFE | ||||||
|  |         case OPT_TA_IN_IP_EXTRACERTS: | ||||||
|  |             opt_ta_in_ip_extracerts = 1; | ||||||
|  |             break; | ||||||
|  | #endif | ||||||
|         case OPT_NO_CACHE_EXTRACERTS: |         case OPT_NO_CACHE_EXTRACERTS: | ||||||
|             opt_no_cache_extracerts = 1; |             opt_no_cache_extracerts = 1; | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|  | @ -311,21 +311,31 @@ static int check_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *store, | ||||||
| /*
 | /*
 | ||||||
|  * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security |  * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security | ||||||
|  * (NDS); Authentication Framework (AF)], only to use for IP messages |  * (NDS); Authentication Framework (AF)], only to use for IP messages | ||||||
|  * and if the ctx option is explicitly set: use self-issued certificates |  * and if the ctx option is explicitly set: use self-issued certificates from | ||||||
|  * from extraCerts as trust anchor to validate sender cert - |  * extraCerts as trust anchors when validating the CMP message protection cert | ||||||
|  * provided it also can validate the newly enrolled certificate |  * in this and any subsequent responses from the server in the same transaction, | ||||||
|  |  * but only if these extraCerts can also be used as trust anchors for validating | ||||||
|  |  * the newly enrolled certificate received in the IP message. | ||||||
|  */ |  */ | ||||||
| static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx, | static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx, | ||||||
|                                 const OSSL_CMP_MSG *msg, X509 *scrt) |                                 const OSSL_CMP_MSG *msg, X509 *scrt) | ||||||
| { | { | ||||||
|     int valid = 0; |     int valid = 0; | ||||||
|     X509_STORE *store; |     X509_STORE *store; | ||||||
|  |     STACK_OF(X509) *extraCerts; | ||||||
| 
 | 
 | ||||||
|     if (!ctx->permitTAInExtraCertsForIR) |     if (!ctx->permitTAInExtraCertsForIR) | ||||||
|         return 0; |         return 0; | ||||||
| 
 | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Initially, use extraCerts from the IP message. | ||||||
|  |      * For subsequent msgs (pollRep or PKIConf) in the same transaction, | ||||||
|  |      * use extraCertsIn remembered from earlier message (typically, the IP message). | ||||||
|  |      * The extraCertsIn field will be cleared by OSSL_CMP_CTX_reinit(). | ||||||
|  |      */ | ||||||
|  |     extraCerts = ctx->extraCertsIn == NULL ? msg->extraCerts : ctx->extraCertsIn; | ||||||
|     if ((store = X509_STORE_new()) == NULL |     if ((store = X509_STORE_new()) == NULL | ||||||
|             || !ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts, |             || !ossl_cmp_X509_STORE_add1_certs(store, extraCerts, | ||||||
|                                                1 /* self-issued only */)) |                                                1 /* self-issued only */)) | ||||||
|         goto err; |         goto err; | ||||||
| 
 | 
 | ||||||
|  | @ -334,7 +344,7 @@ static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx, | ||||||
|     if (!valid) { |     if (!valid) { | ||||||
|         ossl_cmp_warn(ctx, |         ossl_cmp_warn(ctx, | ||||||
|                       "also exceptional 3GPP mode cert path validation failed"); |                       "also exceptional 3GPP mode cert path validation failed"); | ||||||
|     } else { |     } else if (OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_IP) { | ||||||
|         /*
 |         /*
 | ||||||
|          * verify that the newly enrolled certificate (which assumed rid == |          * verify that the newly enrolled certificate (which assumed rid == | ||||||
|          * OSSL_CMP_CERTREQID) can also be validated with the same trusted store |          * OSSL_CMP_CERTREQID) can also be validated with the same trusted store | ||||||
|  | @ -416,8 +426,7 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, | ||||||
| { | { | ||||||
|     int ret = 0; |     int ret = 0; | ||||||
| 
 | 
 | ||||||
|     if (ctx->permitTAInExtraCertsForIR |     if (ctx->permitTAInExtraCertsForIR) | ||||||
|             && OSSL_CMP_MSG_get_bodytype(msg) == OSSL_CMP_PKIBODY_IP) |  | ||||||
|         ossl_cmp_info(ctx, mode_3gpp ? |         ossl_cmp_info(ctx, mode_3gpp ? | ||||||
|                       "normal mode failed; trying now 3GPP mode trusting extraCerts" |                       "normal mode failed; trying now 3GPP mode trusting extraCerts" | ||||||
|                       : "trying first normal mode using trust store"); |                       : "trying first normal mode using trust store"); | ||||||
|  | @ -544,10 +553,11 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) | ||||||
|  * (in this order) and is path is validated against ctx->trusted. |  * (in this order) and is path is validated against ctx->trusted. | ||||||
|  * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). |  * On success cache the found cert using ossl_cmp_ctx_set1_validatedSrvCert(). | ||||||
|  * |  * | ||||||
|  * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg, |  * If ctx->permitTAInExtraCertsForIR is true, when validating a CMP IP message, | ||||||
|  * the trust anchor for validating the IP msg may be taken from msg->extraCerts |  * trust anchors for validating the IP message (and any subsequent responses | ||||||
|  * if a self-issued certificate is found there that can be used to |  * by the server in the same transaction) may be taken from msg->extraCerts | ||||||
|  * validate the enrolled certificate returned in the IP. |  * if self-issued certificates are found there that can also be used | ||||||
|  |  * to validate the newly enrolled certificate returned in the IP msg. | ||||||
|  * This is according to the need given in 3GPP TS 33.310. |  * This is according to the need given in 3GPP TS 33.310. | ||||||
|  * |  * | ||||||
|  * Returns 1 on success, 0 on error or validation failed. |  * Returns 1 on success, 0 on error or validation failed. | ||||||
|  |  | ||||||
|  | @ -70,6 +70,7 @@ Server authentication options: | ||||||
| [B<-expect_sender> I<name>] | [B<-expect_sender> I<name>] | ||||||
| [B<-ignore_keyusage>] | [B<-ignore_keyusage>] | ||||||
| [B<-unprotected_errors>] | [B<-unprotected_errors>] | ||||||
|  | [B<-ta_in_ip_extracerts>] | ||||||
| [B<-no_cache_extracerts>] | [B<-no_cache_extracerts>] | ||||||
| [B<-srvcertout> I<filename>] | [B<-srvcertout> I<filename>] | ||||||
| [B<-extracertsout> I<filename>] | [B<-extracertsout> I<filename>] | ||||||
|  | @ -714,6 +715,23 @@ with a signature key." | ||||||
| 
 | 
 | ||||||
| =back | =back | ||||||
| 
 | 
 | ||||||
|  | =item B<-ta_in_ip_extracerts> | ||||||
|  | 
 | ||||||
|  | This is a quirk option added to support 3GPP TS 33.310, | ||||||
|  | available only if OpenSSL has been built with B<OPENSSL_CMP_APP_ALLOW_UNSAFE>. | ||||||
|  | B<WARNING:> This leads to behavior violating RFCs 4210 and 9810. | ||||||
|  | 
 | ||||||
|  | It allows using self-issued certificates from the extraCerts in an IP message | ||||||
|  | as trust anchors when validating the CMP message protection certificate | ||||||
|  | in this and any subsequent responses from the server in the same transaction, | ||||||
|  | but only if these extraCerts can also be used as trust anchors for validating | ||||||
|  | the newly enrolled certificate received in the IP message. | ||||||
|  | 
 | ||||||
|  | Note that using this option is dangerous as the to-be-trusted certificates | ||||||
|  | obtained this way have not been authenticated (at least not at CMP level). | ||||||
|  | Taking them over as initial trust anchors | ||||||
|  | implements a form of trust-on-first-use (TOFU). | ||||||
|  | 
 | ||||||
| =item B<-no_cache_extracerts> | =item B<-no_cache_extracerts> | ||||||
| 
 | 
 | ||||||
| Do not cache certificates in the extraCerts field of CMP messages received. | Do not cache certificates in the extraCerts field of CMP messages received. | ||||||
|  | @ -1529,6 +1547,8 @@ and B<-rsp_crl> options were added in OpenSSL 3.4. | ||||||
| B<-centralkeygen>, B<-newkeyout>, B<-rsp_key> and | B<-centralkeygen>, B<-newkeyout>, B<-rsp_key> and | ||||||
| B<-rsp_keypass> were added in OpenSSL 3.5. | B<-rsp_keypass> were added in OpenSSL 3.5. | ||||||
| 
 | 
 | ||||||
|  | The B<-ta_in_ip_extracerts> quirk option was added in OpenSSL 3.6. | ||||||
|  | 
 | ||||||
| =head1 COPYRIGHT | =head1 COPYRIGHT | ||||||
| 
 | 
 | ||||||
| Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. | Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. | ||||||
|  |  | ||||||
|  | @ -343,13 +343,18 @@ Else, 'digitalSignature' must be allowed by CMP signer certificates. | ||||||
| 
 | 
 | ||||||
| =item B<OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR> | =item B<OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR> | ||||||
| 
 | 
 | ||||||
| Allow retrieving a trust anchor from extraCerts and using that |  | ||||||
| to validate the certificate chain of an IP message. |  | ||||||
| This is a quirk option added to support 3GPP TS 33.310. | This is a quirk option added to support 3GPP TS 33.310. | ||||||
|  | It leads to behavior violating RFCs 4210 and 9810. | ||||||
|  | It allows using self-issued certificates from the extraCerts in an IP message | ||||||
|  | as trust anchors when validating the CMP message protection certificate | ||||||
|  | in this and any subsequent responses from the server in the same transaction, | ||||||
|  | but only if these extraCerts can also be used as trust anchors for validating | ||||||
|  | the newly enrolled certificate received in the IP message. | ||||||
| 
 | 
 | ||||||
| Note that using this option is dangerous as the certificate obtained | Note that using this option is dangerous as the to-be-trusted certificates | ||||||
| this way has not been authenticated (at least not at CMP level). | obtained this way have not been authenticated (at least not at CMP level). | ||||||
| Taking it over as a trust anchor implements trust-on-first-use (TOFU). | Taking them over as initial trust anchors | ||||||
|  | implements a form of trust-on-first-use (TOFU). | ||||||
| 
 | 
 | ||||||
| =item B<OSSL_CMP_OPT_NO_CACHE_EXTRACERTS> | =item B<OSSL_CMP_OPT_NO_CACHE_EXTRACERTS> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue