mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 946348 - Refactor fingerprint handling. r=abr
This commit is contained in:
parent
fbf5f9b668
commit
da6e334879
@ -4,6 +4,7 @@
|
||||
* 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 <iomanip>
|
||||
#include "logging.h"
|
||||
#include "nspr.h"
|
||||
#include "cryptohi.h"
|
||||
@ -25,6 +26,9 @@ DtlsIdentity::~DtlsIdentity() {
|
||||
CERT_DestroyCertificate(cert_);
|
||||
}
|
||||
|
||||
const std::string DtlsIdentity::DEFAULT_HASH_ALGORITHM = "sha-256";
|
||||
const size_t DtlsIdentity::HASH_ALGORITHM_MAX_LENGTH = 64;
|
||||
|
||||
TemporaryRef<DtlsIdentity> DtlsIdentity::Generate() {
|
||||
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
@ -86,7 +90,7 @@ TemporaryRef<DtlsIdentity> DtlsIdentity::Generate() {
|
||||
// now with some slack in case the other side expects
|
||||
// some before expiry.
|
||||
//
|
||||
// Note: explicit casts necessary to avoid
|
||||
// Note: explicit casts necessary to avoid
|
||||
// warning C4307: '*' : integral constant overflow
|
||||
static const PRTime oneDay = PRTime(PR_USEC_PER_SEC)
|
||||
* PRTime(60) // sec
|
||||
@ -206,8 +210,29 @@ nsresult DtlsIdentity::ComputeFingerprint(const CERTCertificate *cert,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Format the fingerprint in RFC 4572 Section 5 format, colons and
|
||||
// all.
|
||||
// Format the fingerprint in RFC 4572 Section 5 attribute format, including both
|
||||
// the hash name and the fingerprint, colons and all.
|
||||
// returns an empty string if there is a problem
|
||||
std::string DtlsIdentity::GetFormattedFingerprint(const std::string &algorithm) {
|
||||
unsigned char digest[HASH_ALGORITHM_MAX_LENGTH];
|
||||
size_t digest_length;
|
||||
|
||||
nsresult res = this->ComputeFingerprint(algorithm,
|
||||
digest,
|
||||
sizeof(digest),
|
||||
&digest_length);
|
||||
if (NS_FAILED(res)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Unable to compute " << algorithm
|
||||
<< " hash for identity: nsresult = 0x"
|
||||
<< std::hex << std::uppercase
|
||||
<< static_cast<uint32_t>(res)
|
||||
<< std::nouppercase << std::dec);
|
||||
return "";
|
||||
}
|
||||
|
||||
return algorithm + " " + this->FormatFingerprint(digest, digest_length);
|
||||
}
|
||||
|
||||
std::string DtlsIdentity::FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size) {
|
||||
std::string str("");
|
||||
@ -215,7 +240,7 @@ std::string DtlsIdentity::FormatFingerprint(const unsigned char *digest,
|
||||
|
||||
for (std::size_t i=0; i < size; i++) {
|
||||
PR_snprintf(group, sizeof(group), "%.2X", digest[i]);
|
||||
if (i != 0){
|
||||
if (i != 0) {
|
||||
str += ":";
|
||||
}
|
||||
str += group;
|
||||
|
@ -32,6 +32,8 @@ class DtlsIdentity {
|
||||
CERTCertificate *cert() { return cert_; }
|
||||
SECKEYPrivateKey *privkey() { return privkey_; }
|
||||
|
||||
std::string GetFormattedFingerprint(const std::string &algorithm = DEFAULT_HASH_ALGORITHM);
|
||||
|
||||
nsresult ComputeFingerprint(const std::string algorithm,
|
||||
unsigned char *digest,
|
||||
std::size_t size,
|
||||
@ -43,8 +45,6 @@ class DtlsIdentity {
|
||||
std::size_t size,
|
||||
std::size_t *digest_length);
|
||||
|
||||
static std::string FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size);
|
||||
static nsresult ParseFingerprint(const std::string fp,
|
||||
unsigned char *digest,
|
||||
size_t size, size_t *length);
|
||||
@ -56,6 +56,12 @@ class DtlsIdentity {
|
||||
: privkey_(privkey), cert_(cert) {}
|
||||
DISALLOW_COPY_ASSIGN(DtlsIdentity);
|
||||
|
||||
static const std::string DEFAULT_HASH_ALGORITHM;
|
||||
static const size_t HASH_ALGORITHM_MAX_LENGTH;
|
||||
|
||||
std::string FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size);
|
||||
|
||||
ScopedSECKEYPrivateKey privkey_;
|
||||
CERTCertificate *cert_; // TODO: Using a smart pointer here causes link
|
||||
// errors.
|
||||
|
@ -1178,10 +1178,10 @@ short vcmAddRemoteStreamHint(
|
||||
* Get DTLS key data
|
||||
*
|
||||
* @param[in] peerconnection - the peerconnection in use
|
||||
* @param[out] digest_algp - the digest algorithm e.g. 'SHA-1'
|
||||
* @param[in] max_digest_alg_len - length of string
|
||||
* @param[out] digest_algp - the digest algorithm e.g. 'sha-256'
|
||||
* @param[in] max_digest_alg_len - available length of string
|
||||
* @param[out] digestp - the digest string
|
||||
* @param[in] max_digest_len - length of string
|
||||
* @param[in] max_digest_len - available length of string
|
||||
*
|
||||
* Returns: zero(0) for success; otherwise, ERROR for failure
|
||||
*/
|
||||
@ -1197,33 +1197,10 @@ static short vcmGetDtlsIdentity_m(const char *peerconnection,
|
||||
sipcc::PeerConnectionWrapper pc(peerconnection);
|
||||
ENSURE_PC(pc, VCM_ERROR);
|
||||
|
||||
unsigned char digest[TransportLayerDtls::kMaxDigestLength];
|
||||
size_t digest_len;
|
||||
|
||||
mozilla::RefPtr<DtlsIdentity> id = pc.impl()->GetIdentity();
|
||||
|
||||
if (!id) {
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
nsresult res = id->ComputeFingerprint("sha-256", digest, sizeof(digest),
|
||||
&digest_len);
|
||||
if (!NS_SUCCEEDED(res)) {
|
||||
CSFLogError( logTag, "%s: Could not compute identity fingerprint", __FUNCTION__);
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
// digest_len should be 32 for SHA-256
|
||||
PR_ASSERT(digest_len == 32);
|
||||
std::string fingerprint_txt = DtlsIdentity::FormatFingerprint(digest, digest_len);
|
||||
if (max_digest_len <= fingerprint_txt.size()) {
|
||||
CSFLogError( logTag, "%s: Formatted digest will not fit in provided buffer",
|
||||
__FUNCTION__);
|
||||
return VCM_ERROR;
|
||||
}
|
||||
|
||||
sstrncpy(digest_algp, "sha-256", max_digest_alg_len);
|
||||
sstrncpy(digestp, fingerprint_txt.c_str(), max_digest_len);
|
||||
std::string algorithm = pc.impl()->GetFingerprintAlgorithm();
|
||||
sstrncpy(digest_algp, algorithm.c_str(), max_digest_alg_len);
|
||||
std::string value = pc.impl()->GetFingerprintHexValue();
|
||||
sstrncpy(digestp, value.c_str(), max_digest_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -789,26 +789,9 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Set the fingerprint. Right now assume we only have one
|
||||
// DTLS identity
|
||||
unsigned char fingerprint[DTLS_FINGERPRINT_LENGTH];
|
||||
size_t fingerprint_length;
|
||||
res = mIdentity->ComputeFingerprint("sha-256",
|
||||
fingerprint,
|
||||
sizeof(fingerprint),
|
||||
&fingerprint_length);
|
||||
|
||||
if (NS_FAILED(res)) {
|
||||
CSFLogError(logTag, "%s: ComputeFingerprint failed: %u",
|
||||
__FUNCTION__, static_cast<uint32_t>(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
mFingerprint = "sha-256 " + mIdentity->FormatFingerprint(fingerprint,
|
||||
fingerprint_length);
|
||||
if (NS_FAILED(res)) {
|
||||
CSFLogError(logTag, "%s: do_GetService failed: %u",
|
||||
__FUNCTION__, static_cast<uint32_t>(res));
|
||||
mFingerprint = mIdentity->GetFormattedFingerprint();
|
||||
if (mFingerprint.empty()) {
|
||||
CSFLogError(logTag, "%s: unable to get fingerprint", __FUNCTION__);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -816,11 +799,56 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
||||
}
|
||||
|
||||
RefPtr<DtlsIdentity> const
|
||||
PeerConnectionImpl::GetIdentity() {
|
||||
PeerConnectionImpl::GetIdentity() const
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL_NO_CHECK();
|
||||
return mIdentity;
|
||||
}
|
||||
|
||||
std::string
|
||||
PeerConnectionImpl::GetFingerprint() const
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL_NO_CHECK();
|
||||
return mFingerprint;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::FingerprintSplitHelper(std::string& fingerprint,
|
||||
size_t& spaceIdx) const
|
||||
{
|
||||
fingerprint = GetFingerprint();
|
||||
spaceIdx = fingerprint.find_first_of(' ');
|
||||
if (spaceIdx == std::string::npos) {
|
||||
CSFLogError(logTag, "%s: fingerprint is messed up: %s",
|
||||
__FUNCTION__, fingerprint.c_str());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::string
|
||||
PeerConnectionImpl::GetFingerprintAlgorithm() const
|
||||
{
|
||||
std::string fp;
|
||||
size_t spc;
|
||||
if (NS_SUCCEEDED(FingerprintSplitHelper(fp, spc))) {
|
||||
return fp.substr(0, spc);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string
|
||||
PeerConnectionImpl::GetFingerprintHexValue() const
|
||||
{
|
||||
std::string fp;
|
||||
size_t spc;
|
||||
if (NS_SUCCEEDED(FingerprintSplitHelper(fp, spc))) {
|
||||
return fp.substr(spc + 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
|
||||
{
|
||||
|
@ -246,7 +246,10 @@ public:
|
||||
}
|
||||
|
||||
// Get the DTLS identity
|
||||
mozilla::RefPtr<DtlsIdentity> const GetIdentity();
|
||||
mozilla::RefPtr<DtlsIdentity> const GetIdentity() const;
|
||||
std::string GetFingerprint() const;
|
||||
std::string GetFingerprintAlgorithm() const;
|
||||
std::string GetFingerprintHexValue() const;
|
||||
|
||||
// Create a fake media stream
|
||||
nsresult CreateFakeMediaStream(uint32_t hint, nsIDOMMediaStream** retval);
|
||||
@ -532,6 +535,10 @@ private:
|
||||
nsresult IceGatheringStateChange_m(
|
||||
mozilla::dom::PCImplIceGatheringState aState);
|
||||
|
||||
NS_IMETHOD FingerprintSplitHelper(
|
||||
std::string& fingerprint, size_t& spaceIdx) const;
|
||||
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// Fills in an RTCStatsReportInternal. Must be run on STS.
|
||||
void GetStats_s(
|
||||
|
Loading…
Reference in New Issue
Block a user