Bug 1304587 - Avoid using types that correspond to char/char16_t strings in PKCS #11 IDL files. r=keeler
Typically, the interfaces involved don't need to use raw char/char16_t strings,
and hence can benefit from the additional safety of using the Mozilla string
classes.
In some places, this patch also changes some UTF-16 APIs to UTF-8 where the
implementations can never actually support UTF-16. This reduces the amount of
code and runtime conversion.
MozReview-Commit-ID: y8o5wLBohe
--- a/security/manager/ssl/nsIPK11Token.idl
+++ b/security/manager/ssl/nsIPK11Token.idl
@@ -11,23 +11,31 @@ interface nsIPK11Token : nsISupports
{
const long ASK_EVERY_TIME = -1;
const long ASK_FIRST_TIME = 0;
const long ASK_EXPIRE_TIME = 1;
/*
* The name of the token
*/
- readonly attribute wstring tokenName;
-
- readonly attribute wstring tokenLabel;
- readonly attribute wstring tokenManID;
- readonly attribute wstring tokenHWVersion;
- readonly attribute wstring tokenFWVersion;
- readonly attribute wstring tokenSerialNumber;
+ readonly attribute AUTF8String tokenName;
+ readonly attribute AUTF8String tokenLabel;
+ /**
+ * Manufacturer ID of the token.
+ */
+ readonly attribute AUTF8String tokenManID;
+ /**
+ * Hardware version of the token.
+ */
+ readonly attribute AUTF8String tokenHWVersion;
+ /**
+ * Firmware version of the token.
+ */
+ readonly attribute AUTF8String tokenFWVersion;
+ readonly attribute AUTF8String tokenSerialNumber;
/*
* Login information
*/
boolean isLoggedIn();
void login(in boolean force);
void logoutSimple();
void logoutAndDropAuthenticatedResources();
@@ -37,19 +45,26 @@ interface nsIPK11Token : nsISupports
*/
void reset();
/*
* Password information
*/
readonly attribute long minimumPasswordLength;
readonly attribute boolean needsUserInit;
- boolean checkPassword(in wstring password); /* Logs out if check fails */
- void initPassword(in wstring initialPassword);
- void changePassword(in wstring oldPassword, in wstring newPassword);
+ /**
+ * Checks whether the given password is correct. Logs the token out if an
+ * incorrect password is given.
+ *
+ * @param password The password to check.
+ * @return true if the password was correct, false otherwise.
+ */
+ boolean checkPassword(in AUTF8String password);
+ void initPassword(in AUTF8String initialPassword);
+ void changePassword(in AUTF8String oldPassword, in AUTF8String newPassword);
long getAskPasswordTimes();
long getAskPasswordTimeout();
void setAskPasswordDefaults([const] in long askTimes, [const] in long timeout);
/*
* Other attributes
*/
boolean isHardwareToken();
--- a/security/manager/ssl/nsIPK11TokenDB.idl
+++ b/security/manager/ssl/nsIPK11TokenDB.idl
@@ -28,15 +28,15 @@ interface nsIPK11TokenDB : nsISupports
/*
* Get the internal key database token
*/
nsIPK11Token getInternalKeyToken();
/*
* Find a token by name
*/
- nsIPK11Token findTokenByName(in wstring tokenName);
+ nsIPK11Token findTokenByName(in AUTF8String tokenName);
/*
* List all tokens
*/
nsISimpleEnumerator listTokens();
};
--- a/security/manager/ssl/nsIPKCS11Module.idl
+++ b/security/manager/ssl/nsIPKCS11Module.idl
@@ -7,15 +7,15 @@
#include "nsISupports.idl"
interface nsIPKCS11Slot;
interface nsISimpleEnumerator;
[scriptable, uuid(8a44bdf9-d1a5-4734-bd5a-34ed7fe564c2)]
interface nsIPKCS11Module : nsISupports
{
- readonly attribute wstring name;
- readonly attribute wstring libName;
+ readonly attribute AUTF8String name;
+ readonly attribute AUTF8String libName;
- nsIPKCS11Slot findSlotByName(in wstring name);
+ nsIPKCS11Slot findSlotByName(in AUTF8String name);
nsISimpleEnumerator listSlots();
};
--- a/security/manager/ssl/nsIPKCS11ModuleDB.idl
+++ b/security/manager/ssl/nsIPKCS11ModuleDB.idl
@@ -16,19 +16,19 @@ interface nsISimpleEnumerator;
[scriptable, uuid(ff9fbcd7-9517-4334-b97a-ceed78909974)]
interface nsIPKCS11ModuleDB : nsISupports
{
nsIPKCS11Module getInternal();
nsIPKCS11Module getInternalFIPS();
- nsIPKCS11Module findModuleByName(in wstring name);
+ nsIPKCS11Module findModuleByName(in AUTF8String name);
- nsIPKCS11Slot findSlotByName(in wstring name);
+ nsIPKCS11Slot findSlotByName(in AUTF8String name);
nsISimpleEnumerator listModules();
readonly attribute boolean canToggleFIPS;
void toggleFIPSMode();
readonly attribute boolean isFIPSEnabled;
--- a/security/manager/ssl/nsIPKCS11Slot.idl
+++ b/security/manager/ssl/nsIPKCS11Slot.idl
@@ -5,34 +5,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIPK11Token;
[scriptable, uuid(c2d4f296-ee60-11d4-998b-00b0d02354a0)]
interface nsIPKCS11Slot : nsISupports {
-
- readonly attribute wstring name;
- readonly attribute wstring desc;
- readonly attribute wstring manID;
- readonly attribute wstring HWVersion;
- readonly attribute wstring FWVersion;
+ readonly attribute AUTF8String name;
+ readonly attribute AUTF8String desc;
+ /**
+ * Manufacturer ID of the slot.
+ */
+ readonly attribute AUTF8String manID;
+ /**
+ * Hardware version of the slot.
+ */
+ readonly attribute AUTF8String HWVersion;
+ /**
+ * Firmware version of the slot.
+ */
+ readonly attribute AUTF8String FWVersion;
const unsigned long SLOT_DISABLED = 0;
const unsigned long SLOT_NOT_PRESENT = 1;
const unsigned long SLOT_UNINITIALIZED = 2;
const unsigned long SLOT_NOT_LOGGED_IN = 3;
const unsigned long SLOT_LOGGED_IN = 4;
const unsigned long SLOT_READY = 5;
readonly attribute unsigned long status;
/* This is really a workaround for now. All of the "slot" functions
* (isTokenPresent(), etc.) are in nsIPK11Token. For now, return the
* token and handle those things there.
*/
nsIPK11Token getToken();
/* more fun with workarounds - we're referring to everything by token name */
- readonly attribute wstring tokenName;
-
+ readonly attribute AUTF8String tokenName;
};
-
--- a/security/manager/ssl/nsPK11TokenDB.cpp
+++ b/security/manager/ssl/nsPK11TokenDB.cpp
@@ -1,24 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPK11TokenDB.h"
+#include "ScopedNSSTypes.h"
#include "mozilla/Casting.h"
#include "mozilla/Unused.h"
#include "nsIMutableArray.h"
#include "nsISupports.h"
#include "nsNSSComponent.h"
+#include "nsPromiseFlatString.h"
#include "nsReadableUtils.h"
#include "nsServiceManagerUtils.h"
#include "prerror.h"
-#include "ScopedNSSTypes.h"
#include "secerr.h"
extern mozilla::LazyLogModule gPIPNSSLog;
NS_IMPL_ISUPPORTS(nsPK11Token, nsIPK11Token)
nsPK11Token::nsPK11Token(PK11SlotInfo* slot)
: mUIContext(new PipUIContext())
@@ -33,58 +34,56 @@ nsPK11Token::nsPK11Token(PK11SlotInfo* s
mSeries = PK11_GetSlotSeries(slot);
Unused << refreshTokenInfo(locker);
}
nsresult
nsPK11Token::refreshTokenInfo(const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
- mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot.get()));
+ mTokenName = PK11_GetTokenName(mSlot.get());
CK_TOKEN_INFO tokInfo;
nsresult rv = MapSECStatus(PK11_GetTokenInfo(mSlot.get(), &tokInfo));
if (NS_FAILED(rv)) {
return rv;
}
// Set the Label field
const char* ccLabel = mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(tokInfo.label);
- const nsACString& cLabel = Substring(
- ccLabel,
- ccLabel + PL_strnlen(ccLabel, sizeof(tokInfo.label)));
- mTokenLabel = NS_ConvertUTF8toUTF16(cLabel);
+ // TODO(Bug 1305930): Stop using PL_strnlen() if/when all our supported
+ // platforms provide strnlen().
+ mTokenLabel.Assign(ccLabel, PL_strnlen(ccLabel, sizeof(tokInfo.label)));
mTokenLabel.Trim(" ", false, true);
// Set the Manufacturer field
const char* ccManID =
mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(tokInfo.manufacturerID);
- const nsACString& cManID = Substring(
+ mTokenManufacturerID.Assign(
ccManID,
- ccManID + PL_strnlen(ccManID, sizeof(tokInfo.manufacturerID)));
- mTokenManID = NS_ConvertUTF8toUTF16(cManID);
- mTokenManID.Trim(" ", false, true);
+ PL_strnlen(ccManID, sizeof(tokInfo.manufacturerID)));
+ mTokenManufacturerID.Trim(" ", false, true);
// Set the Hardware Version field
+ mTokenHWVersion.Truncate();
mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.major);
mTokenHWVersion.Append('.');
mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.minor);
// Set the Firmware Version field
+ mTokenFWVersion.Truncate();
mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.major);
mTokenFWVersion.Append('.');
mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.minor);
// Set the Serial Number field
const char* ccSerial =
mozilla::BitwiseCast<char*, CK_CHAR*>(tokInfo.serialNumber);
- const nsACString& cSerial = Substring(
- ccSerial,
- ccSerial + PL_strnlen(ccSerial, sizeof(tokInfo.serialNumber)));
- mTokenSerialNum = NS_ConvertUTF8toUTF16(cSerial);
+ mTokenSerialNum.Assign(ccSerial,
+ PL_strnlen(ccSerial, sizeof(tokInfo.serialNumber)));
mTokenSerialNum.Trim(" ", false, true);
return NS_OK;
}
nsPK11Token::~nsPK11Token()
{
nsNSSShutDownPreventionLock locker;
@@ -102,147 +101,71 @@ nsPK11Token::virtualDestroyNSSReference(
}
void
nsPK11Token::destructorSafeDestroyNSSReference()
{
mSlot = nullptr;
}
-NS_IMETHODIMP
-nsPK11Token::GetTokenName(char16_t** aTokenName)
+nsresult
+nsPK11Token::GetAttributeHelper(const nsACString& attribute,
+ /*out*/ nsACString& xpcomOutParam)
{
- NS_ENSURE_ARG_POINTER(aTokenName);
-
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
- // handle removals/insertions
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshTokenInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aTokenName = ToNewUnicode(mTokenName);
- if (!*aTokenName) return NS_ERROR_OUT_OF_MEMORY;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPK11Token::GetTokenLabel(char16_t** aTokLabel)
-{
- NS_ENSURE_ARG_POINTER(aTokLabel);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- // handle removals/insertions
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshTokenInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aTokLabel = ToNewUnicode(mTokenLabel);
- if (!*aTokLabel) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPK11Token::GetTokenManID(char16_t** aTokManID)
-{
- NS_ENSURE_ARG_POINTER(aTokManID);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- // handle removals/insertions
+ // Handle removals/insertions.
if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
nsresult rv = refreshTokenInfo(locker);
if (NS_FAILED(rv)) {
return rv;
}
}
- *aTokManID = ToNewUnicode(mTokenManID);
- if (!*aTokManID) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
-}
-NS_IMETHODIMP
-nsPK11Token::GetTokenHWVersion(char16_t** aTokHWVersion)
-{
- NS_ENSURE_ARG_POINTER(aTokHWVersion);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- // handle removals/insertions
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshTokenInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aTokHWVersion = ToNewUnicode(mTokenHWVersion);
- if (!*aTokHWVersion) return NS_ERROR_OUT_OF_MEMORY;
+ xpcomOutParam = attribute;
return NS_OK;
}
NS_IMETHODIMP
-nsPK11Token::GetTokenFWVersion(char16_t** aTokFWVersion)
+nsPK11Token::GetTokenName(/*out*/ nsACString& tokenName)
{
- NS_ENSURE_ARG_POINTER(aTokFWVersion);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
+ return GetAttributeHelper(mTokenName, tokenName);
+}
- // handle removals/insertions
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshTokenInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aTokFWVersion = ToNewUnicode(mTokenFWVersion);
- if (!*aTokFWVersion) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
+NS_IMETHODIMP
+nsPK11Token::GetTokenLabel(/*out*/ nsACString& tokenLabel)
+{
+ return GetAttributeHelper(mTokenLabel, tokenLabel);
}
NS_IMETHODIMP
-nsPK11Token::GetTokenSerialNumber(char16_t** aTokSerialNum)
+nsPK11Token::GetTokenManID(/*out*/ nsACString& tokenManufacturerID)
{
- NS_ENSURE_ARG_POINTER(aTokSerialNum);
+ return GetAttributeHelper(mTokenManufacturerID, tokenManufacturerID);
+}
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
+NS_IMETHODIMP
+nsPK11Token::GetTokenHWVersion(/*out*/ nsACString& tokenHWVersion)
+{
+ return GetAttributeHelper(mTokenHWVersion, tokenHWVersion);
+}
- // handle removals/insertions
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshTokenInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aTokSerialNum = ToNewUnicode(mTokenSerialNum);
- if (!*aTokSerialNum) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
+NS_IMETHODIMP
+nsPK11Token::GetTokenFWVersion(/*out*/ nsACString& tokenFWVersion)
+{
+ return GetAttributeHelper(mTokenFWVersion, tokenFWVersion);
+}
+
+NS_IMETHODIMP
+nsPK11Token::GetTokenSerialNumber(/*out*/ nsACString& tokenSerialNum)
+{
+ return GetAttributeHelper(mTokenSerialNum, tokenSerialNum);
}
NS_IMETHODIMP
nsPK11Token::IsLoggedIn(bool* _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
@@ -338,52 +261,48 @@ nsPK11Token::GetNeedsUserInit(bool* aNee
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
*aNeedsUserInit = PK11_NeedUserInit(mSlot.get());
return NS_OK;
}
NS_IMETHODIMP
-nsPK11Token::CheckPassword(const char16_t* password, bool* _retval)
+nsPK11Token::CheckPassword(const nsACString& password, bool* _retval)
{
- // Note: It's OK for |password| to be null.
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- NS_ConvertUTF16toUTF8 utf8Password(password);
SECStatus srv =
- PK11_CheckUserPassword(mSlot.get(), const_cast<char*>(utf8Password.get()));
+ PK11_CheckUserPassword(mSlot.get(), PromiseFlatCString(password).get());
if (srv != SECSuccess) {
*_retval = false;
PRErrorCode error = PR_GetError();
if (error != SEC_ERROR_BAD_PASSWORD) {
/* something really bad happened - throw an exception */
return mozilla::psm::GetXPCOMFromNSSError(error);
}
} else {
*_retval = true;
}
return NS_OK;
}
NS_IMETHODIMP
-nsPK11Token::InitPassword(const char16_t* initialPassword)
+nsPK11Token::InitPassword(const nsACString& initialPassword)
{
- // Note: It's OK for |initialPassword| to be null.
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- NS_ConvertUTF16toUTF8 utf8Password(initialPassword);
return MapSECStatus(
- PK11_InitPin(mSlot.get(), "", const_cast<char*>(utf8Password.get())));
+ PK11_InitPin(mSlot.get(), "", PromiseFlatCString(initialPassword).get()));
}
NS_IMETHODIMP
nsPK11Token::GetAskPasswordTimes(int32_t* askTimes)
{
NS_ENSURE_ARG_POINTER(askTimes);
nsNSSShutDownPreventionLock locker;
@@ -417,35 +336,31 @@ nsPK11Token::SetAskPasswordDefaults(cons
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
PK11_SetSlotPWValues(mSlot.get(), askTimes, askTimeout);
return NS_OK;
}
NS_IMETHODIMP
-nsPK11Token::ChangePassword(const char16_t* oldPassword,
- const char16_t* newPassword)
+nsPK11Token::ChangePassword(const nsACString& oldPassword,
+ const nsACString& newPassword)
{
- // Note: It's OK for |oldPassword| and |newPassword| to be null.
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- NS_ConvertUTF16toUTF8 utf8OldPassword(oldPassword);
- NS_ConvertUTF16toUTF8 utf8NewPassword(newPassword);
-
- // nsCString.get() will return an empty string instead of nullptr even if it
- // was initialized with nullptr. PK11_ChangePW() has different semantics for
- // the empty string and for nullptr, so we can't just use get().
+ // PK11_ChangePW() has different semantics for the empty string and for
+ // nullptr. In order to support this difference, we need to check IsVoid() to
+ // find out if our caller supplied null/undefined args or just empty strings.
// See Bug 447589.
return MapSECStatus(PK11_ChangePW(
mSlot.get(),
- (oldPassword ? const_cast<char*>(utf8OldPassword.get()) : nullptr),
- (newPassword ? const_cast<char*>(utf8NewPassword.get()) : nullptr)));
+ oldPassword.IsVoid() ? nullptr : PromiseFlatCString(oldPassword).get(),
+ newPassword.IsVoid() ? nullptr : PromiseFlatCString(newPassword).get()));
}
NS_IMETHODIMP
nsPK11Token::IsHardwareToken(bool* _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
@@ -520,29 +435,28 @@ nsPK11TokenDB::GetInternalKeyToken(nsIPK
nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot.get());
token.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
-nsPK11TokenDB::FindTokenByName(const char16_t* tokenName, nsIPK11Token** _retval)
+nsPK11TokenDB::FindTokenByName(const nsACString& tokenName,
+ /*out*/ nsIPK11Token** _retval)
{
- // Note: It's OK for |tokenName| to be null.
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
- NS_ConvertUTF16toUTF8 utf8TokenName(tokenName);
UniquePK11SlotInfo slot(
- PK11_FindSlotByName(const_cast<char*>(utf8TokenName.get())));
+ PK11_FindSlotByName(PromiseFlatCString(tokenName).get()));
if (!slot) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot.get());
token.forget(_retval);
return NS_OK;
--- a/security/manager/ssl/nsPK11TokenDB.h
+++ b/security/manager/ssl/nsPK11TokenDB.h
@@ -28,24 +28,29 @@ public:
protected:
virtual ~nsPK11Token();
private:
friend class nsPK11TokenDB;
nsresult refreshTokenInfo(const nsNSSShutDownPreventionLock& proofOfLock);
- nsString mTokenName;
- nsString mTokenLabel, mTokenManID, mTokenHWVersion, mTokenFWVersion;
- nsString mTokenSerialNum;
+ nsCString mTokenName;
+ nsCString mTokenLabel;
+ nsCString mTokenManufacturerID;
+ nsCString mTokenHWVersion;
+ nsCString mTokenFWVersion;
+ nsCString mTokenSerialNum;
mozilla::UniquePK11SlotInfo mSlot;
int mSeries;
nsCOMPtr<nsIInterfaceRequestor> mUIContext;
virtual void virtualDestroyNSSReference() override;
void destructorSafeDestroyNSSReference();
+ nsresult GetAttributeHelper(const nsACString& attribute,
+ /*out*/ nsACString& xpcomOutParam);
};
class nsPK11TokenDB : public nsIPK11TokenDB
, public nsNSSShutDownObject
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPK11TOKENDB
--- a/security/manager/ssl/nsPKCS11Slot.cpp
+++ b/security/manager/ssl/nsPKCS11Slot.cpp
@@ -6,16 +6,17 @@
#include "mozilla/Casting.h"
#include "mozilla/Logging.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "nsCOMPtr.h"
#include "nsIMutableArray.h"
#include "nsPK11TokenDB.h"
+#include "nsPromiseFlatString.h"
#include "secmod.h"
using mozilla::LogLevel;
extern mozilla::LazyLogModule gPIPNSSLog;
NS_IMPL_ISUPPORTS(nsPKCS11Slot, nsIPKCS11Slot)
@@ -39,39 +40,37 @@ nsPKCS11Slot::refreshSlotInfo(const nsNS
nsresult rv = MapSECStatus(PK11_GetSlotInfo(mSlot.get(), &slotInfo));
if (NS_FAILED(rv)) {
return rv;
}
// Set the Description field
const char* ccDesc =
mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(slotInfo.slotDescription);
- const nsACString& cDesc = Substring(
- ccDesc,
- ccDesc + PL_strnlen(ccDesc, sizeof(slotInfo.slotDescription)));
- mSlotDesc = NS_ConvertUTF8toUTF16(cDesc);
+ // TODO(Bug 1305930): Stop using PL_strnlen() if/when all our supported
+ // platforms provide strnlen().
+ mSlotDesc.Assign(ccDesc, PL_strnlen(ccDesc, sizeof(slotInfo.slotDescription)));
mSlotDesc.Trim(" ", false, true);
// Set the Manufacturer field
const char* ccManID =
mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(slotInfo.manufacturerID);
- const nsACString& cManID = Substring(
+ mSlotManufacturerID.Assign(
ccManID,
- ccManID + PL_strnlen(ccManID, sizeof(slotInfo.manufacturerID)));
- mSlotManID = NS_ConvertUTF8toUTF16(cManID);
- mSlotManID.Trim(" ", false, true);
+ PL_strnlen(ccManID, sizeof(slotInfo.manufacturerID)));
+ mSlotManufacturerID.Trim(" ", false, true);
// Set the Hardware Version field
- mSlotHWVersion = EmptyString();
+ mSlotHWVersion.Truncate();
mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.major);
mSlotHWVersion.Append('.');
mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.minor);
// Set the Firmware Version field
- mSlotFWVersion = EmptyString();
+ mSlotFWVersion.Truncate();
mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.major);
mSlotFWVersion.Append('.');
mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.minor);
return NS_OK;
}
nsPKCS11Slot::~nsPKCS11Slot()
@@ -91,124 +90,82 @@ nsPKCS11Slot::virtualDestroyNSSReference
}
void
nsPKCS11Slot::destructorSafeDestroyNSSReference()
{
mSlot = nullptr;
}
-NS_IMETHODIMP
-nsPKCS11Slot::GetName(char16_t** aName)
+nsresult
+nsPKCS11Slot::GetAttributeHelper(const nsACString& attribute,
+ /*out*/ nsACString& xpcomOutParam)
{
- NS_ENSURE_ARG_POINTER(aName);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown())
- return NS_ERROR_NOT_AVAILABLE;
-
- // |csn| is non-owning.
- char* csn = PK11_GetSlotName(mSlot.get());
- if (*csn) {
- *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(csn));
- } else if (PK11_HasRootCerts(mSlot.get())) {
- // This is a workaround to an Root Module bug - the root certs module has
- // no slot name. Not bothering to localize, because this is a workaround
- // and for now all the slot names returned by NSS are char * anyway.
- *aName = ToNewUnicode(NS_LITERAL_STRING("Root Certificates"));
- } else {
- // same as above, this is a catch-all
- *aName = ToNewUnicode(NS_LITERAL_STRING("Unnamed Slot"));
- }
- if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPKCS11Slot::GetDesc(char16_t** aDesc)
-{
- NS_ENSURE_ARG_POINTER(aDesc);
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown())
- return NS_ERROR_NOT_AVAILABLE;
-
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshSlotInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
-
- *aDesc = ToNewUnicode(mSlotDesc);
- if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPKCS11Slot::GetManID(char16_t** aManID)
-{
- NS_ENSURE_ARG_POINTER(aManID);
-
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
nsresult rv = refreshSlotInfo(locker);
if (NS_FAILED(rv)) {
return rv;
}
}
- *aManID = ToNewUnicode(mSlotManID);
- if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
+
+ xpcomOutParam = attribute;
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11Slot::GetHWVersion(char16_t** aHWVersion)
+nsPKCS11Slot::GetName(/*out*/ nsACString& name)
{
- NS_ENSURE_ARG_POINTER(aHWVersion);
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
+ // |csn| is non-owning.
+ char* csn = PK11_GetSlotName(mSlot.get());
+ if (csn && *csn) {
+ name = csn;
+ } else if (PK11_HasRootCerts(mSlot.get())) {
+ // This is a workaround to an Root Module bug - the root certs module has
+ // no slot name. Not bothering to localize, because this is a workaround
+ // and for now all the slot names returned by NSS are char * anyway.
+ name = NS_LITERAL_CSTRING("Root Certificates");
+ } else {
+ // same as above, this is a catch-all
+ name = NS_LITERAL_CSTRING("Unnamed Slot");
}
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshSlotInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aHWVersion = ToNewUnicode(mSlotHWVersion);
- if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11Slot::GetFWVersion(char16_t** aFWVersion)
+nsPKCS11Slot::GetDesc(/*out*/ nsACString& desc)
{
- NS_ENSURE_ARG_POINTER(aFWVersion);
+ return GetAttributeHelper(mSlotDesc, desc);
+}
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
+NS_IMETHODIMP
+nsPKCS11Slot::GetManID(/*out*/ nsACString& manufacturerID)
+{
+ return GetAttributeHelper(mSlotManufacturerID, manufacturerID);
+}
- if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
- nsresult rv = refreshSlotInfo(locker);
- if (NS_FAILED(rv)) {
- return rv;
- }
- }
- *aFWVersion = ToNewUnicode(mSlotFWVersion);
- if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
+NS_IMETHODIMP
+nsPKCS11Slot::GetHWVersion(/*out*/ nsACString& hwVersion)
+{
+ return GetAttributeHelper(mSlotHWVersion, hwVersion);
+}
+
+NS_IMETHODIMP
+nsPKCS11Slot::GetFWVersion(/*out*/ nsACString& fwVersion)
+{
+ return GetAttributeHelper(mSlotFWVersion, fwVersion);
}
NS_IMETHODIMP
nsPKCS11Slot::GetToken(nsIPK11Token** _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
@@ -216,38 +173,35 @@ nsPKCS11Slot::GetToken(nsIPK11Token** _r
return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIPK11Token> token = new nsPK11Token(mSlot.get());
token.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11Slot::GetTokenName(char16_t** aName)
+nsPKCS11Slot::GetTokenName(/*out*/ nsACString& tokenName)
{
- NS_ENSURE_ARG_POINTER(aName);
-
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
if (!PK11_IsPresent(mSlot.get())) {
- *aName = nullptr;
+ tokenName.SetIsVoid(true);
return NS_OK;
}
if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
nsresult rv = refreshSlotInfo(locker);
if (NS_FAILED(rv)) {
return rv;
}
}
- *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot.get())));
- if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
+ tokenName = PK11_GetTokenName(mSlot.get());
return NS_OK;
}
NS_IMETHODIMP
nsPKCS11Slot::GetStatus(uint32_t* _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
@@ -303,73 +257,69 @@ nsPKCS11Module::virtualDestroyNSSReferen
void
nsPKCS11Module::destructorSafeDestroyNSSReference()
{
mModule = nullptr;
}
NS_IMETHODIMP
-nsPKCS11Module::GetName(char16_t** aName)
+nsPKCS11Module::GetName(/*out*/ nsACString& name)
{
- NS_ENSURE_ARG_POINTER(aName);
-
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(mModule->commonName));
+ name = mModule->commonName;
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11Module::GetLibName(char16_t** aName)
+nsPKCS11Module::GetLibName(/*out*/ nsACString& libName)
{
- NS_ENSURE_ARG_POINTER(aName);
-
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- if ( mModule->dllName ) {
- *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(mModule->dllName));
+ if (mModule->dllName) {
+ libName = mModule->dllName;
} else {
- *aName = nullptr;
+ libName.SetIsVoid(true);
}
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11Module::FindSlotByName(const char16_t* aName, nsIPKCS11Slot** _retval)
+nsPKCS11Module::FindSlotByName(const nsACString& name,
+ /*out*/ nsIPKCS11Slot** _retval)
{
- // Note: It's OK for |aName| to be null.
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
- NS_ConvertUTF16toUTF8 asciiname(aName);
- MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"\n", asciiname.get()));
+ const nsCString& flatName = PromiseFlatCString(name);
+ MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"", flatName.get()));
UniquePK11SlotInfo slotInfo;
UniquePK11SlotList slotList(PK11_FindSlotsByNames(mModule->dllName,
- asciiname.get() /*slotName*/,
+ flatName.get() /*slotName*/,
nullptr /*tokenName*/,
false));
if (!slotList) {
/* name must be the token name */
slotList.reset(PK11_FindSlotsByNames(mModule->dllName, nullptr /*slotName*/,
- asciiname.get() /*tokenName*/, false));
+ flatName.get() /*tokenName*/, false));
}
if (slotList && slotList->head && slotList->head->slot) {
slotInfo.reset(PK11_ReferenceSlot(slotList->head->slot));
}
if (!slotInfo) {
// workaround - the builtin module has no name
- if (!asciiname.EqualsLiteral("Root Certificates")) {
+ if (!flatName.EqualsLiteral("Root Certificates")) {
// Give up.
return NS_ERROR_FAILURE;
}
slotInfo.reset(PK11_ReferenceSlot(mModule->slots[0]));
}
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotInfo.get());
@@ -464,56 +414,52 @@ nsPKCS11ModuleDB::GetInternalFIPS(nsIPKC
}
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod.get());
module.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
-nsPKCS11ModuleDB::FindModuleByName(const char16_t* aName,
- nsIPKCS11Module** _retval)
+nsPKCS11ModuleDB::FindModuleByName(const nsACString& name,
+ /*out*/ nsIPKCS11Module** _retval)
{
- // Note: It's OK for |aName| to be null.
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
- NS_ConvertUTF16toUTF8 utf8Name(aName);
- UniqueSECMODModule mod(SECMOD_FindModule(const_cast<char*>(utf8Name.get())));
+ UniqueSECMODModule mod(SECMOD_FindModule(PromiseFlatCString(name).get()));
if (!mod) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod.get());
module.forget(_retval);
return NS_OK;
}
/* This is essentially the same as nsIPK11Token::findTokenByName, except
* that it returns an nsIPKCS11Slot, which may be desired.
*/
NS_IMETHODIMP
-nsPKCS11ModuleDB::FindSlotByName(const char16_t* aName,
- nsIPKCS11Slot** _retval)
+nsPKCS11ModuleDB::FindSlotByName(const nsACString& name,
+ /*out*/ nsIPKCS11Slot** _retval)
{
- // Note: It's OK for |aName| to be null.
NS_ENSURE_ARG_POINTER(_retval);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
- NS_ConvertUTF16toUTF8 utf8Name(aName);
UniquePK11SlotInfo slotInfo(
- PK11_FindSlotByName(const_cast<char*>(utf8Name.get())));
+ PK11_FindSlotByName(PromiseFlatCString(name).get()));
if (!slotInfo) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotInfo.get());
slot.forget(_retval);
return NS_OK;
}
--- a/security/manager/ssl/nsPKCS11Slot.h
+++ b/security/manager/ssl/nsPKCS11Slot.h
@@ -26,22 +26,27 @@ public:
explicit nsPKCS11Slot(PK11SlotInfo* slot);
protected:
virtual ~nsPKCS11Slot();
private:
mozilla::UniquePK11SlotInfo mSlot;
- nsString mSlotDesc, mSlotManID, mSlotHWVersion, mSlotFWVersion;
+ nsCString mSlotDesc;
+ nsCString mSlotManufacturerID;
+ nsCString mSlotHWVersion;
+ nsCString mSlotFWVersion;
int mSeries;
virtual void virtualDestroyNSSReference() override;
void destructorSafeDestroyNSSReference();
nsresult refreshSlotInfo(const nsNSSShutDownPreventionLock& proofOfLock);
+ nsresult GetAttributeHelper(const nsACString& attribute,
+ /*out*/ nsACString& xpcomOutParam);
};
class nsPKCS11Module : public nsIPKCS11Module,
public nsNSSShutDownObject
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPKCS11MODULE
--- a/security/manager/ssl/nsPKCS12Blob.cpp
+++ b/security/manager/ssl/nsPKCS12Blob.cpp
@@ -138,17 +138,17 @@ nsPKCS12Blob::ImportFromFileHelper(nsIFi
{
nsNSSShutDownPreventionLock locker;
nsresult rv = NS_OK;
SECStatus srv = SECSuccess;
SEC_PKCS12DecoderContext *dcx = nullptr;
SECItem unicodePw;
UniquePK11SlotInfo slot;
- nsXPIDLString tokenName;
+ nsAutoCString tokenName;
unicodePw.data = nullptr;
aWantRetry = rr_do_not_retry;
if (aImportMode == im_try_zero_length_secitem)
{
unicodePw.len = 0;
}
@@ -158,21 +158,21 @@ nsPKCS12Blob::ImportFromFileHelper(nsIFi
rv = getPKCS12FilePassword(&unicodePw);
if (NS_FAILED(rv)) goto finish;
if (!unicodePw.data) {
handleError(PIP_PKCS12_USER_CANCELED);
return NS_OK;
}
}
- mToken->GetTokenName(getter_Copies(tokenName));
- {
- NS_ConvertUTF16toUTF8 tokenNameCString(tokenName);
- slot = UniquePK11SlotInfo(PK11_FindSlotByName(tokenNameCString.get()));
+ rv = mToken->GetTokenName(tokenName);
+ if (NS_FAILED(rv)) {
+ goto finish;
}
+ slot = UniquePK11SlotInfo(PK11_FindSlotByName(tokenName.get()));
if (!slot) {
srv = SECFailure;
goto finish;
}
// initialize the decoder
dcx = SEC_PKCS12DecoderStart(&unicodePw, slot.get(), nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr);
--- a/security/manager/ssl/tests/unit/test_pkcs11_slot.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_slot.js
@@ -18,16 +18,19 @@ function run_test() {
do_register_cleanup(() => {
pkcs11.deleteModule("PKCS11 Test Module");
});
pkcs11.addModule("PKCS11 Test Module", libraryFile.path, 0, 0);
let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
.getService(Ci.nsIPKCS11ModuleDB);
let testModule = moduleDB.findModuleByName("PKCS11 Test Module");
+ // TODO(Bug 1306632): Add a slot to the PSM PKCS 11 test module with a name
+ // with high codepoints, then add a test to ensure
+ // findSlotByName() is able to find the slot.
let testSlot = testModule.findSlotByName("Test PKCS11 Slot");
equal(testSlot.name, "Test PKCS11 Slot",
"Actual and expected name should match");
equal(testSlot.desc, "Test PKCS11 Slot",
"Actual and expected description should match");
equal(testSlot.manID, "Test PKCS11 Manufacturer ID",
"Actual and expected manufacturer ID should match");
--- a/security/manager/ssl/tests/unit/test_pkcs11_token.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_token.js
@@ -54,18 +54,18 @@ function checkPasswordFeaturesAndResetPa
token.setAskPasswordDefaults(10, 20);
equal(token.getAskPasswordTimes(), 10,
"Actual and expected ask password times should match");
equal(token.getAskPasswordTimeout(), 20,
"Actual and expected ask password timeout should match");
ok(token.checkPassword(initialPW),
"checkPassword() should succeed if the correct initial password is given");
- token.changePassword(initialPW, "newPW");
- ok(token.checkPassword("newPW"),
+ token.changePassword(initialPW, "newPW ÿ 一二三");
+ ok(token.checkPassword("newPW ÿ 一二三"),
"checkPassword() should succeed if the correct new password is given");
ok(!token.checkPassword("wrongPW"),
"checkPassword() should fail if an incorrect password is given");
ok(!token.isLoggedIn(),
"Token should be logged out after an incorrect password was given");
ok(!token.needsUserInit,
"Token should still be init with a password even if an incorrect " +