diff -up ./lib/pk11wrap/pk11pars.c.add_ems_policy ./lib/pk11wrap/pk11pars.c --- ./lib/pk11wrap/pk11pars.c.add_ems_policy 2023-06-12 15:37:49.292905411 -0700 +++ ./lib/pk11wrap/pk11pars.c 2023-06-12 17:18:35.129938514 -0700 @@ -389,6 +389,8 @@ static const oidValDef kxOptList[] = { { CIPHER_NAME("ECDHE-RSA"), SEC_OID_TLS_ECDHE_RSA, NSS_USE_ALG_IN_SSL_KX }, { CIPHER_NAME("ECDH-ECDSA"), SEC_OID_TLS_ECDH_ECDSA, NSS_USE_ALG_IN_SSL_KX }, { CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX }, + /* not really a key exchange, but it's the closest fit */ + { CIPHER_NAME("TLS-REQUIRE-EMS"), SEC_OID_TLS_REQUIRE_EMS, NSS_USE_ALG_IN_SSL_KX }, }; static const oidValDef signOptList[] = { diff -up ./lib/pk11wrap/secmodti.h.add_ems_policy ./lib/pk11wrap/secmodti.h --- ./lib/pk11wrap/secmodti.h.add_ems_policy 2023-06-04 01:42:53.000000000 -0700 +++ ./lib/pk11wrap/secmodti.h 2023-06-12 17:18:35.129938514 -0700 @@ -202,4 +202,10 @@ struct PK11GenericObjectStr { /* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */ #define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL +/* this oid value could change values if it's added after other new + * upstream oids. We protect applications by hiding the define in a private + * header file that only NSS sees. Currently it's only available through + * the policy code */ +#define SEC_OID_TLS_REQUIRE_EMS SEC_OID_PRIVATE_1 + #endif /* _SECMODTI_H_ */ diff -up ./lib/ssl/ssl3con.c.add_ems_policy ./lib/ssl/ssl3con.c --- ./lib/ssl/ssl3con.c.add_ems_policy 2023-06-04 01:42:53.000000000 -0700 +++ ./lib/ssl/ssl3con.c 2023-06-12 17:18:35.130938525 -0700 @@ -36,6 +36,7 @@ #include "pk11func.h" #include "secmod.h" #include "blapi.h" +#include "secmodti.h" /* until SEC_OID_TLS_REQUIRE_EMS is upstream */ #include @@ -3480,6 +3481,29 @@ ssl3_ComputeMasterSecretInt(sslSocket *s CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params; unsigned int master_params_len; + /* if we are using TLS and we aren't using the extended master secret, + * and SEC_OID_TLS_REQUIRE_EMS policy is true, fail. The caller will + * send and alert (eventually). In the RSA Server case, the alert + * won't happen until Finish time because the upper level code + * can't tell a difference between this failure and an RSA decrypt + * failure, so it will proceed with a faux key */ + if (isTLS) { + PRUint32 policy; + SECStatus rv; + + /* first fetch the policy for this algorithm */ + rv = NSS_GetAlgorithmPolicy(SEC_OID_TLS_REQUIRE_EMS, &policy); + /* we only look at the policy if we can fetch it. */ + if (rv == SECSuccess) { + if (policy & NSS_USE_ALG_IN_SSL_KX) { + /* just set the error, we don't want to map any errors + * set by NSS_GetAlgorithmPolicy here */ + PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); + return SECFailure; + } + } + } + if (isTLS12) { if (isDH) master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH; diff -up ./lib/util/secoid.c.add_ems_policy ./lib/util/secoid.c --- ./lib/util/secoid.c.add_ems_policy 2023-06-12 15:37:49.293905422 -0700 +++ ./lib/util/secoid.c 2023-06-12 17:20:29.498142775 -0700 @@ -1795,6 +1795,11 @@ const static SECOidData oids[SEC_OID_TOT SEC_OID_EXT_KEY_USAGE_IPSEC_USER, "IPsec User", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION), + + /* this will change upstream. for now apps shouldn't use it */ + /* we need it for the policy code. */ + ODE(SEC_OID_PRIVATE_1, + "TLS Require EMS", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION), }; /* PRIVATE EXTENDED SECOID Table @@ -2095,6 +2100,8 @@ SECOID_Init(void) /* turn off NSS_USE_POLICY_IN_SSL by default */ xOids[SEC_OID_APPLY_SSL_POLICY].notPolicyFlags = NSS_USE_POLICY_IN_SSL; + /* turn off TLS REQUIRE EMS by default */ + xOids[SEC_OID_PRIVATE_1].notPolicyFlags = ~0; envVal = PR_GetEnvSecure("NSS_HASH_ALG_SUPPORT"); if (envVal) diff -up ./lib/util/secoidt.h.add_ems_policy ./lib/util/secoidt.h --- ./lib/util/secoidt.h.add_ems_policy 2023-06-12 17:18:35.131938535 -0700 +++ ./lib/util/secoidt.h 2023-06-12 17:21:49.675987022 -0700 @@ -501,6 +501,9 @@ typedef enum { SEC_OID_EXT_KEY_USAGE_IPSEC_END = 361, SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL = 362, SEC_OID_EXT_KEY_USAGE_IPSEC_USER = 363, + /* this will change upstream. for now apps shouldn't use it */ + /* give it an obscure name here */ + SEC_OID_PRIVATE_1 = 372, SEC_OID_TOTAL } SECOidTag;