Bug 1928997: Update tabs icon in Unified Search popup r=desktop-theme-reviewers,daleh...
[gecko.git] / security / manager / ssl / nsNSSCertificate.cpp
blobd0413c0340e0cd21695c51e91ecc6f4e3eef7ef4
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsNSSCertificate.h"
8 #include "CertVerifier.h"
9 #include "ExtendedValidation.h"
10 #include "NSSCertDBTrustDomain.h"
11 #include "X509CertValidity.h"
12 #include "certdb.h"
13 #include "ipc/IPCMessageUtils.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Base64.h"
16 #include "mozilla/Casting.h"
17 #include "mozilla/NotNull.h"
18 #include "mozilla/Span.h"
19 #include "mozilla/TextUtils.h"
20 #include "mozilla/Unused.h"
21 #include "mozilla/ipc/TransportSecurityInfoUtils.h"
22 #include "mozilla/ipc/IPDLParamTraits.h"
23 #include "mozilla/net/DNS.h"
24 #include "mozpkix/Result.h"
25 #include "mozpkix/pkixnss.h"
26 #include "mozpkix/pkixtypes.h"
27 #include "mozpkix/pkixutil.h"
28 #include "nsArray.h"
29 #include "nsCOMPtr.h"
30 #include "nsIClassInfoImpl.h"
31 #include "nsIObjectInputStream.h"
32 #include "nsIObjectOutputStream.h"
33 #include "nsIX509Cert.h"
34 #include "nsNSSCertHelper.h"
35 #include "nsNSSCertTrust.h"
36 #include "nsPK11TokenDB.h"
37 #include "nsPKCS12Blob.h"
38 #include "nsProxyRelease.h"
39 #include "nsReadableUtils.h"
40 #include "nsString.h"
41 #include "nsThreadUtils.h"
42 #include "nsUnicharUtils.h"
43 #include "nspr.h"
44 #include "prerror.h"
45 #include "secasn1.h"
46 #include "secder.h"
47 #include "secerr.h"
48 #include "ssl.h"
50 #ifdef XP_WIN
51 # include <winsock.h> // for htonl
52 #endif
54 using namespace mozilla;
55 using namespace mozilla::psm;
57 extern LazyLogModule gPIPNSSLog;
59 NS_IMPL_ISUPPORTS(nsNSSCertificate, nsIX509Cert, nsISerializable, nsIClassInfo)
61 nsNSSCertificate::nsNSSCertificate() : mCert("nsNSSCertificate::mCert") {}
63 nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert)
64 : mCert("nsNSSCertificate::mCert") {
65 if (cert) {
66 mDER.AppendElements(cert->derCert.data, cert->derCert.len);
67 auto lock = mCert.Lock();
68 auto& maybeCert = lock.ref();
69 maybeCert.emplace(UniqueCERTCertificate(CERT_DupCertificate(cert)));
73 nsNSSCertificate::nsNSSCertificate(nsTArray<uint8_t>&& der)
74 : mDER(std::move(der)), mCert("nsNSSCertificate::mCert") {}
76 UniqueCERTCertificate nsNSSCertificate::GetOrInstantiateCert() {
77 auto lock = mCert.Lock();
78 auto& maybeCert = lock.ref();
79 if (maybeCert.isSome()) {
80 return UniqueCERTCertificate(CERT_DupCertificate((*maybeCert).get()));
83 if (!EnsureNSSInitializedChromeOrContent()) {
84 return nullptr;
87 SECItem derItem = {siBuffer, mDER.Elements(),
88 static_cast<unsigned int>(mDER.Length())};
89 UniqueCERTCertificate cert(CERT_NewTempCertificate(
90 CERT_GetDefaultCertDB(), &derItem, nullptr, false, true));
91 if (!cert) {
92 return nullptr;
94 maybeCert.emplace(std::move(cert));
96 return UniqueCERTCertificate(CERT_DupCertificate((*maybeCert).get()));
99 nsresult nsNSSCertificate::GetCertType(uint32_t* aCertType) {
100 UniqueCERTCertificate cert(GetOrInstantiateCert());
101 if (!cert) {
102 return NS_ERROR_FAILURE;
104 CERTCertTrust certTrust{0, 0, 0};
105 // If there is no stored trust information, CERT_GetCertTrust will return
106 // SECFailure. This isn't a failure. In this case, all trust bits will remain
107 // unset.
108 Unused << CERT_GetCertTrust(cert.get(), &certTrust);
109 nsNSSCertTrust trust(&certTrust);
110 if (cert->nickname && trust.HasAnyUser()) {
111 *aCertType = nsIX509Cert::USER_CERT;
112 return NS_OK;
114 if (trust.HasAnyCA()) {
115 *aCertType = nsIX509Cert::CA_CERT;
116 return NS_OK;
118 if (trust.HasPeer(true, false)) {
119 *aCertType = nsIX509Cert::SERVER_CERT;
120 return NS_OK;
122 if (trust.HasPeer(false, true) && cert->emailAddr) {
123 *aCertType = nsIX509Cert::EMAIL_CERT;
124 return NS_OK;
126 if (CERT_IsCACert(cert.get(), nullptr)) {
127 *aCertType = nsIX509Cert::CA_CERT;
128 return NS_OK;
130 if (cert->emailAddr) {
131 *aCertType = nsIX509Cert::EMAIL_CERT;
132 return NS_OK;
134 *aCertType = nsIX509Cert::UNKNOWN_CERT;
135 return NS_OK;
138 NS_IMETHODIMP
139 nsNSSCertificate::GetDbKey(nsACString& aDbKey) {
140 static_assert(sizeof(uint64_t) == 8, "type size consistency check");
141 static_assert(sizeof(uint32_t) == 4, "type size consistency check");
143 pkix::Input certInput;
144 pkix::Result result = certInput.Init(mDER.Elements(), mDER.Length());
145 if (result != pkix::Result::Success) {
146 return NS_ERROR_INVALID_ARG;
148 // NB: since we're not building a trust path, the endEntityOrCA parameter is
149 // irrelevant.
150 pkix::BackCert cert(certInput, pkix::EndEntityOrCA::MustBeEndEntity, nullptr);
151 result = cert.Init();
152 if (result != pkix::Result::Success) {
153 return NS_ERROR_INVALID_ARG;
156 // The format of the key is the base64 encoding of the following:
157 // 4 bytes: {0, 0, 0, 0} (this was intended to be the module ID, but it was
158 // never implemented)
159 // 4 bytes: {0, 0, 0, 0} (this was intended to be the slot ID, but it was
160 // never implemented)
161 // 4 bytes: <serial number length in big-endian order>
162 // 4 bytes: <DER-encoded issuer distinguished name length in big-endian order>
163 // n bytes: <bytes of serial number>
164 // m bytes: <DER-encoded issuer distinguished name>
165 nsAutoCString buf;
166 const char leadingZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0};
167 buf.Append(leadingZeroes, sizeof(leadingZeroes));
168 uint32_t serialNumberLen = htonl(cert.GetSerialNumber().GetLength());
169 buf.Append(BitwiseCast<const char*, const uint32_t*>(&serialNumberLen),
170 sizeof(uint32_t));
171 uint32_t issuerLen = htonl(cert.GetIssuer().GetLength());
172 buf.Append(BitwiseCast<const char*, const uint32_t*>(&issuerLen),
173 sizeof(uint32_t));
174 buf.Append(BitwiseCast<const char*, const unsigned char*>(
175 cert.GetSerialNumber().UnsafeGetData()),
176 cert.GetSerialNumber().GetLength());
177 buf.Append(BitwiseCast<const char*, const unsigned char*>(
178 cert.GetIssuer().UnsafeGetData()),
179 cert.GetIssuer().GetLength());
181 return Base64Encode(buf, aDbKey);
184 NS_IMETHODIMP
185 nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) {
186 aDisplayName.Truncate();
188 UniqueCERTCertificate cert(GetOrInstantiateCert());
189 if (!cert) {
190 return NS_ERROR_FAILURE;
193 UniquePORTString commonName(CERT_GetCommonName(&cert->subject));
194 UniquePORTString organizationalUnitName(CERT_GetOrgUnitName(&cert->subject));
195 UniquePORTString organizationName(CERT_GetOrgName(&cert->subject));
197 // Only use the nickname for built-in roots where we already have a hard-coded
198 // reasonable display name (unfortunately we have to strip off the leading
199 // slot identifier followed by a ':'). Otherwise, attempt to use the following
200 // in order:
201 // - the common name, if present
202 // - an organizational unit name, if present
203 // - an organization name, if present
204 // - the entire subject distinguished name, if non-empty
205 // - an email address, if one can be found
206 // In the unlikely event that none of these fields are present and non-empty
207 // (the subject really shouldn't be empty), an empty string is returned.
208 nsAutoCString builtInRootNickname;
209 nsAutoCString fullNickname(cert->nickname);
210 static const nsLiteralCString kBuiltinObjectTokenPrefix =
211 "Builtin Object Token:"_ns;
212 if (StringBeginsWith(fullNickname, kBuiltinObjectTokenPrefix)) {
213 // Substring will gracefully handle the case where index is the last
214 // character in the string (that is, if the nickname is just
215 // "Builtin Object Token:"). In that case, we'll get an empty string.
216 builtInRootNickname =
217 Substring(fullNickname, kBuiltinObjectTokenPrefix.Length());
219 const char* nameOptions[] = {builtInRootNickname.get(),
220 commonName.get(),
221 organizationalUnitName.get(),
222 organizationName.get(),
223 cert->subjectName,
224 cert->emailAddr};
226 for (auto nameOption : nameOptions) {
227 if (nameOption) {
228 size_t len = strlen(nameOption);
229 if (len > 0) {
230 LossyUTF8ToUTF16(nameOption, len, aDisplayName);
231 return NS_OK;
236 return NS_OK;
239 NS_IMETHODIMP
240 nsNSSCertificate::GetEmailAddress(nsAString& aEmailAddress) {
241 UniqueCERTCertificate cert(GetOrInstantiateCert());
242 if (!cert) {
243 return NS_ERROR_FAILURE;
245 if (cert->emailAddr) {
246 CopyUTF8toUTF16(MakeStringSpan(cert->emailAddr), aEmailAddress);
247 } else {
248 GetPIPNSSBundleString("CertNoEmailAddress", aEmailAddress);
250 return NS_OK;
253 NS_IMETHODIMP
254 nsNSSCertificate::GetEmailAddresses(nsTArray<nsString>& aAddresses) {
255 UniqueCERTCertificate cert(GetOrInstantiateCert());
256 if (!cert) {
257 return NS_ERROR_FAILURE;
259 uint32_t length = 0;
260 for (const char* aAddr = CERT_GetFirstEmailAddress(cert.get()); aAddr;
261 aAddr = CERT_GetNextEmailAddress(cert.get(), aAddr)) {
262 ++(length);
265 aAddresses.SetCapacity(length);
267 for (const char* aAddr = CERT_GetFirstEmailAddress(cert.get()); aAddr;
268 aAddr = CERT_GetNextEmailAddress(cert.get(), aAddr)) {
269 CopyASCIItoUTF16(MakeStringSpan(aAddr), *aAddresses.AppendElement());
272 return NS_OK;
275 NS_IMETHODIMP
276 nsNSSCertificate::ContainsEmailAddress(const nsAString& aEmailAddress,
277 bool* result) {
278 NS_ENSURE_ARG(result);
279 *result = false;
281 UniqueCERTCertificate cert(GetOrInstantiateCert());
282 if (!cert) {
283 return NS_ERROR_FAILURE;
285 for (const char* aAddr = CERT_GetFirstEmailAddress(cert.get()); aAddr;
286 aAddr = CERT_GetNextEmailAddress(cert.get(), aAddr)) {
287 nsAutoString certAddr;
288 LossyUTF8ToUTF16(aAddr, strlen(aAddr), certAddr);
289 ToLowerCase(certAddr);
291 nsAutoString testAddr(aEmailAddress);
292 ToLowerCase(testAddr);
294 if (certAddr == testAddr) {
295 *result = true;
296 break;
300 return NS_OK;
303 NS_IMETHODIMP
304 nsNSSCertificate::GetCommonName(nsAString& aCommonName) {
305 aCommonName.Truncate();
306 UniqueCERTCertificate cert(GetOrInstantiateCert());
307 if (!cert) {
308 return NS_ERROR_FAILURE;
310 UniquePORTString commonName(CERT_GetCommonName(&cert->subject));
311 if (commonName) {
312 LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
314 return NS_OK;
317 NS_IMETHODIMP
318 nsNSSCertificate::GetOrganization(nsAString& aOrganization) {
319 aOrganization.Truncate();
320 UniqueCERTCertificate cert(GetOrInstantiateCert());
321 if (!cert) {
322 return NS_ERROR_FAILURE;
324 UniquePORTString organization(CERT_GetOrgName(&cert->subject));
325 if (organization) {
326 LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
327 aOrganization);
329 return NS_OK;
332 NS_IMETHODIMP
333 nsNSSCertificate::GetIssuerCommonName(nsAString& aCommonName) {
334 aCommonName.Truncate();
335 UniqueCERTCertificate cert(GetOrInstantiateCert());
336 if (!cert) {
337 return NS_ERROR_FAILURE;
339 UniquePORTString commonName(CERT_GetCommonName(&cert->issuer));
340 if (commonName) {
341 LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName);
343 return NS_OK;
346 NS_IMETHODIMP
347 nsNSSCertificate::GetIssuerOrganization(nsAString& aOrganization) {
348 aOrganization.Truncate();
349 UniqueCERTCertificate cert(GetOrInstantiateCert());
350 if (!cert) {
351 return NS_ERROR_FAILURE;
353 UniquePORTString organization(CERT_GetOrgName(&cert->issuer));
354 if (organization) {
355 LossyUTF8ToUTF16(organization.get(), strlen(organization.get()),
356 aOrganization);
358 return NS_OK;
361 NS_IMETHODIMP
362 nsNSSCertificate::GetIssuerOrganizationUnit(nsAString& aOrganizationUnit) {
363 aOrganizationUnit.Truncate();
364 UniqueCERTCertificate cert(GetOrInstantiateCert());
365 if (!cert) {
366 return NS_ERROR_FAILURE;
368 UniquePORTString organizationUnit(CERT_GetOrgUnitName(&cert->issuer));
369 if (organizationUnit) {
370 LossyUTF8ToUTF16(organizationUnit.get(), strlen(organizationUnit.get()),
371 aOrganizationUnit);
373 return NS_OK;
376 NS_IMETHODIMP
377 nsNSSCertificate::GetOrganizationalUnit(nsAString& aOrganizationalUnit) {
378 aOrganizationalUnit.Truncate();
379 UniqueCERTCertificate cert(GetOrInstantiateCert());
380 if (!cert) {
381 return NS_ERROR_FAILURE;
383 UniquePORTString orgunit(CERT_GetOrgUnitName(&cert->subject));
384 if (orgunit) {
385 LossyUTF8ToUTF16(orgunit.get(), strlen(orgunit.get()), aOrganizationalUnit);
387 return NS_OK;
390 NS_IMETHODIMP
391 nsNSSCertificate::GetSubjectName(nsAString& _subjectName) {
392 _subjectName.Truncate();
393 UniqueCERTCertificate cert(GetOrInstantiateCert());
394 if (!cert) {
395 return NS_ERROR_FAILURE;
397 if (cert->subjectName) {
398 LossyUTF8ToUTF16(cert->subjectName, strlen(cert->subjectName),
399 _subjectName);
401 return NS_OK;
404 NS_IMETHODIMP
405 nsNSSCertificate::GetIssuerName(nsAString& _issuerName) {
406 _issuerName.Truncate();
407 UniqueCERTCertificate cert(GetOrInstantiateCert());
408 if (!cert) {
409 return NS_ERROR_FAILURE;
411 if (cert->issuerName) {
412 LossyUTF8ToUTF16(cert->issuerName, strlen(cert->issuerName), _issuerName);
414 return NS_OK;
417 NS_IMETHODIMP
418 nsNSSCertificate::GetSerialNumber(nsAString& _serialNumber) {
419 _serialNumber.Truncate();
420 UniqueCERTCertificate cert(GetOrInstantiateCert());
421 if (!cert) {
422 return NS_ERROR_FAILURE;
424 UniquePORTString tmpstr(
425 CERT_Hexify(&cert->serialNumber, true /* use colon delimiters */));
426 if (tmpstr) {
427 _serialNumber = NS_ConvertASCIItoUTF16(tmpstr.get());
428 return NS_OK;
430 return NS_ERROR_FAILURE;
433 nsresult nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint,
434 SECOidTag aHashAlg) {
435 aFingerprint.Truncate();
437 if (!EnsureNSSInitializedChromeOrContent()) {
438 return NS_ERROR_NOT_AVAILABLE;
441 nsTArray<uint8_t> digestArray;
442 nsresult rv =
443 Digest::DigestBuf(aHashAlg, mDER.Elements(), mDER.Length(), digestArray);
444 if (NS_FAILED(rv)) {
445 return rv;
447 SECItem digestItem = {siBuffer, digestArray.Elements(),
448 static_cast<unsigned int>(digestArray.Length())};
450 UniquePORTString fpStr(
451 CERT_Hexify(&digestItem, true /* use colon delimiters */));
452 if (!fpStr) {
453 return NS_ERROR_FAILURE;
456 aFingerprint.AssignASCII(fpStr.get());
457 return NS_OK;
460 NS_IMETHODIMP
461 nsNSSCertificate::GetSha256Fingerprint(nsAString& aSha256Fingerprint) {
462 return GetCertificateHash(aSha256Fingerprint, SEC_OID_SHA256);
465 NS_IMETHODIMP
466 nsNSSCertificate::GetSha1Fingerprint(nsAString& _sha1Fingerprint) {
467 return GetCertificateHash(_sha1Fingerprint, SEC_OID_SHA1);
470 NS_IMETHODIMP
471 nsNSSCertificate::GetTokenName(nsAString& aTokenName) {
472 UniqueCERTCertificate cert(GetOrInstantiateCert());
473 if (!cert) {
474 return NS_ERROR_FAILURE;
476 UniquePK11SlotInfo internalSlot(PK11_GetInternalSlot());
477 if (!internalSlot) {
478 return NS_ERROR_FAILURE;
480 nsCOMPtr<nsIPK11Token> token(
481 new nsPK11Token(cert->slot ? cert->slot : internalSlot.get()));
482 nsAutoCString tmp;
483 nsresult rv = token->GetTokenName(tmp);
484 if (NS_FAILED(rv)) {
485 return rv;
487 aTokenName.Assign(NS_ConvertUTF8toUTF16(tmp));
488 return NS_OK;
491 NS_IMETHODIMP
492 nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(
493 nsACString& aSha256SPKIDigest) {
494 aSha256SPKIDigest.Truncate();
496 if (!EnsureNSSInitializedChromeOrContent()) {
497 return NS_ERROR_NOT_AVAILABLE;
500 pkix::Input certInput;
501 pkix::Result result = certInput.Init(mDER.Elements(), mDER.Length());
502 if (result != pkix::Result::Success) {
503 return NS_ERROR_INVALID_ARG;
505 // NB: since we're not building a trust path, the endEntityOrCA parameter is
506 // irrelevant.
507 pkix::BackCert cert(certInput, pkix::EndEntityOrCA::MustBeEndEntity, nullptr);
508 result = cert.Init();
509 if (result != pkix::Result::Success) {
510 return NS_ERROR_INVALID_ARG;
512 pkix::Input derPublicKey = cert.GetSubjectPublicKeyInfo();
513 nsTArray<uint8_t> digestArray;
514 nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(),
515 derPublicKey.GetLength(), digestArray);
516 if (NS_FAILED(rv)) {
517 return rv;
519 rv = Base64Encode(nsDependentCSubstring(
520 reinterpret_cast<const char*>(digestArray.Elements()),
521 digestArray.Length()),
522 aSha256SPKIDigest);
523 if (NS_WARN_IF(NS_FAILED(rv))) {
524 return rv;
526 return NS_OK;
529 NS_IMETHODIMP
530 nsNSSCertificate::GetRawDER(nsTArray<uint8_t>& aArray) {
531 aArray.SetLength(mDER.Length());
532 memcpy(aArray.Elements(), mDER.Elements(), mDER.Length());
533 return NS_OK;
536 NS_IMETHODIMP
537 nsNSSCertificate::GetBase64DERString(nsACString& base64DERString) {
538 nsDependentCSubstring derString(
539 reinterpret_cast<const char*>(mDER.Elements()), mDER.Length());
540 nsresult rv = Base64Encode(derString, base64DERString);
541 if (NS_FAILED(rv)) {
542 return rv;
544 return NS_OK;
547 CERTCertificate* nsNSSCertificate::GetCert() {
548 UniqueCERTCertificate cert(GetOrInstantiateCert());
549 return cert.release(); // caller takes ownership
552 NS_IMETHODIMP
553 nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity) {
554 NS_ENSURE_ARG(aValidity);
555 pkix::Input certInput;
556 pkix::Result rv = certInput.Init(mDER.Elements(), mDER.Length());
557 if (rv != pkix::Success) {
558 return NS_ERROR_FAILURE;
560 nsCOMPtr<nsIX509CertValidity> validity = new X509CertValidity(certInput);
561 validity.forget(aValidity);
562 return NS_OK;
565 // NB: Any updates (except disk-only fields) must be kept in sync with
566 // |SerializeToIPC|.
567 NS_IMETHODIMP
568 nsNSSCertificate::Write(nsIObjectOutputStream* aStream) {
569 // This field used to be the cached EV status, but it is no longer necessary.
570 nsresult rv = aStream->Write32(0);
571 if (NS_FAILED(rv)) {
572 return rv;
574 rv = aStream->Write32(mDER.Length());
575 if (NS_FAILED(rv)) {
576 return rv;
578 return aStream->WriteBytes(Span(mDER));
581 // NB: Any updates (except disk-only fields) must be kept in sync with
582 // |DeserializeFromIPC|.
583 NS_IMETHODIMP
584 nsNSSCertificate::Read(nsIObjectInputStream* aStream) {
585 auto lock = mCert.Lock();
586 auto& maybeCert = lock.ref();
587 if (!mDER.IsEmpty() || maybeCert.isSome()) {
588 return NS_ERROR_ALREADY_INITIALIZED;
591 // This field is no longer used.
592 uint32_t unusedCachedEVStatus;
593 nsresult rv = aStream->Read32(&unusedCachedEVStatus);
594 if (NS_FAILED(rv)) {
595 return rv;
598 uint32_t len;
599 rv = aStream->Read32(&len);
600 if (NS_FAILED(rv)) {
601 return rv;
604 rv = aStream->ReadByteArray(len, mDER);
605 if (NS_FAILED(rv)) {
606 return rv;
608 return NS_OK;
611 void nsNSSCertificate::SerializeToIPC(IPC::MessageWriter* aWriter) {
612 bool hasCert = !mDER.IsEmpty();
613 WriteParam(aWriter, hasCert);
615 if (!hasCert) {
616 return;
619 WriteParam(aWriter, mDER);
622 bool nsNSSCertificate::DeserializeFromIPC(IPC::MessageReader* aReader) {
623 auto lock = mCert.Lock();
624 auto& maybeCert = lock.ref();
625 if (!mDER.IsEmpty() || maybeCert.isSome()) {
626 return false;
629 bool hasCert = false;
630 if (!ReadParam(aReader, &hasCert)) {
631 return false;
634 if (!hasCert) {
635 return true;
638 if (!ReadParam(aReader, &mDER)) {
639 return false;
641 return true;
644 NS_IMETHODIMP
645 nsNSSCertificate::GetInterfaces(nsTArray<nsIID>& array) {
646 array.Clear();
647 return NS_OK;
650 NS_IMETHODIMP
651 nsNSSCertificate::GetScriptableHelper(nsIXPCScriptable** _retval) {
652 *_retval = nullptr;
653 return NS_OK;
656 NS_IMETHODIMP
657 nsNSSCertificate::GetContractID(nsACString& aContractID) {
658 aContractID.SetIsVoid(true);
659 return NS_OK;
662 NS_IMETHODIMP
663 nsNSSCertificate::GetClassDescription(nsACString& aClassDescription) {
664 aClassDescription.SetIsVoid(true);
665 return NS_OK;
668 NS_IMETHODIMP
669 nsNSSCertificate::GetClassID(nsCID** aClassID) {
670 *aClassID = (nsCID*)moz_xmalloc(sizeof(nsCID));
671 return GetClassIDNoAlloc(*aClassID);
674 NS_IMETHODIMP
675 nsNSSCertificate::GetFlags(uint32_t* aFlags) {
676 *aFlags = nsIClassInfo::THREADSAFE;
677 return NS_OK;
680 NS_IMETHODIMP
681 nsNSSCertificate::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) {
682 static NS_DEFINE_CID(kNSSCertificateCID, NS_X509CERT_CID);
684 *aClassIDNoAlloc = kNSSCertificateCID;
685 return NS_OK;