1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
7 #include "TransportSecurityInfo.h"
9 #include "ipc/IPCMessageUtils.h"
10 #include "mozilla/Base64.h"
11 #include "mozpkix/pkixtypes.h"
12 #include "nsBase64Encoder.h"
13 #include "nsIObjectInputStream.h"
14 #include "nsIObjectOutputStream.h"
15 #include "nsIWebProgressListener.h"
16 #include "nsNSSCertHelper.h"
17 #include "nsNSSComponent.h"
18 #include "nsNSSHelper.h"
19 #include "nsReadableUtils.h"
20 #include "nsServiceManagerUtils.h"
21 #include "nsStringStream.h"
22 #include "nsXULAppAPI.h"
23 #include "nsIX509Cert.h"
27 #include "mozilla/ipc/IPDLParamTraits.h"
29 // nsITransportSecurityInfo should not be created via do_CreateInstance. This
30 // stub prevents that.
32 already_AddRefed
<nsISupports
>
33 mozCreateComponent
<mozilla::psm::TransportSecurityInfo
>() {
40 TransportSecurityInfo::TransportSecurityInfo(
41 uint32_t aSecurityState
, PRErrorCode aErrorCode
,
42 nsTArray
<RefPtr
<nsIX509Cert
>>&& aFailedCertChain
,
43 nsCOMPtr
<nsIX509Cert
>& aServerCert
,
44 nsTArray
<RefPtr
<nsIX509Cert
>>&& aSucceededCertChain
,
45 Maybe
<uint16_t> aCipherSuite
, Maybe
<nsCString
> aKeaGroupName
,
46 Maybe
<nsCString
> aSignatureSchemeName
, Maybe
<uint16_t> aProtocolVersion
,
47 uint16_t aCertificateTransparencyStatus
, Maybe
<bool> aIsAcceptedEch
,
48 Maybe
<bool> aIsDelegatedCredential
,
49 Maybe
<OverridableErrorCategory
> aOverridableErrorCategory
,
50 bool aMadeOCSPRequests
, bool aUsedPrivateDNS
, Maybe
<bool> aIsEV
,
51 bool aNPNCompleted
, const nsCString
& aNegotiatedNPN
, bool aResumed
,
52 bool aIsBuiltCertChainRootBuiltInRoot
, const nsCString
& aPeerId
)
53 : mSecurityState(aSecurityState
),
54 mErrorCode(aErrorCode
),
55 mFailedCertChain(std::move(aFailedCertChain
)),
56 mServerCert(aServerCert
),
57 mSucceededCertChain(std::move(aSucceededCertChain
)),
58 mCipherSuite(aCipherSuite
),
59 mKeaGroupName(aKeaGroupName
),
60 mSignatureSchemeName(aSignatureSchemeName
),
61 mProtocolVersion(aProtocolVersion
),
62 mCertificateTransparencyStatus(aCertificateTransparencyStatus
),
63 mIsAcceptedEch(aIsAcceptedEch
),
64 mIsDelegatedCredential(aIsDelegatedCredential
),
65 mOverridableErrorCategory(aOverridableErrorCategory
),
66 mMadeOCSPRequests(aMadeOCSPRequests
),
67 mUsedPrivateDNS(aUsedPrivateDNS
),
69 mNPNCompleted(aNPNCompleted
),
70 mNegotiatedNPN(aNegotiatedNPN
),
72 mIsBuiltCertChainRootBuiltInRoot(aIsBuiltCertChainRootBuiltInRoot
),
75 NS_IMPL_ISUPPORTS(TransportSecurityInfo
, nsITransportSecurityInfo
)
78 TransportSecurityInfo::GetSecurityState(uint32_t* state
) {
79 *state
= mSecurityState
;
84 TransportSecurityInfo::GetErrorCode(int32_t* state
) {
90 TransportSecurityInfo::GetErrorCodeString(nsAString
& aErrorString
) {
91 const char* codeName
= PR_ErrorToName(mErrorCode
);
92 aErrorString
.Truncate();
94 aErrorString
= NS_ConvertASCIItoUTF16(codeName
);
100 // 16786594-0296-4471-8096-8f84497ca428
101 #define TRANSPORTSECURITYINFO_CID \
103 0x16786594, 0x0296, 0x4471, { \
104 0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28 \
107 static NS_DEFINE_CID(kTransportSecurityInfoCID
, TRANSPORTSECURITYINFO_CID
);
109 // This is a new magic value. However, it re-uses the first 4 bytes
110 // of the previous value. This is so when older versions attempt to
111 // read a newer serialized TransportSecurityInfo, they will actually
112 // fail and return NS_ERROR_FAILURE instead of silently failing.
113 #define TRANSPORTSECURITYINFOMAGIC \
115 0xa9863a23, 0x1faa, 0x4169, { \
116 0xb0, 0xd2, 0x81, 0x29, 0xec, 0x7c, 0xb1, 0xde \
119 static NS_DEFINE_CID(kTransportSecurityInfoMagic
, TRANSPORTSECURITYINFOMAGIC
);
122 TransportSecurityInfo::ToString(nsACString
& aResult
) {
123 RefPtr
<nsBase64Encoder
> stream(new nsBase64Encoder());
124 nsCOMPtr
<nsIObjectOutputStream
> objStream(NS_NewObjectOutputStream(stream
));
125 nsresult rv
= objStream
->WriteID(kTransportSecurityInfoCID
);
129 rv
= objStream
->WriteID(NS_ISUPPORTS_IID
);
134 rv
= objStream
->WriteID(kTransportSecurityInfoMagic
);
139 rv
= objStream
->Write32(mSecurityState
);
143 // mSubRequestsBrokenSecurity was removed in bug 748809
144 rv
= objStream
->Write32(0);
148 // mSubRequestsNoSecurity was removed in bug 748809
149 rv
= objStream
->Write32(0);
153 rv
= objStream
->Write32(static_cast<uint32_t>(mErrorCode
));
158 // Re-purpose mErrorMessageCached to represent serialization version
159 // If string doesn't match exact version it will be treated as older
161 rv
= objStream
->WriteWStringZ(NS_ConvertUTF8toUTF16("9").get());
166 // moved from nsISSLStatus
167 rv
= NS_WriteOptionalCompoundObject(objStream
, mServerCert
,
168 NS_GET_IID(nsIX509Cert
), true);
169 NS_ENSURE_SUCCESS(rv
, rv
);
171 rv
= objStream
->Write16(mCipherSuite
.isSome() ? *mCipherSuite
: 0);
172 NS_ENSURE_SUCCESS(rv
, rv
);
174 rv
= objStream
->Write16(mProtocolVersion
.isSome() ? *mProtocolVersion
: 0);
175 NS_ENSURE_SUCCESS(rv
, rv
);
177 rv
= objStream
->Write32(mOverridableErrorCategory
.isSome()
178 ? *mOverridableErrorCategory
179 : OverridableErrorCategory::ERROR_UNSET
);
180 NS_ENSURE_SUCCESS(rv
, rv
);
181 rv
= objStream
->WriteBoolean(mIsEV
.isSome() ? *mIsEV
: false);
182 NS_ENSURE_SUCCESS(rv
, rv
);
184 rv
= objStream
->WriteBoolean(mIsEV
.isSome()); // previously mHasIsEV
185 NS_ENSURE_SUCCESS(rv
, rv
);
186 rv
= objStream
->WriteBoolean(
187 mCipherSuite
.isSome()); // previously mHaveCipherSuiteAndProtocol
188 NS_ENSURE_SUCCESS(rv
, rv
);
189 rv
= objStream
->WriteBoolean(
190 mOverridableErrorCategory
.isSome()); // previously mHaveCertErrorBits
191 NS_ENSURE_SUCCESS(rv
, rv
);
193 rv
= objStream
->Write16(mCertificateTransparencyStatus
);
194 NS_ENSURE_SUCCESS(rv
, rv
);
196 rv
= objStream
->WriteStringZ(mKeaGroupName
.isSome() ? (*mKeaGroupName
).get()
198 NS_ENSURE_SUCCESS(rv
, rv
);
200 rv
= objStream
->WriteStringZ(
201 mSignatureSchemeName
.isSome() ? (*mSignatureSchemeName
).get() : "");
202 NS_ENSURE_SUCCESS(rv
, rv
);
204 rv
= objStream
->Write16(mSucceededCertChain
.Length());
205 NS_ENSURE_SUCCESS(rv
, rv
);
207 for (const auto& cert
: mSucceededCertChain
) {
208 rv
= objStream
->WriteCompoundObject(cert
, NS_GET_IID(nsIX509Cert
), true);
209 NS_ENSURE_SUCCESS(rv
, rv
);
211 // END moved from nsISSLStatus
212 rv
= objStream
->Write16(mFailedCertChain
.Length());
213 NS_ENSURE_SUCCESS(rv
, rv
);
214 for (const auto& cert
: mFailedCertChain
) {
215 rv
= objStream
->WriteCompoundObject(cert
, NS_GET_IID(nsIX509Cert
), true);
216 NS_ENSURE_SUCCESS(rv
, rv
);
219 rv
= objStream
->WriteBoolean(
220 mIsDelegatedCredential
.isSome() ? *mIsDelegatedCredential
: false);
225 rv
= objStream
->WriteBoolean(mNPNCompleted
);
230 rv
= objStream
->WriteStringZ(mNegotiatedNPN
.get());
235 rv
= objStream
->WriteBoolean(mResumed
);
240 rv
= objStream
->WriteBoolean(mIsBuiltCertChainRootBuiltInRoot
);
245 rv
= objStream
->WriteBoolean(mIsAcceptedEch
.isSome() ? *mIsAcceptedEch
251 rv
= objStream
->WriteStringZ(mPeerId
.get());
256 rv
= objStream
->WriteBoolean(mMadeOCSPRequests
);
261 rv
= objStream
->WriteBoolean(mUsedPrivateDNS
);
266 rv
= stream
->Finish(aResult
);
274 nsresult
TransportSecurityInfo::ReadOldOverridableErrorBits(
275 nsIObjectInputStream
* aStream
,
276 OverridableErrorCategory
& aOverridableErrorCategory
) {
277 bool isDomainMismatch
;
278 nsresult rv
= aStream
->ReadBoolean(&isDomainMismatch
);
279 NS_ENSURE_SUCCESS(rv
, rv
);
280 bool isNotValidAtThisTime
;
281 rv
= aStream
->ReadBoolean(&isNotValidAtThisTime
);
282 NS_ENSURE_SUCCESS(rv
, rv
);
284 rv
= aStream
->ReadBoolean(&isUntrusted
);
285 NS_ENSURE_SUCCESS(rv
, rv
);
287 aOverridableErrorCategory
=
288 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST
;
289 } else if (isDomainMismatch
) {
290 aOverridableErrorCategory
=
291 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN
;
292 } else if (isNotValidAtThisTime
) {
293 aOverridableErrorCategory
=
294 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME
;
296 aOverridableErrorCategory
=
297 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET
;
303 // This is for backward compatibility to be able to read nsISSLStatus
304 // serialized object.
305 nsresult
TransportSecurityInfo::ReadSSLStatus(
306 nsIObjectInputStream
* aStream
, nsCOMPtr
<nsIX509Cert
>& aServerCert
,
307 Maybe
<uint16_t>& aCipherSuite
, Maybe
<uint16_t>& aProtocolVersion
,
308 Maybe
<OverridableErrorCategory
>& aOverridableErrorCategory
,
309 Maybe
<bool>& aIsEV
, uint16_t& aCertificateTransparencyStatus
,
310 Maybe
<nsCString
>& aKeaGroupName
, Maybe
<nsCString
>& aSignatureSchemeName
,
311 nsTArray
<RefPtr
<nsIX509Cert
>>& aSucceededCertChain
) {
312 bool nsISSLStatusPresent
;
313 nsresult rv
= aStream
->ReadBoolean(&nsISSLStatusPresent
);
314 NS_ENSURE_SUCCESS(rv
, rv
);
315 if (!nsISSLStatusPresent
) {
318 // nsISSLStatus present. Prepare to read elements.
319 // Throw away cid, validate iid
322 rv
= aStream
->ReadID(&cid
);
323 NS_ENSURE_SUCCESS(rv
, rv
);
324 rv
= aStream
->ReadID(&iid
);
325 NS_ENSURE_SUCCESS(rv
, rv
);
327 static const nsIID nsSSLStatusIID
= {
331 {0xb8, 0x89, 0x7c, 0x79, 0xcf, 0x28, 0xfe, 0xe8}};
332 if (!iid
.Equals(nsSSLStatusIID
)) {
333 return NS_ERROR_UNEXPECTED
;
336 nsCOMPtr
<nsISupports
> cert
;
337 rv
= aStream
->ReadObject(true, getter_AddRefs(cert
));
338 NS_ENSURE_SUCCESS(rv
, rv
);
341 aServerCert
= do_QueryInterface(cert
);
343 return NS_NOINTERFACE
;
347 uint16_t cipherSuite
;
348 rv
= aStream
->Read16(&cipherSuite
);
349 NS_ENSURE_SUCCESS(rv
, rv
);
351 // The code below is a workaround to allow serializing new fields
352 // while preserving binary compatibility with older streams. For more details
353 // on the binary compatibility requirement, refer to bug 1248628.
354 // Here, we take advantage of the fact that mProtocolVersion was originally
355 // stored as a 16 bits integer, but the highest 8 bits were never used.
356 // These bits are now used for stream versioning.
357 uint16_t protocolVersionAndStreamFormatVersion
;
358 rv
= aStream
->Read16(&protocolVersionAndStreamFormatVersion
);
359 NS_ENSURE_SUCCESS(rv
, rv
);
360 const uint8_t streamFormatVersion
=
361 (protocolVersionAndStreamFormatVersion
>> 8) & 0xFF;
363 OverridableErrorCategory overridableErrorCategory
;
364 rv
= ReadOldOverridableErrorBits(aStream
, overridableErrorCategory
);
365 NS_ENSURE_SUCCESS(rv
, rv
);
367 rv
= aStream
->ReadBoolean(&isEV
);
368 NS_ENSURE_SUCCESS(rv
, rv
);
370 rv
= aStream
->ReadBoolean(&hasIsEVStatus
);
371 NS_ENSURE_SUCCESS(rv
, rv
);
375 bool haveCipherSuiteAndProtocol
;
376 rv
= aStream
->ReadBoolean(&haveCipherSuiteAndProtocol
);
377 if (haveCipherSuiteAndProtocol
) {
378 aCipherSuite
.emplace(cipherSuite
);
379 aProtocolVersion
.emplace(protocolVersionAndStreamFormatVersion
& 0xFF);
381 NS_ENSURE_SUCCESS(rv
, rv
);
382 bool haveCertErrorBits
;
383 rv
= aStream
->ReadBoolean(&haveCertErrorBits
);
384 NS_ENSURE_SUCCESS(rv
, rv
);
385 if (haveCertErrorBits
) {
386 aOverridableErrorCategory
.emplace(overridableErrorCategory
);
389 // Added in version 1 (see bug 1305289).
390 if (streamFormatVersion
>= 1) {
391 rv
= aStream
->Read16(&aCertificateTransparencyStatus
);
392 NS_ENSURE_SUCCESS(rv
, rv
);
395 // Added in version 2 (see bug 1304923).
396 if (streamFormatVersion
>= 2) {
397 nsCString keaGroupName
;
398 rv
= aStream
->ReadCString(keaGroupName
);
399 NS_ENSURE_SUCCESS(rv
, rv
);
400 if (haveCipherSuiteAndProtocol
) {
401 aKeaGroupName
.emplace(keaGroupName
);
404 nsCString signatureSchemeName
;
405 rv
= aStream
->ReadCString(signatureSchemeName
);
406 NS_ENSURE_SUCCESS(rv
, rv
);
407 if (haveCipherSuiteAndProtocol
) {
408 aSignatureSchemeName
.emplace(signatureSchemeName
);
412 // Added in version 3 (see bug 1406856).
413 if (streamFormatVersion
>= 3) {
414 rv
= ReadCertList(aStream
, aSucceededCertChain
);
419 // Read only to consume bytes from the stream.
420 nsTArray
<RefPtr
<nsIX509Cert
>> failedCertChain
;
421 rv
= ReadCertList(aStream
, failedCertChain
);
429 // This is for backward compatability to be able to read nsIX509CertList
430 // serialized object.
431 nsresult
TransportSecurityInfo::ReadCertList(
432 nsIObjectInputStream
* aStream
, nsTArray
<RefPtr
<nsIX509Cert
>>& aCertList
) {
433 bool nsIX509CertListPresent
;
435 nsresult rv
= aStream
->ReadBoolean(&nsIX509CertListPresent
);
436 NS_ENSURE_SUCCESS(rv
, rv
);
437 if (!nsIX509CertListPresent
) {
440 // nsIX509CertList present. Prepare to read elements.
441 // Throw away cid, validate iid
444 rv
= aStream
->ReadID(&cid
);
445 NS_ENSURE_SUCCESS(rv
, rv
);
446 rv
= aStream
->ReadID(&iid
);
447 NS_ENSURE_SUCCESS(rv
, rv
);
449 static const nsIID nsIX509CertListIID
= {
453 {0x96, 0xf5, 0xf0, 0xb7, 0xff, 0xf6, 0x2c, 0x68}};
455 if (!iid
.Equals(nsIX509CertListIID
)) {
456 return NS_ERROR_UNEXPECTED
;
459 uint32_t certListSize
;
460 rv
= aStream
->Read32(&certListSize
);
461 NS_ENSURE_SUCCESS(rv
, rv
);
463 return ReadCertificatesFromStream(aStream
, certListSize
, aCertList
);
466 nsresult
TransportSecurityInfo::ReadCertificatesFromStream(
467 nsIObjectInputStream
* aStream
, uint32_t aSize
,
468 nsTArray
<RefPtr
<nsIX509Cert
>>& aCertList
) {
470 for (uint32_t i
= 0; i
< aSize
; ++i
) {
471 nsCOMPtr
<nsISupports
> support
;
472 rv
= aStream
->ReadObject(true, getter_AddRefs(support
));
473 NS_ENSURE_SUCCESS(rv
, rv
);
474 nsCOMPtr
<nsIX509Cert
> cert
= do_QueryInterface(support
);
476 return NS_ERROR_UNEXPECTED
;
478 RefPtr
<nsIX509Cert
> castedCert(cert
.get());
479 aCertList
.AppendElement(castedCert
);
484 static nsITransportSecurityInfo::OverridableErrorCategory
485 IntToOverridableErrorCategory(uint32_t intVal
) {
487 case static_cast<uint32_t>(
488 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST
):
489 return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TRUST
;
490 case static_cast<uint32_t>(
491 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN
):
492 return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_DOMAIN
;
493 case static_cast<uint32_t>(
494 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME
):
495 return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME
;
499 return nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET
;
502 nsresult
TransportSecurityInfo::Read(const nsCString
& aSerializedSecurityInfo
,
503 nsITransportSecurityInfo
** aResult
) {
506 nsCString decodedSecurityInfo
;
507 nsresult rv
= Base64Decode(aSerializedSecurityInfo
, decodedSecurityInfo
);
511 nsCOMPtr
<nsIInputStream
> inputStream
;
512 rv
= NS_NewCStringInputStream(getter_AddRefs(inputStream
),
513 std::move(decodedSecurityInfo
));
517 nsCOMPtr
<nsIObjectInputStream
> objStream(
518 NS_NewObjectInputStream(inputStream
));
524 rv
= objStream
->ReadID(&cid
);
528 if (!cid
.Equals(kTransportSecurityInfoCID
)) {
529 return NS_ERROR_UNEXPECTED
;
532 rv
= objStream
->ReadID(&iid
);
536 if (!iid
.Equals(NS_ISUPPORTS_IID
)) {
541 rv
= objStream
->ReadID(&id
);
545 if (!id
.Equals(kTransportSecurityInfoMagic
)) {
546 return NS_ERROR_UNEXPECTED
;
549 uint32_t aSecurityState
= 0;
550 PRErrorCode aErrorCode
= 0;
551 nsTArray
<RefPtr
<nsIX509Cert
>> aFailedCertChain
;
552 nsCOMPtr
<nsIX509Cert
> aServerCert
;
553 nsTArray
<RefPtr
<nsIX509Cert
>> aSucceededCertChain
;
554 Maybe
<uint16_t> aCipherSuite
;
555 Maybe
<nsCString
> aKeaGroupName
;
556 Maybe
<nsCString
> aSignatureSchemeName
;
557 Maybe
<uint16_t> aProtocolVersion
;
558 uint16_t aCertificateTransparencyStatus
;
559 Maybe
<bool> aIsAcceptedEch
;
560 Maybe
<bool> aIsDelegatedCredential
;
561 Maybe
<OverridableErrorCategory
> aOverridableErrorCategory
;
562 bool aMadeOCSPRequests
= false;
563 bool aUsedPrivateDNS
= false;
565 bool aNPNCompleted
= false;
566 nsCString aNegotiatedNPN
;
567 bool aResumed
= false;
568 bool aIsBuiltCertChainRootBuiltInRoot
= false;
570 rv
= objStream
->Read32(&aSecurityState
);
574 // mSubRequestsBrokenSecurity was removed in bug 748809
575 uint32_t unusedSubRequestsBrokenSecurity
;
576 rv
= objStream
->Read32(&unusedSubRequestsBrokenSecurity
);
580 // mSubRequestsNoSecurity was removed in bug 748809
581 uint32_t unusedSubRequestsNoSecurity
;
582 rv
= objStream
->Read32(&unusedSubRequestsNoSecurity
);
587 rv
= objStream
->Read32(&errorCode
);
591 // PRErrorCode will be a negative value
592 aErrorCode
= static_cast<PRErrorCode
>(errorCode
);
594 // Re-purpose mErrorMessageCached to represent serialization version
595 // If string doesn't match exact version it will be treated as older
597 nsAutoString serVersion
;
598 rv
= objStream
->ReadString(serVersion
);
603 int32_t serVersionParsedToInt
= 0;
605 if (!serVersion
.IsEmpty()) {
606 char first
= serVersion
.First();
607 // Check whether the first character of serVersion is a number
608 // since ToInteger() skipps some non integer values.
609 if (first
>= '0' && first
<= '9') {
610 nsresult error
= NS_OK
;
611 serVersionParsedToInt
= serVersion
.ToInteger(&error
);
612 if (NS_FAILED(error
)) {
618 // moved from nsISSLStatus
619 if (serVersionParsedToInt
< 1) {
620 // nsISSLStatus may be present
621 rv
= ReadSSLStatus(objStream
, aServerCert
, aCipherSuite
, aProtocolVersion
,
622 aOverridableErrorCategory
, aIsEV
,
623 aCertificateTransparencyStatus
, aKeaGroupName
,
624 aSignatureSchemeName
, aSucceededCertChain
);
625 NS_ENSURE_SUCCESS(rv
, rv
);
627 nsCOMPtr
<nsISupports
> cert
;
628 rv
= NS_ReadOptionalObject(objStream
, true, getter_AddRefs(cert
));
629 NS_ENSURE_SUCCESS(rv
, rv
);
632 aServerCert
= do_QueryInterface(cert
);
634 return NS_NOINTERFACE
;
638 uint16_t cipherSuite
;
639 rv
= objStream
->Read16(&cipherSuite
);
640 NS_ENSURE_SUCCESS(rv
, rv
);
642 uint16_t protocolVersion
;
643 rv
= objStream
->Read16(&protocolVersion
);
644 NS_ENSURE_SUCCESS(rv
, rv
);
646 OverridableErrorCategory overridableErrorCategory
;
647 if (serVersionParsedToInt
< 8) {
648 rv
= ReadOldOverridableErrorBits(objStream
, overridableErrorCategory
);
649 NS_ENSURE_SUCCESS(rv
, rv
);
651 uint32_t overridableErrorCategoryInt
;
652 rv
= objStream
->Read32(&overridableErrorCategoryInt
);
653 NS_ENSURE_SUCCESS(rv
, rv
);
654 overridableErrorCategory
=
655 IntToOverridableErrorCategory(overridableErrorCategoryInt
);
658 rv
= objStream
->ReadBoolean(&isEV
);
659 NS_ENSURE_SUCCESS(rv
, rv
);
661 rv
= objStream
->ReadBoolean(&hasIsEVStatus
);
662 NS_ENSURE_SUCCESS(rv
, rv
);
666 bool haveCipherSuiteAndProtocol
;
667 rv
= objStream
->ReadBoolean(&haveCipherSuiteAndProtocol
);
668 NS_ENSURE_SUCCESS(rv
, rv
);
669 if (haveCipherSuiteAndProtocol
) {
670 aCipherSuite
.emplace(cipherSuite
);
671 aProtocolVersion
.emplace(protocolVersion
);
673 bool haveCertErrorBits
;
674 rv
= objStream
->ReadBoolean(&haveCertErrorBits
);
675 NS_ENSURE_SUCCESS(rv
, rv
);
676 if (haveCertErrorBits
) {
677 aOverridableErrorCategory
.emplace(overridableErrorCategory
);
680 rv
= objStream
->Read16(&aCertificateTransparencyStatus
);
681 NS_ENSURE_SUCCESS(rv
, rv
);
683 nsCString keaGroupName
;
684 rv
= objStream
->ReadCString(keaGroupName
);
685 NS_ENSURE_SUCCESS(rv
, rv
);
686 if (haveCipherSuiteAndProtocol
) {
687 aKeaGroupName
.emplace(keaGroupName
);
690 nsCString signatureSchemeName
;
691 rv
= objStream
->ReadCString(signatureSchemeName
);
692 NS_ENSURE_SUCCESS(rv
, rv
);
693 if (haveCipherSuiteAndProtocol
) {
694 aSignatureSchemeName
.emplace(signatureSchemeName
);
697 if (serVersionParsedToInt
< 3) {
698 // The old data structure of certList(nsIX509CertList) presents
699 rv
= ReadCertList(objStream
, aSucceededCertChain
);
700 NS_ENSURE_SUCCESS(rv
, rv
);
703 rv
= objStream
->Read16(&certCount
);
704 NS_ENSURE_SUCCESS(rv
, rv
);
707 ReadCertificatesFromStream(objStream
, certCount
, aSucceededCertChain
);
708 NS_ENSURE_SUCCESS(rv
, rv
);
711 // END moved from nsISSLStatus
712 if (serVersionParsedToInt
< 3) {
713 // The old data structure of certList(nsIX509CertList) presents
714 rv
= ReadCertList(objStream
, aFailedCertChain
);
715 NS_ENSURE_SUCCESS(rv
, rv
);
718 rv
= objStream
->Read16(&certCount
);
719 NS_ENSURE_SUCCESS(rv
, rv
);
721 rv
= ReadCertificatesFromStream(objStream
, certCount
, aFailedCertChain
);
722 NS_ENSURE_SUCCESS(rv
, rv
);
725 // mIsDelegatedCredential added in bug 1562773
726 if (serVersionParsedToInt
>= 2) {
727 bool isDelegatedCredential
;
728 rv
= objStream
->ReadBoolean(&isDelegatedCredential
);
732 // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
733 // cipher suite and protocol information, which means it has this
735 if (aCipherSuite
.isSome()) {
736 aIsDelegatedCredential
.emplace(isDelegatedCredential
);
740 // mNPNCompleted, mNegotiatedNPN, mResumed added in bug 1584104
741 if (serVersionParsedToInt
>= 4) {
742 rv
= objStream
->ReadBoolean(&aNPNCompleted
);
747 rv
= objStream
->ReadCString(aNegotiatedNPN
);
752 rv
= objStream
->ReadBoolean(&aResumed
);
758 // mIsBuiltCertChainRootBuiltInRoot added in bug 1485652
759 if (serVersionParsedToInt
>= 5) {
760 rv
= objStream
->ReadBoolean(&aIsBuiltCertChainRootBuiltInRoot
);
766 // mIsAcceptedEch added in bug 1678079
767 if (serVersionParsedToInt
>= 6) {
769 rv
= objStream
->ReadBoolean(&isAcceptedEch
);
773 // If aCipherSuite is Some, the serialized TransportSecurityinfo had its
774 // cipher suite and protocol information, which means it has this
776 if (aCipherSuite
.isSome()) {
777 aIsAcceptedEch
.emplace(isAcceptedEch
);
781 // mPeerId added in bug 1738664
782 if (serVersionParsedToInt
>= 7) {
783 rv
= objStream
->ReadCString(aPeerId
);
789 if (serVersionParsedToInt
>= 9) {
790 rv
= objStream
->ReadBoolean(&aMadeOCSPRequests
);
795 rv
= objStream
->ReadBoolean(&aUsedPrivateDNS
);
801 RefPtr
<nsITransportSecurityInfo
> securityInfo(new TransportSecurityInfo(
802 aSecurityState
, aErrorCode
, std::move(aFailedCertChain
), aServerCert
,
803 std::move(aSucceededCertChain
), aCipherSuite
, aKeaGroupName
,
804 aSignatureSchemeName
, aProtocolVersion
, aCertificateTransparencyStatus
,
805 aIsAcceptedEch
, aIsDelegatedCredential
, aOverridableErrorCategory
,
806 aMadeOCSPRequests
, aUsedPrivateDNS
, aIsEV
, aNPNCompleted
, aNegotiatedNPN
,
807 aResumed
, aIsBuiltCertChainRootBuiltInRoot
, aPeerId
));
808 securityInfo
.forget(aResult
);
812 void TransportSecurityInfo::SerializeToIPC(IPC::MessageWriter
* aWriter
) {
813 WriteParam(aWriter
, mSecurityState
);
814 WriteParam(aWriter
, mErrorCode
);
815 WriteParam(aWriter
, mFailedCertChain
);
816 WriteParam(aWriter
, mServerCert
);
817 WriteParam(aWriter
, mSucceededCertChain
);
818 WriteParam(aWriter
, mCipherSuite
);
819 WriteParam(aWriter
, mKeaGroupName
);
820 WriteParam(aWriter
, mSignatureSchemeName
);
821 WriteParam(aWriter
, mProtocolVersion
);
822 WriteParam(aWriter
, mCertificateTransparencyStatus
);
823 WriteParam(aWriter
, mIsAcceptedEch
);
824 WriteParam(aWriter
, mIsDelegatedCredential
);
825 WriteParam(aWriter
, mOverridableErrorCategory
);
826 WriteParam(aWriter
, mMadeOCSPRequests
);
827 WriteParam(aWriter
, mUsedPrivateDNS
);
828 WriteParam(aWriter
, mIsEV
);
829 WriteParam(aWriter
, mNPNCompleted
);
830 WriteParam(aWriter
, mNegotiatedNPN
);
831 WriteParam(aWriter
, mResumed
);
832 WriteParam(aWriter
, mIsBuiltCertChainRootBuiltInRoot
);
833 WriteParam(aWriter
, mPeerId
);
836 bool TransportSecurityInfo::DeserializeFromIPC(
837 IPC::MessageReader
* aReader
, RefPtr
<nsITransportSecurityInfo
>* aResult
) {
838 uint32_t aSecurityState
;
839 PRErrorCode aErrorCode
;
840 nsTArray
<RefPtr
<nsIX509Cert
>> aFailedCertChain
;
841 nsCOMPtr
<nsIX509Cert
> aServerCert
;
842 nsTArray
<RefPtr
<nsIX509Cert
>> aSucceededCertChain
;
843 Maybe
<uint16_t> aCipherSuite
;
844 Maybe
<nsCString
> aKeaGroupName
;
845 Maybe
<nsCString
> aSignatureSchemeName
;
846 Maybe
<uint16_t> aProtocolVersion
;
847 uint16_t aCertificateTransparencyStatus
;
848 Maybe
<bool> aIsAcceptedEch
;
849 Maybe
<bool> aIsDelegatedCredential
;
850 Maybe
<OverridableErrorCategory
> aOverridableErrorCategory
;
851 bool aMadeOCSPRequests
;
852 bool aUsedPrivateDNS
;
855 nsCString aNegotiatedNPN
;
857 bool aIsBuiltCertChainRootBuiltInRoot
;
860 if (!ReadParam(aReader
, &aSecurityState
) ||
861 !ReadParam(aReader
, &aErrorCode
) ||
862 !ReadParam(aReader
, &aFailedCertChain
) ||
863 !ReadParam(aReader
, &aServerCert
) ||
864 !ReadParam(aReader
, &aSucceededCertChain
) ||
865 !ReadParam(aReader
, &aCipherSuite
) ||
866 !ReadParam(aReader
, &aKeaGroupName
) ||
867 !ReadParam(aReader
, &aSignatureSchemeName
) ||
868 !ReadParam(aReader
, &aProtocolVersion
) ||
869 !ReadParam(aReader
, &aCertificateTransparencyStatus
) ||
870 !ReadParam(aReader
, &aIsAcceptedEch
) ||
871 !ReadParam(aReader
, &aIsDelegatedCredential
) ||
872 !ReadParam(aReader
, &aOverridableErrorCategory
) ||
873 !ReadParam(aReader
, &aMadeOCSPRequests
) ||
874 !ReadParam(aReader
, &aUsedPrivateDNS
) || !ReadParam(aReader
, &aIsEV
) ||
875 !ReadParam(aReader
, &aNPNCompleted
) ||
876 !ReadParam(aReader
, &aNegotiatedNPN
) || !ReadParam(aReader
, &aResumed
) ||
877 !ReadParam(aReader
, &aIsBuiltCertChainRootBuiltInRoot
) ||
878 !ReadParam(aReader
, &aPeerId
)) {
882 RefPtr
<nsITransportSecurityInfo
> securityInfo(new TransportSecurityInfo(
883 aSecurityState
, aErrorCode
, std::move(aFailedCertChain
), aServerCert
,
884 std::move(aSucceededCertChain
), aCipherSuite
, aKeaGroupName
,
885 aSignatureSchemeName
, aProtocolVersion
, aCertificateTransparencyStatus
,
886 aIsAcceptedEch
, aIsDelegatedCredential
, aOverridableErrorCategory
,
887 aMadeOCSPRequests
, aUsedPrivateDNS
, aIsEV
, aNPNCompleted
, aNegotiatedNPN
,
888 aResumed
, aIsBuiltCertChainRootBuiltInRoot
, aPeerId
));
889 *aResult
= std::move(securityInfo
);
894 TransportSecurityInfo::GetFailedCertChain(
895 nsTArray
<RefPtr
<nsIX509Cert
>>& aFailedCertChain
) {
896 MOZ_ASSERT(aFailedCertChain
.IsEmpty());
897 if (!aFailedCertChain
.IsEmpty()) {
898 return NS_ERROR_INVALID_ARG
;
900 aFailedCertChain
.AppendElements(mFailedCertChain
);
904 NS_IMETHODIMP
TransportSecurityInfo::GetServerCert(nsIX509Cert
** aServerCert
) {
905 NS_ENSURE_ARG_POINTER(aServerCert
);
906 nsCOMPtr
<nsIX509Cert
> cert
= mServerCert
;
907 cert
.forget(aServerCert
);
912 TransportSecurityInfo::GetSucceededCertChain(
913 nsTArray
<RefPtr
<nsIX509Cert
>>& aSucceededCertChain
) {
914 MOZ_ASSERT(aSucceededCertChain
.IsEmpty());
915 if (!aSucceededCertChain
.IsEmpty()) {
916 return NS_ERROR_INVALID_ARG
;
918 aSucceededCertChain
.AppendElements(mSucceededCertChain
);
922 NS_IMETHODIMP
TransportSecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
923 bool* aIsBuiltInRoot
) {
924 NS_ENSURE_ARG_POINTER(aIsBuiltInRoot
);
925 *aIsBuiltInRoot
= mIsBuiltCertChainRootBuiltInRoot
;
930 TransportSecurityInfo::GetCipherName(nsACString
& aCipherName
) {
931 if (mCipherSuite
.isNothing()) {
932 return NS_ERROR_NOT_AVAILABLE
;
934 SSLCipherSuiteInfo cipherInfo
;
935 if (SSL_GetCipherSuiteInfo(*mCipherSuite
, &cipherInfo
, sizeof(cipherInfo
)) !=
937 return NS_ERROR_FAILURE
;
940 aCipherName
.Assign(cipherInfo
.cipherSuiteName
);
945 TransportSecurityInfo::GetKeyLength(uint32_t* aKeyLength
) {
946 NS_ENSURE_ARG_POINTER(aKeyLength
);
948 if (mCipherSuite
.isNothing()) {
949 return NS_ERROR_NOT_AVAILABLE
;
951 SSLCipherSuiteInfo cipherInfo
;
952 if (SSL_GetCipherSuiteInfo(*mCipherSuite
, &cipherInfo
, sizeof(cipherInfo
)) !=
954 return NS_ERROR_FAILURE
;
957 *aKeyLength
= cipherInfo
.symKeyBits
;
962 TransportSecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength
) {
963 NS_ENSURE_ARG_POINTER(aSecretKeyLength
);
965 if (mCipherSuite
.isNothing()) {
966 return NS_ERROR_NOT_AVAILABLE
;
968 SSLCipherSuiteInfo cipherInfo
;
969 if (SSL_GetCipherSuiteInfo(*mCipherSuite
, &cipherInfo
, sizeof(cipherInfo
)) !=
971 return NS_ERROR_FAILURE
;
974 *aSecretKeyLength
= cipherInfo
.effectiveKeyBits
;
979 TransportSecurityInfo::GetKeaGroupName(nsACString
& aKeaGroupName
) {
980 if (mKeaGroupName
.isNothing()) {
981 return NS_ERROR_NOT_AVAILABLE
;
983 aKeaGroupName
.Assign(*mKeaGroupName
);
988 TransportSecurityInfo::GetSignatureSchemeName(nsACString
& aSignatureScheme
) {
989 if (mSignatureSchemeName
.isNothing()) {
990 return NS_ERROR_NOT_AVAILABLE
;
992 aSignatureScheme
.Assign(*mSignatureSchemeName
);
997 TransportSecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion
) {
998 if (mProtocolVersion
.isNothing()) {
999 return NS_ERROR_NOT_AVAILABLE
;
1001 *aProtocolVersion
= *mProtocolVersion
;
1006 TransportSecurityInfo::GetCertificateTransparencyStatus(
1007 uint16_t* aCertificateTransparencyStatus
) {
1008 NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus
);
1010 *aCertificateTransparencyStatus
= mCertificateTransparencyStatus
;
1015 TransportSecurityInfo::GetMadeOCSPRequests(bool* aMadeOCSPRequests
) {
1016 *aMadeOCSPRequests
= mMadeOCSPRequests
;
1021 TransportSecurityInfo::GetUsedPrivateDNS(bool* aUsedPrivateDNS
) {
1022 *aUsedPrivateDNS
= mUsedPrivateDNS
;
1027 uint16_t TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
1028 const mozilla::psm::CertificateTransparencyInfo
& info
) {
1029 using mozilla::ct::CTPolicyCompliance
;
1031 if (!info
.enabled
|| info
.policyCompliance
.isNothing()) {
1033 return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE
;
1036 switch (*info
.policyCompliance
) {
1037 case CTPolicyCompliance::Compliant
:
1038 return nsITransportSecurityInfo::
1039 CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT
;
1040 case CTPolicyCompliance::NotEnoughScts
:
1041 return nsITransportSecurityInfo ::
1042 CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS
;
1043 case CTPolicyCompliance::NotDiverseScts
:
1044 return nsITransportSecurityInfo ::
1045 CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS
;
1047 MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type");
1050 return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE
;
1054 TransportSecurityInfo::GetOverridableErrorCategory(
1055 OverridableErrorCategory
* aOverridableErrorCategory
) {
1056 NS_ENSURE_ARG_POINTER(aOverridableErrorCategory
);
1058 if (mOverridableErrorCategory
.isSome()) {
1059 *aOverridableErrorCategory
= *mOverridableErrorCategory
;
1061 *aOverridableErrorCategory
= OverridableErrorCategory::ERROR_UNSET
;
1067 TransportSecurityInfo::GetIsExtendedValidation(bool* aIsEV
) {
1068 NS_ENSURE_ARG_POINTER(aIsEV
);
1071 // Never allow bad certs for EV, regardless of overrides.
1072 if (mOverridableErrorCategory
.isSome()) {
1076 if (!mIsEV
.isSome()) {
1077 return NS_ERROR_NOT_AVAILABLE
;
1085 TransportSecurityInfo::GetIsAcceptedEch(bool* aIsAcceptedEch
) {
1086 NS_ENSURE_ARG_POINTER(aIsAcceptedEch
);
1088 if (mIsAcceptedEch
.isNothing()) {
1089 return NS_ERROR_NOT_AVAILABLE
;
1091 *aIsAcceptedEch
= *mIsAcceptedEch
;
1096 TransportSecurityInfo::GetIsDelegatedCredential(bool* aIsDelegatedCredential
) {
1097 NS_ENSURE_ARG_POINTER(aIsDelegatedCredential
);
1099 if (mIsDelegatedCredential
.isNothing()) {
1100 return NS_ERROR_NOT_AVAILABLE
;
1102 *aIsDelegatedCredential
= *mIsDelegatedCredential
;
1107 TransportSecurityInfo::GetNegotiatedNPN(nsACString
& aNegotiatedNPN
) {
1108 if (!mNPNCompleted
) {
1109 return NS_ERROR_NOT_CONNECTED
;
1112 aNegotiatedNPN
= mNegotiatedNPN
;
1117 TransportSecurityInfo::GetResumed(bool* aResumed
) {
1118 NS_ENSURE_ARG_POINTER(aResumed
);
1119 *aResumed
= mResumed
;
1124 TransportSecurityInfo::GetPeerId(nsACString
& aResult
) {
1125 aResult
.Assign(mPeerId
);
1130 } // namespace mozilla