tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TransportSecurityInfo.cpp (34926B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 *
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "TransportSecurityInfo.h"
      8 
      9 #include "ipc/IPCMessageUtils.h"
     10 #include "ipc/IPCMessageUtilsSpecializations.h"
     11 #include "mozilla/Base64.h"
     12 #include "mozpkix/pkixtypes.h"
     13 #include "nsBase64Encoder.h"
     14 #include "nsIObjectInputStream.h"
     15 #include "nsIObjectOutputStream.h"
     16 #include "nsIWebProgressListener.h"
     17 #include "nsNSSCertHelper.h"
     18 #include "nsNSSComponent.h"
     19 #include "nsNSSHelper.h"
     20 #include "nsReadableUtils.h"
     21 #include "nsServiceManagerUtils.h"
     22 #include "nsStringStream.h"
     23 #include "nsXULAppAPI.h"
     24 #include "nsIX509Cert.h"
     25 #include "secerr.h"
     26 #include "ssl.h"
     27 
     28 // nsITransportSecurityInfo should not be created via do_CreateInstance. This
     29 // stub prevents that.
     30 template <>
     31 already_AddRefed<nsISupports>
     32 mozCreateComponent<mozilla::psm::TransportSecurityInfo>() {
     33  return nullptr;
     34 }
     35 
     36 namespace mozilla {
     37 namespace psm {
     38 
     39 TransportSecurityInfo::TransportSecurityInfo(
     40    uint32_t aSecurityState, PRErrorCode aErrorCode,
     41    nsTArray<RefPtr<nsIX509Cert>>&& aHandshakeCertificates,
     42    nsCOMPtr<nsIX509Cert>& aServerCert,
     43    nsTArray<RefPtr<nsIX509Cert>>&& aSucceededCertChain,
     44    Maybe<uint16_t> aCipherSuite, Maybe<nsCString> aKeaGroupName,
     45    Maybe<nsCString> aSignatureSchemeName, Maybe<uint16_t> aProtocolVersion,
     46    uint16_t aCertificateTransparencyStatus, Maybe<bool> aIsAcceptedEch,
     47    Maybe<bool> aIsDelegatedCredential,
     48    Maybe<OverridableErrorCategory> aOverridableErrorCategory,
     49    bool aMadeOCSPRequests, bool aUsedPrivateDNS, Maybe<bool> aIsEV,
     50    bool aNPNCompleted, const nsCString& aNegotiatedNPN, bool aResumed,
     51    bool aIsBuiltCertChainRootBuiltInRoot, const nsCString& aPeerId)
     52    : mSecurityState(aSecurityState),
     53      mErrorCode(aErrorCode),
     54      mHandshakeCertificates(std::move(aHandshakeCertificates)),
     55      mServerCert(aServerCert),
     56      mSucceededCertChain(std::move(aSucceededCertChain)),
     57      mCipherSuite(aCipherSuite),
     58      mKeaGroupName(aKeaGroupName),
     59      mSignatureSchemeName(aSignatureSchemeName),
     60      mProtocolVersion(aProtocolVersion),
     61      mCertificateTransparencyStatus(aCertificateTransparencyStatus),
     62      mIsAcceptedEch(aIsAcceptedEch),
     63      mIsDelegatedCredential(aIsDelegatedCredential),
     64      mOverridableErrorCategory(aOverridableErrorCategory),
     65      mMadeOCSPRequests(aMadeOCSPRequests),
     66      mUsedPrivateDNS(aUsedPrivateDNS),
     67      mIsEV(aIsEV),
     68      mNPNCompleted(aNPNCompleted),
     69      mNegotiatedNPN(aNegotiatedNPN),
     70      mResumed(aResumed),
     71      mIsBuiltCertChainRootBuiltInRoot(aIsBuiltCertChainRootBuiltInRoot),
     72      mPeerId(aPeerId) {}
     73 
     74 NS_IMPL_ISUPPORTS(TransportSecurityInfo, nsITransportSecurityInfo)
     75 
     76 NS_IMETHODIMP
     77 TransportSecurityInfo::GetSecurityState(uint32_t* state) {
     78  *state = mSecurityState;
     79  return NS_OK;
     80 }
     81 
     82 NS_IMETHODIMP
     83 TransportSecurityInfo::GetErrorCode(int32_t* state) {
     84  *state = mErrorCode;
     85  return NS_OK;
     86 }
     87 
     88 NS_IMETHODIMP
     89 TransportSecurityInfo::GetErrorCodeString(nsAString& aErrorString) {
     90  const char* codeName = PR_ErrorToName(mErrorCode);
     91  aErrorString.Truncate();
     92  if (codeName) {
     93    aErrorString = NS_ConvertASCIItoUTF16(codeName);
     94  }
     95 
     96  return NS_OK;
     97 }
     98 
     99 // 16786594-0296-4471-8096-8f84497ca428
    100 #define TRANSPORTSECURITYINFO_CID \
    101  {0x16786594, 0x0296, 0x4471, {0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28}}
    102 static NS_DEFINE_CID(kTransportSecurityInfoCID, TRANSPORTSECURITYINFO_CID);
    103 
    104 // This is a new magic value. However, it re-uses the first 4 bytes
    105 // of the previous value. This is so when older versions attempt to
    106 // read a newer serialized TransportSecurityInfo, they will actually
    107 // fail and return NS_ERROR_FAILURE instead of silently failing.
    108 #define TRANSPORTSECURITYINFOMAGIC \
    109  {0xa9863a23, 0x1faa, 0x4169, {0xb0, 0xd2, 0x81, 0x29, 0xec, 0x7c, 0xb1, 0xde}}
    110 static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC);
    111 
    112 NS_IMETHODIMP
    113 TransportSecurityInfo::ToString(nsACString& aResult) {
    114  RefPtr<nsBase64Encoder> stream(new nsBase64Encoder());
    115  nsCOMPtr<nsIObjectOutputStream> objStream(NS_NewObjectOutputStream(stream));
    116  nsresult rv = objStream->WriteID(kTransportSecurityInfoCID);
    117  if (NS_FAILED(rv)) {
    118    return rv;
    119  }
    120  rv = objStream->WriteID(NS_ISUPPORTS_IID);
    121  if (NS_FAILED(rv)) {
    122    return rv;
    123  }
    124 
    125  rv = objStream->WriteID(kTransportSecurityInfoMagic);
    126  if (NS_FAILED(rv)) {
    127    return rv;
    128  }
    129 
    130  rv = objStream->Write32(mSecurityState);
    131  if (NS_FAILED(rv)) {
    132    return rv;
    133  }
    134  // mSubRequestsBrokenSecurity was removed in bug 748809
    135  rv = objStream->Write32(0);
    136  if (NS_FAILED(rv)) {
    137    return rv;
    138  }
    139  // mSubRequestsNoSecurity was removed in bug 748809
    140  rv = objStream->Write32(0);
    141  if (NS_FAILED(rv)) {
    142    return rv;
    143  }
    144  rv = objStream->Write32(static_cast<uint32_t>(mErrorCode));
    145  if (NS_FAILED(rv)) {
    146    return rv;
    147  }
    148 
    149  // Re-purpose mErrorMessageCached to represent serialization version
    150  // If string doesn't match exact version it will be treated as older
    151  // serialization.
    152  rv = objStream->WriteWStringZ(NS_ConvertUTF8toUTF16("9").get());
    153  if (NS_FAILED(rv)) {
    154    return rv;
    155  }
    156 
    157  // moved from nsISSLStatus
    158  rv = NS_WriteOptionalCompoundObject(objStream, mServerCert,
    159                                      NS_GET_IID(nsIX509Cert), true);
    160  NS_ENSURE_SUCCESS(rv, rv);
    161 
    162  rv = objStream->Write16(mCipherSuite.isSome() ? *mCipherSuite : 0);
    163  NS_ENSURE_SUCCESS(rv, rv);
    164 
    165  rv = objStream->Write16(mProtocolVersion.isSome() ? *mProtocolVersion : 0);
    166  NS_ENSURE_SUCCESS(rv, rv);
    167 
    168  rv = objStream->Write32(mOverridableErrorCategory.isSome()
    169                              ? *mOverridableErrorCategory
    170                              : OverridableErrorCategory::ERROR_UNSET);
    171  NS_ENSURE_SUCCESS(rv, rv);
    172  rv = objStream->WriteBoolean(mIsEV.isSome() ? *mIsEV : false);
    173  NS_ENSURE_SUCCESS(rv, rv);
    174 
    175  rv = objStream->WriteBoolean(mIsEV.isSome());  // previously mHasIsEV
    176  NS_ENSURE_SUCCESS(rv, rv);
    177  rv = objStream->WriteBoolean(
    178      mCipherSuite.isSome());  // previously mHaveCipherSuiteAndProtocol
    179  NS_ENSURE_SUCCESS(rv, rv);
    180  rv = objStream->WriteBoolean(
    181      mOverridableErrorCategory.isSome());  // previously mHaveCertErrorBits
    182  NS_ENSURE_SUCCESS(rv, rv);
    183 
    184  rv = objStream->Write16(mCertificateTransparencyStatus);
    185  NS_ENSURE_SUCCESS(rv, rv);
    186 
    187  rv = objStream->WriteStringZ(mKeaGroupName.isSome() ? (*mKeaGroupName).get()
    188                                                      : "");
    189  NS_ENSURE_SUCCESS(rv, rv);
    190 
    191  rv = objStream->WriteStringZ(
    192      mSignatureSchemeName.isSome() ? (*mSignatureSchemeName).get() : "");
    193  NS_ENSURE_SUCCESS(rv, rv);
    194 
    195  rv = objStream->Write16(mSucceededCertChain.Length());
    196  NS_ENSURE_SUCCESS(rv, rv);
    197 
    198  for (const auto& cert : mSucceededCertChain) {
    199    rv = objStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true);
    200    NS_ENSURE_SUCCESS(rv, rv);
    201  }
    202  // END moved from nsISSLStatus
    203  rv = objStream->Write16(mHandshakeCertificates.Length());
    204  NS_ENSURE_SUCCESS(rv, rv);
    205  for (const auto& cert : mHandshakeCertificates) {
    206    rv = objStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true);
    207    NS_ENSURE_SUCCESS(rv, rv);
    208  }
    209 
    210  rv = objStream->WriteBoolean(
    211      mIsDelegatedCredential.isSome() ? *mIsDelegatedCredential : false);
    212  if (NS_FAILED(rv)) {
    213    return rv;
    214  }
    215 
    216  rv = objStream->WriteBoolean(mNPNCompleted);
    217  if (NS_FAILED(rv)) {
    218    return rv;
    219  }
    220 
    221  rv = objStream->WriteStringZ(mNegotiatedNPN.get());
    222  if (NS_FAILED(rv)) {
    223    return rv;
    224  }
    225 
    226  rv = objStream->WriteBoolean(mResumed);
    227  if (NS_FAILED(rv)) {
    228    return rv;
    229  }
    230 
    231  rv = objStream->WriteBoolean(mIsBuiltCertChainRootBuiltInRoot);
    232  if (NS_FAILED(rv)) {
    233    return rv;
    234  }
    235 
    236  rv = objStream->WriteBoolean(mIsAcceptedEch.isSome() ? *mIsAcceptedEch
    237                                                       : false);
    238  if (NS_FAILED(rv)) {
    239    return rv;
    240  }
    241 
    242  rv = objStream->WriteStringZ(mPeerId.get());
    243  if (NS_FAILED(rv)) {
    244    return rv;
    245  }
    246 
    247  rv = objStream->WriteBoolean(mMadeOCSPRequests);
    248  if (NS_FAILED(rv)) {
    249    return rv;
    250  }
    251 
    252  rv = objStream->WriteBoolean(mUsedPrivateDNS);
    253  if (NS_FAILED(rv)) {
    254    return rv;
    255  }
    256 
    257  rv = stream->Finish(aResult);
    258  if (NS_FAILED(rv)) {
    259    return rv;
    260  }
    261 
    262  return NS_OK;
    263 }
    264 
    265 nsresult TransportSecurityInfo::ReadOldOverridableErrorBits(
    266    nsIObjectInputStream* aStream,
    267    OverridableErrorCategory& aOverridableErrorCategory) {
    268  bool isDomainMismatch;
    269  nsresult rv = aStream->ReadBoolean(&isDomainMismatch);
    270  NS_ENSURE_SUCCESS(rv, rv);
    271  bool isNotValidAtThisTime;
    272  rv = aStream->ReadBoolean(&isNotValidAtThisTime);
    273  NS_ENSURE_SUCCESS(rv, rv);
    274  bool isUntrusted;
    275  rv = aStream->ReadBoolean(&isUntrusted);
    276  NS_ENSURE_SUCCESS(rv, rv);
    277  if (isUntrusted) {
    278    aOverridableErrorCategory =
    279        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST;
    280  } else if (isDomainMismatch) {
    281    aOverridableErrorCategory =
    282        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN;
    283  } else if (isNotValidAtThisTime) {
    284    aOverridableErrorCategory =
    285        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME;
    286  } else {
    287    aOverridableErrorCategory =
    288        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
    289  }
    290 
    291  return NS_OK;
    292 }
    293 
    294 // This is for backward compatibility to be able to read nsISSLStatus
    295 // serialized object.
    296 nsresult TransportSecurityInfo::ReadSSLStatus(
    297    nsIObjectInputStream* aStream, nsCOMPtr<nsIX509Cert>& aServerCert,
    298    Maybe<uint16_t>& aCipherSuite, Maybe<uint16_t>& aProtocolVersion,
    299    Maybe<OverridableErrorCategory>& aOverridableErrorCategory,
    300    Maybe<bool>& aIsEV, uint16_t& aCertificateTransparencyStatus,
    301    Maybe<nsCString>& aKeaGroupName, Maybe<nsCString>& aSignatureSchemeName,
    302    nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain) {
    303  bool nsISSLStatusPresent;
    304  nsresult rv = aStream->ReadBoolean(&nsISSLStatusPresent);
    305  NS_ENSURE_SUCCESS(rv, rv);
    306  if (!nsISSLStatusPresent) {
    307    return NS_OK;
    308  }
    309  // nsISSLStatus present.  Prepare to read elements.
    310  // Throw away cid, validate iid
    311  nsCID cid;
    312  nsIID iid;
    313  rv = aStream->ReadID(&cid);
    314  NS_ENSURE_SUCCESS(rv, rv);
    315  rv = aStream->ReadID(&iid);
    316  NS_ENSURE_SUCCESS(rv, rv);
    317 
    318  static const nsIID nsSSLStatusIID = {
    319      0xfa9ba95b,
    320      0xca3b,
    321      0x498a,
    322      {0xb8, 0x89, 0x7c, 0x79, 0xcf, 0x28, 0xfe, 0xe8}};
    323  if (!iid.Equals(nsSSLStatusIID)) {
    324    return NS_ERROR_UNEXPECTED;
    325  }
    326 
    327  nsCOMPtr<nsISupports> cert;
    328  rv = aStream->ReadObject(true, getter_AddRefs(cert));
    329  NS_ENSURE_SUCCESS(rv, rv);
    330 
    331  if (cert) {
    332    aServerCert = do_QueryInterface(cert);
    333    if (!aServerCert) {
    334      return NS_NOINTERFACE;
    335    }
    336  }
    337 
    338  uint16_t cipherSuite;
    339  rv = aStream->Read16(&cipherSuite);
    340  NS_ENSURE_SUCCESS(rv, rv);
    341 
    342  // The code below is a workaround to allow serializing new fields
    343  // while preserving binary compatibility with older streams. For more details
    344  // on the binary compatibility requirement, refer to bug 1248628.
    345  // Here, we take advantage of the fact that mProtocolVersion was originally
    346  // stored as a 16 bits integer, but the highest 8 bits were never used.
    347  // These bits are now used for stream versioning.
    348  uint16_t protocolVersionAndStreamFormatVersion;
    349  rv = aStream->Read16(&protocolVersionAndStreamFormatVersion);
    350  NS_ENSURE_SUCCESS(rv, rv);
    351  const uint8_t streamFormatVersion =
    352      (protocolVersionAndStreamFormatVersion >> 8) & 0xFF;
    353 
    354  OverridableErrorCategory overridableErrorCategory;
    355  rv = ReadOldOverridableErrorBits(aStream, overridableErrorCategory);
    356  NS_ENSURE_SUCCESS(rv, rv);
    357  bool isEV;
    358  rv = aStream->ReadBoolean(&isEV);
    359  NS_ENSURE_SUCCESS(rv, rv);
    360  bool hasIsEVStatus;
    361  rv = aStream->ReadBoolean(&hasIsEVStatus);
    362  NS_ENSURE_SUCCESS(rv, rv);
    363  if (hasIsEVStatus) {
    364    aIsEV.emplace(isEV);
    365  }
    366  bool haveCipherSuiteAndProtocol;
    367  rv = aStream->ReadBoolean(&haveCipherSuiteAndProtocol);
    368  if (haveCipherSuiteAndProtocol) {
    369    aCipherSuite.emplace(cipherSuite);
    370    aProtocolVersion.emplace(protocolVersionAndStreamFormatVersion & 0xFF);
    371  }
    372  NS_ENSURE_SUCCESS(rv, rv);
    373  bool haveCertErrorBits;
    374  rv = aStream->ReadBoolean(&haveCertErrorBits);
    375  NS_ENSURE_SUCCESS(rv, rv);
    376  if (haveCertErrorBits) {
    377    aOverridableErrorCategory.emplace(overridableErrorCategory);
    378  }
    379 
    380  // Added in version 1 (see bug 1305289).
    381  if (streamFormatVersion >= 1) {
    382    rv = aStream->Read16(&aCertificateTransparencyStatus);
    383    NS_ENSURE_SUCCESS(rv, rv);
    384  }
    385 
    386  // Added in version 2 (see bug 1304923).
    387  if (streamFormatVersion >= 2) {
    388    nsCString keaGroupName;
    389    rv = aStream->ReadCString(keaGroupName);
    390    NS_ENSURE_SUCCESS(rv, rv);
    391    if (haveCipherSuiteAndProtocol) {
    392      aKeaGroupName.emplace(keaGroupName);
    393    }
    394 
    395    nsCString signatureSchemeName;
    396    rv = aStream->ReadCString(signatureSchemeName);
    397    NS_ENSURE_SUCCESS(rv, rv);
    398    if (haveCipherSuiteAndProtocol) {
    399      aSignatureSchemeName.emplace(signatureSchemeName);
    400    }
    401  }
    402 
    403  // Added in version 3 (see bug 1406856).
    404  if (streamFormatVersion >= 3) {
    405    rv = ReadCertList(aStream, aSucceededCertChain);
    406    if (NS_FAILED(rv)) {
    407      return rv;
    408    }
    409 
    410    // Read only to consume bytes from the stream.
    411    nsTArray<RefPtr<nsIX509Cert>> handshakeCertificates;
    412    rv = ReadCertList(aStream, handshakeCertificates);
    413    if (NS_FAILED(rv)) {
    414      return rv;
    415    }
    416  }
    417  return rv;
    418 }
    419 
    420 // This is for backward compatability to be able to read nsIX509CertList
    421 // serialized object.
    422 nsresult TransportSecurityInfo::ReadCertList(
    423    nsIObjectInputStream* aStream, nsTArray<RefPtr<nsIX509Cert>>& aCertList) {
    424  bool nsIX509CertListPresent;
    425 
    426  nsresult rv = aStream->ReadBoolean(&nsIX509CertListPresent);
    427  NS_ENSURE_SUCCESS(rv, rv);
    428  if (!nsIX509CertListPresent) {
    429    return NS_OK;
    430  }
    431  // nsIX509CertList present.  Prepare to read elements.
    432  // Throw away cid, validate iid
    433  nsCID cid;
    434  nsIID iid;
    435  rv = aStream->ReadID(&cid);
    436  NS_ENSURE_SUCCESS(rv, rv);
    437  rv = aStream->ReadID(&iid);
    438  NS_ENSURE_SUCCESS(rv, rv);
    439 
    440  static const nsIID nsIX509CertListIID = {
    441      0xae74cda5,
    442      0xcd2f,
    443      0x473f,
    444      {0x96, 0xf5, 0xf0, 0xb7, 0xff, 0xf6, 0x2c, 0x68}};
    445 
    446  if (!iid.Equals(nsIX509CertListIID)) {
    447    return NS_ERROR_UNEXPECTED;
    448  }
    449 
    450  uint32_t certListSize;
    451  rv = aStream->Read32(&certListSize);
    452  NS_ENSURE_SUCCESS(rv, rv);
    453 
    454  return ReadCertificatesFromStream(aStream, certListSize, aCertList);
    455 }
    456 
    457 nsresult TransportSecurityInfo::ReadCertificatesFromStream(
    458    nsIObjectInputStream* aStream, uint32_t aSize,
    459    nsTArray<RefPtr<nsIX509Cert>>& aCertList) {
    460  nsresult rv;
    461  for (uint32_t i = 0; i < aSize; ++i) {
    462    nsCOMPtr<nsISupports> support;
    463    rv = aStream->ReadObject(true, getter_AddRefs(support));
    464    NS_ENSURE_SUCCESS(rv, rv);
    465    nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(support);
    466    if (!cert) {
    467      return NS_ERROR_UNEXPECTED;
    468    }
    469    RefPtr<nsIX509Cert> castedCert(cert.get());
    470    aCertList.AppendElement(castedCert);
    471  }
    472  return NS_OK;
    473 }
    474 
    475 static nsITransportSecurityInfo::OverridableErrorCategory
    476 IntToOverridableErrorCategory(uint32_t intVal) {
    477  switch (intVal) {
    478    case static_cast<uint32_t>(
    479        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST):
    480      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST;
    481    case static_cast<uint32_t>(
    482        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN):
    483      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN;
    484    case static_cast<uint32_t>(
    485        nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME):
    486      return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME;
    487    default:
    488      break;
    489  }
    490  return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
    491 }
    492 
    493 nsresult TransportSecurityInfo::Read(const nsCString& aSerializedSecurityInfo,
    494                                     nsITransportSecurityInfo** aResult) {
    495  *aResult = nullptr;
    496 
    497  nsCString decodedSecurityInfo;
    498  nsresult rv = Base64Decode(aSerializedSecurityInfo, decodedSecurityInfo);
    499  if (NS_FAILED(rv)) {
    500    return rv;
    501  }
    502  nsCOMPtr<nsIInputStream> inputStream;
    503  rv = NS_NewCStringInputStream(getter_AddRefs(inputStream),
    504                                std::move(decodedSecurityInfo));
    505  if (NS_FAILED(rv)) {
    506    return rv;
    507  }
    508  nsCOMPtr<nsIObjectInputStream> objStream(
    509      NS_NewObjectInputStream(inputStream));
    510  if (!objStream) {
    511    return rv;
    512  }
    513 
    514  nsCID cid;
    515  rv = objStream->ReadID(&cid);
    516  if (NS_FAILED(rv)) {
    517    return rv;
    518  }
    519  if (!cid.Equals(kTransportSecurityInfoCID)) {
    520    return NS_ERROR_UNEXPECTED;
    521  }
    522  nsIID iid;
    523  rv = objStream->ReadID(&iid);
    524  if (NS_FAILED(rv)) {
    525    return rv;
    526  }
    527  if (!iid.Equals(NS_ISUPPORTS_IID)) {
    528    return rv;
    529  }
    530 
    531  nsID id;
    532  rv = objStream->ReadID(&id);
    533  if (NS_FAILED(rv)) {
    534    return rv;
    535  }
    536  if (!id.Equals(kTransportSecurityInfoMagic)) {
    537    return NS_ERROR_UNEXPECTED;
    538  }
    539 
    540  uint32_t aSecurityState = 0;
    541  PRErrorCode aErrorCode = 0;
    542  nsTArray<RefPtr<nsIX509Cert>> aHandshakeCertificates;
    543  nsCOMPtr<nsIX509Cert> aServerCert;
    544  nsTArray<RefPtr<nsIX509Cert>> aSucceededCertChain;
    545  Maybe<uint16_t> aCipherSuite;
    546  Maybe<nsCString> aKeaGroupName;
    547  Maybe<nsCString> aSignatureSchemeName;
    548  Maybe<uint16_t> aProtocolVersion;
    549  uint16_t aCertificateTransparencyStatus;
    550  Maybe<bool> aIsAcceptedEch;
    551  Maybe<bool> aIsDelegatedCredential;
    552  Maybe<OverridableErrorCategory> aOverridableErrorCategory;
    553  bool aMadeOCSPRequests = false;
    554  bool aUsedPrivateDNS = false;
    555  Maybe<bool> aIsEV;
    556  bool aNPNCompleted = false;
    557  nsCString aNegotiatedNPN;
    558  bool aResumed = false;
    559  bool aIsBuiltCertChainRootBuiltInRoot = false;
    560  nsCString aPeerId;
    561  rv = objStream->Read32(&aSecurityState);
    562  if (NS_FAILED(rv)) {
    563    return rv;
    564  }
    565  // mSubRequestsBrokenSecurity was removed in bug 748809
    566  uint32_t unusedSubRequestsBrokenSecurity;
    567  rv = objStream->Read32(&unusedSubRequestsBrokenSecurity);
    568  if (NS_FAILED(rv)) {
    569    return rv;
    570  }
    571  // mSubRequestsNoSecurity was removed in bug 748809
    572  uint32_t unusedSubRequestsNoSecurity;
    573  rv = objStream->Read32(&unusedSubRequestsNoSecurity);
    574  if (NS_FAILED(rv)) {
    575    return rv;
    576  }
    577  uint32_t errorCode;
    578  rv = objStream->Read32(&errorCode);
    579  if (NS_FAILED(rv)) {
    580    return rv;
    581  }
    582  // PRErrorCode will be a negative value
    583  aErrorCode = static_cast<PRErrorCode>(errorCode);
    584 
    585  // Re-purpose mErrorMessageCached to represent serialization version
    586  // If string doesn't match exact version it will be treated as older
    587  // serialization.
    588  nsAutoString serVersion;
    589  rv = objStream->ReadString(serVersion);
    590  if (NS_FAILED(rv)) {
    591    return rv;
    592  }
    593 
    594  int32_t serVersionParsedToInt = 0;
    595 
    596  if (!serVersion.IsEmpty()) {
    597    char first = serVersion.First();
    598    // Check whether the first character of serVersion is a number
    599    // since ToInteger() skipps some non integer values.
    600    if (first >= '0' && first <= '9') {
    601      nsresult error = NS_OK;
    602      serVersionParsedToInt = serVersion.ToInteger(&error);
    603      if (NS_FAILED(error)) {
    604        return error;
    605      }
    606    }
    607  }
    608 
    609  // moved from nsISSLStatus
    610  if (serVersionParsedToInt < 1) {
    611    // nsISSLStatus may be present
    612    rv = ReadSSLStatus(objStream, aServerCert, aCipherSuite, aProtocolVersion,
    613                       aOverridableErrorCategory, aIsEV,
    614                       aCertificateTransparencyStatus, aKeaGroupName,
    615                       aSignatureSchemeName, aSucceededCertChain);
    616    NS_ENSURE_SUCCESS(rv, rv);
    617  } else {
    618    nsCOMPtr<nsISupports> cert;
    619    rv = NS_ReadOptionalObject(objStream, true, getter_AddRefs(cert));
    620    NS_ENSURE_SUCCESS(rv, rv);
    621 
    622    if (cert) {
    623      aServerCert = do_QueryInterface(cert);
    624      if (!aServerCert) {
    625        return NS_NOINTERFACE;
    626      }
    627    }
    628 
    629    uint16_t cipherSuite;
    630    rv = objStream->Read16(&cipherSuite);
    631    NS_ENSURE_SUCCESS(rv, rv);
    632 
    633    uint16_t protocolVersion;
    634    rv = objStream->Read16(&protocolVersion);
    635    NS_ENSURE_SUCCESS(rv, rv);
    636 
    637    OverridableErrorCategory overridableErrorCategory;
    638    if (serVersionParsedToInt < 8) {
    639      rv = ReadOldOverridableErrorBits(objStream, overridableErrorCategory);
    640      NS_ENSURE_SUCCESS(rv, rv);
    641    } else {
    642      uint32_t overridableErrorCategoryInt;
    643      rv = objStream->Read32(&overridableErrorCategoryInt);
    644      NS_ENSURE_SUCCESS(rv, rv);
    645      overridableErrorCategory =
    646          IntToOverridableErrorCategory(overridableErrorCategoryInt);
    647    }
    648    bool isEV;
    649    rv = objStream->ReadBoolean(&isEV);
    650    NS_ENSURE_SUCCESS(rv, rv);
    651    bool hasIsEVStatus;
    652    rv = objStream->ReadBoolean(&hasIsEVStatus);
    653    NS_ENSURE_SUCCESS(rv, rv);
    654    if (hasIsEVStatus) {
    655      aIsEV.emplace(isEV);
    656    }
    657    bool haveCipherSuiteAndProtocol;
    658    rv = objStream->ReadBoolean(&haveCipherSuiteAndProtocol);
    659    NS_ENSURE_SUCCESS(rv, rv);
    660    if (haveCipherSuiteAndProtocol) {
    661      aCipherSuite.emplace(cipherSuite);
    662      aProtocolVersion.emplace(protocolVersion);
    663    }
    664    bool haveCertErrorBits;
    665    rv = objStream->ReadBoolean(&haveCertErrorBits);
    666    NS_ENSURE_SUCCESS(rv, rv);
    667    if (haveCertErrorBits) {
    668      aOverridableErrorCategory.emplace(overridableErrorCategory);
    669    }
    670 
    671    rv = objStream->Read16(&aCertificateTransparencyStatus);
    672    NS_ENSURE_SUCCESS(rv, rv);
    673 
    674    nsCString keaGroupName;
    675    rv = objStream->ReadCString(keaGroupName);
    676    NS_ENSURE_SUCCESS(rv, rv);
    677    if (haveCipherSuiteAndProtocol) {
    678      aKeaGroupName.emplace(keaGroupName);
    679    }
    680 
    681    nsCString signatureSchemeName;
    682    rv = objStream->ReadCString(signatureSchemeName);
    683    NS_ENSURE_SUCCESS(rv, rv);
    684    if (haveCipherSuiteAndProtocol) {
    685      aSignatureSchemeName.emplace(signatureSchemeName);
    686    }
    687 
    688    if (serVersionParsedToInt < 3) {
    689      // The old data structure of certList(nsIX509CertList) presents
    690      rv = ReadCertList(objStream, aSucceededCertChain);
    691      NS_ENSURE_SUCCESS(rv, rv);
    692    } else {
    693      uint16_t certCount;
    694      rv = objStream->Read16(&certCount);
    695      NS_ENSURE_SUCCESS(rv, rv);
    696 
    697      rv =
    698          ReadCertificatesFromStream(objStream, certCount, aSucceededCertChain);
    699      NS_ENSURE_SUCCESS(rv, rv);
    700    }
    701  }
    702  // END moved from nsISSLStatus
    703  if (serVersionParsedToInt < 3) {
    704    // The old data structure of certList(nsIX509CertList) presents
    705    rv = ReadCertList(objStream, aHandshakeCertificates);
    706    NS_ENSURE_SUCCESS(rv, rv);
    707  } else {
    708    uint16_t certCount;
    709    rv = objStream->Read16(&certCount);
    710    NS_ENSURE_SUCCESS(rv, rv);
    711 
    712    rv = ReadCertificatesFromStream(objStream, certCount,
    713                                    aHandshakeCertificates);
    714    NS_ENSURE_SUCCESS(rv, rv);
    715  }
    716 
    717  // mIsDelegatedCredential added in bug 1562773
    718  if (serVersionParsedToInt >= 2) {
    719    bool isDelegatedCredential;
    720    rv = objStream->ReadBoolean(&isDelegatedCredential);
    721    if (NS_FAILED(rv)) {
    722      return rv;
    723    }
    724    // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
    725    // cipher suite and protocol information, which means it has this
    726    // information.
    727    if (aCipherSuite.isSome()) {
    728      aIsDelegatedCredential.emplace(isDelegatedCredential);
    729    }
    730  }
    731 
    732  // mNPNCompleted, mNegotiatedNPN, mResumed added in bug 1584104
    733  if (serVersionParsedToInt >= 4) {
    734    rv = objStream->ReadBoolean(&aNPNCompleted);
    735    if (NS_FAILED(rv)) {
    736      return rv;
    737    }
    738 
    739    rv = objStream->ReadCString(aNegotiatedNPN);
    740    if (NS_FAILED(rv)) {
    741      return rv;
    742    }
    743 
    744    rv = objStream->ReadBoolean(&aResumed);
    745    if (NS_FAILED(rv)) {
    746      return rv;
    747    }
    748  }
    749 
    750  // mIsBuiltCertChainRootBuiltInRoot added in bug 1485652
    751  if (serVersionParsedToInt >= 5) {
    752    rv = objStream->ReadBoolean(&aIsBuiltCertChainRootBuiltInRoot);
    753    if (NS_FAILED(rv)) {
    754      return rv;
    755    }
    756  }
    757 
    758  // mIsAcceptedEch added in bug 1678079
    759  if (serVersionParsedToInt >= 6) {
    760    bool isAcceptedEch;
    761    rv = objStream->ReadBoolean(&isAcceptedEch);
    762    if (NS_FAILED(rv)) {
    763      return rv;
    764    }
    765    // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
    766    // cipher suite and protocol information, which means it has this
    767    // information.
    768    if (aCipherSuite.isSome()) {
    769      aIsAcceptedEch.emplace(isAcceptedEch);
    770    }
    771  }
    772 
    773  // mPeerId added in bug 1738664
    774  if (serVersionParsedToInt >= 7) {
    775    rv = objStream->ReadCString(aPeerId);
    776    if (NS_FAILED(rv)) {
    777      return rv;
    778    }
    779  }
    780 
    781  if (serVersionParsedToInt >= 9) {
    782    rv = objStream->ReadBoolean(&aMadeOCSPRequests);
    783    if (NS_FAILED(rv)) {
    784      return rv;
    785    }
    786 
    787    rv = objStream->ReadBoolean(&aUsedPrivateDNS);
    788    if (NS_FAILED(rv)) {
    789      return rv;
    790    };
    791  }
    792 
    793  RefPtr<nsITransportSecurityInfo> securityInfo(new TransportSecurityInfo(
    794      aSecurityState, aErrorCode, std::move(aHandshakeCertificates),
    795      aServerCert, std::move(aSucceededCertChain), aCipherSuite, aKeaGroupName,
    796      aSignatureSchemeName, aProtocolVersion, aCertificateTransparencyStatus,
    797      aIsAcceptedEch, aIsDelegatedCredential, aOverridableErrorCategory,
    798      aMadeOCSPRequests, aUsedPrivateDNS, aIsEV, aNPNCompleted, aNegotiatedNPN,
    799      aResumed, aIsBuiltCertChainRootBuiltInRoot, aPeerId));
    800  securityInfo.forget(aResult);
    801  return NS_OK;
    802 }
    803 
    804 void TransportSecurityInfo::SerializeToIPC(IPC::MessageWriter* aWriter) {
    805  WriteParam(aWriter, mSecurityState);
    806  WriteParam(aWriter, mErrorCode);
    807  WriteParam(aWriter, mHandshakeCertificates);
    808  WriteParam(aWriter, mServerCert);
    809  WriteParam(aWriter, mSucceededCertChain);
    810  WriteParam(aWriter, mCipherSuite);
    811  WriteParam(aWriter, mKeaGroupName);
    812  WriteParam(aWriter, mSignatureSchemeName);
    813  WriteParam(aWriter, mProtocolVersion);
    814  WriteParam(aWriter, mCertificateTransparencyStatus);
    815  WriteParam(aWriter, mIsAcceptedEch);
    816  WriteParam(aWriter, mIsDelegatedCredential);
    817  WriteParam(aWriter, mOverridableErrorCategory);
    818  WriteParam(aWriter, mMadeOCSPRequests);
    819  WriteParam(aWriter, mUsedPrivateDNS);
    820  WriteParam(aWriter, mIsEV);
    821  WriteParam(aWriter, mNPNCompleted);
    822  WriteParam(aWriter, mNegotiatedNPN);
    823  WriteParam(aWriter, mResumed);
    824  WriteParam(aWriter, mIsBuiltCertChainRootBuiltInRoot);
    825  WriteParam(aWriter, mPeerId);
    826 }
    827 
    828 bool TransportSecurityInfo::DeserializeFromIPC(
    829    IPC::MessageReader* aReader, RefPtr<nsITransportSecurityInfo>* aResult) {
    830  uint32_t aSecurityState;
    831  PRErrorCode aErrorCode;
    832  nsTArray<RefPtr<nsIX509Cert>> aHandshakeCertificates;
    833  nsCOMPtr<nsIX509Cert> aServerCert;
    834  nsTArray<RefPtr<nsIX509Cert>> aSucceededCertChain;
    835  Maybe<uint16_t> aCipherSuite;
    836  Maybe<nsCString> aKeaGroupName;
    837  Maybe<nsCString> aSignatureSchemeName;
    838  Maybe<uint16_t> aProtocolVersion;
    839  uint16_t aCertificateTransparencyStatus;
    840  Maybe<bool> aIsAcceptedEch;
    841  Maybe<bool> aIsDelegatedCredential;
    842  Maybe<OverridableErrorCategory> aOverridableErrorCategory;
    843  bool aMadeOCSPRequests;
    844  bool aUsedPrivateDNS;
    845  Maybe<bool> aIsEV;
    846  bool aNPNCompleted;
    847  nsCString aNegotiatedNPN;
    848  bool aResumed;
    849  bool aIsBuiltCertChainRootBuiltInRoot;
    850  nsCString aPeerId;
    851 
    852  if (!ReadParam(aReader, &aSecurityState) ||
    853      !ReadParam(aReader, &aErrorCode) ||
    854      !ReadParam(aReader, &aHandshakeCertificates) ||
    855      !ReadParam(aReader, &aServerCert) ||
    856      !ReadParam(aReader, &aSucceededCertChain) ||
    857      !ReadParam(aReader, &aCipherSuite) ||
    858      !ReadParam(aReader, &aKeaGroupName) ||
    859      !ReadParam(aReader, &aSignatureSchemeName) ||
    860      !ReadParam(aReader, &aProtocolVersion) ||
    861      !ReadParam(aReader, &aCertificateTransparencyStatus) ||
    862      !ReadParam(aReader, &aIsAcceptedEch) ||
    863      !ReadParam(aReader, &aIsDelegatedCredential) ||
    864      !ReadParam(aReader, &aOverridableErrorCategory) ||
    865      !ReadParam(aReader, &aMadeOCSPRequests) ||
    866      !ReadParam(aReader, &aUsedPrivateDNS) || !ReadParam(aReader, &aIsEV) ||
    867      !ReadParam(aReader, &aNPNCompleted) ||
    868      !ReadParam(aReader, &aNegotiatedNPN) || !ReadParam(aReader, &aResumed) ||
    869      !ReadParam(aReader, &aIsBuiltCertChainRootBuiltInRoot) ||
    870      !ReadParam(aReader, &aPeerId)) {
    871    return false;
    872  }
    873 
    874  RefPtr<nsITransportSecurityInfo> securityInfo(new TransportSecurityInfo(
    875      aSecurityState, aErrorCode, std::move(aHandshakeCertificates),
    876      aServerCert, std::move(aSucceededCertChain), aCipherSuite, aKeaGroupName,
    877      aSignatureSchemeName, aProtocolVersion, aCertificateTransparencyStatus,
    878      aIsAcceptedEch, aIsDelegatedCredential, aOverridableErrorCategory,
    879      aMadeOCSPRequests, aUsedPrivateDNS, aIsEV, aNPNCompleted, aNegotiatedNPN,
    880      aResumed, aIsBuiltCertChainRootBuiltInRoot, aPeerId));
    881  *aResult = std::move(securityInfo);
    882  return true;
    883 }
    884 
    885 NS_IMETHODIMP
    886 TransportSecurityInfo::GetHandshakeCertificates(
    887    nsTArray<RefPtr<nsIX509Cert>>& aHandshakeCertificates) {
    888  MOZ_ASSERT(aHandshakeCertificates.IsEmpty());
    889  if (!aHandshakeCertificates.IsEmpty()) {
    890    return NS_ERROR_INVALID_ARG;
    891  }
    892  aHandshakeCertificates.AppendElements(mHandshakeCertificates);
    893  return NS_OK;
    894 }
    895 
    896 NS_IMETHODIMP TransportSecurityInfo::GetServerCert(nsIX509Cert** aServerCert) {
    897  NS_ENSURE_ARG_POINTER(aServerCert);
    898  nsCOMPtr<nsIX509Cert> cert = mServerCert;
    899  cert.forget(aServerCert);
    900  return NS_OK;
    901 }
    902 
    903 NS_IMETHODIMP
    904 TransportSecurityInfo::GetSucceededCertChain(
    905    nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain) {
    906  MOZ_ASSERT(aSucceededCertChain.IsEmpty());
    907  if (!aSucceededCertChain.IsEmpty()) {
    908    return NS_ERROR_INVALID_ARG;
    909  }
    910  aSucceededCertChain.AppendElements(mSucceededCertChain);
    911  return NS_OK;
    912 }
    913 
    914 NS_IMETHODIMP TransportSecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
    915    bool* aIsBuiltInRoot) {
    916  NS_ENSURE_ARG_POINTER(aIsBuiltInRoot);
    917  *aIsBuiltInRoot = mIsBuiltCertChainRootBuiltInRoot;
    918  return NS_OK;
    919 }
    920 
    921 NS_IMETHODIMP
    922 TransportSecurityInfo::GetCipherName(nsACString& aCipherName) {
    923  if (mCipherSuite.isNothing()) {
    924    return NS_ERROR_NOT_AVAILABLE;
    925  }
    926  SSLCipherSuiteInfo cipherInfo;
    927  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
    928      SECSuccess) {
    929    return NS_ERROR_FAILURE;
    930  }
    931 
    932  aCipherName.Assign(cipherInfo.cipherSuiteName);
    933  return NS_OK;
    934 }
    935 
    936 NS_IMETHODIMP
    937 TransportSecurityInfo::GetKeyLength(uint32_t* aKeyLength) {
    938  NS_ENSURE_ARG_POINTER(aKeyLength);
    939 
    940  if (mCipherSuite.isNothing()) {
    941    return NS_ERROR_NOT_AVAILABLE;
    942  }
    943  SSLCipherSuiteInfo cipherInfo;
    944  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
    945      SECSuccess) {
    946    return NS_ERROR_FAILURE;
    947  }
    948 
    949  *aKeyLength = cipherInfo.symKeyBits;
    950  return NS_OK;
    951 }
    952 
    953 NS_IMETHODIMP
    954 TransportSecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength) {
    955  NS_ENSURE_ARG_POINTER(aSecretKeyLength);
    956 
    957  if (mCipherSuite.isNothing()) {
    958    return NS_ERROR_NOT_AVAILABLE;
    959  }
    960  SSLCipherSuiteInfo cipherInfo;
    961  if (SSL_GetCipherSuiteInfo(*mCipherSuite, &cipherInfo, sizeof(cipherInfo)) !=
    962      SECSuccess) {
    963    return NS_ERROR_FAILURE;
    964  }
    965 
    966  *aSecretKeyLength = cipherInfo.effectiveKeyBits;
    967  return NS_OK;
    968 }
    969 
    970 NS_IMETHODIMP
    971 TransportSecurityInfo::GetKeaGroupName(nsACString& aKeaGroupName) {
    972  if (mKeaGroupName.isNothing()) {
    973    return NS_ERROR_NOT_AVAILABLE;
    974  }
    975  aKeaGroupName.Assign(*mKeaGroupName);
    976  return NS_OK;
    977 }
    978 
    979 NS_IMETHODIMP
    980 TransportSecurityInfo::GetSignatureSchemeName(nsACString& aSignatureScheme) {
    981  if (mSignatureSchemeName.isNothing()) {
    982    return NS_ERROR_NOT_AVAILABLE;
    983  }
    984  aSignatureScheme.Assign(*mSignatureSchemeName);
    985  return NS_OK;
    986 }
    987 
    988 NS_IMETHODIMP
    989 TransportSecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion) {
    990  if (mProtocolVersion.isNothing()) {
    991    return NS_ERROR_NOT_AVAILABLE;
    992  }
    993  *aProtocolVersion = *mProtocolVersion;
    994  return NS_OK;
    995 }
    996 
    997 NS_IMETHODIMP
    998 TransportSecurityInfo::GetCertificateTransparencyStatus(
    999    uint16_t* aCertificateTransparencyStatus) {
   1000  NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus);
   1001 
   1002  *aCertificateTransparencyStatus = mCertificateTransparencyStatus;
   1003  return NS_OK;
   1004 }
   1005 
   1006 NS_IMETHODIMP
   1007 TransportSecurityInfo::GetMadeOCSPRequests(bool* aMadeOCSPRequests) {
   1008  *aMadeOCSPRequests = mMadeOCSPRequests;
   1009  return NS_OK;
   1010 }
   1011 
   1012 NS_IMETHODIMP
   1013 TransportSecurityInfo::GetUsedPrivateDNS(bool* aUsedPrivateDNS) {
   1014  *aUsedPrivateDNS = mUsedPrivateDNS;
   1015  return NS_OK;
   1016 }
   1017 
   1018 // static
   1019 uint16_t TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
   1020    const mozilla::psm::CertificateTransparencyInfo& info) {
   1021  using mozilla::ct::CTPolicyCompliance;
   1022 
   1023  if (!info.enabled || info.policyCompliance.isNothing()) {
   1024    // CT disabled.
   1025    return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
   1026  }
   1027 
   1028  switch (*info.policyCompliance) {
   1029    case CTPolicyCompliance::Compliant:
   1030      return nsITransportSecurityInfo::
   1031          CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT;
   1032    case CTPolicyCompliance::NotEnoughScts:
   1033      return nsITransportSecurityInfo ::
   1034          CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS;
   1035    case CTPolicyCompliance::NotDiverseScts:
   1036      return nsITransportSecurityInfo ::
   1037          CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS;
   1038    default:
   1039      MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
   1040  }
   1041 
   1042  return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE;
   1043 }
   1044 
   1045 NS_IMETHODIMP
   1046 TransportSecurityInfo::GetOverridableErrorCategory(
   1047    OverridableErrorCategory* aOverridableErrorCategory) {
   1048  NS_ENSURE_ARG_POINTER(aOverridableErrorCategory);
   1049 
   1050  if (mOverridableErrorCategory.isSome()) {
   1051    *aOverridableErrorCategory = *mOverridableErrorCategory;
   1052  } else {
   1053    *aOverridableErrorCategory = OverridableErrorCategory::ERROR_UNSET;
   1054  }
   1055  return NS_OK;
   1056 }
   1057 
   1058 NS_IMETHODIMP
   1059 TransportSecurityInfo::GetIsExtendedValidation(bool* aIsEV) {
   1060  NS_ENSURE_ARG_POINTER(aIsEV);
   1061 
   1062  *aIsEV = false;
   1063  // Never allow bad certs for EV, regardless of overrides.
   1064  if (mOverridableErrorCategory.isSome()) {
   1065    return NS_OK;
   1066  }
   1067 
   1068  if (!mIsEV.isSome()) {
   1069    return NS_ERROR_NOT_AVAILABLE;
   1070  }
   1071 
   1072  *aIsEV = *mIsEV;
   1073  return NS_OK;
   1074 }
   1075 
   1076 NS_IMETHODIMP
   1077 TransportSecurityInfo::GetIsAcceptedEch(bool* aIsAcceptedEch) {
   1078  NS_ENSURE_ARG_POINTER(aIsAcceptedEch);
   1079 
   1080  if (mIsAcceptedEch.isNothing()) {
   1081    return NS_ERROR_NOT_AVAILABLE;
   1082  }
   1083  *aIsAcceptedEch = *mIsAcceptedEch;
   1084  return NS_OK;
   1085 }
   1086 
   1087 NS_IMETHODIMP
   1088 TransportSecurityInfo::GetIsDelegatedCredential(bool* aIsDelegatedCredential) {
   1089  NS_ENSURE_ARG_POINTER(aIsDelegatedCredential);
   1090 
   1091  if (mIsDelegatedCredential.isNothing()) {
   1092    return NS_ERROR_NOT_AVAILABLE;
   1093  }
   1094  *aIsDelegatedCredential = *mIsDelegatedCredential;
   1095  return NS_OK;
   1096 }
   1097 
   1098 NS_IMETHODIMP
   1099 TransportSecurityInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN) {
   1100  if (!mNPNCompleted) {
   1101    return NS_ERROR_NOT_CONNECTED;
   1102  }
   1103 
   1104  aNegotiatedNPN = mNegotiatedNPN;
   1105  return NS_OK;
   1106 }
   1107 
   1108 NS_IMETHODIMP
   1109 TransportSecurityInfo::GetResumed(bool* aResumed) {
   1110  NS_ENSURE_ARG_POINTER(aResumed);
   1111  *aResumed = mResumed;
   1112  return NS_OK;
   1113 }
   1114 
   1115 NS_IMETHODIMP
   1116 TransportSecurityInfo::GetPeerId(nsACString& aResult) {
   1117  aResult.Assign(mPeerId);
   1118  return NS_OK;
   1119 }
   1120 
   1121 }  // namespace psm
   1122 }  // namespace mozilla