Bug 1272794 - Clean up Digest class API r=keeler,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D40983
This commit is contained in:
Moritz Birghan 2020-11-11 22:16:38 +00:00
Родитель 96f7c5cf5c
Коммит 21cf959be5
9 изменённых файлов: 174 добавлений и 136 удалений

Просмотреть файл

@ -102,8 +102,7 @@ BackgroundFileSaver::BackgroundFileSaver()
mSha256Enabled(false),
mSignatureInfoEnabled(false),
mActualTarget(nullptr),
mActualTargetKeepPartial(false),
mDigestContext(nullptr) {
mActualTargetKeepPartial(false) {
LOG(("Created BackgroundFileSaver [this = %p]", this));
}
@ -518,16 +517,15 @@ nsresult BackgroundFileSaver::ProcessStateChange() {
}
}
// Create the digest context if requested and NSS hasn't been shut down.
if (sha256Enabled && !mDigestContext) {
mDigestContext =
UniquePK11Context(PK11_CreateDigestContext(SEC_OID_SHA256));
NS_ENSURE_TRUE(mDigestContext, NS_ERROR_OUT_OF_MEMORY);
// Create the digest if requested and NSS hasn't been shut down.
if (sha256Enabled && mDigest.isNothing()) {
mDigest.emplace(Digest());
mDigest->Begin(SEC_OID_SHA256);
}
// When we are requested to append to an existing file, we should read the
// existing data and ensure we include it as part of the final hash.
if (mDigestContext && append && !isContinuation) {
if (mDigest.isSome() && append && !isContinuation) {
nsCOMPtr<nsIInputStream> inputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), mActualTarget,
PR_RDONLY | nsIFile::OS_READAHEAD);
@ -545,9 +543,8 @@ nsresult BackgroundFileSaver::ProcessStateChange() {
break;
}
nsresult rv = MapSECStatus(
PK11_DigestOp(mDigestContext.get(),
BitwiseCast<unsigned char*, char*>(buffer), count));
nsresult rv =
mDigest->Update(BitwiseCast<unsigned char*, char*>(buffer), count);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -582,14 +579,14 @@ nsresult BackgroundFileSaver::ProcessStateChange() {
NS_ENSURE_SUCCESS(rv, rv);
outputStream = bufferedStream;
// Wrap the output stream so that it feeds the digest context if needed.
if (mDigestContext) {
// Constructing the DigestOutputStream cannot fail. Passing mDigestContext
// Wrap the output stream so that it feeds the digest if needed.
if (mDigest.isSome()) {
// Constructing the DigestOutputStream cannot fail. Passing mDigest
// to DigestOutputStream is safe, because BackgroundFileSaver always
// outlives the outputStream. BackgroundFileSaver is reference-counted
// before the call to AsyncCopy, and mDigestContext is never destroyed
// before the call to AsyncCopy, and mDigest is never destroyed
// before AsyncCopyCallback.
outputStream = new DigestOutputStream(outputStream, mDigestContext.get());
outputStream = new DigestOutputStream(outputStream, mDigest.ref());
}
// Start copying our input to the target file. No errors can be raised past
@ -675,13 +672,13 @@ bool BackgroundFileSaver::CheckCompletion() {
}
// Finish computing the hash
if (!failed && mDigestContext) {
Digest d;
rv = d.End(SEC_OID_SHA256, mDigestContext);
if (!failed && mDigest.isSome()) {
nsTArray<uint8_t> outArray;
rv = mDigest->End(outArray);
if (NS_SUCCEEDED(rv)) {
MutexAutoLock lock(mLock);
mSha256 = nsDependentCSubstring(
BitwiseCast<char*, unsigned char*>(d.get().data), d.get().len);
BitwiseCast<char*, uint8_t*>(outArray.Elements()), outArray.Length());
}
}
@ -1077,9 +1074,8 @@ nsresult BackgroundFileSaverStreamListener::NotifySuspendOrResume() {
NS_IMPL_ISUPPORTS(DigestOutputStream, nsIOutputStream)
DigestOutputStream::DigestOutputStream(nsIOutputStream* aStream,
PK11Context* aContext)
: mOutputStream(aStream), mDigestContext(aContext) {
MOZ_ASSERT(mDigestContext, "Can't have null digest context");
Digest& aDigest)
: mOutputStream(aStream), mDigest(aDigest) {
MOZ_ASSERT(mOutputStream, "Can't have null output stream");
}
@ -1091,9 +1087,8 @@ DigestOutputStream::Flush() { return mOutputStream->Flush(); }
NS_IMETHODIMP
DigestOutputStream::Write(const char* aBuf, uint32_t aCount, uint32_t* retval) {
nsresult rv = MapSECStatus(PK11_DigestOp(
mDigestContext, BitwiseCast<const unsigned char*, const char*>(aBuf),
aCount));
nsresult rv = mDigest.Update(
BitwiseCast<const unsigned char*, const char*>(aBuf), aCount);
NS_ENSURE_SUCCESS(rv, rv);
return mOutputStream->Write(aBuf, aCount, retval);

Просмотреть файл

@ -228,7 +228,7 @@ class BackgroundFileSaver : public nsIBackgroundFileSaver {
* Used to calculate the file hash. This keeps state across file renames and
* is lazily initialized in ProcessStateChange.
*/
UniquePK11Context mDigestContext;
Maybe<Digest> mDigest;
//////////////////////////////////////////////////////////////////////////////
//// Private methods
@ -376,15 +376,15 @@ class DigestOutputStream : public nsIOutputStream {
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
// Constructor. Neither parameter may be null. The caller owns both.
DigestOutputStream(nsIOutputStream* outputStream, PK11Context* aContext);
DigestOutputStream(nsIOutputStream* aStream, Digest& aDigest);
private:
virtual ~DigestOutputStream() = default;
// Calls to write are passed to this stream.
nsCOMPtr<nsIOutputStream> mOutputStream;
// Digest context used to compute the hash, owned by the caller.
PK11Context* mDigestContext;
// Digest used to compute the hash, owned by the caller.
Digest& mDigest;
// Don't accidentally copy construct.
DigestOutputStream(const DigestOutputStream& d) = delete;

Просмотреть файл

@ -77,9 +77,10 @@ struct DigestWithAlgorithm {
};
// The digest must have a lifetime greater than or equal to the returned string.
inline nsDependentCSubstring DigestToDependentString(const Digest& digest) {
return nsDependentCSubstring(
BitwiseCast<char*, unsigned char*>(digest.get().data), digest.get().len);
inline nsDependentCSubstring DigestToDependentString(
nsTArray<uint8_t>& digest) {
return nsDependentCSubstring(BitwiseCast<char*, uint8_t*>(digest.Elements()),
digest.Length());
}
// Reads a maximum of 8MB from a stream into the supplied buffer.
@ -142,7 +143,7 @@ nsresult FindAndLoadOneEntry(
/*out*/ nsACString& filename,
/*out*/ SECItem& buf,
/*optional, in*/ SECOidTag digestAlgorithm = SEC_OID_SHA1,
/*optional, out*/ Digest* bufDigest = nullptr) {
/*optional, out*/ nsTArray<uint8_t>* bufDigest = nullptr) {
nsCOMPtr<nsIUTF8StringEnumerator> files;
nsresult rv = zip->FindEntries(searchPattern, getter_AddRefs(files));
if (NS_FAILED(rv) || !files) {
@ -176,7 +177,8 @@ nsresult FindAndLoadOneEntry(
}
if (bufDigest) {
rv = bufDigest->DigestBuf(digestAlgorithm, buf.data, buf.len - 1);
rv = Digest::DigestBuf(digestAlgorithm,
Span<uint8_t>{buf.data, buf.len - 1}, *bufDigest);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -210,13 +212,9 @@ nsresult VerifyStreamContentDigest(
return NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE;
}
UniquePK11Context digestContext(
PK11_CreateDigestContext(digestFromManifest.mAlgorithm));
if (!digestContext) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
Digest digest;
rv = MapSECStatus(PK11_DigestBegin(digestContext.get()));
rv = digest.Begin(digestFromManifest.mAlgorithm);
NS_ENSURE_SUCCESS(rv, rv);
uint64_t totalBytesRead = 0;
@ -235,7 +233,7 @@ nsresult VerifyStreamContentDigest(
return NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE;
}
rv = MapSECStatus(PK11_DigestOp(digestContext.get(), buf.data, bytesRead));
rv = digest.Update(buf.data, bytesRead);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -246,11 +244,11 @@ nsresult VerifyStreamContentDigest(
}
// Verify that the digests match.
Digest digest;
rv = digest.End(digestFromManifest.mAlgorithm, digestContext);
nsTArray<uint8_t> outArray;
rv = digest.End(outArray);
NS_ENSURE_SUCCESS(rv, rv);
nsDependentCSubstring digestStr(DigestToDependentString(digest));
nsDependentCSubstring digestStr(DigestToDependentString(outArray));
if (!digestStr.Equals(digestFromManifest.mDigest)) {
return NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY;
}
@ -749,13 +747,13 @@ Span<const uint8_t> GetPKCS7SignerCert(
}
nsresult VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer,
const SECItem& detachedSHA1Digest,
const SECItem& detachedSHA256Digest,
nsTArray<uint8_t>& detachedSHA1Digest,
nsTArray<uint8_t>& detachedSHA256Digest,
/*out*/ SECOidTag& digestAlgorithm,
/*out*/ nsTArray<uint8_t>& signerCert) {
if (NS_WARN_IF(!buffer.data || buffer.len == 0 || !detachedSHA1Digest.data ||
detachedSHA1Digest.len == 0 || !detachedSHA256Digest.data ||
detachedSHA256Digest.len == 0)) {
if (NS_WARN_IF(!buffer.data || buffer.len == 0 ||
detachedSHA1Digest.Length() == 0 ||
detachedSHA256Digest.Length() == 0)) {
return NS_ERROR_INVALID_ARG;
}
@ -799,17 +797,21 @@ nsresult VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer,
NSSCMSSignerInfo* signerInfo =
GetSignerInfoForDigestAlgorithm(signedData, SEC_OID_SHA256);
const SECItem* detachedDigest = &detachedSHA256Digest;
nsTArray<uint8_t>* tmpDetachedDigest = &detachedSHA256Digest;
digestAlgorithm = SEC_OID_SHA256;
if (!signerInfo) {
signerInfo = GetSignerInfoForDigestAlgorithm(signedData, SEC_OID_SHA1);
if (!signerInfo) {
return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
}
detachedDigest = &detachedSHA1Digest;
tmpDetachedDigest = &detachedSHA1Digest;
digestAlgorithm = SEC_OID_SHA1;
}
const SECItem detachedDigest = {
siBuffer, tmpDetachedDigest->Elements(),
static_cast<unsigned int>(tmpDetachedDigest->Length())};
// Get the certificate that issued the PKCS7 signature.
Span<const uint8_t> signerCertSpan =
GetPKCS7SignerCert(signerInfo, collectedCerts);
@ -853,7 +855,7 @@ nsresult VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer,
return mozilla::psm::GetXPCOMFromNSSError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
}
return MapSECStatus(NSS_CMSSignerInfo_Verify(
signerInfo, const_cast<SECItem*>(detachedDigest), &pkcs7DataOid));
signerInfo, const_cast<SECItem*>(&detachedDigest), &pkcs7DataOid));
}
class CoseVerificationContext {
@ -1187,15 +1189,16 @@ nsresult VerifyPK7Signature(
// Calculate both the SHA-1 and SHA-256 hashes of the signature file - we
// don't know what algorithm the PKCS#7 signature used.
Digest sfCalculatedSHA1Digest;
rv = sfCalculatedSHA1Digest.DigestBuf(SEC_OID_SHA1, sfBuffer.data,
sfBuffer.len - 1);
nsTArray<uint8_t> sfCalculatedSHA1Digest;
rv = Digest::DigestBuf(SEC_OID_SHA1, sfBuffer.data, sfBuffer.len - 1,
sfCalculatedSHA1Digest);
if (NS_FAILED(rv)) {
return rv;
}
Digest sfCalculatedSHA256Digest;
rv = sfCalculatedSHA256Digest.DigestBuf(SEC_OID_SHA256, sfBuffer.data,
sfBuffer.len - 1);
nsTArray<uint8_t> sfCalculatedSHA256Digest;
rv = Digest::DigestBuf(SEC_OID_SHA256, sfBuffer.data, sfBuffer.len - 1,
sfCalculatedSHA256Digest);
if (NS_FAILED(rv)) {
return rv;
}
@ -1204,9 +1207,8 @@ nsresult VerifyPK7Signature(
// If we get here, the signature has to verify even if PKCS#7 is not required.
sigBuffer.type = siBuffer;
SECOidTag digestToUse;
rv =
VerifySignature(aTrustedRoot, sigBuffer, sfCalculatedSHA1Digest.get(),
sfCalculatedSHA256Digest.get(), digestToUse, aSignerCert);
rv = VerifySignature(aTrustedRoot, sigBuffer, sfCalculatedSHA1Digest,
sfCalculatedSHA256Digest, digestToUse, aSignerCert);
if (NS_FAILED(rv)) {
return rv;
}
@ -1225,17 +1227,18 @@ nsresult VerifyPK7Signature(
// Read PK7 manifest (MF) file.
ScopedAutoSECItem manifestBuffer;
Digest mfCalculatedDigest;
nsTArray<uint8_t> digestArray;
nsAutoCString mfFilename;
rv = FindAndLoadOneEntry(aZip, nsLiteralCString(JAR_MF_SEARCH_STRING),
mfFilename, manifestBuffer, digestToUse,
&mfCalculatedDigest);
&digestArray);
if (NS_FAILED(rv)) {
return rv;
}
nsDependentCSubstring calculatedDigest(
DigestToDependentString(mfCalculatedDigest));
BitwiseCast<char*, uint8_t*>(digestArray.Elements()),
digestArray.Length());
if (!mfDigest.Equals(calculatedDigest)) {
return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
}

Просмотреть файл

@ -36,15 +36,16 @@ static nsresult GetBase64HashSPKI(const BackCert& cert,
Input derPublicKey = cert.GetSubjectPublicKeyInfo();
hashSPKIDigest.Truncate();
Digest digest;
nsresult nsrv = digest.DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(),
derPublicKey.GetLength());
nsTArray<uint8_t> digestArray;
nsresult nsrv =
Digest::DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(),
derPublicKey.GetLength(), digestArray);
if (NS_FAILED(nsrv)) {
return nsrv;
}
return Base64Encode(nsDependentCSubstring(
BitwiseCast<char*, unsigned char*>(digest.get().data),
digest.get().len),
BitwiseCast<char*, uint8_t*>(digestArray.Elements()),
digestArray.Length()),
hashSPKIDigest);
}

Просмотреть файл

@ -47,10 +47,10 @@ class BinaryHashSearchArrayComparator {
// storage (Enterprise Root).
// See also the constants in RootCertificateTelemetryUtils.h.
int32_t RootCABinNumber(Span<const uint8_t> cert) {
Digest digest;
nsTArray<uint8_t> digestArray;
// Compute SHA256 hash of the certificate
nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert.data(), cert.size());
nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, cert, digestArray);
if (NS_WARN_IF(NS_FAILED(rv))) {
return ROOT_CERTIFICATE_HASH_FAILURE;
}
@ -58,16 +58,15 @@ int32_t RootCABinNumber(Span<const uint8_t> cert) {
// Compare against list of stored hashes
size_t idx;
MOZ_LOG(
gPublicKeyPinningTelemetryLog, LogLevel::Debug,
("pkpinTelem: First bytes %02x %02x %02x %02x\n", digest.get().data[0],
digest.get().data[1], digest.get().data[2], digest.get().data[3]));
MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
("pkpinTelem: First bytes %02x %02x %02x %02x\n",
digestArray.ElementAt(0), digestArray.ElementAt(1),
digestArray.ElementAt(2), digestArray.ElementAt(3)));
if (mozilla::BinarySearchIf(
ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
BinaryHashSearchArrayComparator(
static_cast<uint8_t*>(digest.get().data), digest.get().len),
&idx)) {
if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
BinaryHashSearchArrayComparator(
digestArray.Elements(), digestArray.Length()),
&idx)) {
MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
("pkpinTelem: Telemetry index was %zu, bin is %d\n", idx,
ROOT_TABLE[idx].binNumber));

Просмотреть файл

@ -86,57 +86,96 @@ MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11Context, PK11Context,
* Typical usage, for digesting a buffer in memory:
*
* nsCOMPtr<nsISupports> nssDummy = do_GetService("@mozilla.org/psm;1", &rv);
* Digest digest;
* nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen);
* nsTArray<uint8_t> digestArray;
* nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen,
* digestArray);
* NS_ENSURE_SUCCESS(rv, rv);
* rv = MapSECStatus(SomeNSSFunction(..., digest.get(), ...));
*
* Less typical usage, for digesting while doing streaming I/O and similar:
*
* Digest digest;
* UniquePK11Context digestContext(PK11_CreateDigestContext(SEC_OID_SHA256));
* NS_ENSURE_TRUE(digestContext, NS_ERROR_OUT_OF_MEMORY);
* rv = MapSECStatus(PK11_DigestBegin(digestContext.get()));
* nsresult rv = digest.Begin(SEC_OID_SHA256);
* NS_ENSURE_SUCCESS(rv, rv);
* for (...) {
* rv = MapSECStatus(PK11_DigestOp(digestContext.get(), ...));
* rv = digest.Update(buf, len);
* NS_ENSURE_SUCCESS(rv, rv);
* }
* rv = digest.End(SEC_OID_SHA256, digestContext);
* nsTArray<uint8_t> digestArray;
* rv = digest.End(digestArray);
* NS_ENSURE_SUCCESS(rv, rv)
*/
class Digest {
public:
Digest() : mItemBuf() {
mItem.type = siBuffer;
mItem.data = mItemBuf;
mItem.len = 0;
explicit Digest() : mLen(0), mDigestContext(nullptr) {}
static nsresult DigestBuf(SECOidTag hashAlg, Span<const uint8_t> buf,
/*out*/ nsTArray<uint8_t>& out) {
return Digest::DigestBuf(hashAlg, buf.Elements(), buf.Length(), out);
}
nsresult DigestBuf(SECOidTag hashAlg, const uint8_t* buf, uint32_t len) {
if (len > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
static nsresult DigestBuf(SECOidTag hashAlg, const uint8_t* buf, uint32_t len,
/*out*/ nsTArray<uint8_t>& out) {
Digest digest;
nsresult rv = digest.Begin(hashAlg);
if (NS_FAILED(rv)) {
return rv;
}
rv = digest.Update(buf, len);
if (NS_FAILED(rv)) {
return rv;
}
rv = digest.End(out);
if (NS_FAILED(rv)) {
return rv;
}
return rv;
}
nsresult Begin(SECOidTag hashAlg) {
if (hashAlg != SEC_OID_SHA1 && hashAlg != SEC_OID_SHA256) {
return NS_ERROR_INVALID_ARG;
}
mDigestContext = UniquePK11Context(PK11_CreateDigestContext(hashAlg));
if (!mDigestContext) {
return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
}
nsresult rv = SetLength(hashAlg);
NS_ENSURE_SUCCESS(rv, rv);
return MapSECStatus(
PK11_HashBuf(hashAlg, mItem.data, buf, static_cast<int32_t>(len)));
return MapSECStatus(PK11_DigestBegin(mDigestContext.get()));
}
nsresult End(SECOidTag hashAlg, UniquePK11Context& context) {
nsresult rv = SetLength(hashAlg);
NS_ENSURE_SUCCESS(rv, rv);
nsresult Update(Span<const uint8_t> in) {
return Update(in.Elements(), in.Length());
}
nsresult Update(const unsigned char* buf, const uint32_t len) {
if (!mDigestContext) {
return NS_ERROR_NOT_INITIALIZED;
}
return MapSECStatus(PK11_DigestOp(mDigestContext.get(), buf, len));
}
nsresult End(/*out*/ nsTArray<uint8_t>& out) {
if (!mDigestContext) {
return NS_ERROR_NOT_INITIALIZED;
}
out.SetLength(mLen);
uint32_t len;
rv = MapSECStatus(
PK11_DigestFinal(context.get(), mItem.data, &len, mItem.len));
nsresult rv = MapSECStatus(
PK11_DigestFinal(mDigestContext.get(), out.Elements(), &len, mLen));
NS_ENSURE_SUCCESS(rv, rv);
context = nullptr;
NS_ENSURE_TRUE(len == mItem.len, NS_ERROR_UNEXPECTED);
mDigestContext = nullptr;
NS_ENSURE_TRUE(len == mLen, NS_ERROR_UNEXPECTED);
return NS_OK;
}
const SECItem& get() const { return mItem; }
private:
nsresult SetLength(SECOidTag hashType) {
#ifdef _MSC_VER
@ -147,16 +186,10 @@ class Digest {
#endif
switch (hashType) {
case SEC_OID_SHA1:
mItem.len = SHA1_LENGTH;
mLen = SHA1_LENGTH;
break;
case SEC_OID_SHA256:
mItem.len = SHA256_LENGTH;
break;
case SEC_OID_SHA384:
mItem.len = SHA384_LENGTH;
break;
case SEC_OID_SHA512:
mItem.len = SHA512_LENGTH;
mLen = SHA256_LENGTH;
break;
default:
return NS_ERROR_INVALID_ARG;
@ -168,8 +201,8 @@ class Digest {
return NS_OK;
}
uint8_t mItemBuf[HASH_LENGTH_MAX];
SECItem mItem;
uint8_t mLen;
UniquePK11Context mDigestContext;
};
namespace internal {

Просмотреть файл

@ -101,12 +101,15 @@ void LossyUTF8ToUTF16(const char* str, uint32_t len,
nsresult GetCertFingerprintByOidTag(CERTCertificate* nsscert, SECOidTag aOidTag,
nsCString& fp) {
Digest digest;
nsresult rv =
digest.DigestBuf(aOidTag, nsscert->derCert.data, nsscert->derCert.len);
nsTArray<uint8_t> digestArray;
nsresult rv = Digest::DigestBuf(aOidTag, nsscert->derCert.data,
nsscert->derCert.len, digestArray);
NS_ENSURE_SUCCESS(rv, rv);
UniquePORTString tmpstr(CERT_Hexify(const_cast<SECItem*>(&digest.get()), 1));
SECItem digestItem = {siBuffer, digestArray.Elements(),
static_cast<unsigned int>(digestArray.Length())};
UniquePORTString tmpstr(CERT_Hexify(&digestItem, 1));
NS_ENSURE_TRUE(tmpstr, NS_ERROR_OUT_OF_MEMORY);
fp.Assign(tmpstr.get());

Просмотреть файл

@ -581,15 +581,17 @@ nsNSSCertificate::GetSerialNumber(nsAString& _serialNumber) {
nsresult nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint,
SECOidTag aHashAlg) {
aFingerprint.Truncate();
Digest digest;
nsresult rv =
digest.DigestBuf(aHashAlg, mCert->derCert.data, mCert->derCert.len);
nsTArray<uint8_t> digestArray;
nsresult rv = Digest::DigestBuf(aHashAlg, mCert->derCert.data,
mCert->derCert.len, digestArray);
if (NS_FAILED(rv)) {
return rv;
}
SECItem digestItem = {siBuffer, digestArray.Elements(),
static_cast<unsigned int>(digestArray.Length())};
UniquePORTString fpStr(CERT_Hexify(const_cast<SECItem*>(&digest.get()),
true /* use colon delimiters */));
UniquePORTString fpStr(
CERT_Hexify(&digestItem, true /* use colon delimiters */));
if (!fpStr) {
return NS_ERROR_FAILURE;
}
@ -647,15 +649,15 @@ nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest(
return NS_ERROR_INVALID_ARG;
}
pkix::Input derPublicKey = cert.GetSubjectPublicKeyInfo();
Digest digest;
nsresult rv = digest.DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(),
derPublicKey.GetLength());
nsTArray<uint8_t> digestArray;
nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(),
derPublicKey.GetLength(), digestArray);
if (NS_FAILED(rv)) {
return rv;
}
rv = Base64Encode(nsDependentCSubstring(
BitwiseCast<char*, unsigned char*>(digest.get().data),
digest.get().len),
BitwiseCast<char*, uint8_t*>(digestArray.Elements()),
digestArray.Length()),
aSha256SPKIDigest);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

Просмотреть файл

@ -2563,18 +2563,20 @@ nsNSSComponent::IsCertContentSigningRoot(const nsTArray<uint8_t>& cert,
bool* result) {
NS_ENSURE_ARG_POINTER(result);
*result = false;
if (cert.Length() > std::numeric_limits<uint32_t>::max()) {
return NS_ERROR_INVALID_ARG;
}
Digest digest;
nsresult rv =
digest.DigestBuf(SEC_OID_SHA256, cert.Elements(), cert.Length());
nsTArray<uint8_t> digestArray;
nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, cert.Elements(),
cert.Length(), digestArray);
if (NS_FAILED(rv)) {
return rv;
}
UniquePORTString fingerprintCString(CERT_Hexify(
const_cast<SECItem*>(&digest.get()), true /* use colon delimiters */));
SECItem digestItem = {siBuffer, digestArray.Elements(),
static_cast<unsigned int>(digestArray.Length())};
UniquePORTString fingerprintCString(
CERT_Hexify(&digestItem, true /* use colon delimiters */));
if (!fingerprintCString) {
return NS_ERROR_FAILURE;
}