mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 879137: Move nsCryptoHash and nsCryptoHMAC to their own source file, r=cviecco
--HG-- extra : rebase_source : 71b6093529a6e9ec7749cb6f48911d441984b348
This commit is contained in:
parent
e02ea7cd75
commit
71a4c34abc
@ -31,6 +31,7 @@ CPP_SOURCES += [
|
||||
'nsCRLInfo.cpp',
|
||||
'nsCRLManager.cpp',
|
||||
'nsCrypto.cpp',
|
||||
'nsCryptoHash.cpp',
|
||||
'nsDataSignatureVerifier.cpp',
|
||||
'nsIdentityChecking.cpp',
|
||||
'nsKeygenHandler.cpp',
|
||||
|
412
security/manager/ssl/src/nsCryptoHash.cpp
Normal file
412
security/manager/ssl/src/nsCryptoHash.cpp
Normal file
@ -0,0 +1,412 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
#define FORCE_PR_LOG 1
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "nsCryptoHash.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIKeyModule.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#include "sechash.h"
|
||||
#include "pk11pub.h"
|
||||
#include "base64.h"
|
||||
|
||||
#define NS_CRYPTO_HASH_BUFFER_SIZE 4096
|
||||
|
||||
//---------------------------------------------
|
||||
// Implementing nsICryptoHash
|
||||
//---------------------------------------------
|
||||
|
||||
nsCryptoHash::nsCryptoHash()
|
||||
: mHashContext(nullptr)
|
||||
, mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsCryptoHash::~nsCryptoHash()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(calledFromObject);
|
||||
}
|
||||
|
||||
void nsCryptoHash::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void nsCryptoHash::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
if (mHashContext)
|
||||
HASH_Destroy(mHashContext);
|
||||
mHashContext = nullptr;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCryptoHash, nsICryptoHash)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Init(uint32_t algorithm)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
HASH_HashType hashType = (HASH_HashType)algorithm;
|
||||
if (mHashContext)
|
||||
{
|
||||
if ((!mInitialized) && (HASH_GetType(mHashContext) == hashType))
|
||||
{
|
||||
mInitialized = true;
|
||||
HASH_Begin(mHashContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Destroy current hash context if the type was different
|
||||
// or Finish method wasn't called.
|
||||
HASH_Destroy(mHashContext);
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
mHashContext = HASH_Create(hashType);
|
||||
if (!mHashContext)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
HASH_Begin(mHashContext);
|
||||
mInitialized = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::InitWithString(const nsACString & aAlgorithm)
|
||||
{
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("md2"))
|
||||
return Init(nsICryptoHash::MD2);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("md5"))
|
||||
return Init(nsICryptoHash::MD5);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha1"))
|
||||
return Init(nsICryptoHash::SHA1);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha256"))
|
||||
return Init(nsICryptoHash::SHA256);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha384"))
|
||||
return Init(nsICryptoHash::SHA384);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha512"))
|
||||
return Init(nsICryptoHash::SHA512);
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Update(const uint8_t *data, uint32_t len)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
HASH_Update(mHashContext, data, len);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::UpdateFromStream(nsIInputStream *data, uint32_t aLen)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!data)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
uint64_t n;
|
||||
nsresult rv = data->Available(&n);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if the user has passed UINT32_MAX, then read
|
||||
// everything in the stream
|
||||
|
||||
uint64_t len = aLen;
|
||||
if (aLen == UINT32_MAX)
|
||||
len = n;
|
||||
|
||||
// So, if the stream has NO data available for the hash,
|
||||
// or if the data available is less then what the caller
|
||||
// requested, we can not fulfill the hash update. In this
|
||||
// case, just return NS_ERROR_NOT_AVAILABLE indicating
|
||||
// that there is not enough data in the stream to satisify
|
||||
// the request.
|
||||
|
||||
if (n == 0 || n < len)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
|
||||
uint32_t read, readLimit;
|
||||
|
||||
while(NS_SUCCEEDED(rv) && len>0)
|
||||
{
|
||||
readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
|
||||
|
||||
rv = data->Read(buffer, readLimit, &read);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = Update((const uint8_t*)buffer, read);
|
||||
|
||||
len -= read;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Finish(bool ascii, nsACString & _retval)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
uint32_t hashLen = 0;
|
||||
unsigned char buffer[HASH_LENGTH_MAX];
|
||||
unsigned char* pbuffer = buffer;
|
||||
|
||||
HASH_End(mHashContext, pbuffer, &hashLen, HASH_LENGTH_MAX);
|
||||
|
||||
mInitialized = false;
|
||||
|
||||
if (ascii)
|
||||
{
|
||||
char *asciiData = BTOA_DataToAscii(buffer, hashLen);
|
||||
NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
_retval.Assign(asciiData);
|
||||
PORT_Free(asciiData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_retval.Assign((const char*)buffer, hashLen);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Implementing nsICryptoHMAC
|
||||
//---------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCryptoHMAC, nsICryptoHMAC)
|
||||
|
||||
nsCryptoHMAC::nsCryptoHMAC()
|
||||
{
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
nsCryptoHMAC::~nsCryptoHMAC()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(calledFromObject);
|
||||
}
|
||||
|
||||
void nsCryptoHMAC::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void nsCryptoHMAC::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
if (mHMACContext)
|
||||
PK11_DestroyContext(mHMACContext, true);
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
/* void init (in unsigned long aAlgorithm, in nsIKeyObject aKeyObject); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Init(uint32_t aAlgorithm, nsIKeyObject *aKeyObject)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (mHMACContext)
|
||||
{
|
||||
PK11_DestroyContext(mHMACContext, true);
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
CK_MECHANISM_TYPE HMACMechType;
|
||||
switch (aAlgorithm)
|
||||
{
|
||||
case nsCryptoHMAC::MD2:
|
||||
HMACMechType = CKM_MD2_HMAC; break;
|
||||
case nsCryptoHMAC::MD5:
|
||||
HMACMechType = CKM_MD5_HMAC; break;
|
||||
case nsCryptoHMAC::SHA1:
|
||||
HMACMechType = CKM_SHA_1_HMAC; break;
|
||||
case nsCryptoHMAC::SHA256:
|
||||
HMACMechType = CKM_SHA256_HMAC; break;
|
||||
case nsCryptoHMAC::SHA384:
|
||||
HMACMechType = CKM_SHA384_HMAC; break;
|
||||
case nsCryptoHMAC::SHA512:
|
||||
HMACMechType = CKM_SHA512_HMAC; break;
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aKeyObject);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
int16_t keyType;
|
||||
rv = aKeyObject->GetType(&keyType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_TRUE(keyType == nsIKeyObject::SYM_KEY, NS_ERROR_INVALID_ARG);
|
||||
|
||||
PK11SymKey* key;
|
||||
// GetKeyObj doesn't addref the key
|
||||
rv = aKeyObject->GetKeyObj((void**)&key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SECItem rawData;
|
||||
rawData.data = 0;
|
||||
rawData.len = 0;
|
||||
mHMACContext = PK11_CreateContextBySymKey(
|
||||
HMACMechType, CKA_SIGN, key, &rawData);
|
||||
NS_ENSURE_TRUE(mHMACContext, NS_ERROR_FAILURE);
|
||||
|
||||
SECStatus ss = PK11_DigestBegin(mHMACContext);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void update ([array, size_is (aLen), const] in octet aData, in unsigned long aLen); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Update(const uint8_t *aData, uint32_t aLen)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aData)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
SECStatus ss = PK11_DigestOp(mHMACContext, aData, aLen);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void updateFromStream (in nsIInputStream aStream, in unsigned long aLen); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, uint32_t aLen)
|
||||
{
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aStream)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
uint64_t n;
|
||||
nsresult rv = aStream->Available(&n);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if the user has passed UINT32_MAX, then read
|
||||
// everything in the stream
|
||||
|
||||
uint64_t len = aLen;
|
||||
if (aLen == UINT32_MAX)
|
||||
len = n;
|
||||
|
||||
// So, if the stream has NO data available for the hash,
|
||||
// or if the data available is less then what the caller
|
||||
// requested, we can not fulfill the HMAC update. In this
|
||||
// case, just return NS_ERROR_NOT_AVAILABLE indicating
|
||||
// that there is not enough data in the stream to satisify
|
||||
// the request.
|
||||
|
||||
if (n == 0 || n < len)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
|
||||
uint32_t read, readLimit;
|
||||
|
||||
while(NS_SUCCEEDED(rv) && len > 0)
|
||||
{
|
||||
readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
|
||||
|
||||
rv = aStream->Read(buffer, readLimit, &read);
|
||||
if (read == 0)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = Update((const uint8_t*)buffer, read);
|
||||
|
||||
len -= read;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* ACString finish (in bool aASCII); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Finish(bool aASCII, nsACString & _retval)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
uint32_t hashLen = 0;
|
||||
unsigned char buffer[HASH_LENGTH_MAX];
|
||||
unsigned char* pbuffer = buffer;
|
||||
|
||||
PK11_DigestFinal(mHMACContext, pbuffer, &hashLen, HASH_LENGTH_MAX);
|
||||
if (aASCII)
|
||||
{
|
||||
char *asciiData = BTOA_DataToAscii(buffer, hashLen);
|
||||
NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
_retval.Assign(asciiData);
|
||||
PORT_Free(asciiData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_retval.Assign((const char*)buffer, hashLen);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void reset (); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Reset()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
SECStatus ss = PK11_DigestBegin(mHMACContext);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
56
security/manager/ssl/src/nsCryptoHash.h
Normal file
56
security/manager/ssl/src/nsCryptoHash.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef _nsCryptoHash_h_
|
||||
#define _nsCryptoHash_h_
|
||||
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsICryptoHMAC.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "hasht.h"
|
||||
#include "secmodt.h"
|
||||
|
||||
class nsIInputStream;
|
||||
|
||||
#define NS_CRYPTO_HASH_CID {0x36a1d3b3, 0xd886, 0x4317, {0x96, 0xff, 0x87, 0xb0, 0x00, 0x5c, 0xfe, 0xf7}}
|
||||
#define NS_CRYPTO_HMAC_CID {0xa496d0a2, 0xdff7, 0x4e23, {0xbd, 0x65, 0x1c, 0xa7, 0x42, 0xfa, 0x17, 0x8a}}
|
||||
|
||||
class nsCryptoHash : public nsICryptoHash, public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICRYPTOHASH
|
||||
|
||||
nsCryptoHash();
|
||||
|
||||
private:
|
||||
~nsCryptoHash();
|
||||
|
||||
HASHContext* mHashContext;
|
||||
bool mInitialized;
|
||||
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
};
|
||||
|
||||
class nsCryptoHMAC : public nsICryptoHMAC, public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICRYPTOHMAC
|
||||
|
||||
nsCryptoHMAC();
|
||||
|
||||
private:
|
||||
~nsCryptoHMAC();
|
||||
PK11Context* mHMACContext;
|
||||
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
};
|
||||
|
||||
#endif // _nsCryptoHash_h_
|
||||
|
@ -68,23 +68,18 @@
|
||||
#include "nsICRLManager.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "GeneratedEvents.h"
|
||||
#include "nsIKeyModule.h"
|
||||
#include "SharedSSLState.h"
|
||||
|
||||
#include "nss.h"
|
||||
#include "pk11func.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
#include "secmod.h"
|
||||
#include "sechash.h"
|
||||
#include "secmime.h"
|
||||
#include "ocsp.h"
|
||||
#include "cms.h"
|
||||
#include "nssckbi.h"
|
||||
#include "base64.h"
|
||||
#include "secerr.h"
|
||||
#include "sslerr.h"
|
||||
#include "cert.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
#include <algorithm>
|
||||
@ -104,8 +99,6 @@ using namespace mozilla::psm;
|
||||
PRLogModuleInfo* gPIPNSSLog = nullptr;
|
||||
#endif
|
||||
|
||||
#define NS_CRYPTO_HASH_BUFFER_SIZE 4096
|
||||
|
||||
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
|
||||
|
||||
int nsNSSComponent::mInstanceCount = 0;
|
||||
@ -2270,394 +2263,6 @@ nsNSSComponent::GetDefaultCertVerifier(RefPtr<CertVerifier> &out)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Implementing nsICryptoHash
|
||||
//---------------------------------------------
|
||||
|
||||
nsCryptoHash::nsCryptoHash()
|
||||
: mHashContext(nullptr)
|
||||
, mInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsCryptoHash::~nsCryptoHash()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(calledFromObject);
|
||||
}
|
||||
|
||||
void nsCryptoHash::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void nsCryptoHash::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
if (mHashContext)
|
||||
HASH_Destroy(mHashContext);
|
||||
mHashContext = nullptr;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCryptoHash, nsICryptoHash)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Init(uint32_t algorithm)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
HASH_HashType hashType = (HASH_HashType)algorithm;
|
||||
if (mHashContext)
|
||||
{
|
||||
if ((!mInitialized) && (HASH_GetType(mHashContext) == hashType))
|
||||
{
|
||||
mInitialized = true;
|
||||
HASH_Begin(mHashContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Destroy current hash context if the type was different
|
||||
// or Finish method wasn't called.
|
||||
HASH_Destroy(mHashContext);
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
mHashContext = HASH_Create(hashType);
|
||||
if (!mHashContext)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
HASH_Begin(mHashContext);
|
||||
mInitialized = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::InitWithString(const nsACString & aAlgorithm)
|
||||
{
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("md2"))
|
||||
return Init(nsICryptoHash::MD2);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("md5"))
|
||||
return Init(nsICryptoHash::MD5);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha1"))
|
||||
return Init(nsICryptoHash::SHA1);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha256"))
|
||||
return Init(nsICryptoHash::SHA256);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha384"))
|
||||
return Init(nsICryptoHash::SHA384);
|
||||
|
||||
if (aAlgorithm.LowerCaseEqualsLiteral("sha512"))
|
||||
return Init(nsICryptoHash::SHA512);
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Update(const uint8_t *data, uint32_t len)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
HASH_Update(mHashContext, data, len);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::UpdateFromStream(nsIInputStream *data, uint32_t aLen)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!data)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
uint64_t n;
|
||||
nsresult rv = data->Available(&n);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if the user has passed UINT32_MAX, then read
|
||||
// everything in the stream
|
||||
|
||||
uint64_t len = aLen;
|
||||
if (aLen == UINT32_MAX)
|
||||
len = n;
|
||||
|
||||
// So, if the stream has NO data available for the hash,
|
||||
// or if the data available is less then what the caller
|
||||
// requested, we can not fulfill the hash update. In this
|
||||
// case, just return NS_ERROR_NOT_AVAILABLE indicating
|
||||
// that there is not enough data in the stream to satisify
|
||||
// the request.
|
||||
|
||||
if (n == 0 || n < len)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
|
||||
uint32_t read, readLimit;
|
||||
|
||||
while(NS_SUCCEEDED(rv) && len>0)
|
||||
{
|
||||
readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
|
||||
|
||||
rv = data->Read(buffer, readLimit, &read);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = Update((const uint8_t*)buffer, read);
|
||||
|
||||
len -= read;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCryptoHash::Finish(bool ascii, nsACString & _retval)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
uint32_t hashLen = 0;
|
||||
unsigned char buffer[HASH_LENGTH_MAX];
|
||||
unsigned char* pbuffer = buffer;
|
||||
|
||||
HASH_End(mHashContext, pbuffer, &hashLen, HASH_LENGTH_MAX);
|
||||
|
||||
mInitialized = false;
|
||||
|
||||
if (ascii)
|
||||
{
|
||||
char *asciiData = BTOA_DataToAscii(buffer, hashLen);
|
||||
NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
_retval.Assign(asciiData);
|
||||
PORT_Free(asciiData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_retval.Assign((const char*)buffer, hashLen);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// Implementing nsICryptoHMAC
|
||||
//---------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCryptoHMAC, nsICryptoHMAC)
|
||||
|
||||
nsCryptoHMAC::nsCryptoHMAC()
|
||||
{
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
nsCryptoHMAC::~nsCryptoHMAC()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(calledFromObject);
|
||||
}
|
||||
|
||||
void nsCryptoHMAC::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void nsCryptoHMAC::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
if (isAlreadyShutDown())
|
||||
return;
|
||||
|
||||
if (mHMACContext)
|
||||
PK11_DestroyContext(mHMACContext, true);
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
/* void init (in unsigned long aAlgorithm, in nsIKeyObject aKeyObject); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Init(uint32_t aAlgorithm, nsIKeyObject *aKeyObject)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (mHMACContext)
|
||||
{
|
||||
PK11_DestroyContext(mHMACContext, true);
|
||||
mHMACContext = nullptr;
|
||||
}
|
||||
|
||||
CK_MECHANISM_TYPE HMACMechType;
|
||||
switch (aAlgorithm)
|
||||
{
|
||||
case nsCryptoHMAC::MD2:
|
||||
HMACMechType = CKM_MD2_HMAC; break;
|
||||
case nsCryptoHMAC::MD5:
|
||||
HMACMechType = CKM_MD5_HMAC; break;
|
||||
case nsCryptoHMAC::SHA1:
|
||||
HMACMechType = CKM_SHA_1_HMAC; break;
|
||||
case nsCryptoHMAC::SHA256:
|
||||
HMACMechType = CKM_SHA256_HMAC; break;
|
||||
case nsCryptoHMAC::SHA384:
|
||||
HMACMechType = CKM_SHA384_HMAC; break;
|
||||
case nsCryptoHMAC::SHA512:
|
||||
HMACMechType = CKM_SHA512_HMAC; break;
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aKeyObject);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
int16_t keyType;
|
||||
rv = aKeyObject->GetType(&keyType);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_TRUE(keyType == nsIKeyObject::SYM_KEY, NS_ERROR_INVALID_ARG);
|
||||
|
||||
PK11SymKey* key;
|
||||
// GetKeyObj doesn't addref the key
|
||||
rv = aKeyObject->GetKeyObj((void**)&key);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SECItem rawData;
|
||||
rawData.data = 0;
|
||||
rawData.len = 0;
|
||||
mHMACContext = PK11_CreateContextBySymKey(
|
||||
HMACMechType, CKA_SIGN, key, &rawData);
|
||||
NS_ENSURE_TRUE(mHMACContext, NS_ERROR_FAILURE);
|
||||
|
||||
SECStatus ss = PK11_DigestBegin(mHMACContext);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void update ([array, size_is (aLen), const] in octet aData, in unsigned long aLen); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Update(const uint8_t *aData, uint32_t aLen)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aData)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
SECStatus ss = PK11_DigestOp(mHMACContext, aData, aLen);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void updateFromStream (in nsIInputStream aStream, in unsigned long aLen); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, uint32_t aLen)
|
||||
{
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aStream)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
uint64_t n;
|
||||
nsresult rv = aStream->Available(&n);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if the user has passed UINT32_MAX, then read
|
||||
// everything in the stream
|
||||
|
||||
uint64_t len = aLen;
|
||||
if (aLen == UINT32_MAX)
|
||||
len = n;
|
||||
|
||||
// So, if the stream has NO data available for the hash,
|
||||
// or if the data available is less then what the caller
|
||||
// requested, we can not fulfill the HMAC update. In this
|
||||
// case, just return NS_ERROR_NOT_AVAILABLE indicating
|
||||
// that there is not enough data in the stream to satisify
|
||||
// the request.
|
||||
|
||||
if (n == 0 || n < len)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
|
||||
uint32_t read, readLimit;
|
||||
|
||||
while(NS_SUCCEEDED(rv) && len > 0)
|
||||
{
|
||||
readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
|
||||
|
||||
rv = aStream->Read(buffer, readLimit, &read);
|
||||
if (read == 0)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = Update((const uint8_t*)buffer, read);
|
||||
|
||||
len -= read;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* ACString finish (in bool aASCII); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Finish(bool aASCII, nsACString & _retval)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
if (!mHMACContext)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
uint32_t hashLen = 0;
|
||||
unsigned char buffer[HASH_LENGTH_MAX];
|
||||
unsigned char* pbuffer = buffer;
|
||||
|
||||
PK11_DigestFinal(mHMACContext, pbuffer, &hashLen, HASH_LENGTH_MAX);
|
||||
if (aASCII)
|
||||
{
|
||||
char *asciiData = BTOA_DataToAscii(buffer, hashLen);
|
||||
NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
_retval.Assign(asciiData);
|
||||
PORT_Free(asciiData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_retval.Assign((const char*)buffer, hashLen);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void reset (); */
|
||||
NS_IMETHODIMP nsCryptoHMAC::Reset()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
SECStatus ss = PK11_DigestBegin(mHMACContext);
|
||||
NS_ENSURE_TRUE(ss == SECSuccess, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(PipUIContext, nsIInterfaceRequestor)
|
||||
|
||||
PipUIContext::PipUIContext()
|
||||
|
@ -28,9 +28,6 @@
|
||||
#include "nsITimer.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsICryptoHMAC.h"
|
||||
#include "hasht.h"
|
||||
#include "nsNSSCallbacks.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
|
||||
@ -59,8 +56,6 @@ class CertVerifier;
|
||||
|
||||
#define NS_PSMCONTENTLISTEN_CID {0xc94f4a30, 0x64d7, 0x11d4, {0x99, 0x60, 0x00, 0xb0, 0xd0, 0x23, 0x54, 0xa0}}
|
||||
#define NS_PSMCONTENTLISTEN_CONTRACTID "@mozilla.org/security/psmdownload;1"
|
||||
#define NS_CRYPTO_HASH_CID {0x36a1d3b3, 0xd886, 0x4317, {0x96, 0xff, 0x87, 0xb0, 0x00, 0x5c, 0xfe, 0xf7}}
|
||||
#define NS_CRYPTO_HMAC_CID {0xa496d0a2, 0xdff7, 0x4e23, {0xbd, 0x65, 0x1c, 0xa7, 0x42, 0xfa, 0x17, 0x8a}}
|
||||
|
||||
enum EnsureNSSOperator
|
||||
{
|
||||
@ -168,40 +163,6 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID)
|
||||
|
||||
class nsCryptoHash : public nsICryptoHash, public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICRYPTOHASH
|
||||
|
||||
nsCryptoHash();
|
||||
|
||||
private:
|
||||
~nsCryptoHash();
|
||||
|
||||
HASHContext* mHashContext;
|
||||
bool mInitialized;
|
||||
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
};
|
||||
|
||||
class nsCryptoHMAC : public nsICryptoHMAC, public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICRYPTOHMAC
|
||||
|
||||
nsCryptoHMAC();
|
||||
|
||||
private:
|
||||
~nsCryptoHMAC();
|
||||
PK11Context* mHMACContext;
|
||||
|
||||
virtual void virtualDestroyNSSReference();
|
||||
void destructorSafeDestroyNSSReference();
|
||||
};
|
||||
|
||||
class nsNSSShutDownList;
|
||||
class nsCertVerificationThread;
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "nsCertTree.h"
|
||||
#endif
|
||||
#include "nsCrypto.h"
|
||||
#include "nsCryptoHash.h"
|
||||
//For the NS_CRYPTO_CONTRACTID define
|
||||
#include "nsDOMCID.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user