Import from CS git
This commit is contained in:
parent
d528a029fe
commit
de04ed802b
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,5 +2,5 @@ SOURCES/cbindgen-vendor.tar.xz
|
||||
SOURCES/nspr-4.36.0-2.el8_2.src.rpm
|
||||
SOURCES/nss-3.112.0-1.el9_4.src.rpm
|
||||
SOURCES/nss-3.112.0-4.el8_2.src.rpm
|
||||
SOURCES/thunderbird-140.4.0esr.processed-source.tar.xz
|
||||
SOURCES/thunderbird-langpacks-140.4.0esr-20251013.tar.xz
|
||||
SOURCES/thunderbird-140.5.0esr.processed-source.tar.xz
|
||||
SOURCES/thunderbird-langpacks-140.5.0esr-20251111.tar.xz
|
||||
|
||||
@ -2,5 +2,5 @@ bc4adac8f38f5103d8f88564a1545063dd8d6402 SOURCES/cbindgen-vendor.tar.xz
|
||||
0d0ddbd2a73340b3cbc977997f57222946b1e775 SOURCES/nspr-4.36.0-2.el8_2.src.rpm
|
||||
fd3879b176634d66f8ef64d18fdaeec98e140c23 SOURCES/nss-3.112.0-1.el9_4.src.rpm
|
||||
c3f0aaef37972107442e2796efad71be3a98ce3c SOURCES/nss-3.112.0-4.el8_2.src.rpm
|
||||
a9ee21c5a1c914e16c778da25383aa6b6d4a1b9f SOURCES/thunderbird-140.4.0esr.processed-source.tar.xz
|
||||
11d24d1b3a0f5f19c97012a9cc6da7650e73276e SOURCES/thunderbird-langpacks-140.4.0esr-20251013.tar.xz
|
||||
d520f59fc94847639c7fad352c70806f1e9387ea SOURCES/thunderbird-140.5.0esr.processed-source.tar.xz
|
||||
93aae73f4a8d28e76adcb9298fb3074fa86aa6f7 SOURCES/thunderbird-langpacks-140.5.0esr-20251111.tar.xz
|
||||
|
||||
59
SOURCES/thunderbird-adapt-ml-dsa-support-to-rhel-nss.patch
Normal file
59
SOURCES/thunderbird-adapt-ml-dsa-support-to-rhel-nss.patch
Normal file
@ -0,0 +1,59 @@
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixnss.cpp b/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
index 31aa1ddd67..93ab402bfd 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
@@ -303,6 +303,28 @@ DigestBufNSS(Input item,
|
||||
return Success;
|
||||
}
|
||||
|
||||
+static SECOidTag
|
||||
+findOIDByName(const char *cipherString)
|
||||
+{
|
||||
+ SECOidTag tag;
|
||||
+ SECOidData *oid;
|
||||
+
|
||||
+ for (int i = 1; ; i++) {
|
||||
+ SECOidTag tag = static_cast<SECOidTag>(i);
|
||||
+ oid = SECOID_FindOIDByTag(tag);
|
||||
+
|
||||
+ if (oid == NULL) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (strcasecmp(oid->desc, cipherString) == 0) {
|
||||
+ return tag;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return SEC_OID_UNKNOWN;
|
||||
+}
|
||||
+
|
||||
Result
|
||||
VerifyMLDSASignedDataNSS(Input data,
|
||||
Input signature,
|
||||
@@ -323,17 +345,14 @@ VerifyMLDSASignedDataNSS(Input data,
|
||||
SECItem dataItem(UnsafeMapInputToSECItem(data));
|
||||
CK_MECHANISM_TYPE mechanism;
|
||||
|
||||
- switch (pubk->u.mldsa.paramSet) {
|
||||
- case SEC_OID_ML_DSA_44:
|
||||
- case SEC_OID_ML_DSA_65:
|
||||
- case SEC_OID_ML_DSA_87:
|
||||
- mechanism = CKM_ML_DSA;
|
||||
- signaturePolicyTag = pubk->u.mldsa.paramSet;
|
||||
- hashPolicyTag = SEC_OID_UNKNOWN;
|
||||
- break;
|
||||
- default:
|
||||
- return Result::ERROR_UNSUPPORTED_KEYALG;
|
||||
- break;
|
||||
+ if (pubk->u.mldsa.params == findOIDByName("ML-DSA-44") ||
|
||||
+ pubk->u.mldsa.params == findOIDByName("ML-DSA-65") ||
|
||||
+ pubk->u.mldsa.params == findOIDByName("ML-DSA-87")) {
|
||||
+ hashPolicyTag = SEC_OID_UNKNOWN;
|
||||
+ mechanism = CKM_ML_DSA;
|
||||
+ signaturePolicyTag = pubk->u.mldsa.params;
|
||||
+ } else {
|
||||
+ return Result::ERROR_UNSUPPORTED_KEYALG;
|
||||
}
|
||||
|
||||
SECOidTag policyTags[2] = {signaturePolicyTag, hashPolicyTag};
|
||||
@ -0,0 +1,323 @@
|
||||
diff --git a/toolkit/components/certviewer/content/certDecoder.mjs b/toolkit/components/certviewer/content/certDecoder.mjs
|
||||
--- a/toolkit/components/certviewer/content/certDecoder.mjs
|
||||
+++ b/toolkit/components/certviewer/content/certDecoder.mjs
|
||||
@@ -5,10 +5,11 @@
|
||||
import {
|
||||
Certificate,
|
||||
ECNamedCurves,
|
||||
ECPublicKey,
|
||||
RSAPublicKey,
|
||||
+ MLDSAPublicKey,
|
||||
} from "./vendor/pkijs.js";
|
||||
|
||||
const getTimeZone = () => {
|
||||
let timeZone = new Date().toString().match(/\(([A-Za-z\s].*)\)/);
|
||||
if (timeZone === null) {
|
||||
@@ -45,10 +46,19 @@
|
||||
x, // x coordinate
|
||||
y, // y coordinate
|
||||
xy: `04:${x}:${y}`, // 04 (uncompressed) public key
|
||||
};
|
||||
}
|
||||
+ if (publicKey instanceof MLDSAPublicKey) {
|
||||
+ let keyHex = publicKey.rhoT1.valueBlock.valueHex;
|
||||
+ let keyBytes = new Uint8Array(keyHex);
|
||||
+ return {
|
||||
+ kty: publicKey.alg,
|
||||
+ keysize: keyBytes.length,
|
||||
+ rhoT1: hashify(keyHex),
|
||||
+ };
|
||||
+ }
|
||||
return { kty: "Unknown" };
|
||||
};
|
||||
|
||||
const getX509Ext = (extensions, v) => {
|
||||
for (var extension in extensions) {
|
||||
@@ -1132,10 +1142,13 @@
|
||||
"2.16.840.1.101.3.4.3.2": "DSA with SHA-256",
|
||||
"1.2.840.10045.4.1": "ECDSA with SHA-1",
|
||||
"1.2.840.10045.4.3.2": "ECDSA with SHA-256",
|
||||
"1.2.840.10045.4.3.3": "ECDSA with SHA-384",
|
||||
"1.2.840.10045.4.3.4": "ECDSA with SHA-512",
|
||||
+ "2.16.840.1.101.3.4.3.17": "ML-DSA-44",
|
||||
+ "2.16.840.1.101.3.4.3.18": "ML-DSA-65",
|
||||
+ "2.16.840.1.101.3.4.3.19": "ML-DSA-87",
|
||||
},
|
||||
|
||||
aia: {
|
||||
"1.3.6.1.5.5.7.48.1": "Online Certificate Status Protocol (OCSP)",
|
||||
"1.3.6.1.5.5.7.48.2": "CA Issuers",
|
||||
diff --git a/toolkit/components/certviewer/content/certviewer.mjs b/toolkit/components/certviewer/content/certviewer.mjs
|
||||
--- a/toolkit/components/certviewer/content/certviewer.mjs
|
||||
+++ b/toolkit/components/certviewer/content/certviewer.mjs
|
||||
@@ -74,10 +74,23 @@
|
||||
}
|
||||
}
|
||||
return result ? result : false;
|
||||
};
|
||||
|
||||
+const getMLDSASecurityLevel = signatureName => {
|
||||
+ switch (signatureName) {
|
||||
+ case "ML-DSA-44":
|
||||
+ return "Level 2 (NIST)";
|
||||
+ case "ML-DSA-65":
|
||||
+ return "Level 3 (NIST)";
|
||||
+ case "ML-DSA-87":
|
||||
+ return "Level 5 (NIST)";
|
||||
+ default:
|
||||
+ return null;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
export const adjustCertInformation = cert => {
|
||||
let certItems = [];
|
||||
let tabName = cert?.subject?.cn || "";
|
||||
if (cert && !tabName) {
|
||||
// No common name, use the value of the last item in the cert's entries.
|
||||
@@ -173,10 +186,15 @@
|
||||
createEntryItem("key-size", cert.subjectPublicKeyInfo.keysize),
|
||||
createEntryItem("curve", cert.subjectPublicKeyInfo.crv),
|
||||
createEntryItem("public-value", cert.subjectPublicKeyInfo.xy, true),
|
||||
createEntryItem("exponent", cert.subjectPublicKeyInfo.e),
|
||||
createEntryItem("modulus", cert.subjectPublicKeyInfo.n, true),
|
||||
+ createEntryItem(
|
||||
+ "mldsa-public-value",
|
||||
+ cert.subjectPublicKeyInfo.rhoT1,
|
||||
+ true
|
||||
+ ),
|
||||
].filter(elem => elem != null);
|
||||
}
|
||||
return items;
|
||||
},
|
||||
certItems,
|
||||
@@ -190,14 +208,23 @@
|
||||
createEntryItem("serial-number", cert.serialNumber, true),
|
||||
createEntryItem(
|
||||
"signature-algorithm",
|
||||
cert.signature ? cert.signature.name : null
|
||||
),
|
||||
+ ];
|
||||
+
|
||||
+ const secLvl = getMLDSASecurityLevel(cert.signature?.name);
|
||||
+ if (secLvl) {
|
||||
+ items.push(createEntryItem("security-level", secLvl));
|
||||
+ }
|
||||
+
|
||||
+ items.push(
|
||||
createEntryItem("version", cert.version),
|
||||
- createEntryItem("download", cert.files ? cert.files.pem : null),
|
||||
- ].filter(elem => elem != null);
|
||||
- return items;
|
||||
+ createEntryItem("download", cert.files ? cert.files.pem : null)
|
||||
+ );
|
||||
+
|
||||
+ return items.filter(elem => elem != null);
|
||||
},
|
||||
certItems,
|
||||
"miscellaneous",
|
||||
false
|
||||
);
|
||||
diff --git a/toolkit/components/certviewer/content/vendor/pkijs.js b/toolkit/components/certviewer/content/vendor/pkijs.js
|
||||
--- a/toolkit/components/certviewer/content/vendor/pkijs.js
|
||||
+++ b/toolkit/components/certviewer/content/vendor/pkijs.js
|
||||
@@ -8609,10 +8609,90 @@
|
||||
this.publicExponent = new Integer({ valueHex: stringToArrayBuffer(fromBase64(json.e, true)).slice(0, 3) });
|
||||
}
|
||||
}
|
||||
RSAPublicKey.CLASS_NAME = "RSAPublicKey";
|
||||
|
||||
+/* @see https://www.ietf.org/archive/id/draft-ietf-lamps-dilithium-certificates-11.html */
|
||||
+const RHO_T1 = "rhoT1";
|
||||
+const ALG = "alg";
|
||||
+const CLEAR_PROPS_MLDSA = [RHO_T1, ALG];
|
||||
+const MLDSA_MIN_LENGTH = 32;
|
||||
+class MLDSAPublicKey extends PkiObject {
|
||||
+ constructor(parameters = {}) {
|
||||
+ super();
|
||||
+
|
||||
+ this.rhoT1 = getParametersValue(parameters, RHO_T1, MLDSAPublicKey.defaultValues(RHO_T1));
|
||||
+ this.alg = getParametersValue(parameters, ALG, MLDSAPublicKey.defaultValues(ALG));
|
||||
+
|
||||
+ if (parameters.json) {
|
||||
+ this.fromJSON(parameters.json);
|
||||
+ }
|
||||
+
|
||||
+ if (parameters.schema) {
|
||||
+ this.fromSchema(parameters.schema);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static defaultValues(memberName) {
|
||||
+ switch (memberName) {
|
||||
+ case RHO_T1:
|
||||
+ return new BitString();
|
||||
+ case ALG:
|
||||
+ return "";
|
||||
+ default:
|
||||
+ return super.defaultValues(memberName);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static schema(parameters = {}) {
|
||||
+ const names = getParametersValue(parameters, "names", {});
|
||||
+ return new BitString({ name: names.rhoT1 || RHO_T1 });
|
||||
+ }
|
||||
+
|
||||
+ fromSchema(schema) {
|
||||
+ clearProps(schema, CLEAR_PROPS_MLDSA);
|
||||
+
|
||||
+ const asn1 = compareSchema(schema, schema, MLDSAPublicKey.schema({
|
||||
+ names: { rhoT1: RHO_T1 }
|
||||
+ }));
|
||||
+
|
||||
+ AsnError.assertSchema(asn1, this.className);
|
||||
+
|
||||
+ const bitString = asn1.result.rhoT1;
|
||||
+ const length = bitString.valueBlock.valueHexView.length;
|
||||
+
|
||||
+ if (length < MLDSA_MIN_LENGTH || (length - MLDSA_MIN_LENGTH) % 320 !== 0) {
|
||||
+ throw new Error(`Invalid ML-DSA key length: ${length} bytes`);
|
||||
+ }
|
||||
+
|
||||
+ this.rhoT1 = bitString;
|
||||
+ }
|
||||
+
|
||||
+ toSchema() {
|
||||
+ return this.rhoT1;
|
||||
+ }
|
||||
+
|
||||
+ toJSON() {
|
||||
+ return {
|
||||
+ rhoT1: Convert.ToBase64Url(this.rhoT1.valueBlock.valueHexView),
|
||||
+ alg: this.alg
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ fromJSON(json) {
|
||||
+ ParameterError.assert("json", json, "rhoT1");
|
||||
+ const rawBuffer = stringToArrayBuffer(fromBase64(json.rhoT1, true));
|
||||
+
|
||||
+ if (rawBuffer.byteLength < MLDSA_MIN_LENGTH || (rawBuffer.byteLength - MLDSA_MIN_LENGTH) % 320 !== 0) {
|
||||
+ throw new Error(`Invalid ML-DSA key length: ${rawBuffer.byteLength} bytes`);
|
||||
+ }
|
||||
+
|
||||
+ this.rhoT1 = new BitString({ valueHex: rawBuffer });
|
||||
+ }
|
||||
+}
|
||||
+MLDSAPublicKey.CLASS_NAME = "MLDSAPublicKey";
|
||||
+
|
||||
const ALGORITHM$1 = "algorithm";
|
||||
const SUBJECT_PUBLIC_KEY = "subjectPublicKey";
|
||||
const CLEAR_PROPS$1a = [ALGORITHM$1, SUBJECT_PUBLIC_KEY];
|
||||
class PublicKeyInfo extends PkiObject {
|
||||
constructor(parameters = {}) {
|
||||
@@ -8657,10 +8737,22 @@
|
||||
catch (ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
+ case "2.16.840.1.101.3.4.3.17":
|
||||
+ /* Already a bitstring */
|
||||
+ this._parsedKey = new MLDSAPublicKey({ rhoT1: this.subjectPublicKey, alg: "ML-DSA-44" });
|
||||
+ break;
|
||||
+ case "2.16.840.1.101.3.4.3.18":
|
||||
+ /* Already a bitstring */
|
||||
+ this._parsedKey = new MLDSAPublicKey({ rhoT1: this.subjectPublicKey, alg: "ML-DSA-65" });
|
||||
+ break;
|
||||
+ case "2.16.840.1.101.3.4.3.19":
|
||||
+ /* Already a bitstring */
|
||||
+ this._parsedKey = new MLDSAPublicKey({ rhoT1: this.subjectPublicKey, alg: "ML-DSA-87" });
|
||||
+ break;
|
||||
}
|
||||
this._parsedKey || (this._parsedKey = null);
|
||||
}
|
||||
return this._parsedKey || undefined;
|
||||
}
|
||||
@@ -8724,10 +8816,19 @@
|
||||
jwk.kty = "EC";
|
||||
break;
|
||||
case "1.2.840.113549.1.1.1":
|
||||
jwk.kty = "RSA";
|
||||
break;
|
||||
+ case "2.16.840.1.101.3.4.3.17":
|
||||
+ jwk.kty = "ML-DSA-44";
|
||||
+ break;
|
||||
+ case "2.16.840.1.101.3.4.3.18":
|
||||
+ jwk.kty = "ML-DSA-65";
|
||||
+ break;
|
||||
+ case "2.16.840.1.101.3.4.3.19":
|
||||
+ jwk.kty = "ML-DSA-87";
|
||||
+ break;
|
||||
}
|
||||
const publicKeyJWK = this.parsedKey.toJSON();
|
||||
Object.assign(jwk, publicKeyJWK);
|
||||
return jwk;
|
||||
}
|
||||
@@ -8746,10 +8847,31 @@
|
||||
this.algorithm = new AlgorithmIdentifier({
|
||||
algorithmId: "1.2.840.113549.1.1.1",
|
||||
algorithmParams: new Null()
|
||||
});
|
||||
break;
|
||||
+ case "ML-DSA-44":
|
||||
+ this.parsedKey = new MLDSAPublicKey({ json });
|
||||
+ this.algorithm = new AlgorithmIdentifier({
|
||||
+ algorithmId: "2.16.840.1.101.3.4.3.17",
|
||||
+ algorithmParams: new Null()
|
||||
+ });
|
||||
+ break;
|
||||
+ case "ML-DSA-65":
|
||||
+ this.parsedKey = new MLDSAPublicKey({ json });
|
||||
+ this.algorithm = new AlgorithmIdentifier({
|
||||
+ algorithmId: "2.16.840.1.101.3.4.3.18",
|
||||
+ algorithmParams: new Null()
|
||||
+ });
|
||||
+ break;
|
||||
+ case "ML-DSA-87":
|
||||
+ this.parsedKey = new MLDSAPublicKey({ json });
|
||||
+ this.algorithm = new AlgorithmIdentifier({
|
||||
+ algorithmId: "2.16.840.1.101.3.4.3.19",
|
||||
+ algorithmParams: new Null()
|
||||
+ });
|
||||
+ break;
|
||||
default:
|
||||
throw new Error(`Invalid value for "kty" parameter: ${json.kty}`);
|
||||
}
|
||||
this.subjectPublicKey = new BitString({ valueHex: this.parsedKey.toSchema().toBER(false) });
|
||||
}
|
||||
@@ -24078,6 +24200,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
initCryptoEngine();
|
||||
|
||||
-export { AbstractCryptoEngine, AccessDescription, Accuracy, AlgorithmIdentifier, AltName, ArgumentError, AsnError, AttCertValidityPeriod, Attribute, AttributeCertificateInfoV1, AttributeCertificateInfoV2, AttributeCertificateV1, AttributeCertificateV2, AttributeTypeAndValue, AuthenticatedSafe, AuthorityKeyIdentifier, BasicConstraints, BasicOCSPResponse, CAVersion, CRLBag, CRLDistributionPoints, CertBag, CertID, Certificate, CertificateChainValidationEngine, CertificatePolicies, CertificateRevocationList, CertificateSet, CertificateTemplate, CertificationRequest, ChainValidationCode, ChainValidationError, ContentInfo, CryptoEngine, DigestInfo, DistributionPoint, ECCCMSSharedInfo, ECNamedCurves, ECPrivateKey, ECPublicKey, EncapsulatedContentInfo, EncryptedContentInfo, EncryptedData, EnvelopedData, ExtKeyUsage, Extension, ExtensionValueFactory, Extensions, GeneralName, GeneralNames, GeneralSubtree, HASHED_MESSAGE, HASH_ALGORITHM, Holder, InfoAccess, IssuerAndSerialNumber, IssuerSerial, IssuingDistributionPoint, KEKIdentifier, KEKRecipientInfo, KeyAgreeRecipientIdentifier, KeyAgreeRecipientInfo, KeyBag, KeyTransRecipientInfo, MICROS, MILLIS, MacData, MessageImprint, NameConstraints, OCSPRequest, OCSPResponse, ObjectDigestInfo, OriginatorIdentifierOrKey, OriginatorInfo, OriginatorPublicKey, OtherCertificateFormat, OtherKeyAttribute, OtherPrimeInfo, OtherRecipientInfo, OtherRevocationInfoFormat, PBES2Params, PBKDF2Params, PFX, PKCS8ShroudedKeyBag, PKIStatus, PKIStatusInfo, POLICY_IDENTIFIER, POLICY_QUALIFIERS, ParameterError, PasswordRecipientinfo, PkiObject, PolicyConstraints, PolicyInformation, PolicyMapping, PolicyMappings, PolicyQualifierInfo, PrivateKeyInfo, PrivateKeyUsagePeriod, PublicKeyInfo, QCStatement, QCStatements, RDN, RSAESOAEPParams, RSAPrivateKey, RSAPublicKey, RSASSAPSSParams, RecipientEncryptedKey, RecipientEncryptedKeys, RecipientIdentifier, RecipientInfo, RecipientKeyIdentifier, RelativeDistinguishedNames, Request, ResponseBytes, ResponseData, RevocationInfoChoices, RevokedCertificate, SECONDS, SafeBag, SafeBagValueFactory, SafeContents, SecretBag, Signature, SignedAndUnsignedAttributes, SignedCertificateTimestamp, SignedCertificateTimestampList, SignedData, SignedDataVerifyError, SignerInfo, SingleResponse, SubjectDirectoryAttributes, TBSRequest, TSTInfo, TYPE$4 as TYPE, TYPE_AND_VALUES, Time, TimeStampReq, TimeStampResp, TimeType, V2Form, VALUE$5 as VALUE, VALUE_BEFORE_DECODE, checkCA, createCMSECDSASignature, createECDSASignatureFromCMS, engine, getAlgorithmByOID, getAlgorithmParameters, getCrypto, getEngine, getHashAlgorithm, getOIDByAlgorithm, getRandomValues, id_AnyPolicy, id_AuthorityInfoAccess, id_AuthorityKeyIdentifier, id_BaseCRLNumber, id_BasicConstraints, id_CRLBag_X509CRL, id_CRLDistributionPoints, id_CRLNumber, id_CRLReason, id_CertBag_AttributeCertificate, id_CertBag_SDSICertificate, id_CertBag_X509Certificate, id_CertificateIssuer, id_CertificatePolicies, id_ContentType_Data, id_ContentType_EncryptedData, id_ContentType_EnvelopedData, id_ContentType_SignedData, id_ExtKeyUsage, id_FreshestCRL, id_InhibitAnyPolicy, id_InvalidityDate, id_IssuerAltName, id_IssuingDistributionPoint, id_KeyUsage, id_MicrosoftAppPolicies, id_MicrosoftCaVersion, id_MicrosoftCertTemplateV1, id_MicrosoftCertTemplateV2, id_MicrosoftPrevCaCertHash, id_NameConstraints, id_PKIX_OCSP_Basic, id_PolicyConstraints, id_PolicyMappings, id_PrivateKeyUsagePeriod, id_QCStatements, id_SignedCertificateTimestampList, id_SubjectAltName, id_SubjectDirectoryAttributes, id_SubjectInfoAccess, id_SubjectKeyIdentifier, id_ad, id_ad_caIssuers, id_ad_ocsp, id_eContentType_TSTInfo, id_pkix, id_sha1, id_sha256, id_sha384, id_sha512, kdf, setEngine, stringPrep, verifySCTsForCertificate };
|
||||
+export { AbstractCryptoEngine, AccessDescription, Accuracy, AlgorithmIdentifier, AltName, ArgumentError, AsnError, AttCertValidityPeriod, Attribute, AttributeCertificateInfoV1, AttributeCertificateInfoV2, AttributeCertificateV1, AttributeCertificateV2, AttributeTypeAndValue, AuthenticatedSafe, AuthorityKeyIdentifier, BasicConstraints, BasicOCSPResponse, CAVersion, CRLBag, CRLDistributionPoints, CertBag, CertID, Certificate, CertificateChainValidationEngine, CertificatePolicies, CertificateRevocationList, CertificateSet, CertificateTemplate, CertificationRequest, ChainValidationCode, ChainValidationError, ContentInfo, CryptoEngine, DigestInfo, DistributionPoint, ECCCMSSharedInfo, ECNamedCurves, ECPrivateKey, ECPublicKey, EncapsulatedContentInfo, EncryptedContentInfo, EncryptedData, EnvelopedData, ExtKeyUsage, Extension, ExtensionValueFactory, Extensions, GeneralName, GeneralNames, GeneralSubtree, HASHED_MESSAGE, HASH_ALGORITHM, Holder, InfoAccess, IssuerAndSerialNumber, IssuerSerial, IssuingDistributionPoint, KEKIdentifier, KEKRecipientInfo, KeyAgreeRecipientIdentifier, KeyAgreeRecipientInfo, KeyBag, KeyTransRecipientInfo, MICROS, MILLIS, MacData, MessageImprint, NameConstraints, OCSPRequest, OCSPResponse, ObjectDigestInfo, OriginatorIdentifierOrKey, OriginatorInfo, OriginatorPublicKey, OtherCertificateFormat, OtherKeyAttribute, OtherPrimeInfo, OtherRecipientInfo, OtherRevocationInfoFormat, PBES2Params, PBKDF2Params, PFX, PKCS8ShroudedKeyBag, PKIStatus, PKIStatusInfo, POLICY_IDENTIFIER, POLICY_QUALIFIERS, ParameterError, PasswordRecipientinfo, PkiObject, PolicyConstraints, PolicyInformation, PolicyMapping, PolicyMappings, PolicyQualifierInfo, PrivateKeyInfo, PrivateKeyUsagePeriod, PublicKeyInfo, QCStatement, QCStatements, RDN, RSAESOAEPParams, RSAPrivateKey, RSAPublicKey, RSASSAPSSParams, RecipientEncryptedKey, RecipientEncryptedKeys, RecipientIdentifier, RecipientInfo, RecipientKeyIdentifier, RelativeDistinguishedNames, Request, ResponseBytes, ResponseData, RevocationInfoChoices, RevokedCertificate, SECONDS, SafeBag, SafeBagValueFactory, SafeContents, SecretBag, Signature, SignedAndUnsignedAttributes, SignedCertificateTimestamp, SignedCertificateTimestampList, SignedData, SignedDataVerifyError, SignerInfo, SingleResponse, SubjectDirectoryAttributes, TBSRequest, TSTInfo, TYPE$4 as TYPE, TYPE_AND_VALUES, Time, TimeStampReq, TimeStampResp, TimeType, V2Form, VALUE$5 as VALUE, VALUE_BEFORE_DECODE, checkCA, createCMSECDSASignature, createECDSASignatureFromCMS, engine, getAlgorithmByOID, getAlgorithmParameters, getCrypto, getEngine, getHashAlgorithm, getOIDByAlgorithm, getRandomValues, id_AnyPolicy, id_AuthorityInfoAccess, id_AuthorityKeyIdentifier, id_BaseCRLNumber, id_BasicConstraints, id_CRLBag_X509CRL, id_CRLDistributionPoints, id_CRLNumber, id_CRLReason, id_CertBag_AttributeCertificate, id_CertBag_SDSICertificate, id_CertBag_X509Certificate, id_CertificateIssuer, id_CertificatePolicies, id_ContentType_Data, id_ContentType_EncryptedData, id_ContentType_EnvelopedData, id_ContentType_SignedData, id_ExtKeyUsage, id_FreshestCRL, id_InhibitAnyPolicy, id_InvalidityDate, id_IssuerAltName, id_IssuingDistributionPoint, id_KeyUsage, id_MicrosoftAppPolicies, id_MicrosoftCaVersion, id_MicrosoftCertTemplateV1, id_MicrosoftCertTemplateV2, id_MicrosoftPrevCaCertHash, id_NameConstraints, id_PKIX_OCSP_Basic, id_PolicyConstraints, id_PolicyMappings, id_PrivateKeyUsagePeriod, id_QCStatements, id_SignedCertificateTimestampList, id_SubjectAltName, id_SubjectDirectoryAttributes, id_SubjectInfoAccess, id_SubjectKeyIdentifier, id_ad, id_ad_caIssuers, id_ad_ocsp, id_eContentType_TSTInfo, id_pkix, id_sha1, id_sha256, id_sha384, id_sha512, kdf, setEngine, stringPrep, verifySCTsForCertificate, MLDSAPublicKey };
|
||||
diff --git a/toolkit/locales/en-US/toolkit/about/certviewer.ftl b/toolkit/locales/en-US/toolkit/about/certviewer.ftl
|
||||
--- a/toolkit/locales/en-US/toolkit/about/certviewer.ftl
|
||||
+++ b/toolkit/locales/en-US/toolkit/about/certviewer.ftl
|
||||
@@ -45,20 +45,22 @@
|
||||
certificate-viewer-organization = Organization
|
||||
certificate-viewer-organizational-unit = Organizational Unit
|
||||
certificate-viewer-policy = Policy
|
||||
certificate-viewer-protocol = Protocol
|
||||
certificate-viewer-public-value = Public Value
|
||||
+certificate-viewer-mldsa-public-value = Public Value
|
||||
certificate-viewer-purposes = Purposes
|
||||
certificate-viewer-qualifier = Qualifier
|
||||
certificate-viewer-qualifiers = Qualifiers
|
||||
certificate-viewer-required = Required
|
||||
certificate-viewer-unsupported = <unsupported>
|
||||
# Inc. means Incorporated, e.g GitHub is incorporated in Delaware
|
||||
certificate-viewer-inc-state-province = Inc. State/Province
|
||||
certificate-viewer-state-province = State/Province
|
||||
certificate-viewer-sha-1 = SHA-1
|
||||
certificate-viewer-sha-256 = SHA-256
|
||||
+certificate-viewer-security-level = Security Level
|
||||
certificate-viewer-serial-number = Serial Number
|
||||
certificate-viewer-signature-algorithm = Signature Algorithm
|
||||
certificate-viewer-signature-scheme = Signature Scheme
|
||||
certificate-viewer-timestamp = Timestamp
|
||||
certificate-viewer-value = Value
|
||||
|
||||
190
SOURCES/thunderbird-add-mlkem768-secp256r1-support.patch
Normal file
190
SOURCES/thunderbird-add-mlkem768-secp256r1-support.patch
Normal file
File diff suppressed because one or more lines are too long
48
SOURCES/thunderbird-enable-ml-dsa-in-manager-ssl.patch
Normal file
48
SOURCES/thunderbird-enable-ml-dsa-in-manager-ssl.patch
Normal file
@ -0,0 +1,48 @@
|
||||
diff --git a/security/manager/ssl/nsNSSCallbacks.cpp b/security/manager/ssl/nsNSSCallbacks.cpp
|
||||
index 2dc48c9f4c..0a7b84d787 100644
|
||||
--- a/security/manager/ssl/nsNSSCallbacks.cpp
|
||||
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
|
||||
@@ -722,6 +722,15 @@ nsCString getSignatureName(uint32_t aSignatureScheme) {
|
||||
case ssl_sig_rsa_pkcs1_sha1md5:
|
||||
signatureName = "RSA-PKCS1-SHA1MD5"_ns;
|
||||
break;
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ signatureName = "ML-DSA-44"_ns;
|
||||
+ break;
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ signatureName = "ML-DSA-65"_ns;
|
||||
+ break;
|
||||
+ case ssl_sig_mldsa87:
|
||||
+ signatureName = "ML-DSA-87"_ns;
|
||||
+ break;
|
||||
// All other groups are not enabled in Firefox. See sEnabledSignatureSchemes
|
||||
// in nsNSSIOLayer.cpp.
|
||||
default:
|
||||
@@ -1061,6 +1070,13 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
glean::ssl::auth_ecdsa_curve_full.AccumulateSingleSample(
|
||||
ECCCurve(channelInfo.authKeyBits));
|
||||
break;
|
||||
+ case ssl_auth_mldsa44:
|
||||
+ case ssl_auth_mldsa65:
|
||||
+ case ssl_auth_mldsa87:
|
||||
+ /* TODO: add auth_mldsa_key_size_full in ssl/metrics.yaml
|
||||
+ glean::ssl::auth_mldsa_key_size_full.AccumulateSingleSample(
|
||||
+ NonECCKeySize(channelInfo.authKeyBits)); */
|
||||
+ break;
|
||||
default:
|
||||
MOZ_CRASH("impossible auth algorithm");
|
||||
break;
|
||||
diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp
|
||||
index b1a5f5c2df..7443011b13 100644
|
||||
--- a/security/manager/ssl/nsNSSIOLayer.cpp
|
||||
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
|
||||
@@ -1300,6 +1300,9 @@ static PRFileDesc* nsSSLIOLayerImportFD(PRFileDesc* fd,
|
||||
// Please change getSignatureName in nsNSSCallbacks.cpp when changing the list
|
||||
// here. See NOTE at SSL_SignatureSchemePrefSet call site.
|
||||
static const SSLSignatureScheme sEnabledSignatureSchemes[] = {
|
||||
+ ssl_sig_mldsa87,
|
||||
+ ssl_sig_mldsa65,
|
||||
+ ssl_sig_mldsa44,
|
||||
ssl_sig_ecdsa_secp256r1_sha256,
|
||||
ssl_sig_ecdsa_secp384r1_sha384,
|
||||
ssl_sig_ecdsa_secp521r1_sha512,
|
||||
@ -0,0 +1,239 @@
|
||||
diff --git a/security/nss/lib/mozpkix/include/pkix/pkixder.h b/security/nss/lib/mozpkix/include/pkix/pkixder.h
|
||||
index ac1ec24393..40eb5027af 100644
|
||||
--- a/security/nss/lib/mozpkix/include/pkix/pkixder.h
|
||||
+++ b/security/nss/lib/mozpkix/include/pkix/pkixder.h
|
||||
@@ -488,7 +488,7 @@ inline Result OptionalExtensions(Reader& input, uint8_t tag,
|
||||
Result DigestAlgorithmIdentifier(Reader& input,
|
||||
/*out*/ DigestAlgorithm& algorithm);
|
||||
|
||||
-enum class PublicKeyAlgorithm { RSA_PKCS1, RSA_PSS, ECDSA };
|
||||
+enum class PublicKeyAlgorithm { RSA_PKCS1, RSA_PSS, ECDSA, MLDSA };
|
||||
|
||||
Result SignatureAlgorithmIdentifierValue(
|
||||
Reader& input,
|
||||
diff --git a/security/nss/lib/mozpkix/include/pkix/pkixnss.h b/security/nss/lib/mozpkix/include/pkix/pkixnss.h
|
||||
index 6711959e71..b87e88a599 100644
|
||||
--- a/security/nss/lib/mozpkix/include/pkix/pkixnss.h
|
||||
+++ b/security/nss/lib/mozpkix/include/pkix/pkixnss.h
|
||||
@@ -50,6 +50,13 @@ Result VerifyECDSASignedDataNSS(Input data, DigestAlgorithm digestAlgorithm,
|
||||
Input signature, Input subjectPublicKeyInfo,
|
||||
void* pkcs11PinArg);
|
||||
|
||||
+// Verifies the ML-DSA signature on the given data using the given ML-DSA
|
||||
+// public key
|
||||
+Result VerifyMLDSASignedDataNSS(Input data,
|
||||
+ Input signature,
|
||||
+ Input subjectPublicKeyInfo,
|
||||
+ void* pkcs11PinArg);
|
||||
+
|
||||
// Computes the digest of the given data using the given digest algorithm.
|
||||
//
|
||||
// item contains the data to hash.
|
||||
diff --git a/security/nss/lib/mozpkix/include/pkix/pkixtypes.h b/security/nss/lib/mozpkix/include/pkix/pkixtypes.h
|
||||
index 6a07d6e885..f24bd546e4 100644
|
||||
--- a/security/nss/lib/mozpkix/include/pkix/pkixtypes.h
|
||||
+++ b/security/nss/lib/mozpkix/include/pkix/pkixtypes.h
|
||||
@@ -334,6 +334,10 @@ class TrustDomain {
|
||||
Input signature,
|
||||
Input subjectPublicKeyInfo) = 0;
|
||||
|
||||
+ virtual Result VerifyMLDSASignedData(Input data,
|
||||
+ Input signature,
|
||||
+ Input subjectPublicKeyInfo) = 0;
|
||||
+
|
||||
// Check that the validity duration is acceptable.
|
||||
//
|
||||
// Return Success if the validity duration is acceptable,
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixc.cpp b/security/nss/lib/mozpkix/lib/pkixc.cpp
|
||||
index 5dea13c43e..f797a3b3a1 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixc.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixc.cpp
|
||||
@@ -143,6 +143,15 @@ class CodeSigningTrustDomain final : public TrustDomain {
|
||||
subjectPublicKeyInfo, nullptr);
|
||||
}
|
||||
|
||||
+ virtual Result VerifyMLDSASignedData(Input data,
|
||||
+ Input signature,
|
||||
+ Input subjectPublicKeyInfo) override {
|
||||
+ return VerifyMLDSASignedDataNSS(data,
|
||||
+ signature,
|
||||
+ subjectPublicKeyInfo,
|
||||
+ nullptr);
|
||||
+ }
|
||||
+
|
||||
virtual Result CheckValidityIsAcceptable(Time notBefore, Time notAfter,
|
||||
EndEntityOrCA endEntityOrCA,
|
||||
KeyPurposeId keyPurpose) override {
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixcheck.cpp b/security/nss/lib/mozpkix/lib/pkixcheck.cpp
|
||||
index 8b7e1bf73e..4ce73f3944 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixcheck.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixcheck.cpp
|
||||
@@ -118,6 +118,9 @@ CheckSignatureAlgorithm(TrustDomain& trustDomain,
|
||||
// for any curve that we support, the chances of us encountering a curve
|
||||
// during path building is too low to be worth bothering with.
|
||||
break;
|
||||
+
|
||||
+ case der::PublicKeyAlgorithm::MLDSA:
|
||||
+ break;
|
||||
MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
|
||||
}
|
||||
|
||||
@@ -248,6 +251,24 @@ CheckSubjectPublicKeyInfoContents(Reader& input, TrustDomain& trustDomain,
|
||||
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01
|
||||
};
|
||||
|
||||
+ // Params for pure ML-DSA-44 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-44 2.16.840.1.101.3.4.3.17
|
||||
+ static const uint8_t id_ml_dsa_44[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x11
|
||||
+ };
|
||||
+
|
||||
+ // Params for pure ML-DSA-65 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-65 2.16.840.1.101.3.4.3.18
|
||||
+ static const uint8_t id_ml_dsa_65[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x12
|
||||
+ };
|
||||
+
|
||||
+ // Params for pure ML-DSA-87 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-87 2.16.840.1.101.3.4.3.19
|
||||
+ static const uint8_t id_ml_dsa_87[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x13
|
||||
+ };
|
||||
+
|
||||
if (algorithmOID.MatchRest(id_ecPublicKey)) {
|
||||
// An id-ecPublicKey AlgorithmIdentifier has a parameter that identifes
|
||||
// the curve being used. Although RFC 5480 specifies multiple forms, we
|
||||
@@ -361,6 +382,30 @@ CheckSubjectPublicKeyInfoContents(Reader& input, TrustDomain& trustDomain,
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
+ } else if (algorithmOID.MatchRest(id_ml_dsa_44) ||
|
||||
+ algorithmOID.MatchRest(id_ml_dsa_65) ||
|
||||
+ algorithmOID.MatchRest(id_ml_dsa_87)) {
|
||||
+
|
||||
+ /*
|
||||
+ * The ML-DSA AlgorithmIdentifier is expected to contain only the OID,
|
||||
+ * with no parameters field present. According to the Internet-Draft
|
||||
+ * https://www.ietf.org/archive/id/draft-ietf-lamps-dilithium-certificates-11.html
|
||||
+ * (Section 3), the AlgorithmIdentifier for ML-DSA variants must omit the `parameters`
|
||||
+ * field entirely.
|
||||
+ * In DER encoding, the absence of the parameters field means that after parsing the
|
||||
+ * OID, no additional bytes should remain. Calling `der::End(algorithm)` confirms that
|
||||
+ * this constraint is satisfied and that the structure is correctly encoded.
|
||||
+ */
|
||||
+ rv = der::End(algorithm);
|
||||
+ if (rv != Success) {
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ Input rawPublicKey;
|
||||
+ rv = subjectPublicKeyReader.SkipToEnd(rawPublicKey);
|
||||
+ if (rv != Success) {
|
||||
+ return rv;
|
||||
+ }
|
||||
} else {
|
||||
return Result::ERROR_UNSUPPORTED_KEYALG;
|
||||
}
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixder.cpp b/security/nss/lib/mozpkix/lib/pkixder.cpp
|
||||
index 59454c7d3c..4ff45ed566 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixder.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixder.cpp
|
||||
@@ -211,6 +211,24 @@ SignatureAlgorithmIdentifierValue(Reader& input,
|
||||
0x00, 0xa2, 0x03, 0x02, 0x01, 0x40
|
||||
};
|
||||
|
||||
+ // Params for pure ML-DSA-44 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-44 2.16.840.1.101.3.4.3.17
|
||||
+ static const uint8_t id_ml_dsa_44[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x11
|
||||
+ };
|
||||
+
|
||||
+ // Params for pure ML-DSA-65 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-65 2.16.840.1.101.3.4.3.18
|
||||
+ static const uint8_t id_ml_dsa_65[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x12
|
||||
+ };
|
||||
+
|
||||
+ // Params for pure ML-DSA-87 signature
|
||||
+ // python DottedOIDToCode.py id-ml-dsa-87 2.16.840.1.101.3.4.3.19
|
||||
+ static const uint8_t id_ml_dsa_87[] = {
|
||||
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x13
|
||||
+ };
|
||||
+
|
||||
// Matching is attempted based on a rough estimate of the commonality of the
|
||||
// algorithm, to minimize the number of MatchRest calls.
|
||||
if (algorithmID.MatchRest(sha256WithRSAEncryption)) {
|
||||
@@ -252,6 +270,10 @@ SignatureAlgorithmIdentifierValue(Reader& input,
|
||||
} else {
|
||||
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
+ } else if (algorithmID.MatchRest(id_ml_dsa_44) ||
|
||||
+ algorithmID.MatchRest(id_ml_dsa_65) ||
|
||||
+ algorithmID.MatchRest(id_ml_dsa_87)) {
|
||||
+ publicKeyAlgorithm = PublicKeyAlgorithm::MLDSA;
|
||||
} else {
|
||||
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixnss.cpp b/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
index 606ef708d8..31aa1ddd67 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixnss.cpp
|
||||
@@ -303,6 +303,44 @@ DigestBufNSS(Input item,
|
||||
return Success;
|
||||
}
|
||||
|
||||
+Result
|
||||
+VerifyMLDSASignedDataNSS(Input data,
|
||||
+ Input signature,
|
||||
+ Input subjectPublicKeyInfo,
|
||||
+ void* pkcs11PinArg)
|
||||
+{
|
||||
+ ScopedSECKEYPublicKey publicKey;
|
||||
+ SECKEYPublicKey *pubk = NULL;
|
||||
+ SECOidTag signaturePolicyTag, hashPolicyTag;
|
||||
+ Result rv = SubjectPublicKeyInfoToSECKEYPublicKey(subjectPublicKeyInfo,
|
||||
+ publicKey);
|
||||
+ if (rv != Success) {
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ pubk = publicKey.get();
|
||||
+ SECItem signatureItem(UnsafeMapInputToSECItem(signature));
|
||||
+ SECItem dataItem(UnsafeMapInputToSECItem(data));
|
||||
+ CK_MECHANISM_TYPE mechanism;
|
||||
+
|
||||
+ switch (pubk->u.mldsa.paramSet) {
|
||||
+ case SEC_OID_ML_DSA_44:
|
||||
+ case SEC_OID_ML_DSA_65:
|
||||
+ case SEC_OID_ML_DSA_87:
|
||||
+ mechanism = CKM_ML_DSA;
|
||||
+ signaturePolicyTag = pubk->u.mldsa.paramSet;
|
||||
+ hashPolicyTag = SEC_OID_UNKNOWN;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return Result::ERROR_UNSUPPORTED_KEYALG;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ SECOidTag policyTags[2] = {signaturePolicyTag, hashPolicyTag};
|
||||
+ return VerifySignedData(pubk, mechanism, nullptr, &signatureItem,
|
||||
+ &dataItem, policyTags, pkcs11PinArg);
|
||||
+}
|
||||
+
|
||||
Result
|
||||
MapPRErrorCodeToResult(PRErrorCode error)
|
||||
{
|
||||
diff --git a/security/nss/lib/mozpkix/lib/pkixverify.cpp b/security/nss/lib/mozpkix/lib/pkixverify.cpp
|
||||
index 8cb58bf7de..ff132d89df 100644
|
||||
--- a/security/nss/lib/mozpkix/lib/pkixverify.cpp
|
||||
+++ b/security/nss/lib/mozpkix/lib/pkixverify.cpp
|
||||
@@ -53,6 +53,9 @@ VerifySignedData(TrustDomain& trustDomain,
|
||||
case der::PublicKeyAlgorithm::RSA_PSS:
|
||||
return trustDomain.VerifyRSAPSSSignedData(signedData.data,
|
||||
digestAlgorithm, signedData.signature, signerSubjectPublicKeyInfo);
|
||||
+ case der::PublicKeyAlgorithm::MLDSA:
|
||||
+ return trustDomain.VerifyMLDSASignedData(signedData.data,
|
||||
+ signedData.signature, signerSubjectPublicKeyInfo);
|
||||
MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,247 @@
|
||||
diff --git a/netwerk/protocol/http/WebTransportCertificateVerifier.cpp b/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
||||
index cc778640a1..298d6a61e8 100644
|
||||
--- a/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
||||
+++ b/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
||||
@@ -53,6 +53,10 @@ class ServerCertHashesTrustDomain : public mozilla::pkix::TrustDomain {
|
||||
mozilla::pkix::Input signature,
|
||||
mozilla::pkix::Input subjectPublicKeyInfo) override;
|
||||
|
||||
+ virtual mozilla::pkix::Result VerifyMLDSASignedData(
|
||||
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
||||
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
||||
+
|
||||
virtual mozilla::pkix::Result DigestBuf(
|
||||
mozilla::pkix::Input item, mozilla::pkix::DigestAlgorithm digestAlg,
|
||||
/*out*/ uint8_t* digestBuf, size_t digestBufLen) override;
|
||||
@@ -151,6 +155,14 @@ mozilla::pkix::Result ServerCertHashesTrustDomain::VerifyECDSASignedData(
|
||||
return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
+mozilla::pkix::Result ServerCertHashesTrustDomain::VerifyMLDSASignedData(
|
||||
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
||||
+ mozilla::pkix::Input subjectPublicKeyInfo) {
|
||||
+ MOZ_ASSERT_UNREACHABLE("not expecting this to be called");
|
||||
+
|
||||
+ return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
+}
|
||||
+
|
||||
mozilla::pkix::Result ServerCertHashesTrustDomain::DigestBuf(
|
||||
mozilla::pkix::Input item, mozilla::pkix::DigestAlgorithm digestAlg,
|
||||
/*out*/ uint8_t* digestBuf, size_t digestBufLen) {
|
||||
diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp
|
||||
index ca330770fb..1e8f1d4996 100644
|
||||
--- a/security/certverifier/CertVerifier.cpp
|
||||
+++ b/security/certverifier/CertVerifier.cpp
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "CertVerifier.h"
|
||||
|
||||
#include <stdint.h>
|
||||
+#include <optional>
|
||||
|
||||
#include "AppTrustDomain.h"
|
||||
#include "CTKnownLogs.h"
|
||||
@@ -1010,7 +1011,7 @@ Result CertVerifier::VerifySSLServerCert(
|
||||
void HashSignatureParams(pkix::Input data, pkix::Input signature,
|
||||
pkix::Input subjectPublicKeyInfo,
|
||||
pkix::der::PublicKeyAlgorithm publicKeyAlgorithm,
|
||||
- pkix::DigestAlgorithm digestAlgorithm,
|
||||
+ std::optional<pkix::DigestAlgorithm> digestAlgorithm,
|
||||
/*out*/ Maybe<nsTArray<uint8_t>>& sha512Hash) {
|
||||
sha512Hash.reset();
|
||||
Digest digest;
|
||||
@@ -1048,10 +1049,14 @@ void HashSignatureParams(pkix::Input data, pkix::Input signature,
|
||||
sizeof(publicKeyAlgorithm)))) {
|
||||
return;
|
||||
}
|
||||
- if (NS_FAILED(
|
||||
- digest.Update(reinterpret_cast<const uint8_t*>(&digestAlgorithm),
|
||||
- sizeof(digestAlgorithm)))) {
|
||||
- return;
|
||||
+ // There is no fallback digest algorithm when it's empty.
|
||||
+ // Check that digestAlgorithm actually contains a value.
|
||||
+ if (digestAlgorithm) {
|
||||
+ pkix::DigestAlgorithm value = digestAlgorithm.value();
|
||||
+ if (NS_FAILED(digest.Update(reinterpret_cast<const uint8_t*>(&value),
|
||||
+ sizeof(value)))) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
nsTArray<uint8_t> result;
|
||||
if (NS_FAILED(digest.End(result))) {
|
||||
@@ -1064,10 +1069,17 @@ Result VerifySignedDataWithCache(
|
||||
der::PublicKeyAlgorithm publicKeyAlg,
|
||||
mozilla::glean::impl::DenominatorMetric telemetryDenominator,
|
||||
mozilla::glean::impl::NumeratorMetric telemetryNumerator, Input data,
|
||||
- DigestAlgorithm digestAlgorithm, Input signature,
|
||||
+ std::optional<DigestAlgorithm> digestAlgorithm, Input signature,
|
||||
Input subjectPublicKeyInfo, SignatureCache* signatureCache, void* pinArg) {
|
||||
telemetryDenominator.Add(1);
|
||||
Maybe<nsTArray<uint8_t>> sha512Hash;
|
||||
+
|
||||
+ // Currently, it is only acceptable for `digestAlgorithm` to be null when the
|
||||
+ // public key algorithm is pure ML-DSA. Fail immediately otherwise.
|
||||
+ if ((publicKeyAlg != der::PublicKeyAlgorithm::MLDSA) && !digestAlgorithm) {
|
||||
+ return Result::ERROR_INVALID_ALGORITHM;
|
||||
+ }
|
||||
+
|
||||
HashSignatureParams(data, signature, subjectPublicKeyInfo, publicKeyAlg,
|
||||
digestAlgorithm, sha512Hash);
|
||||
// If hashing the signature parameters succeeded, see if this signature is in
|
||||
@@ -1080,16 +1092,23 @@ Result VerifySignedDataWithCache(
|
||||
Result result;
|
||||
switch (publicKeyAlg) {
|
||||
case der::PublicKeyAlgorithm::ECDSA:
|
||||
- result = VerifyECDSASignedDataNSS(data, digestAlgorithm, signature,
|
||||
- subjectPublicKeyInfo, pinArg);
|
||||
+ result =
|
||||
+ VerifyECDSASignedDataNSS(data, digestAlgorithm.value(), signature,
|
||||
+ subjectPublicKeyInfo, pinArg);
|
||||
break;
|
||||
case der::PublicKeyAlgorithm::RSA_PKCS1:
|
||||
- result = VerifyRSAPKCS1SignedDataNSS(data, digestAlgorithm, signature,
|
||||
- subjectPublicKeyInfo, pinArg);
|
||||
+ result =
|
||||
+ VerifyRSAPKCS1SignedDataNSS(data, digestAlgorithm.value(), signature,
|
||||
+ subjectPublicKeyInfo, pinArg);
|
||||
break;
|
||||
case der::PublicKeyAlgorithm::RSA_PSS:
|
||||
- result = VerifyRSAPSSSignedDataNSS(data, digestAlgorithm, signature,
|
||||
- subjectPublicKeyInfo, pinArg);
|
||||
+ result =
|
||||
+ VerifyRSAPSSSignedDataNSS(data, digestAlgorithm.value(), signature,
|
||||
+ subjectPublicKeyInfo, pinArg);
|
||||
+ break;
|
||||
+ case der::PublicKeyAlgorithm::MLDSA:
|
||||
+ result = VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
||||
+ pinArg);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unhandled public key algorithm");
|
||||
diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h
|
||||
index 6432547c8a..6e09e6fcdd 100644
|
||||
--- a/security/certverifier/CertVerifier.h
|
||||
+++ b/security/certverifier/CertVerifier.h
|
||||
@@ -331,7 +331,8 @@ mozilla::pkix::Result VerifySignedDataWithCache(
|
||||
mozilla::pkix::der::PublicKeyAlgorithm publicKeyAlg,
|
||||
mozilla::glean::impl::DenominatorMetric telemetryDenominator,
|
||||
mozilla::glean::impl::NumeratorMetric telemetryNumerator,
|
||||
- mozilla::pkix::Input data, mozilla::pkix::DigestAlgorithm digestAlgorithm,
|
||||
+ mozilla::pkix::Input data,
|
||||
+ std::optional<mozilla::pkix::DigestAlgorithm> digestAlgorithm,
|
||||
mozilla::pkix::Input signature, mozilla::pkix::Input subjectPublicKeyInfo,
|
||||
SignatureCache* signatureCache, void* pinArg);
|
||||
|
||||
diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverifier/NSSCertDBTrustDomain.cpp
|
||||
index 70ba17d70f..a3ace3cee7 100644
|
||||
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
|
||||
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
|
||||
@@ -1541,6 +1541,15 @@ Result NSSCertDBTrustDomain::VerifyECDSASignedData(
|
||||
signature, subjectPublicKeyInfo, mSignatureCache, mPinArg);
|
||||
}
|
||||
|
||||
+Result NSSCertDBTrustDomain::VerifyMLDSASignedData(Input data, Input signature,
|
||||
+ Input subjectPublicKeyInfo) {
|
||||
+ return VerifySignedDataWithCache(
|
||||
+ der::PublicKeyAlgorithm::MLDSA,
|
||||
+ mozilla::glean::cert_signature_cache::total,
|
||||
+ mozilla::glean::cert_signature_cache::hits, data, std::nullopt, signature,
|
||||
+ subjectPublicKeyInfo, mSignatureCache, mPinArg);
|
||||
+}
|
||||
+
|
||||
Result NSSCertDBTrustDomain::CheckValidityIsAcceptable(
|
||||
Time notBefore, Time notAfter, EndEntityOrCA endEntityOrCA,
|
||||
KeyPurposeId keyPurpose) {
|
||||
diff --git a/security/certverifier/NSSCertDBTrustDomain.h b/security/certverifier/NSSCertDBTrustDomain.h
|
||||
index fc210f3254..6178201758 100644
|
||||
--- a/security/certverifier/NSSCertDBTrustDomain.h
|
||||
+++ b/security/certverifier/NSSCertDBTrustDomain.h
|
||||
@@ -197,6 +197,10 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
|
||||
mozilla::pkix::Input signature,
|
||||
mozilla::pkix::Input subjectPublicKeyInfo) override;
|
||||
|
||||
+ virtual Result VerifyMLDSASignedData(
|
||||
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
||||
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
||||
+
|
||||
virtual Result DigestBuf(mozilla::pkix::Input item,
|
||||
mozilla::pkix::DigestAlgorithm digestAlg,
|
||||
/*out*/ uint8_t* digestBuf,
|
||||
diff --git a/security/ct/CTLogVerifier.cpp b/security/ct/CTLogVerifier.cpp
|
||||
index d5e665aaca..471213745d 100644
|
||||
--- a/security/ct/CTLogVerifier.cpp
|
||||
+++ b/security/ct/CTLogVerifier.cpp
|
||||
@@ -99,6 +99,10 @@ class SignatureParamsTrustDomain final : public TrustDomain {
|
||||
return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
+ pkix::Result VerifyMLDSASignedData(Input, Input, Input) override {
|
||||
+ return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
+ }
|
||||
+
|
||||
pkix::Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA,
|
||||
KeyPurposeId) override {
|
||||
return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
diff --git a/security/ct/tests/gtest/CTTestUtils.cpp b/security/ct/tests/gtest/CTTestUtils.cpp
|
||||
index 6a25307ec3..dbec7adc91 100644
|
||||
--- a/security/ct/tests/gtest/CTTestUtils.cpp
|
||||
+++ b/security/ct/tests/gtest/CTTestUtils.cpp
|
||||
@@ -807,6 +807,12 @@ class OCSPExtensionTrustDomain : public TrustDomain {
|
||||
subjectPublicKeyInfo, nullptr);
|
||||
}
|
||||
|
||||
+ pkix::Result VerifyMLDSASignedData(Input data, Input signature,
|
||||
+ Input subjectPublicKeyInfo) override {
|
||||
+ return VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
||||
+ nullptr);
|
||||
+ }
|
||||
+
|
||||
pkix::Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA,
|
||||
KeyPurposeId) override {
|
||||
ADD_FAILURE();
|
||||
diff --git a/security/manager/ssl/AppTrustDomain.cpp b/security/manager/ssl/AppTrustDomain.cpp
|
||||
index ab49d7eb1f..3963f90eb1 100644
|
||||
--- a/security/manager/ssl/AppTrustDomain.cpp
|
||||
+++ b/security/manager/ssl/AppTrustDomain.cpp
|
||||
@@ -322,6 +322,12 @@ pkix::Result AppTrustDomain::VerifyECDSASignedData(
|
||||
subjectPublicKeyInfo, nullptr);
|
||||
}
|
||||
|
||||
+pkix::Result AppTrustDomain::VerifyMLDSASignedData(Input data, Input signature,
|
||||
+ Input subjectPublicKeyInfo) {
|
||||
+ return VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
||||
+ nullptr);
|
||||
+}
|
||||
+
|
||||
pkix::Result AppTrustDomain::CheckValidityIsAcceptable(
|
||||
Time /*notBefore*/, Time /*notAfter*/, EndEntityOrCA /*endEntityOrCA*/,
|
||||
KeyPurposeId /*keyPurpose*/) {
|
||||
diff --git a/security/manager/ssl/AppTrustDomain.h b/security/manager/ssl/AppTrustDomain.h
|
||||
index 4b0212ede0..85fdff5f13 100644
|
||||
--- a/security/manager/ssl/AppTrustDomain.h
|
||||
+++ b/security/manager/ssl/AppTrustDomain.h
|
||||
@@ -80,6 +80,9 @@ class AppTrustDomain final : public mozilla::pkix::TrustDomain {
|
||||
mozilla::pkix::DigestAlgorithm digestAlg,
|
||||
/*out*/ uint8_t* digestBuf,
|
||||
size_t digestBufLen) override;
|
||||
+ virtual Result VerifyMLDSASignedData(
|
||||
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
||||
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
||||
|
||||
private:
|
||||
nsTArray<Span<const uint8_t>> mTrustedRoots;
|
||||
diff --git a/security/manager/ssl/TLSClientAuthCertSelection.cpp b/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
||||
index 3a84b15ee6..a3dc5a1af1 100644
|
||||
--- a/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
||||
+++ b/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
||||
@@ -217,6 +217,11 @@ class ClientAuthCertNonverifyingTrustDomain final : public TrustDomain {
|
||||
pkix::Input subjectPublicKeyInfo) override {
|
||||
return pkix::Success;
|
||||
}
|
||||
+ virtual mozilla::pkix::Result VerifyMLDSASignedData(
|
||||
+ pkix::Input data, pkix::Input signature,
|
||||
+ pkix::Input subjectPublicKeyInfo) override {
|
||||
+ return pkix::Success;
|
||||
+ }
|
||||
virtual mozilla::pkix::Result CheckValidityIsAcceptable(
|
||||
pkix::Time notBefore, pkix::Time notAfter,
|
||||
pkix::EndEntityOrCA endEntityOrCA,
|
||||
@ -12,8 +12,6 @@ pref("offline.autoDetect", true);
|
||||
/* Disable global indexing by default*/
|
||||
pref("mailnews.database.global.indexer.enabled", false);
|
||||
|
||||
/* Do not switch to Smart Folders after upgrade to 3.0b4 */
|
||||
pref("mail.folder.views.version", "1");
|
||||
pref("extensions.shownSelectionUI", true);
|
||||
pref("extensions.autoDisableScopes", 0);
|
||||
|
||||
|
||||
50
SOURCES/thunderbird.appdata.xml.in
Normal file
50
SOURCES/thunderbird.appdata.xml.in
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>thunderbird</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<name>Thunderbird</name>
|
||||
<summary>Thunderbird is a free and open source email, newsfeed, chat, and calendaring client</summary>
|
||||
<description>
|
||||
<!-- From https://www.thunderbird.net/en-US/about/ -->
|
||||
<p>
|
||||
Thunderbird is a free and open source email, newsfeed, chat, and
|
||||
calendaring client, that’s easy to set up and customize. One of the core
|
||||
principles of Thunderbird is the use and promotion of open standards -
|
||||
this focus is a rejection of our world of closed platforms and services
|
||||
that can’t communicate with each other. We want our users to have freedom
|
||||
and choice in how they communicate.
|
||||
</p>
|
||||
<p>
|
||||
Thunderbird is an open source project, which means anyone can contribute
|
||||
ideas, designs, code, and time helping fellow users.
|
||||
</p>
|
||||
</description>
|
||||
<categories>
|
||||
<category>Calendar</category>
|
||||
<category>Email</category>
|
||||
<category>Office</category>
|
||||
</categories>
|
||||
|
||||
<url type="homepage">https://www.thunderbird.net/</url>
|
||||
<url type="bugtracker">https://bugzilla.mozilla.org/</url>
|
||||
<url type="faq">https://support.mozilla.org/kb/thunderbird-faq/</url>
|
||||
<url type="help">https://support.mozilla.org/products/thunderbird/</url>
|
||||
<url type="donation">https://www.thunderbird.net/donate/</url>
|
||||
<url type="translate">https://www.thunderbird.net/participate/</url>
|
||||
|
||||
<project_group>Mozilla</project_group>
|
||||
<project_license>MPL-2.0</project_license>
|
||||
<developer_name>Thunderbird Project</developer_name>
|
||||
|
||||
<mimetypes>
|
||||
<mimetype>message/rfc822</mimetype>
|
||||
<mimetype>x-scheme-handler/mailto</mimetype>
|
||||
<mimetype>text/calendar</mimetype>
|
||||
<mimetype>text/vcard</mimetype>
|
||||
<mimetype>text/x-vcard</mimetype>
|
||||
</mimetypes>
|
||||
<releases>
|
||||
<release version="__VERSION__" date="__DATE__"/>
|
||||
</releases>
|
||||
<update_contact>jhorak@redhat.com</update_contact>
|
||||
</component>
|
||||
@ -137,7 +137,7 @@ end}
|
||||
|
||||
Summary: Mozilla Thunderbird mail/newsgroup client
|
||||
Name: thunderbird
|
||||
Version: 140.4.0
|
||||
Version: 140.5.0
|
||||
Release: 2%{?dist}
|
||||
URL: http://www.mozilla.org/projects/thunderbird/
|
||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
||||
@ -165,7 +165,7 @@ ExcludeArch: %{ix86}
|
||||
#Source0: https://archive.mozilla.org/pub/thunderbird/releases/%%{version}%%{?pre_version}/source/thunderbird-%%{version}%%{?pre_version}.processed-source.tar.xz
|
||||
Source0: thunderbird-%{version}%{?pre_version}%{?buildnum}.processed-source.tar.xz
|
||||
%if %{with langpacks}
|
||||
Source1: thunderbird-langpacks-%{version}%{?pre_version}-20251013.tar.xz
|
||||
Source1: thunderbird-langpacks-%{version}%{?pre_version}-20251111.tar.xz
|
||||
%endif
|
||||
Source2: cbindgen-vendor.tar.xz
|
||||
Source3: process-official-tarball
|
||||
@ -177,6 +177,7 @@ Source24: mozilla-api-key
|
||||
Source25: thunderbird-symbolic.svg
|
||||
Source27: google-api-key
|
||||
Source32: node-stdout-nonblocking-wrapper
|
||||
Source33: thunderbird.appdata.xml.in
|
||||
Source35: google-loc-api-key
|
||||
Source401: nss-setup-flags-env.inc
|
||||
Source402: nspr-4.36.0-2.el8_2.src.rpm
|
||||
@ -218,6 +219,20 @@ Patch109: mozilla-bmo1789216-disable-av1.patch
|
||||
Patch110: build-libaom.patch
|
||||
Patch111: av1-else-condition-add.patch
|
||||
|
||||
# ML-DSA support
|
||||
# https://phabricator.services.mozilla.com/D262395
|
||||
Patch120: thunderbird-integrate-ml-dsa-signature-verification-for-pkix-certificate-chain-validation.patch
|
||||
# https://phabricator.services.mozilla.com/D262397
|
||||
Patch121: thunderbird-add-ml-dsa-certificate-support-to-certviewer.patch
|
||||
# https://phabricator.services.mozilla.com/D264144
|
||||
Patch122: thunderbird-enable-ml-dsa-signature-verification-for-certificate-chain-validation.patch
|
||||
# RHEL downstream only - adapts to ML-DSA support in NSS from RHEL 10
|
||||
Patch123: thunderbird-adapt-ml-dsa-support-to-rhel-nss.patch
|
||||
# RHEL downstream only - enable ML-DSA in manager/ssl
|
||||
Patch124: thunderbird-enable-ml-dsa-in-manager-ssl.patch
|
||||
# RHEL downstream only - add mlkem768-secp256r1 support
|
||||
Patch125: thunderbird-add-mlkem768-secp256r1-support.patch
|
||||
|
||||
# ---- Fedora specific patches ----
|
||||
Patch151: firefox-enable-addons.patch
|
||||
Patch152: rhbz-1173156.patch
|
||||
@ -1099,6 +1114,16 @@ echo "--------------------------------------------"
|
||||
%patch -P110 -p1 -b .libaom
|
||||
%patch -P111 -p1 -b .av1-else-condition-add
|
||||
|
||||
%if 0%{?rhel} >= 10
|
||||
# ML-DSA support
|
||||
%patch -P120 -p1 -b .integrate-ml-dsa-signature-verification-for-pkix-certificate-chain-validation
|
||||
%patch -P121 -p1 -b .add-ml-dsa-certificate-support-to-certviewer
|
||||
%patch -P122 -p1 -b .enable-ml-dsa-signature-verification-for-certificate-chain-validation
|
||||
%patch -P123 -p1 -b .adapt-ml-dsa-support-to-rhel-nss
|
||||
%patch -P124 -p1 -b .enable-ml-dsa-in-manager-ssl
|
||||
%patch -P125 -p1 -b .add-mlkem768-secp256r1-support
|
||||
%endif
|
||||
|
||||
# ---- Fedora specific patches ----
|
||||
%patch -P151 -p1 -b .addons
|
||||
%patch -P152 -p1 -b .rhbz-1173156
|
||||
@ -1569,15 +1594,10 @@ touch $RPM_BUILD_ROOT%{mozappdir}/components/xpti.dat
|
||||
%endif
|
||||
|
||||
# Register as an application to be visible in the software center
|
||||
mkdir -p $RPM_BUILD_ROOT%{_datadir}/metainfo
|
||||
%{__cp} -p comm/mail/branding/%{name}/net.thunderbird.Thunderbird.appdata.xml $RPM_BUILD_ROOT%{_datadir}/metainfo/thunderbird.appdata.xml
|
||||
%if 0%{?flatpak}
|
||||
# don't specify icon for flatpak appdata, icons are correctly named and packaged already
|
||||
# as org.mozilla.Thunderbird.png
|
||||
sed -i -e 's|<icon .*||' "$RPM_BUILD_ROOT%{_datadir}/metainfo/thunderbird.appdata.xml"
|
||||
%else
|
||||
sed -i -e 's|<icon .*|<icon type="stock">thunderbird</icon>|' "$RPM_BUILD_ROOT%{_datadir}/metainfo/thunderbird.appdata.xml"
|
||||
%endif
|
||||
mkdir -p %{buildroot}%{_datadir}/metainfo
|
||||
%{__sed} -e "s/__VERSION__/%{version}/" \
|
||||
-e "s/__DATE__/$(date '+%Y-%m-%d')/" \
|
||||
%{SOURCE33} > %{buildroot}%{_datadir}/metainfo/thunderbird.appdata.xml
|
||||
|
||||
# Clean the created bundled rpms.
|
||||
rm -rf %{_srcrpmdir}/libffi*.src.rpm
|
||||
@ -1591,6 +1611,11 @@ find %{_rpmdir} -name "nspr*.rpm" -delete
|
||||
|
||||
#===============================================================================
|
||||
|
||||
%check
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/*.appdata.xml
|
||||
|
||||
#===============================================================================
|
||||
|
||||
%post
|
||||
update-desktop-database &> /dev/null || :
|
||||
touch --no-create %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
@ -1675,6 +1700,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#===============================================================================
|
||||
|
||||
%changelog
|
||||
* Tue Nov 11 2025 Jan Horak <jhorak@redhat.com> - 140.5.0-2
|
||||
- Update to 140.5.0 ESR
|
||||
|
||||
* Mon Oct 13 2025 Jan Horak <jhorak@redhat.com> - 140.4.0-2
|
||||
- Update to 140.4.0 ESR
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user