1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "NSSErrorsService.h"
7 #include "nsIStringBundle.h"
8 #include "nsNSSComponent.h"
9 #include "nsServiceManagerUtils.h"
10 #include "mozpkix/pkixnss.h"
14 #define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties"
15 #define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties"
20 static_assert(mozilla::pkix::ERROR_BASE
==
21 nsINSSErrorsService::MOZILLA_PKIX_ERROR_BASE
,
22 "MOZILLA_PKIX_ERROR_BASE and "
23 "nsINSSErrorsService::MOZILLA_PKIX_ERROR_BASE do not match.");
24 static_assert(mozilla::pkix::ERROR_LIMIT
==
25 nsINSSErrorsService::MOZILLA_PKIX_ERROR_LIMIT
,
26 "MOZILLA_PKIX_ERROR_LIMIT and "
27 "nsINSSErrorsService::MOZILLA_PKIX_ERROR_LIMIT do not match.");
29 static bool IsPSMError(PRErrorCode error
) {
30 return (error
>= mozilla::pkix::ERROR_BASE
&&
31 error
< mozilla::pkix::ERROR_LIMIT
);
34 NS_IMPL_ISUPPORTS(NSSErrorsService
, nsINSSErrorsService
)
36 NSSErrorsService::~NSSErrorsService() = default;
38 nsresult
NSSErrorsService::Init() {
40 nsCOMPtr
<nsIStringBundleService
> bundleService(
41 do_GetService(NS_STRINGBUNDLE_CONTRACTID
, &rv
));
42 if (NS_FAILED(rv
) || !bundleService
) return NS_ERROR_FAILURE
;
44 bundleService
->CreateBundle(PIPNSS_STRBUNDLE_URL
,
45 getter_AddRefs(mPIPNSSBundle
));
46 if (!mPIPNSSBundle
) rv
= NS_ERROR_FAILURE
;
48 bundleService
->CreateBundle(NSSERR_STRBUNDLE_URL
,
49 getter_AddRefs(mNSSErrorsBundle
));
50 if (!mNSSErrorsBundle
) rv
= NS_ERROR_FAILURE
;
55 #define EXPECTED_SEC_ERROR_BASE (-0x2000)
56 #define EXPECTED_SSL_ERROR_BASE (-0x3000)
58 #if SEC_ERROR_BASE != EXPECTED_SEC_ERROR_BASE || \
59 SSL_ERROR_BASE != EXPECTED_SSL_ERROR_BASE
61 "Unexpected change of error code numbers in lib NSS, please adjust the mapping code"
63 * Please ensure the NSS error codes are mapped into the positive range 0x1000
64 * to 0xf000 Search for NS_ERROR_MODULE_SECURITY to ensure there are no
65 * conflicts. The current code also assumes that NSS library error codes are
70 bool IsNSSErrorCode(PRErrorCode code
) {
71 return IS_SEC_ERROR(code
) || IS_SSL_ERROR(code
) || IsPSMError(code
);
74 nsresult
GetXPCOMFromNSSError(PRErrorCode code
) {
76 MOZ_CRASH("Function failed without calling PR_GetError");
79 // The error codes within each module must be a 16 bit value.
80 // For simplicity we use the positive value of the NSS code.
81 return (nsresult
)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY
,
86 NSSErrorsService::IsNSSErrorCode(int32_t aNSPRCode
, bool* _retval
) {
88 return NS_ERROR_INVALID_ARG
;
91 *_retval
= mozilla::psm::IsNSSErrorCode(aNSPRCode
);
96 NSSErrorsService::GetXPCOMFromNSSError(int32_t aNSPRCode
,
97 nsresult
* aXPCOMErrorCode
) {
98 if (!aXPCOMErrorCode
) {
99 return NS_ERROR_INVALID_ARG
;
102 if (!mozilla::psm::IsNSSErrorCode(aNSPRCode
)) {
103 return NS_ERROR_INVALID_ARG
;
106 *aXPCOMErrorCode
= mozilla::psm::GetXPCOMFromNSSError(aNSPRCode
);
112 NSSErrorsService::GetErrorClass(nsresult aXPCOMErrorCode
,
113 uint32_t* aErrorClass
) {
114 NS_ENSURE_ARG(aErrorClass
);
116 if (NS_ERROR_GET_MODULE(aXPCOMErrorCode
) != NS_ERROR_MODULE_SECURITY
||
117 NS_ERROR_GET_SEVERITY(aXPCOMErrorCode
) != NS_ERROR_SEVERITY_ERROR
) {
118 return NS_ERROR_FAILURE
;
121 int32_t aNSPRCode
= -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode
);
123 if (!mozilla::psm::IsNSSErrorCode(aNSPRCode
)) {
124 return NS_ERROR_FAILURE
;
127 if (mozilla::psm::ErrorIsOverridable(aNSPRCode
)) {
128 *aErrorClass
= ERROR_CLASS_BAD_CERT
;
130 *aErrorClass
= ERROR_CLASS_SSL_PROTOCOL
;
136 bool ErrorIsOverridable(PRErrorCode code
) {
138 // Overridable errors.
139 case SEC_ERROR_CA_CERT_INVALID
:
140 case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
:
141 case SEC_ERROR_EXPIRED_CERTIFICATE
:
142 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE
:
143 case SEC_ERROR_INVALID_TIME
:
144 case SEC_ERROR_UNKNOWN_ISSUER
:
145 case SSL_ERROR_BAD_CERT_DOMAIN
:
146 case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED
:
147 case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY
:
148 case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME
:
149 case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE
:
151 MOZILLA_PKIX_ERROR_INSUFFICIENT_CERTIFICATE_TRANSPARENCY
:
152 case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED
:
153 case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE
:
154 case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE
:
155 case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
:
156 case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA
:
158 // Non-overridable errors.
164 static const char* getOverrideErrorStringName(PRErrorCode aErrorCode
) {
165 switch (aErrorCode
) {
166 case SSL_ERROR_SSL_DISABLED
:
167 return "PSMERR_SSL_Disabled";
168 case SSL_ERROR_SSL2_DISABLED
:
169 return "PSMERR_SSL2_Disabled";
170 case SEC_ERROR_REUSED_ISSUER_AND_SERIAL
:
171 return "PSMERR_HostReusedIssuerSerial";
172 case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED
:
173 return "certErrorTrust_MitM";
180 NSSErrorsService::GetErrorMessage(nsresult aXPCOMErrorCode
,
181 nsAString
& aErrorMessage
) {
182 if (NS_ERROR_GET_MODULE(aXPCOMErrorCode
) != NS_ERROR_MODULE_SECURITY
||
183 NS_ERROR_GET_SEVERITY(aXPCOMErrorCode
) != NS_ERROR_SEVERITY_ERROR
) {
184 return NS_ERROR_FAILURE
;
187 int32_t aNSPRCode
= -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode
);
189 if (!mozilla::psm::IsNSSErrorCode(aNSPRCode
)) {
190 return NS_ERROR_FAILURE
;
193 nsCOMPtr
<nsIStringBundle
> theBundle
= mPIPNSSBundle
;
194 const char* idStr
= getOverrideErrorStringName(aNSPRCode
);
197 idStr
= PR_ErrorToName(aNSPRCode
);
198 theBundle
= mNSSErrorsBundle
;
201 if (!idStr
|| !theBundle
) {
202 return NS_ERROR_FAILURE
;
206 nsresult rv
= theBundle
->GetStringFromName(idStr
, msg
);
207 if (NS_SUCCEEDED(rv
)) {
214 } // namespace mozilla