forked from mirrors/gecko-dev
Bug 1596401 - rework certificate deletion so it happens immediately r=rmf
Differential Revision: https://phabricator.services.mozilla.com/D86775
This commit is contained in:
parent
f68ef97340
commit
67e203a187
4 changed files with 35 additions and 60 deletions
|
|
@ -228,13 +228,6 @@ interface nsIX509Cert : nsISupports {
|
|||
[notxpcom, noscript, must_use]
|
||||
CERTCertificatePtr getCert();
|
||||
|
||||
/**
|
||||
* Either delete the certificate from all cert databases,
|
||||
* or mark it as untrusted.
|
||||
*/
|
||||
[must_use]
|
||||
void markForPermDeletion();
|
||||
|
||||
[notxpcom, noscript]
|
||||
void SerializeToIPC(in IpcMessagePtr aMsg);
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ bool nsNSSCertificate::InitFromDER(char* certDER, int derLen) {
|
|||
|
||||
nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert)
|
||||
: mCert(nullptr),
|
||||
mPermDelete(false),
|
||||
mCertType(CERT_TYPE_NOT_YET_INITIALIZED),
|
||||
mSubjectAltNames() {
|
||||
if (cert) {
|
||||
|
|
@ -118,24 +117,9 @@ nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert)
|
|||
|
||||
nsNSSCertificate::nsNSSCertificate()
|
||||
: mCert(nullptr),
|
||||
mPermDelete(false),
|
||||
mCertType(CERT_TYPE_NOT_YET_INITIALIZED),
|
||||
mSubjectAltNames() {}
|
||||
|
||||
nsNSSCertificate::~nsNSSCertificate() {
|
||||
if (mPermDelete) {
|
||||
if (mCertType == nsNSSCertificate::USER_CERT) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
|
||||
PK11_DeleteTokenCertAndKey(mCert.get(), cxt);
|
||||
} else if (mCert->slot && !PK11_IsReadOnly(mCert->slot)) {
|
||||
// If the list of built-ins does contain a non-removable
|
||||
// copy of this certificate, our call will not remove
|
||||
// the certificate permanently, but rather remove all trust.
|
||||
SEC_DeletePermCertificate(mCert.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t getCertType(CERTCertificate* cert) {
|
||||
nsNSSCertTrust trust(cert->trust);
|
||||
if (cert->nickname && trust.HasAnyUser()) {
|
||||
|
|
@ -187,21 +171,6 @@ nsNSSCertificate::GetIsBuiltInRoot(bool* aIsBuiltInRoot) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNSSCertificate::MarkForPermDeletion() {
|
||||
// make sure user is logged in to the token
|
||||
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
|
||||
|
||||
if (mCert->slot && PK11_NeedLogin(mCert->slot) &&
|
||||
!PK11_NeedUserInit(mCert->slot) && !PK11_IsInternal(mCert->slot)) {
|
||||
if (SECSuccess != PK11_Authenticate(mCert->slot, true, ctx)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
mPermDelete = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a pipnss bundle string to the given string.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -68,10 +68,9 @@ class nsNSSCertificate final : public nsIX509Cert,
|
|||
/* out */ nsCOMPtr<nsIX509Cert>& aRoot);
|
||||
|
||||
private:
|
||||
virtual ~nsNSSCertificate();
|
||||
virtual ~nsNSSCertificate() = default;
|
||||
|
||||
mozilla::UniqueCERTCertificate mCert;
|
||||
bool mPermDelete;
|
||||
uint32_t mCertType;
|
||||
std::vector<nsString> mSubjectAltNames;
|
||||
nsresult GetSortableDate(PRTime aTime, nsAString& _aSortableDate);
|
||||
|
|
|
|||
|
|
@ -620,27 +620,41 @@ nsNSSCertificateDB::DeleteCertificate(nsIX509Cert* aCert) {
|
|||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
SECStatus srv = SECSuccess;
|
||||
|
||||
// Temporary certificates aren't on a slot and will go away when the
|
||||
// nsIX509Cert is destructed.
|
||||
if (cert->slot) {
|
||||
uint32_t certType;
|
||||
aCert->GetCertType(&certType);
|
||||
if (NS_FAILED(aCert->MarkForPermDeletion())) {
|
||||
nsresult rv = aCert->GetCertType(&certType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (certType == nsIX509Cert::USER_CERT) {
|
||||
SECStatus srv = PK11_Authenticate(cert->slot, true, nullptr);
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (cert->slot && certType != nsIX509Cert::USER_CERT) {
|
||||
// To delete a cert of a slot (builtin, most likely), mark it as
|
||||
// completely untrusted. This way we keep a copy cached in the
|
||||
// local database, and next time we try to load it off of the
|
||||
// external token/slot, we'll know not to trust it. We don't
|
||||
// want to do that with user certs, because a user may re-store
|
||||
// the cert onto the card again at which point we *will* want to
|
||||
// trust that cert if it chains up properly.
|
||||
nsNSSCertTrust trust(0, 0);
|
||||
srv = ChangeCertTrustWithPossibleAuthentication(cert, trust.GetTrust(),
|
||||
nullptr);
|
||||
srv = PK11_DeleteTokenCertAndKey(cert.get(), nullptr);
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// For certificates that can't be deleted (e.g. built-in roots), un-set
|
||||
// all trust bits.
|
||||
nsNSSCertTrust trust(0, 0);
|
||||
SECStatus srv = ChangeCertTrustWithPossibleAuthentication(
|
||||
cert, trust.GetTrust(), nullptr);
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!PK11_IsReadOnly(cert->slot)) {
|
||||
srv = SEC_DeletePermCertificate(cert.get());
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("cert deleted: %d", srv));
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
|
|
@ -649,7 +663,7 @@ nsNSSCertificateDB::DeleteCertificate(nsIX509Cert* aCert) {
|
|||
nullptr);
|
||||
}
|
||||
|
||||
return (srv) ? NS_ERROR_FAILURE : NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
|||
Loading…
Reference in a new issue