michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "NSSErrorsService.h" michael@0: michael@0: #include "nsNSSComponent.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "secerr.h" michael@0: #include "sslerr.h" michael@0: michael@0: #define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties" michael@0: #define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties" michael@0: michael@0: namespace mozilla { michael@0: namespace psm { michael@0: michael@0: NS_IMPL_ISUPPORTS(NSSErrorsService, nsINSSErrorsService) michael@0: michael@0: nsresult michael@0: NSSErrorsService::Init() michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv)); michael@0: if (NS_FAILED(rv) || !bundleService) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: bundleService->CreateBundle(PIPNSS_STRBUNDLE_URL, michael@0: getter_AddRefs(mPIPNSSBundle)); michael@0: if (!mPIPNSSBundle) michael@0: rv = NS_ERROR_FAILURE; michael@0: michael@0: bundleService->CreateBundle(NSSERR_STRBUNDLE_URL, michael@0: getter_AddRefs(mNSSErrorsBundle)); michael@0: if (!mNSSErrorsBundle) michael@0: rv = NS_ERROR_FAILURE; michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: #define EXPECTED_SEC_ERROR_BASE (-0x2000) michael@0: #define EXPECTED_SSL_ERROR_BASE (-0x3000) michael@0: michael@0: #if SEC_ERROR_BASE != EXPECTED_SEC_ERROR_BASE || SSL_ERROR_BASE != EXPECTED_SSL_ERROR_BASE michael@0: #error "Unexpected change of error code numbers in lib NSS, please adjust the mapping code" michael@0: /* michael@0: * Please ensure the NSS error codes are mapped into the positive range 0x1000 to 0xf000 michael@0: * Search for NS_ERROR_MODULE_SECURITY to ensure there are no conflicts. michael@0: * The current code also assumes that NSS library error codes are negative. michael@0: */ michael@0: #endif michael@0: michael@0: NS_IMETHODIMP michael@0: NSSErrorsService::IsNSSErrorCode(int32_t aNSPRCode, bool *_retval) michael@0: { michael@0: if (!_retval) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *_retval = IS_SEC_ERROR(aNSPRCode) || IS_SSL_ERROR(aNSPRCode); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NSSErrorsService::GetXPCOMFromNSSError(int32_t aNSPRCode, nsresult *aXPCOMErrorCode) michael@0: { michael@0: if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: if (!aXPCOMErrorCode) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: // The error codes within each module may be a 16 bit value. michael@0: // For simplicity let's use the positive value of the NSS code. michael@0: // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113) michael@0: michael@0: *aXPCOMErrorCode = michael@0: (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY, michael@0: -1 * aNSPRCode); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NSSErrorsService::GetErrorClass(nsresult aXPCOMErrorCode, uint32_t *aErrorClass) michael@0: { michael@0: NS_ENSURE_ARG(aErrorClass); michael@0: michael@0: if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY michael@0: || NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode); michael@0: michael@0: if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: switch (aNSPRCode) michael@0: { michael@0: // Overridable errors. michael@0: case SEC_ERROR_UNKNOWN_ISSUER: michael@0: case SEC_ERROR_UNTRUSTED_ISSUER: michael@0: case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: michael@0: case SEC_ERROR_UNTRUSTED_CERT: michael@0: case SSL_ERROR_BAD_CERT_DOMAIN: michael@0: case SEC_ERROR_EXPIRED_CERTIFICATE: michael@0: case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: michael@0: case SEC_ERROR_CA_CERT_INVALID: michael@0: *aErrorClass = ERROR_CLASS_BAD_CERT; michael@0: break; michael@0: // Non-overridable errors. michael@0: default: michael@0: *aErrorClass = ERROR_CLASS_SSL_PROTOCOL; michael@0: break; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: NSSErrorsService::GetErrorMessage(nsresult aXPCOMErrorCode, nsAString &aErrorMessage) michael@0: { michael@0: if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY michael@0: || NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: int32_t aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode); michael@0: michael@0: if (!IS_SEC_ERROR(aNSPRCode) && !IS_SSL_ERROR(aNSPRCode)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsCOMPtr theBundle = mPIPNSSBundle; michael@0: const char *id_str = nsNSSErrors::getOverrideErrorStringName(aNSPRCode); michael@0: michael@0: if (!id_str) { michael@0: id_str = nsNSSErrors::getDefaultErrorStringName(aNSPRCode); michael@0: theBundle = mNSSErrorsBundle; michael@0: } michael@0: michael@0: if (!id_str || !theBundle) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsAutoString msg; michael@0: nsresult rv = michael@0: theBundle->GetStringFromName(NS_ConvertASCIItoUTF16(id_str).get(), michael@0: getter_Copies(msg)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: aErrorMessage = msg; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: } // psm michael@0: } // mozilla