зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1914064 - extend AppTrustDomain to support multiple trust anchors r=jschanck,mach-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D221393
This commit is contained in:
Родитель
851b6f0ed9
Коммит
b3461332f5
|
@ -62,6 +62,7 @@ vendored:third_party/python/appdirs
|
|||
vendored:third_party/python/attrs
|
||||
vendored:third_party/python/blessed
|
||||
vendored:third_party/python/build
|
||||
vendored:third_party/python/cbor2
|
||||
vendored:third_party/python/certifi
|
||||
vendored:third_party/python/chardet
|
||||
vendored:third_party/python/charset_normalizer
|
||||
|
|
|
@ -52,33 +52,45 @@ AppTrustDomain::AppTrustDomain(nsTArray<Span<const uint8_t>>&& collectedCerts)
|
|||
mCertBlocklist(do_GetService(NS_CERT_STORAGE_CID)) {}
|
||||
|
||||
nsresult AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot) {
|
||||
if (!mTrustedRoots.IsEmpty()) {
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
switch (trustedRoot) {
|
||||
case nsIX509CertDB::AppXPCShellRoot:
|
||||
mTrustedRoot = {xpcshellRoot};
|
||||
mTrustedRoots.AppendElements(xpcshellRoots,
|
||||
MOZ_ARRAY_LENGTH(xpcshellRoots));
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AddonsPublicRoot:
|
||||
mTrustedRoot = {addonsPublicRoot};
|
||||
mTrustedRoots.AppendElements(addonsPublicRoots,
|
||||
MOZ_ARRAY_LENGTH(addonsPublicRoots));
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AddonsStageRoot:
|
||||
mTrustedRoot = {addonsStageRoot};
|
||||
mTrustedRoots.AppendElements(addonsStageRoots,
|
||||
MOZ_ARRAY_LENGTH(addonsStageRoots));
|
||||
break;
|
||||
|
||||
case nsIContentSignatureVerifier::ContentSignatureLocalRoot:
|
||||
mTrustedRoot = {contentSignatureLocalRoot};
|
||||
mTrustedRoots.AppendElements(
|
||||
contentSignatureLocalRoots,
|
||||
MOZ_ARRAY_LENGTH(contentSignatureLocalRoots));
|
||||
break;
|
||||
|
||||
case nsIContentSignatureVerifier::ContentSignatureProdRoot:
|
||||
mTrustedRoot = {contentSignatureProdRoot};
|
||||
mTrustedRoots.AppendElements(contentSignatureProdRoots,
|
||||
MOZ_ARRAY_LENGTH(contentSignatureProdRoots));
|
||||
break;
|
||||
|
||||
case nsIContentSignatureVerifier::ContentSignatureStageRoot:
|
||||
mTrustedRoot = {contentSignatureStageRoot};
|
||||
mTrustedRoots.AppendElements(
|
||||
contentSignatureStageRoots,
|
||||
MOZ_ARRAY_LENGTH(contentSignatureStageRoots));
|
||||
break;
|
||||
|
||||
case nsIContentSignatureVerifier::ContentSignatureDevRoot:
|
||||
mTrustedRoot = {contentSignatureDevRoot};
|
||||
mTrustedRoots.AppendElements(contentSignatureDevRoots,
|
||||
MOZ_ARRAY_LENGTH(contentSignatureDevRoots));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -90,12 +102,14 @@ nsresult AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot) {
|
|||
// The intermediate bundled with signed XPI files may have expired and be
|
||||
// considered invalid, which can result in bug 1548973.
|
||||
if (trustedRoot == nsIX509CertDB::AddonsPublicRoot) {
|
||||
mAddonsIntermediate = {addonsPublicIntermediate};
|
||||
mAddonsIntermediates.AppendElements(
|
||||
addonsPublicIntermediates, MOZ_ARRAY_LENGTH(addonsPublicIntermediates));
|
||||
}
|
||||
// Similarly to the above logic for production, we hardcode the intermediate
|
||||
// stage certificate here, so that stage is equivalent to production.
|
||||
if (trustedRoot == nsIX509CertDB::AddonsStageRoot) {
|
||||
mAddonsIntermediate = {addonsStageIntermediate};
|
||||
mAddonsIntermediates.AppendElements(
|
||||
addonsStageIntermediates, MOZ_ARRAY_LENGTH(addonsStageIntermediates));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -103,25 +117,26 @@ nsresult AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot) {
|
|||
|
||||
pkix::Result AppTrustDomain::FindIssuer(Input encodedIssuerName,
|
||||
IssuerChecker& checker, Time) {
|
||||
MOZ_ASSERT(!mTrustedRoot.IsEmpty());
|
||||
if (mTrustedRoot.IsEmpty()) {
|
||||
MOZ_ASSERT(!mTrustedRoots.IsEmpty());
|
||||
if (mTrustedRoots.IsEmpty()) {
|
||||
return pkix::Result::FATAL_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
nsTArray<Input> candidates;
|
||||
Input rootInput;
|
||||
pkix::Result rv =
|
||||
rootInput.Init(mTrustedRoot.Elements(), mTrustedRoot.Length());
|
||||
// This should never fail, since the possible roots are all hard-coded and
|
||||
// they should never be too long.
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
for (const auto& root : mTrustedRoots) {
|
||||
Input rootInput;
|
||||
pkix::Result rv = rootInput.Init(root.Elements(), root.Length());
|
||||
// This should never fail, since the possible roots are all hard-coded and
|
||||
// they should never be too long.
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
candidates.AppendElement(std::move(rootInput));
|
||||
}
|
||||
candidates.AppendElement(std::move(rootInput));
|
||||
if (!mAddonsIntermediate.IsEmpty()) {
|
||||
for (const auto& intermediate : mAddonsIntermediates) {
|
||||
Input intermediateInput;
|
||||
rv = intermediateInput.Init(mAddonsIntermediate.Elements(),
|
||||
mAddonsIntermediate.Length());
|
||||
pkix::Result rv =
|
||||
intermediateInput.Init(intermediate.Elements(), intermediate.Length());
|
||||
// Again, this should never fail for the same reason as above.
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
|
@ -130,7 +145,8 @@ pkix::Result AppTrustDomain::FindIssuer(Input encodedIssuerName,
|
|||
}
|
||||
for (const auto& intermediate : mIntermediates) {
|
||||
Input intermediateInput;
|
||||
rv = intermediateInput.Init(intermediate.Elements(), intermediate.Length());
|
||||
pkix::Result rv =
|
||||
intermediateInput.Init(intermediate.Elements(), intermediate.Length());
|
||||
// This is untrusted input, so skip any intermediates that are too large.
|
||||
if (rv != Success) {
|
||||
continue;
|
||||
|
@ -140,8 +156,8 @@ pkix::Result AppTrustDomain::FindIssuer(Input encodedIssuerName,
|
|||
|
||||
for (const auto& candidate : candidates) {
|
||||
bool keepGoing;
|
||||
rv = checker.Check(candidate, nullptr /*additionalNameConstraints*/,
|
||||
keepGoing);
|
||||
pkix::Result rv = checker.Check(
|
||||
candidate, nullptr /*additionalNameConstraints*/, keepGoing);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -187,11 +203,11 @@ pkix::Result AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
|||
Input candidateCertDER,
|
||||
/*out*/ TrustLevel& trustLevel) {
|
||||
MOZ_ASSERT(policy.IsAnyPolicy());
|
||||
MOZ_ASSERT(!mTrustedRoot.IsEmpty());
|
||||
MOZ_ASSERT(!mTrustedRoots.IsEmpty());
|
||||
if (!policy.IsAnyPolicy()) {
|
||||
return pkix::Result::FATAL_ERROR_INVALID_ARGS;
|
||||
}
|
||||
if (mTrustedRoot.IsEmpty()) {
|
||||
if (mTrustedRoots.IsEmpty()) {
|
||||
return pkix::Result::FATAL_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
@ -218,12 +234,14 @@ pkix::Result AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
|||
return pkix::Result::ERROR_REVOKED_CERTIFICATE;
|
||||
}
|
||||
|
||||
// mTrustedRoot is the only trust anchor for this validation.
|
||||
// mTrustedRoots are the only trust anchors for this validation.
|
||||
Span<const uint8_t> candidateCertDERSpan = {candidateCertDER.UnsafeGetData(),
|
||||
candidateCertDER.GetLength()};
|
||||
if (mTrustedRoot == candidateCertDERSpan) {
|
||||
trustLevel = TrustLevel::TrustAnchor;
|
||||
return Success;
|
||||
for (const auto& trustedRoot : mTrustedRoots) {
|
||||
if (trustedRoot == candidateCertDERSpan) {
|
||||
trustLevel = TrustLevel::TrustAnchor;
|
||||
return Success;
|
||||
}
|
||||
}
|
||||
|
||||
trustLevel = TrustLevel::InheritsTrust;
|
||||
|
|
|
@ -82,8 +82,8 @@ class AppTrustDomain final : public mozilla::pkix::TrustDomain {
|
|||
size_t digestBufLen) override;
|
||||
|
||||
private:
|
||||
Span<const uint8_t> mTrustedRoot;
|
||||
Span<const uint8_t> mAddonsIntermediate;
|
||||
nsTArray<Span<const uint8_t>> mTrustedRoots;
|
||||
nsTArray<Span<const uint8_t>> mAddonsIntermediates;
|
||||
nsTArray<Span<const uint8_t>> mIntermediates;
|
||||
nsCOMPtr<nsICertStorage> mCertBlocklist;
|
||||
};
|
||||
|
|
Двоичные данные
security/manager/ssl/addons-public-intermediate.crt
Двоичные данные
security/manager/ssl/addons-public-intermediate.crt
Двоичный файл не отображается.
|
@ -0,0 +1,41 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIHMzCCBRugAwIBAgIFFxRnUIAwDQYJKoZIhvcNAQEMBQAwfTELMAkGA1UEBhMC
|
||||
VVMxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xLzAtBgNVBAsTJk1vemls
|
||||
bGEgQU1PIFByb2R1Y3Rpb24gU2lnbmluZyBTZXJ2aWNlMR8wHQYDVQQDExZyb290
|
||||
LWNhLXByb2R1Y3Rpb24tYW1vMCIYDzIwMTUwMzE3MDAwMDAwWhgPMjEwMDEyMDMw
|
||||
MDAwMDBaMIGnMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTTW96aWxsYSBDb3Jwb3Jh
|
||||
dGlvbjEvMC0GA1UECxMmTW96aWxsYSBBTU8gUHJvZHVjdGlvbiBTaWduaW5nIFNl
|
||||
cnZpY2UxJjAkBgNVBAMTHXNpZ25pbmdjYTEuYWRkb25zLm1vemlsbGEub3JnMSEw
|
||||
HwYJKoZIhvcNAQkBFhJmb3hzZWNAbW96aWxsYS5jb20wggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQC/qluiiI+wO6qGA4vH7cHvWvXpdju9JnvbwnrbYmxh
|
||||
tUpfS68LbdjGGtv7RP6F1XhHT4MU3v4GuMulH0E4Wfalm8evsb3tBJRMJPICJX5U
|
||||
CLi6VJ6J2vipXSWBf8xbcOB+PY5Kk6L+EZiWaepiM23CdaZjNOJCAB6wFHlGe+zU
|
||||
k87whpLa7GrtrHjTb8u9TSS+mwjhvgfP8ILZrWhzb5H/ybgmD7jYaJGIDY/WDmq1
|
||||
gVe03fShxD09Ml1P7H38o5kbFLnbbqpqC6n8SfUI31MiJAXAN2e6rAOM8EmocAY0
|
||||
EC5KUooXKRsYvHzhwwHkwIbbe6QpTUlIqvw1MPlQPs7Zu/MBnVmyGTSqJxtYoklr
|
||||
0MaEXnJNY3g3FDf1R0Opp2/BEY9Vh3Fc9Pq6qWIhGoMyWdueoSYa+GURqDbsuYnk
|
||||
7ZkysxK+yRoFJu4x3TUBmMKM14jQKLgxvuIzWVn6qg6cw7ye/DYNufc+DSPSTSak
|
||||
SsWJ9IPxiAU7xJ+GCMzaZ10Y3VGOybGLuPxDlSd6KALAoMcl9ghB2mvfB0N3wv6u
|
||||
WnbKuxihq/qDps+FjliNvr7C66mIVH+9rkyHIy6GgIUlwr7E88Qqw+SQeNeph6NI
|
||||
Y85PL4p0Y8KivKP4J928tpp18wLuHNbIG+YaUk5WUDZ6/2621pi19UZQ8iiHxN/X
|
||||
KQIDAQABo4IBiTCCAYUwDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYD
|
||||
VR0lAQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFBY++xz/DCuT+JsV1y2jwuZ4
|
||||
YdztMIGoBgNVHSMEgaAwgZ2AFLO86lh0q+FueCqyq5wjHqhjLJe3oYGBpH8wfTEL
|
||||
MAkGA1UEBhMCVVMxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24xLzAtBgNV
|
||||
BAsTJk1vemlsbGEgQU1PIFByb2R1Y3Rpb24gU2lnbmluZyBTZXJ2aWNlMR8wHQYD
|
||||
VQQDExZyb290LWNhLXByb2R1Y3Rpb24tYW1vggEBMDMGCWCGSAGG+EIBBAQmFiRo
|
||||
dHRwOi8vYWRkb25zLm1vemlsbGEub3JnL2NhL2NybC5wZW0wTgYDVR0eBEcwRaFD
|
||||
MCCCHi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzAfgh1jb250ZW50LXNp
|
||||
Z25hdHVyZS5tb3ppbGxhLm9yZzANBgkqhkiG9w0BAQwFAAOCAgEAKTTFmoGTNjPd
|
||||
T7NruchQNxokV/lT19bfdXvGVGBmYeWdCCOWshLzvxAJ9XVqbi1Nrl4CexJGts6p
|
||||
RTPoJFgwZfbv6YKo1rCgbTB0bRBjucEOEwwv2hkRetdZRAdKon2wxvwbB3h8V54Z
|
||||
4D+zCETq/+8rmEveGdMaO4b2LNgzToxlki6KXF/DGUYjzsB7yjEcAYvQGsZMkaeS
|
||||
wNc2aT/Adj2mqbWpS5R/eA+yhv8KW1etAUzyaTUXyL3KrXyDXJJ5duMdfomQqqL6
|
||||
EeGTxR9iTVqZUNfqw+3/WgJ3Wz2atRFRpkhM67KBJhj6fsWr84omUojaLs8qM8jz
|
||||
lxMjBVZP0QnWta5tc5zmrQFSuAvqDEJ9zI/CoP08OsHyWrTHcj9H5OIH5zCCJoj5
|
||||
MGTgnWcAoiPpIF527tlh8y616YlfNY4d8njKUoTbYzQMmIM7cHIAmXUCbV+tlNiK
|
||||
TrhgxEWfWxWU1Z7HyQH2OZkXLc/Ub5zZctQLeZ4/6zeMwkYBIde04F3ogs6W98ea
|
||||
x7ScfMRQs+v/CBY1zmdd+QjJXuIT2omFxRLIQF/qNr9dLhQ/1Zx0nJj56F3IxaD0
|
||||
VWFT3nrzrFxp9KgcYdnv60Tt9J5LQBc8LaI+8UoKikuW+HfFX3F6li0mXTdaUtuo
|
||||
b7w2V9cDKpiO0A9WD/Fape1mMI9L6YY=
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/addons-public.crt
Двоичные данные
security/manager/ssl/addons-public.crt
Двоичный файл не отображается.
|
@ -0,0 +1,37 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGZTCCBE2gAwIBAgIBATANBgkqhkiG9w0BAQwFADB9MQswCQYDVQQGEwJVUzEc
|
||||
MBoGA1UEChMTTW96aWxsYSBDb3Jwb3JhdGlvbjEvMC0GA1UECxMmTW96aWxsYSBB
|
||||
TU8gUHJvZHVjdGlvbiBTaWduaW5nIFNlcnZpY2UxHzAdBgNVBAMTFnJvb3QtY2Et
|
||||
cHJvZHVjdGlvbi1hbW8wIhgPMjAyNDAyMDEwMDAwMDBaGA8yMjAwMTIwMzAwMDAw
|
||||
MFowfTELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24x
|
||||
LzAtBgNVBAsTJk1vemlsbGEgQU1PIFByb2R1Y3Rpb24gU2lnbmluZyBTZXJ2aWNl
|
||||
MR8wHQYDVQQDExZyb290LWNhLXByb2R1Y3Rpb24tYW1vMIICIDANBgkqhkiG9w0B
|
||||
AQEFAAOCAg0AMIICCAKCAgEAtLth11268Mt+vjD3in+Y4KAEjHzDc+5iVgXnCYL5
|
||||
U3+IRyWy8zD7CFGrsyPRhKS3x3WesM0shTm+ADPg9ZsQFobmSdzAwCTn9wdUbOkK
|
||||
Kx65fKqpTbTxqnqZ6TSXC6OybEqqhNzVJu9jIKiB0YE0bKlLPuyyDxnu9utlPjf0
|
||||
9Cz2FS3uK2dkQx6GmYWGO2vfuPZhziP4NmBQfvcmYxPl3aZU9pAYAOD/HW+4uyNL
|
||||
SIuG9AdDesvTIS/gkWScsXRXtsAcpCV9eC7IXirDNWsx42Tuekija1vFQCUy5KUc
|
||||
QprIk69PH5z8gypmnmdAbbLoInHYqXGaV64iBprGWyNdqucrsI0hC3ZA1elGo6Np
|
||||
/tsLObl6z9+Nl+9VoloQv3ReXc9SyrYwXZlJMWkDDj/7obVxCga2aNaLpw0UMdY+
|
||||
/kpEOARMIwd0hLa+1w1hjnDiJKCWVjwAnwSwtzyQgVo0wMgZbndAuZ9wsva3oAAJ
|
||||
ziKiNbdehlNpWkYe3pSe4D0TYEIMC13mXBccOsL8ohHJgozhEOjzPFEI7YTrCpbM
|
||||
zIZSsL48jhg6M7ZKkgcv7/gLMezltkO65VXymqy9JkRGXUjH6Mt804LTFQjNL4TZ
|
||||
es3L3+RzTaKaBHYOcrl6NnIWdadSfqvOm9BuciUTHk9vojlWNhEN+7R66lFEZ3As
|
||||
uLsCAQOjge0wgeowDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0l
|
||||
AQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFLO86lh0q+FueCqyq5wjHqhjLJe3
|
||||
MIGSBgNVHSMEgYowgYehgYGkfzB9MQswCQYDVQQGEwJVUzEcMBoGA1UEChMTTW96
|
||||
aWxsYSBDb3Jwb3JhdGlvbjEvMC0GA1UECxMmTW96aWxsYSBBTU8gUHJvZHVjdGlv
|
||||
biBTaWduaW5nIFNlcnZpY2UxHzAdBgNVBAMTFnJvb3QtY2EtcHJvZHVjdGlvbi1h
|
||||
bW+CAQEwDQYJKoZIhvcNAQEMBQADggIBAAAJuN23qDiyAZ8y9DhqTfIfdYBXC7jg
|
||||
f7p5DNCj6mcfLxCMLuSvLljYWm0IfHYs5W0lnQgm8+N0m3SAjQd18AzWfXNklFjZ
|
||||
1EcP8MRU/keFEk9SmeHZhP916jQfqQvB45w4QwPcJG0nPkWsYzceqD3uL5g2g4Jg
|
||||
gk+WYWmtE4eeM2BX6cT0itMErYKWei3SF09TdrCX+XpHMixg4nnDdsGe9wxc8F/o
|
||||
diQ48f/7AZo06moMyZvIH4PPcVt0osAU18fLO0RrVJkupMraxbM1XXL1UwJlyV+p
|
||||
kvJutX2xBB1f1BA3xPl3NlQneaLIm3JFsw0r7t0z0n1shC6xCi4+t3Fh6Z38CnbS
|
||||
WwAe5rA2OCQYMjsehxRK9BhmDCG8U65GVd9t8nV4iEJFTrjntBDEFtVD5s4Qnlyv
|
||||
OUrWd2du4dLCs+WW2E6+R7jZtrsIqFD6qwCLqcgBgC9CM9UgHeUBOixmZLBKCNDE
|
||||
N1sRkmcVwXcCl5btdgVVq74Mgsd38xsmYuFoMi6nbDLllm6T2ql8LZExyX2i/vo0
|
||||
pxhEVRaFwj1J1r3TRNXksjdqFcgpNCMf2FRbjDGtVLXRVG0DCCGRayigKgdH78qM
|
||||
HpdXrbaTDFsfMLTAMnGFnqOZMuMobNJS5M6/vqdepoC8L7xmI5dQgW8YGyymr8DP
|
||||
gchMof0tylgn
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/addons-stage-intermediate.crt
Двоичные данные
security/manager/ssl/addons-stage-intermediate.crt
Двоичный файл не отображается.
|
@ -0,0 +1,40 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIHAjCCBOqgAwIBAgIUdREEOjuYrEnheBdNULIseX0XjTswDQYJKoZIhvcNAQEM
|
||||
BQAwczELMAkGA1UEBhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24x
|
||||
KDAmBgNVBAsMH01vemlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAaBgNV
|
||||
BAMME2Nhcy1yb290LWNhLXN0YWdpbmcwIBcNMjQwMjEyMDAwMDAwWhgPMjA1MDEy
|
||||
MzEwMDAwMDBaMH8xCzAJBgNVBAYTAlVTMRwwGgYDVQQKDBNNb3ppbGxhIENvcnBv
|
||||
cmF0aW9uMSgwJgYDVQQLDB9Nb3ppbGxhIFN0YWdpbmcgU2lnbmluZyBTZXJ2aWNl
|
||||
MSgwJgYDVQQDDB9jYXMtaW50ZXJtZWRpYXRlLWFtby1jYS1zdGFnaW5nMIICIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2DueYcyiImliGyqmWYaUpuHClSi2
|
||||
/PE3dgkYKWuEUifLiPyOpvaAzapzFSMiTjb/aVHFUEZ92Ad04euCdT3eYMC8XllU
|
||||
+g8q2JKjbNWro9sOpItyambaVe2Q18twFKd6CBnhkpn8/ntxLgi38HgUFfHVK72B
|
||||
2uoU6TtihCFDer87H90Orfl0UufIfSMl0D6dKwsF4DpQjrGRd9pK2scW0puR8zME
|
||||
3NRmhvn6B0HHrs1kKbJhk6dyOka4/hqmJz9AmpFoRR4g7qFj37A3eN3iVe/+bLL/
|
||||
ZDHiL5Js+tNBQgttbGNhZFVnlYJd/Acpz/whuNkbLPrl8yT1L0sw8sLdCQyI3aHx
|
||||
fWUrg9L+ezXyMDNYYGQYec2mmCedsbvPS9MXFx+K7KZhLCm9JLuW9SL9qo1qY7CX
|
||||
i7r46/6P1nZdekTMv86uE+MjiKN1WOgh2sMU6HBTIhVRQTH1cC/+JvWFAGd78w9g
|
||||
qJlPrB17RYNcghv6Go4Bn/z/n7yY9W+a5+Wp0B5z/XTo0oU8uqFZHcrPo838RPC4
|
||||
PsP7lRhJaQ086ZeNpKflVu+We2MuKtgadYXO/dplBugR4B4dOkAp9W9ey7NSAejB
|
||||
kV1Uwtfz+qVZ+LK0PP40lMKTSga5Ux775XYJZdPHMXQ5ixAn4VTFsYEyhMuFL4f8
|
||||
i1r8Q8hWa3pg9ucCAwEAAaOCAX4wggF6MAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/
|
||||
BAQDAgEGMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBRE3pvXWGvv
|
||||
mroycY24xrHfrXdopDCBnQYDVR0jBIGVMIGSgBRnHYjw7dUlrInD0HrEGq1KNJYA
|
||||
9qF3pHUwczELMAkGA1UEBhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRp
|
||||
b24xKDAmBgNVBAsMH01vemlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAa
|
||||
BgNVBAMME2Nhcy1yb290LWNhLXN0YWdpbmeCAQEwMwYJYIZIAYb4QgEEBCYWJGh0
|
||||
dHA6Ly9hZGRvbnMuYWxsaXpvbS5vcmcvY2EvY3JsLnBlbTBOBgNVHR4ERzBFoUMw
|
||||
IIIeLmNvbnRlbnQtc2lnbmF0dXJlLm1vemlsbGEub3JnMB+CHWNvbnRlbnQtc2ln
|
||||
bmF0dXJlLm1vemlsbGEub3JnMA0GCSqGSIb3DQEBDAUAA4ICAQAAe1cCzYgGE6mm
|
||||
UwqHstpNJVJdFCexmIHsKJscZVuomagekYbccXhZvEtoU+gDSyrCbP2STvOPWs3X
|
||||
TY9QYAIzsdQrdrdOqbuyDdcgKw50inQ+X6A1yOZSCEKl4eweKnTn/LD9PcrReaY8
|
||||
jKIF+rYGHHXocr4O9tQYLFRBL45H2o5vSRQrsM6D75AGrezgqtuZsgB9OOY5CJGb
|
||||
gDY3tIXcHpXr6qM+OazRfGGm35PcTwxHI0OBQsfp656MfqnBSMYjPmPdThX1QzR5
|
||||
ne7I01daDWNYgmHuoDlfZDHBlqL2YUV63QWRRS63YE1Ilf7y/SaeuFFnAFwbedfV
|
||||
JtimfJ8cSqd32KprSg1evmLObN8aaGzSjXXoLKL0eL+AeDl5iam0Yebq4Wxlh2VT
|
||||
gY2QP3+Vtqyqxv9hMZ8i4CGUPkr78Uweo2k0osldnsBLaFdn0SC1asAh61rkRvvN
|
||||
JAwWWAoaw7IMWflpxRlZmqX2OhWe5sZtvfS0PcX3fB3p9YTAerMi42VEFr8WF3pj
|
||||
5tnZkDMPjN8vcFPa4D5JFEB7yew7IfNzopD5fnlewn0ITwezRtju2ShGe2rPjGjR
|
||||
bqq+YWbayCB/uZ0xgEv+jcpAxqrGndmntys9jk5v451BscT6LofKRtyzVrpTOjdI
|
||||
kW5EITPvqhzzozJO38ZSxycAbe+aAQ==
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/addons-stage.crt
Двоичные данные
security/manager/ssl/addons-stage.crt
Двоичный файл не отображается.
|
@ -0,0 +1,36 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGRDCCBCygAwIBAgIBATANBgkqhkiG9w0BAQwFADBzMQswCQYDVQQGEwJVUzEc
|
||||
MBoGA1UECgwTTW96aWxsYSBDb3Jwb3JhdGlvbjEoMCYGA1UECwwfTW96aWxsYSBT
|
||||
dGFnaW5nIFNpZ25pbmcgU2VydmljZTEcMBoGA1UEAwwTY2FzLXJvb3QtY2Etc3Rh
|
||||
Z2luZzAgFw0yNDAyMTIwMDAwMDBaGA8yMDUwMTIzMTAwMDAwMFowczELMAkGA1UE
|
||||
BhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xKDAmBgNVBAsMH01v
|
||||
emlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAaBgNVBAMME2Nhcy1yb290
|
||||
LWNhLXN0YWdpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJLI7O
|
||||
heP24t+vR/afP2U80Os1UQIVWmZLd4Z9/ybt9NaXzeCqCd5uV7lpNCvYZLjw57xN
|
||||
0ZrQiuTw1lAf5IgLKFkjWIWU6YbagQKxX8zGzZ1t8IpvXlP5Qo0kPkYHyJ6FB1GW
|
||||
JKiHlj0tqDpvfb7oooImsdRvw2lhvXa9m8ttFnUS69Wf9Xh14hSb+Cqg5HfHxBkB
|
||||
Z/UcrYeOlq5fkxkrTjrCa+XH2942+ZzcWHSjOF3Sf2/gMug1Dc01ORVbloz5e7AI
|
||||
fdA9Ng9DSjUffCaiTvYqz8f8wZ3gYTd6R8oFfo5Y8y2hjPxPHsTsYaiVvwdx8VBZ
|
||||
1CBvAGbK4PQHPa4nboJhIuL1JDUhZJAOy/4i2pzn77ce1399CrSLfBzGc6ZWmJ4a
|
||||
aoG2wdybiGahMasAYf8M+EWlhcnr0YUjnHDWZ50jJ8D62O+SLMRLyWYmZRfYhOHf
|
||||
3Ed4db1tO2xGDrwoSncbBt706zyBZcNwd1lC21j+cjIDHEmnvv22Csq9KKqMbyd6
|
||||
v76Ils02uWl63EWlXVbnbNrWW2u+7YvrxZ5DK/GZZIorFZuOzoaFH4VUZ5waxofi
|
||||
tCN2C7W/QiejqnXUPZQgNQU48aOq3JlvoiwvVFxoejmfw/6EiAMyuE6Tx2odKFBS
|
||||
1+3EKHpn/AWc2yAos3NfFUhDo3vxonuYwbSlxwIDAQABo4HgMIHdMAwGA1UdEwQF
|
||||
MAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0G
|
||||
A1UdDgQWBBRnHYjw7dUlrInD0HrEGq1KNJYA9jCBhQYDVR0jBH4wfKF3pHUwczEL
|
||||
MAkGA1UEBhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xKDAmBgNV
|
||||
BAsMH01vemlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAaBgNVBAMME2Nh
|
||||
cy1yb290LWNhLXN0YWdpbmeCAQEwDQYJKoZIhvcNAQEMBQADggIBABOMi2kAbJRG
|
||||
kvGjSeeQXKiXNO/dfLadYG938kl/Xagc7eGWvccHeTPBT7lkiQQko9ucXe4pMzOD
|
||||
YGyBZyeMc3uFFqjsT9gg/r4KyitxE987qqPS0cjG1up72UyhfNUBgBxCCx0QrRpZ
|
||||
AbuOAuoTg9tE2uLdqBIemWHHBl/DXKYpmfOd9d6DPI1zxxLp/EegC/mEmiCysA20
|
||||
wBy/dbK6uhQ+gjqaImjclejaAg07b2HR1HiXNNDdCqL3KE///stTkFCrTq9CFU74
|
||||
ZdAiCEPSDYU2Qag/jUgzxqNrsPNjA9CkseCezmaNiU28zuEX8xbbhKxoyagAA4mS
|
||||
lVza5TRvfBo2jbnBFpgfChplDTTfK653k5MF6Q5rPiz4guNqylzq9ZqxGbPGKQbz
|
||||
0K7PqwKAQTWQ/lo85Q8MFVOSgFeMNOYv6ak+N3QXEpzEtMs1Ta5i9Pla4ia+ZZi8
|
||||
4lhd/mblxrq8QcpQmrHgXjb/Kpm5BbKnJYUIYidEfW1BMktsPZVbDc0ePa8hu6oZ
|
||||
Pafl5Rch9rAxeaMFOgYMeOJwlRCt2Fbm+mtnWKFdxy9Peib75pXQD43qYbnK8ucj
|
||||
xNCR3VBsgIgAhyO11hXiBo5nX5OHn2PG1MPV9+H0RQb6g5zOuKrWoh9CzB8mBl7d
|
||||
0JMkzy6TFAcAo3KL5ZNvRqqB8xRmIYLK
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/content-signature-local.crt
Двоичные данные
security/manager/ssl/content-signature-local.crt
Двоичный файл не отображается.
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICKjCCAa+gAwIBAgIIFY4HHiViG/gwCgYIKoZIzj0EAwMwXzELMAkGA1UEBhMC
|
||||
VVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRAwDgYDVQQK
|
||||
EwdNb3ppbGxhMRkwFwYDVQQDExBjc3Jvb3QxNTUzMTg2NzQ3MB4XDTE5MDExOTE3
|
||||
NDU0N1oXDTQ5MDMyMTE3NDU0N1owXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB
|
||||
MRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKEwdNb3ppbGxhMRkwFwYD
|
||||
VQQDExBjc3Jvb3QxNTUzMTg2NzQ3MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEhpId
|
||||
iezJa9Ab2dCesA0pc5FIBdkA6uWWVU2hN3/CpTWcTbhZ6JRCSsGa31YEUEGkDuGl
|
||||
C1ti6hzL0gq/vlnRkMoAcdPU8qdeOp/ZAmVYP+CZcQ0F0S/7PFjqE+5AiLGmozgw
|
||||
NjAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDwYDVR0TAQH/
|
||||
BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEA1UhMQI32zwh4+UmD1tVYRFRLM0sy
|
||||
raFyXTzUlrYF0YW89gvUXETPTmewAST397LAAjEAzGUC8N7h8BWfj6R9ES88UPgr
|
||||
yhRZrsaFZybKjZnBwG7lN9AkrjpKC1h2z4naOXX3
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/content-signature-prod.crt
Двоичные данные
security/manager/ssl/content-signature-prod.crt
Двоичный файл не отображается.
|
@ -0,0 +1,37 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGZTCCBE2gAwIBAgIBATANBgkqhkiG9w0BAQwFADB9MQswCQYDVQQGEwJVUzEc
|
||||
MBoGA1UEChMTTW96aWxsYSBDb3Jwb3JhdGlvbjEvMC0GA1UECxMmTW96aWxsYSBB
|
||||
TU8gUHJvZHVjdGlvbiBTaWduaW5nIFNlcnZpY2UxHzAdBgNVBAMTFnJvb3QtY2Et
|
||||
cHJvZHVjdGlvbi1hbW8wIhgPMjAyNDAyMDEwMDAwMDBaGA8yMjAwMTIwMzAwMDAw
|
||||
MFowfTELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE01vemlsbGEgQ29ycG9yYXRpb24x
|
||||
LzAtBgNVBAsTJk1vemlsbGEgQU1PIFByb2R1Y3Rpb24gU2lnbmluZyBTZXJ2aWNl
|
||||
MR8wHQYDVQQDExZyb290LWNhLXByb2R1Y3Rpb24tYW1vMIICIDANBgkqhkiG9w0B
|
||||
AQEFAAOCAg0AMIICCAKCAgEAtLth11268Mt+vjD3in+Y4KAEjHzDc+5iVgXnCYL5
|
||||
U3+IRyWy8zD7CFGrsyPRhKS3x3WesM0shTm+ADPg9ZsQFobmSdzAwCTn9wdUbOkK
|
||||
Kx65fKqpTbTxqnqZ6TSXC6OybEqqhNzVJu9jIKiB0YE0bKlLPuyyDxnu9utlPjf0
|
||||
9Cz2FS3uK2dkQx6GmYWGO2vfuPZhziP4NmBQfvcmYxPl3aZU9pAYAOD/HW+4uyNL
|
||||
SIuG9AdDesvTIS/gkWScsXRXtsAcpCV9eC7IXirDNWsx42Tuekija1vFQCUy5KUc
|
||||
QprIk69PH5z8gypmnmdAbbLoInHYqXGaV64iBprGWyNdqucrsI0hC3ZA1elGo6Np
|
||||
/tsLObl6z9+Nl+9VoloQv3ReXc9SyrYwXZlJMWkDDj/7obVxCga2aNaLpw0UMdY+
|
||||
/kpEOARMIwd0hLa+1w1hjnDiJKCWVjwAnwSwtzyQgVo0wMgZbndAuZ9wsva3oAAJ
|
||||
ziKiNbdehlNpWkYe3pSe4D0TYEIMC13mXBccOsL8ohHJgozhEOjzPFEI7YTrCpbM
|
||||
zIZSsL48jhg6M7ZKkgcv7/gLMezltkO65VXymqy9JkRGXUjH6Mt804LTFQjNL4TZ
|
||||
es3L3+RzTaKaBHYOcrl6NnIWdadSfqvOm9BuciUTHk9vojlWNhEN+7R66lFEZ3As
|
||||
uLsCAQOjge0wgeowDAYDVR0TBAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwFgYDVR0l
|
||||
AQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFLO86lh0q+FueCqyq5wjHqhjLJe3
|
||||
MIGSBgNVHSMEgYowgYehgYGkfzB9MQswCQYDVQQGEwJVUzEcMBoGA1UEChMTTW96
|
||||
aWxsYSBDb3Jwb3JhdGlvbjEvMC0GA1UECxMmTW96aWxsYSBBTU8gUHJvZHVjdGlv
|
||||
biBTaWduaW5nIFNlcnZpY2UxHzAdBgNVBAMTFnJvb3QtY2EtcHJvZHVjdGlvbi1h
|
||||
bW+CAQEwDQYJKoZIhvcNAQEMBQADggIBAAAJuN23qDiyAZ8y9DhqTfIfdYBXC7jg
|
||||
f7p5DNCj6mcfLxCMLuSvLljYWm0IfHYs5W0lnQgm8+N0m3SAjQd18AzWfXNklFjZ
|
||||
1EcP8MRU/keFEk9SmeHZhP916jQfqQvB45w4QwPcJG0nPkWsYzceqD3uL5g2g4Jg
|
||||
gk+WYWmtE4eeM2BX6cT0itMErYKWei3SF09TdrCX+XpHMixg4nnDdsGe9wxc8F/o
|
||||
diQ48f/7AZo06moMyZvIH4PPcVt0osAU18fLO0RrVJkupMraxbM1XXL1UwJlyV+p
|
||||
kvJutX2xBB1f1BA3xPl3NlQneaLIm3JFsw0r7t0z0n1shC6xCi4+t3Fh6Z38CnbS
|
||||
WwAe5rA2OCQYMjsehxRK9BhmDCG8U65GVd9t8nV4iEJFTrjntBDEFtVD5s4Qnlyv
|
||||
OUrWd2du4dLCs+WW2E6+R7jZtrsIqFD6qwCLqcgBgC9CM9UgHeUBOixmZLBKCNDE
|
||||
N1sRkmcVwXcCl5btdgVVq74Mgsd38xsmYuFoMi6nbDLllm6T2ql8LZExyX2i/vo0
|
||||
pxhEVRaFwj1J1r3TRNXksjdqFcgpNCMf2FRbjDGtVLXRVG0DCCGRayigKgdH78qM
|
||||
HpdXrbaTDFsfMLTAMnGFnqOZMuMobNJS5M6/vqdepoC8L7xmI5dQgW8YGyymr8DP
|
||||
gchMof0tylgn
|
||||
-----END CERTIFICATE-----
|
Двоичные данные
security/manager/ssl/content-signature-stage.crt
Двоичные данные
security/manager/ssl/content-signature-stage.crt
Двоичный файл не отображается.
|
@ -0,0 +1,36 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGRDCCBCygAwIBAgIBATANBgkqhkiG9w0BAQwFADBzMQswCQYDVQQGEwJVUzEc
|
||||
MBoGA1UECgwTTW96aWxsYSBDb3Jwb3JhdGlvbjEoMCYGA1UECwwfTW96aWxsYSBT
|
||||
dGFnaW5nIFNpZ25pbmcgU2VydmljZTEcMBoGA1UEAwwTY2FzLXJvb3QtY2Etc3Rh
|
||||
Z2luZzAgFw0yNDAyMTIwMDAwMDBaGA8yMDUwMTIzMTAwMDAwMFowczELMAkGA1UE
|
||||
BhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xKDAmBgNVBAsMH01v
|
||||
emlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAaBgNVBAMME2Nhcy1yb290
|
||||
LWNhLXN0YWdpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJLI7O
|
||||
heP24t+vR/afP2U80Os1UQIVWmZLd4Z9/ybt9NaXzeCqCd5uV7lpNCvYZLjw57xN
|
||||
0ZrQiuTw1lAf5IgLKFkjWIWU6YbagQKxX8zGzZ1t8IpvXlP5Qo0kPkYHyJ6FB1GW
|
||||
JKiHlj0tqDpvfb7oooImsdRvw2lhvXa9m8ttFnUS69Wf9Xh14hSb+Cqg5HfHxBkB
|
||||
Z/UcrYeOlq5fkxkrTjrCa+XH2942+ZzcWHSjOF3Sf2/gMug1Dc01ORVbloz5e7AI
|
||||
fdA9Ng9DSjUffCaiTvYqz8f8wZ3gYTd6R8oFfo5Y8y2hjPxPHsTsYaiVvwdx8VBZ
|
||||
1CBvAGbK4PQHPa4nboJhIuL1JDUhZJAOy/4i2pzn77ce1399CrSLfBzGc6ZWmJ4a
|
||||
aoG2wdybiGahMasAYf8M+EWlhcnr0YUjnHDWZ50jJ8D62O+SLMRLyWYmZRfYhOHf
|
||||
3Ed4db1tO2xGDrwoSncbBt706zyBZcNwd1lC21j+cjIDHEmnvv22Csq9KKqMbyd6
|
||||
v76Ils02uWl63EWlXVbnbNrWW2u+7YvrxZ5DK/GZZIorFZuOzoaFH4VUZ5waxofi
|
||||
tCN2C7W/QiejqnXUPZQgNQU48aOq3JlvoiwvVFxoejmfw/6EiAMyuE6Tx2odKFBS
|
||||
1+3EKHpn/AWc2yAos3NfFUhDo3vxonuYwbSlxwIDAQABo4HgMIHdMAwGA1UdEwQF
|
||||
MAMBAf8wDgYDVR0PAQH/BAQDAgEGMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0G
|
||||
A1UdDgQWBBRnHYjw7dUlrInD0HrEGq1KNJYA9jCBhQYDVR0jBH4wfKF3pHUwczEL
|
||||
MAkGA1UEBhMCVVMxHDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xKDAmBgNV
|
||||
BAsMH01vemlsbGEgU3RhZ2luZyBTaWduaW5nIFNlcnZpY2UxHDAaBgNVBAMME2Nh
|
||||
cy1yb290LWNhLXN0YWdpbmeCAQEwDQYJKoZIhvcNAQEMBQADggIBABOMi2kAbJRG
|
||||
kvGjSeeQXKiXNO/dfLadYG938kl/Xagc7eGWvccHeTPBT7lkiQQko9ucXe4pMzOD
|
||||
YGyBZyeMc3uFFqjsT9gg/r4KyitxE987qqPS0cjG1up72UyhfNUBgBxCCx0QrRpZ
|
||||
AbuOAuoTg9tE2uLdqBIemWHHBl/DXKYpmfOd9d6DPI1zxxLp/EegC/mEmiCysA20
|
||||
wBy/dbK6uhQ+gjqaImjclejaAg07b2HR1HiXNNDdCqL3KE///stTkFCrTq9CFU74
|
||||
ZdAiCEPSDYU2Qag/jUgzxqNrsPNjA9CkseCezmaNiU28zuEX8xbbhKxoyagAA4mS
|
||||
lVza5TRvfBo2jbnBFpgfChplDTTfK653k5MF6Q5rPiz4guNqylzq9ZqxGbPGKQbz
|
||||
0K7PqwKAQTWQ/lo85Q8MFVOSgFeMNOYv6ak+N3QXEpzEtMs1Ta5i9Pla4ia+ZZi8
|
||||
4lhd/mblxrq8QcpQmrHgXjb/Kpm5BbKnJYUIYidEfW1BMktsPZVbDc0ePa8hu6oZ
|
||||
Pafl5Rch9rAxeaMFOgYMeOJwlRCt2Fbm+mtnWKFdxy9Peib75pXQD43qYbnK8ucj
|
||||
xNCR3VBsgIgAhyO11hXiBo5nX5OHn2PG1MPV9+H0RQb6g5zOuKrWoh9CzB8mBl7d
|
||||
0JMkzy6TFAcAo3KL5ZNvRqqB8xRmIYLK
|
||||
-----END CERTIFICATE-----
|
|
@ -2,49 +2,41 @@
|
|||
# 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/.
|
||||
|
||||
import textwrap
|
||||
|
||||
def _file_byte_generator(filename):
|
||||
with open(filename, "rb") as f:
|
||||
contents = f.read()
|
||||
|
||||
if b"-----BEGIN CERTIFICATE-----" in contents:
|
||||
raise Exception(f"{filename} contains a PEM certificate. Expected DER.")
|
||||
|
||||
# Treat empty files the same as a file containing a lone 0;
|
||||
# a single-element array will fail cert verifcation just as an
|
||||
# empty array would.
|
||||
if not contents:
|
||||
return ["\0"]
|
||||
|
||||
return contents
|
||||
from pyasn1_modules import pem
|
||||
|
||||
|
||||
def _create_header(array_name, cert_bytes):
|
||||
hexified = ["0x%02x" % byte for byte in cert_bytes]
|
||||
|
||||
substs = {"array_name": array_name, "bytes": ", ".join(hexified)}
|
||||
return "const uint8_t %(array_name)s[] = {\n%(bytes)s\n};\n" % substs
|
||||
def read_certificate(filename):
|
||||
with open(filename, "r") as f:
|
||||
try:
|
||||
return pem.readPemFromFile(
|
||||
f, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"
|
||||
)
|
||||
except UnicodeDecodeError:
|
||||
raise Exception(
|
||||
f"Could not decode {filename} (it should be a PEM-encoded certificate)"
|
||||
)
|
||||
|
||||
|
||||
# Create functions named the same as the data arrays that we're going to
|
||||
# write to the headers, so we don't have to duplicate the names like so:
|
||||
#
|
||||
# def arrayName(header, cert_filename):
|
||||
# header.write(_create_header("arrayName", cert_filename))
|
||||
array_names = [
|
||||
"addonsPublicIntermediate",
|
||||
"addonsPublicRoot",
|
||||
"addonsStageRoot",
|
||||
"addonsStageIntermediate",
|
||||
"contentSignatureDevRoot",
|
||||
"contentSignatureLocalRoot",
|
||||
"contentSignatureProdRoot",
|
||||
"contentSignatureStageRoot",
|
||||
"xpcshellRoot",
|
||||
]
|
||||
|
||||
for n in array_names:
|
||||
# Make sure the lambda captures the right string.
|
||||
globals()[n] = lambda header, cert_filename, name=n: header.write(
|
||||
_create_header(name, _file_byte_generator(cert_filename))
|
||||
def write_header(output, array_name, certificates):
|
||||
certificate_names = []
|
||||
for index, certificate in enumerate(certificates):
|
||||
certificate_name = f"{array_name}{index}"
|
||||
certificate_names.append(
|
||||
f"mozilla::Span({certificate_name}, sizeof({certificate_name}))"
|
||||
)
|
||||
output.write(f"const uint8_t {certificate_name}[] = {{\n")
|
||||
certificate_bytes = read_certificate(certificate)
|
||||
hexified = ", ".join(["0x%02x" % byte for byte in certificate_bytes])
|
||||
wrapped = textwrap.wrap(hexified)
|
||||
for line in wrapped:
|
||||
output.write(f" {line}\n")
|
||||
output.write("};\n")
|
||||
output.write(
|
||||
f'const mozilla::Span<const uint8_t> {array_name}[] = {{ {", ".join(certificate_names)} }};\n'
|
||||
)
|
||||
|
||||
|
||||
def generate(output, *args):
|
||||
write_header(output, args[-1], args[0:-1])
|
||||
|
|
|
@ -233,45 +233,52 @@ if CONFIG["CC_TYPE"] in ("clang", "gcc"):
|
|||
headers_arrays_certs = [
|
||||
(
|
||||
"xpcshell.inc",
|
||||
"xpcshellRoot",
|
||||
"tests/unit/test_signed_apps/xpcshellTestRoot.der",
|
||||
"xpcshellRoots",
|
||||
[
|
||||
"tests/unit/test_signed_apps/xpcshellTestRoot.pem",
|
||||
"tests/unit/test_signed_apps/xpcshellTestRoot2.pem",
|
||||
],
|
||||
),
|
||||
("addons-public.inc", "addonsPublicRoot", "addons-public.crt"),
|
||||
("addons-public.inc", "addonsPublicRoots", ["addons-public.pem"]),
|
||||
(
|
||||
"addons-public-intermediate.inc",
|
||||
"addonsPublicIntermediate",
|
||||
"addons-public-intermediate.crt",
|
||||
"addonsPublicIntermediates",
|
||||
["addons-public-intermediate.pem"],
|
||||
),
|
||||
("addons-stage.inc", "addonsStageRoot", "addons-stage.crt"),
|
||||
("addons-stage.inc", "addonsStageRoots", ["addons-stage.pem"]),
|
||||
(
|
||||
"addons-stage-intermediate.inc",
|
||||
"addonsStageIntermediate",
|
||||
"addons-stage-intermediate.crt",
|
||||
"addonsStageIntermediates",
|
||||
["addons-stage-intermediate.pem"],
|
||||
),
|
||||
(
|
||||
"content-signature-prod.inc",
|
||||
"contentSignatureProdRoot",
|
||||
"content-signature-prod.crt",
|
||||
"contentSignatureProdRoots",
|
||||
["content-signature-prod.pem"],
|
||||
),
|
||||
(
|
||||
"content-signature-stage.inc",
|
||||
"contentSignatureStageRoot",
|
||||
"content-signature-stage.crt",
|
||||
"contentSignatureStageRoots",
|
||||
["content-signature-stage.pem"],
|
||||
),
|
||||
# The dev root is the same as the stage root.
|
||||
(
|
||||
"content-signature-dev.inc",
|
||||
"contentSignatureDevRoot",
|
||||
"content-signature-stage.crt",
|
||||
"contentSignatureDevRoots",
|
||||
["content-signature-stage.pem"],
|
||||
),
|
||||
(
|
||||
"content-signature-local.inc",
|
||||
"contentSignatureLocalRoot",
|
||||
"content-signature-local.crt",
|
||||
"contentSignatureLocalRoots",
|
||||
["content-signature-local.pem"],
|
||||
),
|
||||
]
|
||||
|
||||
for header, array_name, cert in headers_arrays_certs:
|
||||
for header, array_name, certs in headers_arrays_certs:
|
||||
GeneratedFile(
|
||||
header, script="gen_cert_header.py", entry_point=array_name, inputs=[cert]
|
||||
header,
|
||||
script="gen_cert_header.py",
|
||||
entry_point="generate",
|
||||
inputs=certs,
|
||||
flags=[array_name],
|
||||
)
|
||||
|
|
|
@ -163,10 +163,11 @@ def getCert(subject, keyName, issuerName, ee, issuerKey="", validity=""):
|
|||
return pycert.Certificate(certSpecificationStream)
|
||||
|
||||
|
||||
def coseAlgorithmToSignatureParams(coseAlgorithm, issuerName, certValidity):
|
||||
"""Given a COSE algorithm ('ES256', 'ES384', 'ES512') and an issuer
|
||||
name, returns a (algorithm id, pykey.ECCKey, encoded certificate)
|
||||
triplet for use with coseSig.
|
||||
def coseAlgorithmToSignatureParams(coseAlgorithm, issuerName, issuerKey, certValidity):
|
||||
"""Given a COSE algorithm ('ES256', 'ES384', 'ES512'), an issuer
|
||||
name, the name of the issuer's key, and a validity period, returns a
|
||||
(algorithm id, pykey.ECCKey, encoded certificate) triplet for use
|
||||
with coseSig.
|
||||
"""
|
||||
if coseAlgorithm == "ES256":
|
||||
keyName = "secp256r1"
|
||||
|
@ -186,7 +187,7 @@ def coseAlgorithmToSignatureParams(coseAlgorithm, issuerName, certValidity):
|
|||
keyName,
|
||||
issuerName,
|
||||
True,
|
||||
"default",
|
||||
issuerKey,
|
||||
certValidity,
|
||||
)
|
||||
return (algId, key, ee.toDER())
|
||||
|
@ -197,6 +198,7 @@ def signZip(
|
|||
outputFile,
|
||||
issuerName,
|
||||
rootName,
|
||||
rootKey,
|
||||
certValidity,
|
||||
manifestHashes,
|
||||
signatureHashes,
|
||||
|
@ -205,14 +207,15 @@ def signZip(
|
|||
emptySignerInfos,
|
||||
headerPaddingFactor,
|
||||
):
|
||||
"""Given a directory containing the files to package up,
|
||||
an output filename to write to, the name of the issuer of
|
||||
the signing certificate, the name of trust anchor, a list of hash algorithms
|
||||
to use in the manifest file, a similar list for the signature file,
|
||||
a similar list for the pkcs#7 signature, a list of COSE signature algorithms
|
||||
to include, whether the pkcs#7 signer info should be kept empty, and how
|
||||
many MB to pad the manifests by (to test handling large manifest files),
|
||||
packages up the files in the directory and creates the output as
|
||||
"""Given a directory containing the files to package up, an output
|
||||
filename to write to, the name of the issuer of the signing
|
||||
certificate, the name of trust anchor, the name of the trust
|
||||
anchor's key, a list of hash algorithms to use in the manifest file,
|
||||
a similar list for the signature file, a similar list for the pkcs#7
|
||||
signature, a list of COSE signature algorithms to include, whether
|
||||
the pkcs#7 signer info should be kept empty, and how many MB to pad
|
||||
the manifests by (to test handling large manifest files), packages
|
||||
up the files in the directory and creates the output as
|
||||
appropriate."""
|
||||
# The header of each manifest starts with the magic string
|
||||
# 'Manifest-Version: 1.0' and ends with a blank line. There can be
|
||||
|
@ -229,6 +232,7 @@ def signZip(
|
|||
# Append the blank line.
|
||||
mfEntries.append("")
|
||||
|
||||
issuerKey = rootKey
|
||||
with zipfile.ZipFile(outputFile, "w", zipfile.ZIP_DEFLATED) as outZip:
|
||||
for fullPath, internalPath in walkDirectory(appDirectory):
|
||||
with open(fullPath, "rb") as inputFile:
|
||||
|
@ -248,13 +252,14 @@ def signZip(
|
|||
intermediates = []
|
||||
coseIssuerName = issuerName
|
||||
if rootName:
|
||||
issuerKey = "default"
|
||||
coseIssuerName = "xpcshell signed app test issuer"
|
||||
intermediate = getCert(
|
||||
coseIssuerName,
|
||||
"default",
|
||||
issuerKey,
|
||||
rootName,
|
||||
False,
|
||||
"",
|
||||
rootKey,
|
||||
certValidity,
|
||||
)
|
||||
intermediate = intermediate.toDER()
|
||||
|
@ -263,6 +268,7 @@ def signZip(
|
|||
coseAlgorithmToSignatureParams(
|
||||
coseAlgorithm,
|
||||
coseIssuerName,
|
||||
issuerKey,
|
||||
certValidity,
|
||||
)
|
||||
for coseAlgorithm in coseAlgorithms
|
||||
|
@ -294,6 +300,8 @@ def signZip(
|
|||
+ "subject:xpcshell signed app test signer\n"
|
||||
+ "extension:keyUsage:digitalSignature"
|
||||
)
|
||||
if issuerKey != "default":
|
||||
cmsSpecification += "\nissuerKey:%s" % issuerKey
|
||||
if certValidity:
|
||||
cmsSpecification += "\nvalidity:%s" % certValidity
|
||||
cmsSpecificationStream = StringIO()
|
||||
|
@ -356,6 +364,13 @@ def main(outputFile, appPath, *args):
|
|||
default="xpcshell signed apps test root",
|
||||
)
|
||||
parser.add_argument("-r", "--root", action="store", help="Root name", default="")
|
||||
parser.add_argument(
|
||||
"-k",
|
||||
"--root-key",
|
||||
action="store",
|
||||
help="Root key name",
|
||||
default="default",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cert-validity",
|
||||
action="store",
|
||||
|
@ -416,6 +431,7 @@ def main(outputFile, appPath, *args):
|
|||
outputFile,
|
||||
parsed.issuer,
|
||||
parsed.root,
|
||||
parsed.root_key,
|
||||
parsed.cert_validity,
|
||||
[hashNameToFunctionAndIdentifier(h) for h in parsed.manifest_hash],
|
||||
[hashNameToFunctionAndIdentifier(h) for h in parsed.signature_hash],
|
||||
|
|
|
@ -1222,6 +1222,17 @@ add_test(function () {
|
|||
);
|
||||
});
|
||||
|
||||
add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function () {
|
||||
certdb.openSignedAppFileAsync(
|
||||
Ci.nsIX509CertDB.AppXPCShellRoot,
|
||||
original_app_path("alternate-root"),
|
||||
check_open_result("alternate-root", Cr.NS_OK, [
|
||||
Ci.nsIAppSignatureInfo.COSE_WITH_SHA256,
|
||||
Ci.nsIAppSignatureInfo.PKCS7_WITH_SHA256,
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
// TODO: tampered MF, tampered SF
|
||||
// TODO: too-large MF, too-large RSA, too-large SF
|
||||
// TODO: MF and SF that end immediately after the last main header
|
||||
|
|
Двоичный файл не отображается.
|
@ -72,6 +72,7 @@ def SignedAppFile(name, flags, app_directory="app/"):
|
|||
# SignedAppFile('huge_manifest.zip', ['-p', 'sha256', '--pad-headers', '10'])
|
||||
# SignedAppFile('validity_expired.zip', ['-c', 'ES256', '-p', 'sha256', '--cert-validity', '19700101-19701212'])
|
||||
# SignedAppFile('validity_not_yet_valid.zip', ['-c', 'ES256', '-p', 'sha256', '--cert-validity', '99990101-99991212'])
|
||||
# SignedAppFile('alternate-root.zip', ['-k', 'alternate', '-c', 'ES256', '-p', 'sha256'])
|
||||
|
||||
# To generate a new entry, add SignedAppFile, run mach build and copy from
|
||||
# objdir/_tests/xpcshell/security/manager/ssl/tests/unit/test_signed_apps/
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFjCCAf6gAwIBAgIUS8131omRM4MvwUT2QslgfFAdPWEwDQYJKoZIhvcNAQEL
|
||||
BQAwKTEnMCUGA1UEAwweeHBjc2hlbGwgc2lnbmVkIGFwcHMgdGVzdCByb290MCIY
|
||||
DzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAxMDEwMDAwMDBaMCkxJzAlBgNVBAMMHnhw
|
||||
Y3NoZWxsIHNpZ25lZCBhcHBzIHRlc3Qgcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl
|
||||
qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg
|
||||
w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx
|
||||
V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1
|
||||
MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs
|
||||
vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMyMDAwDAYDVR0TBAUw
|
||||
AwEB/zALBgNVHQ8EBAMCAiQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcN
|
||||
AQELBQADggEBAKn3fUSM5GDCAsllFSjGiGoj7rEpAHd+wZ2kSJMrVHsmUyXrrETZ
|
||||
X27wVQEdrUzIhlrvNkPFElSXkL/bGcbcKqH1g79i+c6KkuLn4wgmCkHOppvNyNkE
|
||||
Z+Xnk/V+l9jKTtxC1jSR0xcFUUa7If9z5aIRncBDkcXi+NoB4Rp/XvmbU4Hh9YLa
|
||||
2X9iHuOW3SylS1Vkj8Huj97T0cth9emfw3K8gUOY8DQ7Ij9d0Wej57Hx+r5Ai+Ok
|
||||
4cb5NralLdDFdPCDSdluVIvxBU3CLqPXUWsH7mvp92039pXBwZzC37dHAXMDa5TF
|
||||
xrCV3aqI5tLVInOe4haraJ9Eq7wdtIdJ1MY=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFjCCAf6gAwIBAgIUS8131omRM4MvwUT2QslgfFAdPWEwDQYJKoZIhvcNAQEL
|
||||
BQAwKTEnMCUGA1UEAwweeHBjc2hlbGwgc2lnbmVkIGFwcHMgdGVzdCByb290MCIY
|
||||
DzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAxMDEwMDAwMDBaMCkxJzAlBgNVBAMMHnhw
|
||||
Y3NoZWxsIHNpZ25lZCBhcHBzIHRlc3Qgcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBAMF1xlJmCZ93CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1B
|
||||
yMJJisSjs8H2FIf0G2mJQb2ApRw8EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujz
|
||||
byPF2YMTud+vN4NF2s5R1Nbc0qbLPMcG680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+
|
||||
yElEWQvFo+pJ/ZOx11NAXxdzdpmVhmYlR5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2
|
||||
ppzSg3UTH5MrEozihvp9JRwGKtJ+8Bbxh83VToMrNbiTD3S6kKqLx2FnJCqx/W1i
|
||||
FA0YxMC4xo/DdIRXMkrX3obmVS8dHhkdcSFo07sCAwEAAaMyMDAwDAYDVR0TBAUw
|
||||
AwEB/zALBgNVHQ8EBAMCAiQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcN
|
||||
AQELBQADggEBAI7dEL2qcnWE2yRYP/pnOsopc37UJcN8w+7csUb+6vyBIc0cujZJ
|
||||
zfywE/fq8LxMuBPHbeePl3CTwFFw78T5VHe5pzUZIDZHQ/xtkeQDZjhas4dJzdZW
|
||||
zmEbcOK1anyJbjyFX06Wi6G4IdyqmeR2GAcsSA5crfxrNo0mBE+fNgQOKkywQXtS
|
||||
T4HQuEZCjcn4ZnPeB+M+W/AP+rToKYpCfieF8/Lc4a2bK7JX8m15NH1UV1ZEanHn
|
||||
mBUBgJ425/fFzb46ejOCLvtFzmqHue4iuN2oDQqE8IvNIV5bD4UwYd86afRNMxQF
|
||||
RjoDUfBTJnzWLErBuzOGOhQl36blaqwsBxg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,8 @@
|
|||
issuer:xpcshell signed apps test root
|
||||
subject:xpcshell signed apps test root
|
||||
issuerKey:alternate
|
||||
subjectKey:alternate
|
||||
validity:20150101-20350101
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:keyEncipherment,keyCertSign
|
||||
extension:extKeyUsage:codeSigning
|
|
@ -7,7 +7,6 @@ import os
|
|||
from mach.decorators import Command, CommandArgument
|
||||
from mach.util import UserError
|
||||
from mozpack.files import FileFinder
|
||||
from mozpack.path import basedir
|
||||
|
||||
|
||||
def run_module_main_on(module, input_filename, output_is_binary):
|
||||
|
@ -65,17 +64,6 @@ def is_specification_file(filename):
|
|||
)
|
||||
|
||||
|
||||
def is_excluded_directory(directory, exclusions):
|
||||
"""Returns True if the given directory is in or is a
|
||||
subdirectory of a directory in the list of exclusions and
|
||||
False otherwise."""
|
||||
|
||||
for exclusion in exclusions:
|
||||
if directory.startswith(exclusion):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@Command(
|
||||
"generate-test-certs",
|
||||
category="devenv",
|
||||
|
@ -129,12 +117,9 @@ def find_all_specifications(command_context):
|
|||
"testing/xpcshell/moz-http2",
|
||||
"toolkit/mozapps/extensions/test/xpcshell/data/productaddons",
|
||||
]
|
||||
exclusions = ["security/manager/ssl/tests/unit/test_signed_apps"]
|
||||
finder = FileFinder(command_context.topsrcdir)
|
||||
for inclusion_path in inclusions:
|
||||
for f, _ in finder.find(inclusion_path):
|
||||
if basedir(f, exclusions):
|
||||
continue
|
||||
if is_specification_file(f):
|
||||
specifications.append(os.path.join(command_context.topsrcdir, f))
|
||||
return specifications
|
||||
|
|
Загрузка…
Ссылка в новой задаче