blob: f29190357364c3b831746c7cd3015a1ea9f6eeb8 [file] [log] [blame]
This patch makes CERT_SetCertTrust prefer writable tokens that already contain
the certificate when choosing where to store trust settings.
See crbug.com/1132030 .
Upstream bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1680453
Upstream review: https://phabricator.services.mozilla.com/D99840
--- nss/lib/pki/pki3hack.c
+++ nss/lib/pki/pki3hack.c
@@ -1048,9 +1048,9 @@ static NSSToken *
stan_GetTrustToken(
NSSCertificate *c)
{
- NSSToken *ttok = NULL;
- NSSToken *rtok = NULL;
- NSSToken *tok = NULL;
+ NSSToken *token_with_trust_object = NULL;
+ NSSToken *ro_token_without_trust_object = NULL;
+ NSSToken *rw_token_without_trust_object = NULL;
nssCryptokiObject **ip;
nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
if (!instances) {
@@ -1058,30 +1058,48 @@ stan_GetTrustToken(
}
for (ip = instances; *ip; ip++) {
nssCryptokiObject *instance = *ip;
- nssCryptokiObject *to =
+ nssCryptokiObject *trust_object =
nssToken_FindTrustForCertificate(instance->token, NULL,
&c->encoding, &c->issuer, &c->serial,
nssTokenSearchType_TokenOnly);
- NSSToken *ctok = instance->token;
- PRBool ro = PK11_IsReadOnly(ctok->pk11slot);
-
- if (to) {
- nssCryptokiObject_Destroy(to);
- ttok = ctok;
- if (!ro) {
+ NSSToken *current_token = instance->token;
+ PRBool is_read_only = PK11_IsReadOnly(current_token->pk11slot);
+
+ if (trust_object) {
+ nssCryptokiObject_Destroy(trust_object);
+ token_with_trust_object = current_token;
+ if (!is_read_only) {
+ // No point iterating further, as the read-write token that
+ // already has a trust object will be preferred anyway.
break;
}
- } else {
- if (!rtok && ro) {
- rtok = ctok;
- }
- if (!tok && !ro) {
- tok = ctok;
- }
+ continue;
+ }
+ if (!rw_token_without_trust_object && !is_read_only) {
+ rw_token_without_trust_object = current_token;
+ continue;
+ }
+ if (!ro_token_without_trust_object && is_read_only) {
+ ro_token_without_trust_object = current_token;
}
}
nssCryptokiObjectArray_Destroy(instances);
- return ttok ? ttok : (tok ? tok : rtok);
+
+ // Precedence rules:
+ // Note that all tokens considered here have the certificate on them.
+ // read-write token with trust object > any read-write token >
+ // read-only token with trust object > any read-only token
+ if (token_with_trust_object &&
+ !PK11_IsReadOnly(token_with_trust_object->pk11slot)) {
+ return token_with_trust_object;
+ }
+ if (rw_token_without_trust_object ) {
+ return rw_token_without_trust_object;
+ }
+ if (token_with_trust_object) {
+ return token_with_trust_object;
+ }
+ return ro_token_without_trust_object;
}
NSS_EXTERN PRStatus