Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/manager/ssl/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 34 kB image not shown  

Quelle  TransportSecurityInfo.cpp   Sprache: C

 
/* -*- 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 "TransportSecurityInfo.h"

#include "ipc/IPCMessageUtils.h"
#include "mozilla/Base64.h"
#include "mozpkix/pkixtypes.h"
#include "nsBase64Encoder.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsIWebProgressListener.h"
#include "nsNSSCertHelper.h"
#include "nsNSSComponent.h"
#include "nsNSSHelper.h"
#include "nsReadableUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsStringStream.h"
#include "nsXULAppAPI.h"
#include "nsIX509Cert.h"
#include "secerr.h"
#include "ssl.h"

#include "mozilla/ipc/IPDLParamTraits.h"

// nsITransportSecurityInfo should not be created via do_CreateInstance. This
// stub prevents that.
template <>
already_AddRefed<nsISupports>
mozCreateComponent<mozilla::psm::TransportSecurityInfo>() {
  return nullptr;
}

namespace mozilla {
namespace psm {

TransportSecurityInfo::TransportSecurityInfo(
    uint32_t aSecurityState, PRErrorCode aErrorCode,
    nsTArray<RefPtr<nsIX509Cert>>&& aFailedCertChain,
    nsCOMPtr<nsIX509Cert>& aServerCert,
    nsTArray<RefPtr<nsIX509Cert>>&& aSucceededCertChain,
    Maybe<uint16_t> aCipherSuite, Maybe<nsCString> aKeaGroupName,
    Maybe<nsCString> aSignatureSchemeName, Maybe<uint16_t> aProtocolVersion,
    uint16_t aCertificateTransparencyStatus, Maybe<bool> aIsAcceptedEch,
    Maybe<bool> aIsDelegatedCredential,
    Maybe<OverridableErrorCategory> aOverridableErrorCategory,
    bool aMadeOCSPRequests, bool aUsedPrivateDNS, Maybe<bool> aIsEV,
    bool aNPNCompleted, const nsCString& aNegotiatedNPN, bool aResumed,
    bool aIsBuiltCertChainRootBuiltInRoot, const nsCString& aPeerId)
    : mSecurityState(aSecurityState),
      mErrorCode(aErrorCode),
      mFailedCertChain(std::move(aFailedCertChain)),
      mServerCert(aServerCert),
      mSucceededCertChain(std::move(aSucceededCertChain)),
      mCipherSuite(aCipherSuite),
      mKeaGroupName(aKeaGroupName),
      mSignatureSchemeName(aSignatureSchemeName),
      mProtocolVersion(aProtocolVersion),
      mCertificateTransparencyStatus(aCertificateTransparencyStatus),
      mIsAcceptedEch(aIsAcceptedEch),
      mIsDelegatedCredential(aIsDelegatedCredential),
      mOverridableErrorCategory(aOverridableErrorCategory),
      mMadeOCSPRequests(aMadeOCSPRequests),
      mUsedPrivateDNS(aUsedPrivateDNS),
      mIsEV(aIsEV),
      mNPNCompleted(aNPNCompleted),
      mNegotiatedNPN(aNegotiatedNPN),
      mResumed(aResumed),
      mIsBuiltCertChainRootBuiltInRoot(aIsBuiltCertChainRootBuiltInRoot),
      mPeerId(aPeerId) {}

NS_IMPL_ISUPPORTS(TransportSecurityInfo, nsITransportSecurityInfo)

NS_IMETHODIMP
TransportSecurityInfo::GetSecurityState(uint32_t* state) {
  *state = mSecurityState;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetErrorCode(int32_t* state) {
  *state = mErrorCode;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetErrorCodeString(nsAString& aErrorString) {
  const char* codeName = PR_ErrorToName(mErrorCode);
  aErrorString.Truncate();
  if (codeName) {
    aErrorString = NS_ConvertASCIItoUTF16(codeName);
  }

  return NS_OK;
}

// 16786594-0296-4471-8096-8f84497ca428
#define TRANSPORTSECURITYINFO_CID                    \
  {                                                  \
    0x16786594, 0x0296, 0x4471, {                    \
      0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28 \
    }                                                \
  }
static NS_DEFINE_CID(kTransportSecurityInfoCID, TRANSPORTSECURITYINFO_CID);

// This is a new magic value. However, it re-uses the first 4 bytes
// of the previous value. This is so when older versions attempt to
// read a newer serialized TransportSecurityInfo, they will actually
// fail and return NS_ERROR_FAILURE instead of silently failing.
#define TRANSPORTSECURITYINFOMAGIC                   \
  {                                                  \
    0xa9863a23, 0x1faa, 0x4169, {                    \
      0xb0, 0xd2, 0x81, 0x29, 0xec, 0x7c, 0xb1, 0xde \
    }                                                \
  }
static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC);

NS_IMETHODIMP
TransportSecurityInfo::ToString(nsACString& aResult) {
  RefPtr<nsBase64Encoder> stream(new nsBase64Encoder());
  nsCOMPtr<nsIObjectOutputStream> objStream(NS_NewObjectOutputStream(stream));
  nsresult rv = objStream->WriteID(kTransportSecurityInfoCID);
  if (NS_FAILED(rv)) {
    return rv;
  }
  rv = objStream->WriteID(NS_ISUPPORTS_IID);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteID(kTransportSecurityInfoMagic);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->Write32(mSecurityState);
  if (NS_FAILED(rv)) {
    return rv;
  }
  // mSubRequestsBrokenSecurity was removed in bug 748809
  rv = objStream->Write32(0);
  if (NS_FAILED(rv)) {
    return rv;
  }
  // mSubRequestsNoSecurity was removed in bug 748809
  rv = objStream->Write32(0);
  if (NS_FAILED(rv)) {
    return rv;
  }
  rv = objStream->Write32(static_cast<uint32_t>(mErrorCode));
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Re-purpose mErrorMessageCached to represent serialization version
  // If string doesn't match exact version it will be treated as older
  // serialization.
  rv = objStream->WriteWStringZ(NS_ConvertUTF8toUTF16("9").get());
  if (NS_FAILED(rv)) {
    return rv;
  }

  // moved from nsISSLStatus
  rv = NS_WriteOptionalCompoundObject(objStream, mServerCert,
                                      NS_GET_IID(nsIX509Cert), true);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->Write16(mCipherSuite.isSome() ? *mCipherSuite : 0);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->Write16(mProtocolVersion.isSome() ? *mProtocolVersion : 0);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->Write32(mOverridableErrorCategory.isSome()
                              ? *mOverridableErrorCategory
                              : OverridableErrorCategory::ERROR_UNSET);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = objStream->WriteBoolean(mIsEV.isSome() ? *mIsEV : false);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->WriteBoolean(mIsEV.isSome());  // previously mHasIsEV
  NS_ENSURE_SUCCESS(rv, rv);
  rv = objStream->WriteBoolean(
      mCipherSuite.isSome());  // previously mHaveCipherSuiteAndProtocol
  NS_ENSURE_SUCCESS(rv, rv);
  rv = objStream->WriteBoolean(
      mOverridableErrorCategory.isSome());  // previously mHaveCertErrorBits
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->Write16(mCertificateTransparencyStatus);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->WriteStringZ(mKeaGroupName.isSome() ? (*mKeaGroupName).get()
                                                      : "");
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->WriteStringZ(
      mSignatureSchemeName.isSome() ? (*mSignatureSchemeName).get() : "");
  NS_ENSURE_SUCCESS(rv, rv);

  rv = objStream->Write16(mSucceededCertChain.Length());
  NS_ENSURE_SUCCESS(rv, rv);

  for (const auto& cert : mSucceededCertChain) {
    rv = objStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  // END moved from nsISSLStatus
  rv = objStream->Write16(mFailedCertChain.Length());
  NS_ENSURE_SUCCESS(rv, rv);
  for (const auto& cert : mFailedCertChain) {
    rv = objStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = objStream->WriteBoolean(
      mIsDelegatedCredential.isSome() ? *mIsDelegatedCredential : false);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mNPNCompleted);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteStringZ(mNegotiatedNPN.get());
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mResumed);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mIsBuiltCertChainRootBuiltInRoot);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mIsAcceptedEch.isSome() ? *mIsAcceptedEch
                                                       : false);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteStringZ(mPeerId.get());
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mMadeOCSPRequests);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = objStream->WriteBoolean(mUsedPrivateDNS);
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = stream->Finish(aResult);
  if (NS_FAILED(rv)) {
    return rv;
  }

  return NS_OK;
}

nsresult TransportSecurityInfo::ReadOldOverridableErrorBits(
    nsIObjectInputStream* aStream,
    OverridableErrorCategory& aOverridableErrorCategory) {
  bool isDomainMismatch;
  nsresult rv = aStream->ReadBoolean(&isDomainMismatch);
  NS_ENSURE_SUCCESS(rv, rv);
  bool isNotValidAtThisTime;
  rv = aStream->ReadBoolean(&isNotValidAtThisTime);
  NS_ENSURE_SUCCESS(rv, rv);
  bool isUntrusted;
  rv = aStream->ReadBoolean(&isUntrusted);
  NS_ENSURE_SUCCESS(rv, rv);
  if (isUntrusted) {
    aOverridableErrorCategory =
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST;
  } else if (isDomainMismatch) {
    aOverridableErrorCategory =
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN;
  } else if (isNotValidAtThisTime) {
    aOverridableErrorCategory =
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME;
  } else {
    aOverridableErrorCategory =
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
  }

  return NS_OK;
}

// This is for backward compatibility to be able to read nsISSLStatus
// serialized object.
nsresult TransportSecurityInfo::ReadSSLStatus(
    nsIObjectInputStream* aStream, nsCOMPtr<nsIX509Cert>& aServerCert,
    Maybe<uint16_t>& aCipherSuite, Maybe<uint16_t>& aProtocolVersion,
    Maybe<OverridableErrorCategory>& aOverridableErrorCategory,
    Maybe<bool>& aIsEV, uint16_t& aCertificateTransparencyStatus,
    Maybe<nsCString>& aKeaGroupName, Maybe<nsCString>& aSignatureSchemeName,
    nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain) {
  bool nsISSLStatusPresent;
  nsresult rv = aStream->ReadBoolean(&nsISSLStatusPresent);
  NS_ENSURE_SUCCESS(rv, rv);
  if (!nsISSLStatusPresent) {
    return NS_OK;
  }
  // nsISSLStatus present.  Prepare to read elements.
  // Throw away cid, validate iid
  nsCID cid;
  nsIID iid;
  rv = aStream->ReadID(&cid);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = aStream->ReadID(&iid);
  NS_ENSURE_SUCCESS(rv, rv);

  static const nsIID nsSSLStatusIID = {
      0xfa9ba95b,
      0xca3b,
      0x498a,
      {0xb8, 0x89, 0x7c, 0x79, 0xcf, 0x28, 0xfe, 0xe8}};
  if (!iid.Equals(nsSSLStatusIID)) {
    return NS_ERROR_UNEXPECTED;
  }

  nsCOMPtr<nsISupports> cert;
  rv = aStream->ReadObject(true, getter_AddRefs(cert));
  NS_ENSURE_SUCCESS(rv, rv);

  if (cert) {
    aServerCert = do_QueryInterface(cert);
    if (!aServerCert) {
      return NS_NOINTERFACE;
    }
  }

  uint16_t cipherSuite;
  rv = aStream->Read16(&cipherSuite);
  NS_ENSURE_SUCCESS(rv, rv);

  // The code below is a workaround to allow serializing new fields
  // while preserving binary compatibility with older streams. For more details
  // on the binary compatibility requirement, refer to bug 1248628.
  // Here, we take advantage of the fact that mProtocolVersion was originally
  // stored as a 16 bits integer, but the highest 8 bits were never used.
  // These bits are now used for stream versioning.
  uint16_t protocolVersionAndStreamFormatVersion;
  rv = aStream->Read16(&protocolVersionAndStreamFormatVersion);
  NS_ENSURE_SUCCESS(rv, rv);
  const uint8_t streamFormatVersion =
      (protocolVersionAndStreamFormatVersion >> 8) & 0xFF;

  OverridableErrorCategory overridableErrorCategory;
  rv = ReadOldOverridableErrorBits(aStream, overridableErrorCategory);
  NS_ENSURE_SUCCESS(rv, rv);
  bool isEV;
  rv = aStream->ReadBoolean(&isEV);
  NS_ENSURE_SUCCESS(rv, rv);
  bool hasIsEVStatus;
  rv = aStream->ReadBoolean(&hasIsEVStatus);
  NS_ENSURE_SUCCESS(rv, rv);
  if (hasIsEVStatus) {
    aIsEV.emplace(isEV);
  }
  bool haveCipherSuiteAndProtocol;
  rv = aStream->ReadBoolean(&haveCipherSuiteAndProtocol);
  if (haveCipherSuiteAndProtocol) {
    aCipherSuite.emplace(cipherSuite);
    aProtocolVersion.emplace(protocolVersionAndStreamFormatVersion & 0xFF);
  }
  NS_ENSURE_SUCCESS(rv, rv);
  bool haveCertErrorBits;
  rv = aStream->ReadBoolean(&haveCertErrorBits);
  NS_ENSURE_SUCCESS(rv, rv);
  if (haveCertErrorBits) {
    aOverridableErrorCategory.emplace(overridableErrorCategory);
  }

  // Added in version 1 (see bug 1305289).
  if (streamFormatVersion >= 1) {
    rv = aStream->Read16(&aCertificateTransparencyStatus);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Added in version 2 (see bug 1304923).
  if (streamFormatVersion >= 2) {
    nsCString keaGroupName;
    rv = aStream->ReadCString(keaGroupName);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCipherSuiteAndProtocol) {
      aKeaGroupName.emplace(keaGroupName);
    }

    nsCString signatureSchemeName;
    rv = aStream->ReadCString(signatureSchemeName);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCipherSuiteAndProtocol) {
      aSignatureSchemeName.emplace(signatureSchemeName);
    }
  }

  // Added in version 3 (see bug 1406856).
  if (streamFormatVersion >= 3) {
    rv = ReadCertList(aStream, aSucceededCertChain);
    if (NS_FAILED(rv)) {
      return rv;
    }

    // Read only to consume bytes from the stream.
    nsTArray<RefPtr<nsIX509Cert>> failedCertChain;
    rv = ReadCertList(aStream, failedCertChain);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }
  return rv;
}

// This is for backward compatability to be able to read nsIX509CertList
// serialized object.
nsresult TransportSecurityInfo::ReadCertList(
    nsIObjectInputStream* aStream, nsTArray<RefPtr<nsIX509Cert>>& aCertList) {
  bool nsIX509CertListPresent;

  nsresult rv = aStream->ReadBoolean(&nsIX509CertListPresent);
  NS_ENSURE_SUCCESS(rv, rv);
  if (!nsIX509CertListPresent) {
    return NS_OK;
  }
  // nsIX509CertList present.  Prepare to read elements.
  // Throw away cid, validate iid
  nsCID cid;
  nsIID iid;
  rv = aStream->ReadID(&cid);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = aStream->ReadID(&iid);
  NS_ENSURE_SUCCESS(rv, rv);

  static const nsIID nsIX509CertListIID = {
      0xae74cda5,
      0xcd2f,
      0x473f,
      {0x96, 0xf5, 0xf0, 0xb7, 0xff, 0xf6, 0x2c, 0x68}};

  if (!iid.Equals(nsIX509CertListIID)) {
    return NS_ERROR_UNEXPECTED;
  }

  uint32_t certListSize;
  rv = aStream->Read32(&certListSize);
  NS_ENSURE_SUCCESS(rv, rv);

  return ReadCertificatesFromStream(aStream, certListSize, aCertList);
}

nsresult TransportSecurityInfo::ReadCertificatesFromStream(
    nsIObjectInputStream* aStream, uint32_t aSize,
    nsTArray<RefPtr<nsIX509Cert>>& aCertList) {
  nsresult rv;
  for (uint32_t i = 0; i < aSize; ++i) {
    nsCOMPtr<nsISupports> support;
    rv = aStream->ReadObject(true, getter_AddRefs(support));
    NS_ENSURE_SUCCESS(rv, rv);
    nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(support);
    if (!cert) {
      return NS_ERROR_UNEXPECTED;
    }
    RefPtr<nsIX509Cert> castedCert(cert.get());
    aCertList.AppendElement(castedCert);
  }
  return NS_OK;
}

static nsITransportSecurityInfo::OverridableErrorCategory
IntToOverridableErrorCategory(uint32_t intVal) {
  switch (intVal) {
    case static_cast<uint32_t>(
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST):
      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST;
    case static_cast<uint32_t>(
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN):
      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN;
    case static_cast<uint32_t>(
        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME):
      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME;
    default:
      break;
  }
  return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
}

nsresult TransportSecurityInfo::Read(const nsCString& aSerializedSecurityInfo,
                                     nsITransportSecurityInfo** aResult) {
  *aResult = nullptr;

  nsCString decodedSecurityInfo;
  nsresult rv = Base64Decode(aSerializedSecurityInfo, decodedSecurityInfo);
  if (NS_FAILED(rv)) {
    return rv;
  }
  nsCOMPtr<nsIInputStream> inputStream;
  rv = NS_NewCStringInputStream(getter_AddRefs(inputStream),
                                std::move(decodedSecurityInfo));
  if (NS_FAILED(rv)) {
    return rv;
  }
  nsCOMPtr<nsIObjectInputStream> objStream(
      NS_NewObjectInputStream(inputStream));
  if (!objStream) {
    return rv;
  }

  nsCID cid;
  rv = objStream->ReadID(&cid);
  if (NS_FAILED(rv)) {
    return rv;
  }
  if (!cid.Equals(kTransportSecurityInfoCID)) {
    return NS_ERROR_UNEXPECTED;
  }
  nsIID iid;
  rv = objStream->ReadID(&iid);
  if (NS_FAILED(rv)) {
    return rv;
  }
  if (!iid.Equals(NS_ISUPPORTS_IID)) {
    return rv;
  }

  nsID id;
  rv = objStream->ReadID(&id);
  if (NS_FAILED(rv)) {
    return rv;
  }
  if (!id.Equals(kTransportSecurityInfoMagic)) {
    return NS_ERROR_UNEXPECTED;
  }

  uint32_t aSecurityState = 0;
  PRErrorCode aErrorCode = 0;
  nsTArray<RefPtr<nsIX509Cert>> aFailedCertChain;
  nsCOMPtr<nsIX509Cert> aServerCert;
  nsTArray<RefPtr<nsIX509Cert>> aSucceededCertChain;
  Maybe<uint16_t> aCipherSuite;
  Maybe<nsCString> aKeaGroupName;
  Maybe<nsCString> aSignatureSchemeName;
  Maybe<uint16_t> aProtocolVersion;
  uint16_t aCertificateTransparencyStatus;
  Maybe<bool> aIsAcceptedEch;
  Maybe<bool> aIsDelegatedCredential;
  Maybe<OverridableErrorCategory> aOverridableErrorCategory;
  bool aMadeOCSPRequests = false;
  bool aUsedPrivateDNS = false;
  Maybe<bool> aIsEV;
  bool aNPNCompleted = false;
  nsCString aNegotiatedNPN;
  bool aResumed = false;
  bool aIsBuiltCertChainRootBuiltInRoot = false;
  nsCString aPeerId;
  rv = objStream->Read32(&aSecurityState);
  if (NS_FAILED(rv)) {
    return rv;
  }
  // mSubRequestsBrokenSecurity was removed in bug 748809
  uint32_t unusedSubRequestsBrokenSecurity;
  rv = objStream->Read32(&unusedSubRequestsBrokenSecurity);
  if (NS_FAILED(rv)) {
    return rv;
  }
  // mSubRequestsNoSecurity was removed in bug 748809
  uint32_t unusedSubRequestsNoSecurity;
  rv = objStream->Read32(&unusedSubRequestsNoSecurity);
  if (NS_FAILED(rv)) {
    return rv;
  }
  uint32_t errorCode;
  rv = objStream->Read32(&errorCode);
  if (NS_FAILED(rv)) {
    return rv;
  }
  // PRErrorCode will be a negative value
  aErrorCode = static_cast<PRErrorCode>(errorCode);

  // Re-purpose mErrorMessageCached to represent serialization version
  // If string doesn't match exact version it will be treated as older
  // serialization.
  nsAutoString serVersion;
  rv = objStream->ReadString(serVersion);
  if (NS_FAILED(rv)) {
    return rv;
  }

  int32_t serVersionParsedToInt = 0;

  if (!serVersion.IsEmpty()) {
    char first = serVersion.First();
    // Check whether the first character of serVersion is a number
    // since ToInteger() skipps some non integer values.
    if (first >= '0' && first <= '9') {
      nsresult error = NS_OK;
      serVersionParsedToInt = serVersion.ToInteger(&error);
      if (NS_FAILED(error)) {
        return error;
      }
    }
  }

  // moved from nsISSLStatus
  if (serVersionParsedToInt < 1) {
    // nsISSLStatus may be present
    rv = ReadSSLStatus(objStream, aServerCert, aCipherSuite, aProtocolVersion,
                       aOverridableErrorCategory, aIsEV,
                       aCertificateTransparencyStatus, aKeaGroupName,
                       aSignatureSchemeName, aSucceededCertChain);
    NS_ENSURE_SUCCESS(rv, rv);
  } else {
    nsCOMPtr<nsISupports> cert;
    rv = NS_ReadOptionalObject(objStream, true, getter_AddRefs(cert));
    NS_ENSURE_SUCCESS(rv, rv);

    if (cert) {
      aServerCert = do_QueryInterface(cert);
      if (!aServerCert) {
        return NS_NOINTERFACE;
      }
    }

    uint16_t cipherSuite;
    rv = objStream->Read16(&cipherSuite);
    NS_ENSURE_SUCCESS(rv, rv);

    uint16_t protocolVersion;
    rv = objStream->Read16(&protocolVersion);
    NS_ENSURE_SUCCESS(rv, rv);

    OverridableErrorCategory overridableErrorCategory;
    if (serVersionParsedToInt < 8) {
      rv = ReadOldOverridableErrorBits(objStream, overridableErrorCategory);
      NS_ENSURE_SUCCESS(rv, rv);
    } else {
      uint32_t overridableErrorCategoryInt;
      rv = objStream->Read32(&overridableErrorCategoryInt);
      NS_ENSURE_SUCCESS(rv, rv);
      overridableErrorCategory =
          IntToOverridableErrorCategory(overridableErrorCategoryInt);
    }
    bool isEV;
    rv = objStream->ReadBoolean(&isEV);
    NS_ENSURE_SUCCESS(rv, rv);
    bool hasIsEVStatus;
    rv = objStream->ReadBoolean(&hasIsEVStatus);
    NS_ENSURE_SUCCESS(rv, rv);
    if (hasIsEVStatus) {
      aIsEV.emplace(isEV);
    }
    bool haveCipherSuiteAndProtocol;
    rv = objStream->ReadBoolean(&haveCipherSuiteAndProtocol);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCipherSuiteAndProtocol) {
      aCipherSuite.emplace(cipherSuite);
      aProtocolVersion.emplace(protocolVersion);
    }
    bool haveCertErrorBits;
    rv = objStream->ReadBoolean(&haveCertErrorBits);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCertErrorBits) {
      aOverridableErrorCategory.emplace(overridableErrorCategory);
    }

    rv = objStream->Read16(&aCertificateTransparencyStatus);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCString keaGroupName;
    rv = objStream->ReadCString(keaGroupName);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCipherSuiteAndProtocol) {
      aKeaGroupName.emplace(keaGroupName);
    }

    nsCString signatureSchemeName;
    rv = objStream->ReadCString(signatureSchemeName);
    NS_ENSURE_SUCCESS(rv, rv);
    if (haveCipherSuiteAndProtocol) {
      aSignatureSchemeName.emplace(signatureSchemeName);
    }

    if (serVersionParsedToInt < 3) {
      // The old data structure of certList(nsIX509CertList) presents
      rv = ReadCertList(objStream, aSucceededCertChain);
      NS_ENSURE_SUCCESS(rv, rv);
    } else {
      uint16_t certCount;
      rv = objStream->Read16(&certCount);
      NS_ENSURE_SUCCESS(rv, rv);

      rv =
          ReadCertificatesFromStream(objStream, certCount, aSucceededCertChain);
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }
  // END moved from nsISSLStatus
  if (serVersionParsedToInt < 3) {
    // The old data structure of certList(nsIX509CertList) presents
    rv = ReadCertList(objStream, aFailedCertChain);
    NS_ENSURE_SUCCESS(rv, rv);
  } else {
    uint16_t certCount;
    rv = objStream->Read16(&certCount);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = ReadCertificatesFromStream(objStream, certCount, aFailedCertChain);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // mIsDelegatedCredential added in bug 1562773
  if (serVersionParsedToInt >= 2) {
    bool isDelegatedCredential;
    rv = objStream->ReadBoolean(&isDelegatedCredential);
    if (NS_FAILED(rv)) {
      return rv;
    }
    // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
    // cipher suite and protocol information, which means it has this
    // information.
    if (aCipherSuite.isSome()) {
      aIsDelegatedCredential.emplace(isDelegatedCredential);
    }
  }

  // mNPNCompleted, mNegotiatedNPN, mResumed added in bug 1584104
  if (serVersionParsedToInt >= 4) {
    rv = objStream->ReadBoolean(&aNPNCompleted);
    if (NS_FAILED(rv)) {
      return rv;
    }

    rv = objStream->ReadCString(aNegotiatedNPN);
    if (NS_FAILED(rv)) {
      return rv;
    }

    rv = objStream->ReadBoolean(&aResumed);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  // mIsBuiltCertChainRootBuiltInRoot added in bug 1485652
  if (serVersionParsedToInt >= 5) {
    rv = objStream->ReadBoolean(&aIsBuiltCertChainRootBuiltInRoot);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  // mIsAcceptedEch added in bug 1678079
  if (serVersionParsedToInt >= 6) {
    bool isAcceptedEch;
    rv = objStream->ReadBoolean(&isAcceptedEch);
    if (NS_FAILED(rv)) {
      return rv;
    }
    // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
    // cipher suite and protocol information, which means it has this
    // information.
    if (aCipherSuite.isSome()) {
      aIsAcceptedEch.emplace(isAcceptedEch);
    }
  }

  // mPeerId added in bug 1738664
  if (serVersionParsedToInt >= 7) {
    rv = objStream->ReadCString(aPeerId);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  if (serVersionParsedToInt >= 9) {
    rv = objStream->ReadBoolean(&aMadeOCSPRequests);
    if (NS_FAILED(rv)) {
      return rv;
    }

    rv = objStream->ReadBoolean(&aUsedPrivateDNS);
    if (NS_FAILED(rv)) {
      return rv;
    };
  }

  RefPtr<nsITransportSecurityInfo> securityInfo(new TransportSecurityInfo(
      aSecurityState, aErrorCode, std::move(aFailedCertChain), aServerCert,
      std::move(aSucceededCertChain), aCipherSuite, aKeaGroupName,
      aSignatureSchemeName, aProtocolVersion, aCertificateTransparencyStatus,
      aIsAcceptedEch, aIsDelegatedCredential, aOverridableErrorCategory,
      aMadeOCSPRequests, aUsedPrivateDNS, aIsEV, aNPNCompleted, aNegotiatedNPN,
      aResumed, aIsBuiltCertChainRootBuiltInRoot, aPeerId));
  securityInfo.forget(aResult);
  return NS_OK;
}

void TransportSecurityInfo::SerializeToIPC(IPC::MessageWriter* aWriter) {
  WriteParam(aWriter, mSecurityState);
  WriteParam(aWriter, mErrorCode);
  WriteParam(aWriter, mFailedCertChain);
  WriteParam(aWriter, mServerCert);
  WriteParam(aWriter, mSucceededCertChain);
  WriteParam(aWriter, mCipherSuite);
  WriteParam(aWriter, mKeaGroupName);
  WriteParam(aWriter, mSignatureSchemeName);
  WriteParam(aWriter, mProtocolVersion);
  WriteParam(aWriter, mCertificateTransparencyStatus);
  WriteParam(aWriter, mIsAcceptedEch);
  WriteParam(aWriter, mIsDelegatedCredential);
  WriteParam(aWriter, mOverridableErrorCategory);
  WriteParam(aWriter, mMadeOCSPRequests);
  WriteParam(aWriter, mUsedPrivateDNS);
  WriteParam(aWriter, mIsEV);
  WriteParam(aWriter, mNPNCompleted);
  WriteParam(aWriter, mNegotiatedNPN);
  WriteParam(aWriter, mResumed);
  WriteParam(aWriter, mIsBuiltCertChainRootBuiltInRoot);
  WriteParam(aWriter, mPeerId);
}

bool TransportSecurityInfo::DeserializeFromIPC(
    IPC::MessageReader* aReader, RefPtr<nsITransportSecurityInfo>* aResult) {
  uint32_t aSecurityState;
  PRErrorCode aErrorCode;
  nsTArray<RefPtr<nsIX509Cert>> aFailedCertChain;
  nsCOMPtr<nsIX509Cert> aServerCert;
  nsTArray<RefPtr<nsIX509Cert>> aSucceededCertChain;
  Maybe<uint16_t> aCipherSuite;
  Maybe<nsCString> aKeaGroupName;
  Maybe<nsCString> aSignatureSchemeName;
  Maybe<uint16_t> aProtocolVersion;
  uint16_t aCertificateTransparencyStatus;
  Maybe<bool> aIsAcceptedEch;
  Maybe<bool> aIsDelegatedCredential;
  Maybe<OverridableErrorCategory> aOverridableErrorCategory;
  bool aMadeOCSPRequests;
  bool aUsedPrivateDNS;
  Maybe<bool> aIsEV;
  bool aNPNCompleted;
  nsCString aNegotiatedNPN;
  bool aResumed;
  bool aIsBuiltCertChainRootBuiltInRoot;
  nsCString aPeerId;

  if (!ReadParam(aReader, &aSecurityState) ||
      !ReadParam(aReader, &aErrorCode) ||
      !ReadParam(aReader, &aFailedCertChain) ||
      !ReadParam(aReader, &aServerCert) ||
      !ReadParam(aReader, &aSucceededCertChain) ||
      !ReadParam(aReader, &aCipherSuite) ||
      !ReadParam(aReader, &aKeaGroupName) ||
      !ReadParam(aReader, &aSignatureSchemeName) ||
      !ReadParam(aReader, &aProtocolVersion) ||
      !ReadParam(aReader, &aCertificateTransparencyStatus) ||
      !ReadParam(aReader, &aIsAcceptedEch) ||
      !ReadParam(aReader, &aIsDelegatedCredential) ||
      !ReadParam(aReader, &aOverridableErrorCategory) ||
      !ReadParam(aReader, &aMadeOCSPRequests) ||
      !ReadParam(aReader, &aUsedPrivateDNS) || !ReadParam(aReader, &aIsEV) ||
      !ReadParam(aReader, &aNPNCompleted) ||
      !ReadParam(aReader, &aNegotiatedNPN) || !ReadParam(aReader, &aResumed) ||
      !ReadParam(aReader, &aIsBuiltCertChainRootBuiltInRoot) ||
      !ReadParam(aReader, &aPeerId)) {
    return false;
  }

  RefPtr<nsITransportSecurityInfo> securityInfo(new TransportSecurityInfo(
      aSecurityState, aErrorCode, std::move(aFailedCertChain), aServerCert,
      std::move(aSucceededCertChain), aCipherSuite, aKeaGroupName,
      aSignatureSchemeName, aProtocolVersion, aCertificateTransparencyStatus,
      aIsAcceptedEch, aIsDelegatedCredential, aOverridableErrorCategory,
      aMadeOCSPRequests, aUsedPrivateDNS, aIsEV, aNPNCompleted, aNegotiatedNPN,
      aResumed, aIsBuiltCertChainRootBuiltInRoot, aPeerId));
  *aResult = std::move(securityInfo);
  return true;
}

NS_IMETHODIMP
TransportSecurityInfo::GetFailedCertChain(
    nsTArray<RefPtr<nsIX509Cert>>& aFailedCertChain) {
  MOZ_ASSERT(aFailedCertChain.IsEmpty());
  if (!aFailedCertChain.IsEmpty()) {
    return NS_ERROR_INVALID_ARG;
  }
  aFailedCertChain.AppendElements(mFailedCertChain);
  return NS_OK;
}

NS_IMETHODIMP TransportSecurityInfo::GetServerCert(nsIX509Cert** aServerCert) {
  NS_ENSURE_ARG_POINTER(aServerCert);
  nsCOMPtr<nsIX509Cert> cert = mServerCert;
  cert.forget(aServerCert);
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetSucceededCertChain(
    nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain) {
  MOZ_ASSERT(aSucceededCertChain.IsEmpty());
  if (!aSucceededCertChain.IsEmpty()) {
    return NS_ERROR_INVALID_ARG;
  }
  aSucceededCertChain.AppendElements(mSucceededCertChain);
  return NS_OK;
}

NS_IMETHODIMP TransportSecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
    bool* aIsBuiltInRoot) {
  NS_ENSURE_ARG_POINTER(aIsBuiltInRoot);
  *aIsBuiltInRoot = mIsBuiltCertChainRootBuiltInRoot;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetCipherName(nsACString& aCipherName) {
  if (mCipherSuite.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  SSLCipherSuiteInfo cipherInfo;
  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
      SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  aCipherName.Assign(cipherInfo.cipherSuiteName);
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetKeyLength(uint32_t* aKeyLength) {
  NS_ENSURE_ARG_POINTER(aKeyLength);

  if (mCipherSuite.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  SSLCipherSuiteInfo cipherInfo;
  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
      SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  *aKeyLength = cipherInfo.symKeyBits;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength) {
  NS_ENSURE_ARG_POINTER(aSecretKeyLength);

  if (mCipherSuite.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  SSLCipherSuiteInfo cipherInfo;
  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
      SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  *aSecretKeyLength = cipherInfo.effectiveKeyBits;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetKeaGroupName(nsACString& aKeaGroupName) {
  if (mKeaGroupName.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  aKeaGroupName.Assign(*mKeaGroupName);
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetSignatureSchemeName(nsACString& aSignatureScheme) {
  if (mSignatureSchemeName.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  aSignatureScheme.Assign(*mSignatureSchemeName);
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion) {
  if (mProtocolVersion.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  *aProtocolVersion = *mProtocolVersion;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetCertificateTransparencyStatus(
    uint16_t* aCertificateTransparencyStatus) {
  NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus);

  *aCertificateTransparencyStatus = mCertificateTransparencyStatus;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetMadeOCSPRequests(bool* aMadeOCSPRequests) {
  *aMadeOCSPRequests = mMadeOCSPRequests;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetUsedPrivateDNS(bool* aUsedPrivateDNS) {
  *aUsedPrivateDNS = mUsedPrivateDNS;
  return NS_OK;
}

// static
uint16_t TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
    const mozilla::psm::CertificateTransparencyInfo& info) {
  using mozilla::ct::CTPolicyCompliance;

  if (!info.enabled || info.policyCompliance.isNothing()) {
    // CT disabled.
    return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
  }

  switch (*info.policyCompliance) {
    case CTPolicyCompliance::Compliant:
      return nsITransportSecurityInfo::
          CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT;
    case CTPolicyCompliance::NotEnoughScts:
      return nsITransportSecurityInfo ::
          CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS;
    case CTPolicyCompliance::NotDiverseScts:
      return nsITransportSecurityInfo ::
          CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS;
    default:
      MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
  }

  return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
}

NS_IMETHODIMP
TransportSecurityInfo::GetOverridableErrorCategory(
    OverridableErrorCategory* aOverridableErrorCategory) {
  NS_ENSURE_ARG_POINTER(aOverridableErrorCategory);

  if (mOverridableErrorCategory.isSome()) {
    *aOverridableErrorCategory = *mOverridableErrorCategory;
  } else {
    *aOverridableErrorCategory = OverridableErrorCategory::ERROR_UNSET;
  }
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetIsExtendedValidation(bool* aIsEV) {
  NS_ENSURE_ARG_POINTER(aIsEV);

  *aIsEV = false;
  // Never allow bad certs for EV, regardless of overrides.
  if (mOverridableErrorCategory.isSome()) {
    return NS_OK;
  }

  if (!mIsEV.isSome()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  *aIsEV = *mIsEV;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetIsAcceptedEch(bool* aIsAcceptedEch) {
  NS_ENSURE_ARG_POINTER(aIsAcceptedEch);

  if (mIsAcceptedEch.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  *aIsAcceptedEch = *mIsAcceptedEch;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetIsDelegatedCredential(bool* aIsDelegatedCredential) {
  NS_ENSURE_ARG_POINTER(aIsDelegatedCredential);

  if (mIsDelegatedCredential.isNothing()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  *aIsDelegatedCredential = *mIsDelegatedCredential;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN) {
  if (!mNPNCompleted) {
    return NS_ERROR_NOT_CONNECTED;
  }

  aNegotiatedNPN = mNegotiatedNPN;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetResumed(bool* aResumed) {
  NS_ENSURE_ARG_POINTER(aResumed);
  *aResumed = mResumed;
  return NS_OK;
}

NS_IMETHODIMP
TransportSecurityInfo::GetPeerId(nsACString& aResult) {
  aResult.Assign(mPeerId);
  return NS_OK;
}

}  // namespace psm
}  // namespace mozilla

99%


¤ Dauer der Verarbeitung: 0.15 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.