Reland "crypto/x509: Verify standalone Merkle Tree Certs (MTCs)" This reverts commit 96a007fb323e49e5637e018f7f4927addd851d6f, thus relanding commit f89068d3030374395c4b070838d1f4d9bbef5465. The build failure in Chromium's component build was because accessing impl->tbs_sig_alg.get() instantiates the StackAllocated<X509_ALGOR, ...> template, which emits relocations for internal symbols (x509_algor_init and x509_algor_cleanup), and these are not pruned in unoptimized mode. The fix (diff from patchset 1) is to avoid reaching into X509Impl internals to construct the test cert. Instead, all the desired (intentionally invalid) test certs were generated by the MTC demo tool, and checked in as testdata and parsed directly. Original change's description: > Revert "crypto/x509: Verify standalone Merkle Tree Certs (MTCs)" > > This reverts commit f89068d3030374395c4b070838d1f4d9bbef5465. > > Reason for revert: build failure crbug.com/549361069 > > Failure Link: https://ci.chromium.org/ui/p/chrome/builders/try/linux-chrome-dbg-cog-cache-warmer/79105/overview > > Original change's description: > > crypto/x509: Verify standalone Merkle Tree Certs (MTCs) > > > > This implements verification of "standalone" Merkle Tree Certs (see > > draft-ietf-plants-merkle-tree-certs-05, section 6.3) as part of the > > X509_STORE_CTX API, if the flag X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05 > > is specified. > > > > Bug: 503746594 > > Change-Id: Ie5abd17eb34c37139d3be1261e1914976a6a6964 > > Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/100707 > > Reviewed-by: David Benjamin <davidben@google.com> > > Commit-Queue: Lily Chen <chlily@google.com> > > Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> > > TBR=davidben@google.com,boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com,chlily@google.com > > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: 503746594, 549361069 > Change-Id: If43293ba7c2199a463a98dcf848fcc60bdd1e9bb > Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/101307 > Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> > Auto-Submit: Lily Chen <chlily@google.com> > Reviewed-by: David Benjamin <davidben@google.com> > Commit-Queue: David Benjamin <davidben@google.com> # Not skipping CQ checks because this is a reland. Bug: 503746594 Cq-Include-Trybots: luci.boringssl.try:linux_clang_shared_compile,linux_clang_shared_rel_compile Change-Id: I2376b492ecc0e6bfcfc0acb36cc0f1511dd29db7 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/101467 Commit-Queue: Lily Chen <chlily@google.com> Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/build.json b/build.json index ae818d9..2c05e93 100644 --- a/build.json +++ b/build.json
@@ -951,6 +951,7 @@ "crypto/slhdsa/slhdsa_shake_256f_sigver.txt", "crypto/x509/test/*.pem", "crypto/x509/test/*.pk8", + "crypto/x509/test/mtc/*.pem", "third_party/wycheproof_testvectors/*.txt" ], "internal_hdrs": [
diff --git a/crypto/err/x509.errordata b/crypto/err/x509.errordata index e30d667..836e115 100644 --- a/crypto/err/x509.errordata +++ b/crypto/err/x509.errordata
@@ -12,6 +12,8 @@ X509,110,INVALID_DIRECTORY X509,139,INVALID_FIELD_FOR_VERSION X509,111,INVALID_FIELD_NAME +X509,145,INVALID_MTC_CA +X509,146,INVALID_MTC_PROOF X509,136,INVALID_PARAMETER X509,144,INVALID_POLICY_EXTENSION X509,112,INVALID_PSS_PARAMETERS
diff --git a/crypto/obj/obj_dat.h b/crypto/obj/obj_dat.h index feb8f2d..2243ba0 100644 --- a/crypto/obj/obj_dat.h +++ b/crypto/obj/obj_dat.h
@@ -16,7 +16,7 @@ BSSL_NAMESPACE_BEGIN -#define NUM_NID 973 +#define NUM_NID 979 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -7146,6 +7146,39 @@ 0x04, 0x04, 0x02, + /* NID_alg_mtcProof_draft */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0xda, + 0x4b, + 0x2f, + 0x00, + /* NID_rdna_trustAnchorID_draft */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0xda, + 0x4b, + 0x2f, + 0x01, + /* NID_pe_mtcCertificationAuthority_draft */ + 0x2b, + 0x06, + 0x01, + 0x04, + 0x01, + 0x82, + 0xda, + 0x4b, + 0x2f, + 0x02, }; static const ASN1_OBJECT kObjects[NUM_NID] = { @@ -8802,6 +8835,15 @@ 0}, {NULL, NULL, NID_undef, 0, NULL, 0}, {"X-Wing", "X-Wing", NID_X_Wing, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"alg-mtcProof-draft", "alg-mtcProof-draft", NID_alg_mtcProof_draft, 10, + &kObjectData[6241], 0}, + {"rdna-trustAnchorID-draft", "rdna-trustAnchorID-draft", + NID_rdna_trustAnchorID_draft, 10, &kObjectData[6251], 0}, + {"pe-mtcCertificationAuthority-draft", "pe-mtcCertificationAuthority-draft", + NID_pe_mtcCertificationAuthority_draft, 10, &kObjectData[6261], 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -9017,6 +9059,7 @@ 368 /* acceptableResponses */, 446 /* account */, 363 /* ad_timestamping */, + 976 /* alg-mtcProof-draft */, 376 /* algorithm */, 405 /* ansi-X9-62 */, 910 /* anyExtendedKeyUsage */, @@ -9478,6 +9521,7 @@ 489 /* pagerTelephoneNumber */, 374 /* path */, 112 /* pbeWithMD5AndCast5CBC */, + 978 /* pe-mtcCertificationAuthority-draft */, 499 /* personalSignature */, 487 /* personalTitle */, 464 /* photo */, @@ -9531,6 +9575,7 @@ 286 /* qcStatements */, 457 /* qualityLabelledData */, 450 /* rFC822localPart */, + 977 /* rdna-trustAnchorID-draft */, 870 /* registeredAddress */, 400 /* role */, 877 /* roleOccupant */, @@ -9954,6 +9999,7 @@ 901 /* aes-256-gcm */, 428 /* aes-256-ofb */, 914 /* aes-256-xts */, + 976 /* alg-mtcProof-draft */, 376 /* algorithm */, 484 /* associatedDomain */, 485 /* associatedName */, @@ -10432,6 +10478,7 @@ 145 /* pbeWithSHA1And40BitRC4 */, 170 /* pbeWithSHA1AndDES-CBC */, 68 /* pbeWithSHA1AndRC2-CBC */, + 978 /* pe-mtcCertificationAuthority-draft */, 499 /* personalSignature */, 487 /* personalTitle */, 464 /* photo */, @@ -10491,6 +10538,7 @@ 122 /* rc5-cfb */, 121 /* rc5-ecb */, 123 /* rc5-ofb */, + 977 /* rdna-trustAnchorID-draft */, 870 /* registeredAddress */, 460 /* rfc822Mailbox */, 117 /* ripemd160 */, @@ -11544,6 +11592,9 @@ 138 /* 1.3.6.1.4.1.311.10.3.4 (OBJ_ms_efs) */, 648 /* 1.3.6.1.4.1.311.20.2.2 (OBJ_ms_smartcard_login) */, 649 /* 1.3.6.1.4.1.311.20.2.3 (OBJ_ms_upn) */, + 976 /* 1.3.6.1.4.1.44363.47.0 (OBJ_alg_mtcProof_draft) */, + 977 /* 1.3.6.1.4.1.44363.47.1 (OBJ_rdna_trustAnchorID_draft) */, + 978 /* 1.3.6.1.4.1.44363.47.2 (OBJ_pe_mtcCertificationAuthority_draft) */, 751 /* 1.2.392.200011.61.1.1.1.2 (OBJ_camellia_128_cbc) */, 752 /* 1.2.392.200011.61.1.1.1.3 (OBJ_camellia_192_cbc) */, 753 /* 1.2.392.200011.61.1.1.1.4 (OBJ_camellia_256_cbc) */,
diff --git a/crypto/obj/obj_mac.num b/crypto/obj/obj_mac.num index 7b8bd2e..70b8399 100644 --- a/crypto/obj/obj_mac.num +++ b/crypto/obj/obj_mac.num
@@ -959,3 +959,6 @@ ML_DSA_87 969 ML_KEM_768 970 X_Wing 972 +alg_mtcProof_draft 976 +rdna_trustAnchorID_draft 977 +pe_mtcCertificationAuthority_draft 978
diff --git a/crypto/obj/objects.txt b/crypto/obj/objects.txt index 67b9ade..05aaa35 100644 --- a/crypto/obj/objects.txt +++ b/crypto/obj/objects.txt
@@ -1369,3 +1369,11 @@ : AuthANY : auth-any : HKDF : hkdf + +# OIDs for initial experimentation from draft-ietf-plants-merkle-tree-certs. +# id-alg TBD : alg-mtcProof +1 3 6 1 4 1 44363 47 0 : alg-mtcProof-draft +# id-pkix 25 TBD : rdna-trustAnchorID +1 3 6 1 4 1 44363 47 1 : rdna-trustAnchorID-draft +# id-pe TBD : pe-mtcCertificationAuthority +1 3 6 1 4 1 44363 47 2 : pe-mtcCertificationAuthority-draft
diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 17d6eeb..6ba5ecc 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h
@@ -670,6 +670,10 @@ // Merkle Tree Certificate (MTC) verification functions. +// x509_is_merkle_tree_ca returns whether `x509` contains an extension of type +// id-pe-mtcCertificationAuthority. +bool x509_is_merkle_tree_ca(const X509 *x509); + // x509_evaluate_mtc_subtree_inclusion_proof carries out the procedure in // section 4.3.2 of draft-ietf-plants-merkle-tree-certs to evaluate a subtree // inclusion proof for an entry at index `index` with hash `entry_hash` of a @@ -686,6 +690,13 @@ Span<const uint8_t> entry_hash, uint64_t subtree_start, uint64_t subtree_end); +// x509_verify_mtc verifies `x509` as a Merkle Tree Certificate issued by +// `issuer`, which must be an MTC CA represented in X.509 format. `pkey` is the +// `issuer`'s public key. It returns one if the MTC is valid, or zero on error. +// This function only checks the MTC proof itself and does not perform a full +// certificate validation. +int x509_verify_mtc(const X509 *x509, const EVP_PKEY *pkey, const X509 *issuer); + // Standard extensions.
diff --git a/crypto/x509/test/mtc/ca_cert.pem b/crypto/x509/test/mtc/ca_cert.pem new file mode 100644 index 0000000..31aeedb --- /dev/null +++ b/crypto/x509/test/mtc/ca_cert.pem
@@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +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 +AAAAEAAwCgYIKwYBBQUHBiQDAQA= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_10_0.pem b/crypto/x509/test/mtc/cert_10_0.pem new file mode 100644 index 0000000..7225580 --- /dev/null +++ b/crypto/x509/test/mtc/cert_10_0.pem
@@ -0,0 +1,131 @@ +-----BEGIN CERTIFICATE----- +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 +AAAAAAAAAAAAAAAAAAAAAAAABQwQFR0k +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_10_1.pem b/crypto/x509/test/mtc/cert_10_1.pem new file mode 100644 index 0000000..1f9a550 --- /dev/null +++ b/crypto/x509/test/mtc/cert_10_1.pem
@@ -0,0 +1,131 @@ +-----BEGIN CERTIFICATE----- +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 +AAALDxUcJCg= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_2034_0.pem b/crypto/x509/test/mtc/cert_2034_0.pem new file mode 100644 index 0000000..12bd95c --- /dev/null +++ b/crypto/x509/test/mtc/cert_2034_0.pem
@@ -0,0 +1,137 @@ +-----BEGIN CERTIFICATE----- +MIIZJzCCAT6gAwIBAgIHAQAAAAAH8jAMBgorBgEEAYLaSy8AMBkxFzAVBgorBgEE +AYLaSy8BDAczMjQ3My4xMB4XDTIwMDEwMTAwMDAwMFoXDTMwMTIzMTIzNTk1OVow +STFHMEUGA1UEAxM+aHR0cHM6Ly9naXRodWIuY29tL2lldGYtcGxhbnRzLXdnL21l +cmtsZS10cmVlLWNlcnRzL2lzc3Vlcy8xNDYwWTATBgcqhkjOPQIBBggqhkjOPQMB +BwNCAATLGILXqW2z5I4vzs7AeEYPMr393JR3uwzzSMB/ndUv4BXfwegcqmYDssmh +gt/jJWFxWV41zG5+wB9w+55MtfRWoz8wPTAOBgNVHQ8BAf8EBAMCAgQwFwYDVR0R +AQH/BA0wC4IJZS5leGFtcGxlMBIGA1UdEwEB/wQIMAYBAf8CAQUwDAYKKwYBBAGC +2ksvAAOCF9MAAAAAAAAABAAAAAAAB/QBAKUTAApzweH/qK6Xkb9Rh9U/J/6IfWcZ +c7bEHkubPaLrG5et2vSV4vmqPc3JBkPuX2qkZAXM5zuOOjc2xoUAG5+wL/bC1VVY +e+NqD2cbMBOWn3ro54uPRivI1XwNvEtcFk8XZaq9N2kR5fhCIpq9btfOlmr7cTNm +dTdLdrONh1p5Vk24uVwfbSJ9qVNinDLLI7xFo1PldrbmYy1XAESud0hZ4Ny4COkr +/gOuakOCfZxHEwEO8QlNgdBG0dmC3Woj/ptnf2HEwnX0gjHNjmtpXD5Nis3c0kxL +yInjNhUavkeVsvlWaU9OjXZa0oc3je1B38T4EFsd5C7tdFi4TPeBDtIWwASB/VkB +CXS6SgJrgpSHvKcP80FirwkNTZ6q4R+2lw1sYgPZ8mhgn1d01u9LrnNfROCOVly/ +mA7CdZvohfwT0NdNM1TQD1iM5oycDVy7mMqpXe+juNB12le60PZ5/L31MUSpUSZm +BDAXKEIhOi/9hMSvoK1VuXlMyn3eFBBO0QcWauHwRZQ8wfA3cEJjYxgKgxNqovKS +Kw7B4+QnaIeYb+C0Jx0AXsBhj8Ro37cUNhNd5VFy4oC1w479TDkVmIOjhQeIzj92 +s3d5iVlA0tMR18CarlqCCVo/gWO9A0Hc0HNa1PbckvcQx2qcrbLa29Iiw+fJBPzb +45EC3gtrrKxljgfECARpnhSlKGrudBqy9uEwQJ5WT/JrfndJfb/Cfw3qVvtg4aEn +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 +AAAAAAAIEBcbIio= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_2035_0.pem b/crypto/x509/test/mtc/cert_2035_0.pem new file mode 100644 index 0000000..6a7e03b --- /dev/null +++ b/crypto/x509/test/mtc/cert_2035_0.pem
@@ -0,0 +1,135 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_2_0.pem b/crypto/x509/test/mtc/cert_2_0.pem new file mode 100644 index 0000000..0030901 --- /dev/null +++ b/crypto/x509/test/mtc/cert_2_0.pem
@@ -0,0 +1,60 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_32_0.pem b/crypto/x509/test/mtc/cert_32_0.pem new file mode 100644 index 0000000..9eeb06f --- /dev/null +++ b/crypto/x509/test/mtc/cert_32_0.pem
@@ -0,0 +1,130 @@ +-----BEGIN CERTIFICATE----- +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 +X2KEjbK0/AAAAAAAAAAAAAAAAAAFDRMaISo= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_0.pem b/crypto/x509/test/mtc/cert_33_0.pem new file mode 100644 index 0000000..95c348a --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_0.pem
@@ -0,0 +1,131 @@ +-----BEGIN CERTIFICATE----- +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 +ERwk +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_1.pem b/crypto/x509/test/mtc/cert_33_1.pem new file mode 100644 index 0000000..c900bbf --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_1.pem
@@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_2.pem b/crypto/x509/test/mtc/cert_33_2.pem new file mode 100644 index 0000000..2aa5afe --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_2.pem
@@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_3.pem b/crypto/x509/test/mtc/cert_33_3.pem new file mode 100644 index 0000000..d19dc09 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_3.pem
@@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_4.pem b/crypto/x509/test/mtc/cert_33_4.pem new file mode 100644 index 0000000..b921b58 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_4.pem
@@ -0,0 +1,81 @@ +-----BEGIN CERTIFICATE----- +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 +/y+73wAAAAAAAAAAAAAAAAAAAAAKERgeJCc= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_5.pem b/crypto/x509/test/mtc/cert_33_5.pem new file mode 100644 index 0000000..ed50002 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_5.pem
@@ -0,0 +1,132 @@ +-----BEGIN CERTIFICATE----- +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 +ABUiMD4= +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_6.pem b/crypto/x509/test/mtc/cert_33_6.pem new file mode 100644 index 0000000..3392c30 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_6.pem
@@ -0,0 +1,182 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_7.pem b/crypto/x509/test/mtc/cert_33_7.pem new file mode 100644 index 0000000..1abcdbc --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_7.pem
@@ -0,0 +1,201 @@ +-----BEGIN CERTIFICATE----- +MIIlJjCB+aADAgECAgcBAAAAAAAhMAwGCisGAQQBgtpLLwAwGTEXMBUGCisGAQQB +gtpLLwEMBzMyNDczLjEwHhcNMjAwMTAxMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjAA +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyU +d7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0VqNDMEEw +DgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMBcGA1UdEQEB +/wQNMAuCCWQuZXhhbXBsZTAMBgorBgEEAYLaSy8AA4IkGAAAAAAAAAAAIAAAAAAA +QACgwTCZzVZE9nT5TOigqlp5Q2pBimcyw4f6tVVUOpgiRgQbl63a9JXi+ao9zckG +Q+5faqRkBcznO446NzbGhQAbn4pjkCXYwjIHwhXrWvuWcLw2lPsGdGQjYdSTe5yL +4dt8ZKJpKHJzkmz//f2PRjmzt3KLkC+HR8OTZtVI6LrtE0ywL/bC1VVYe+NqD2cb +MBOWn3ro54uPRivI1XwNvEtcFiNlBIH9WQEJdMhMc5L1Fea4ozlnkJYj39ET8HcA +K9svmU/IxZb2sqlKvN5mJPDVWQY6R+0FqvXnS7urTxoMjrzqfaeHR9fufswb0TZ7 +uBxqaL0IKEme4A7GWOMtIR5DeZWsEvhWf+45epOOThfG1SUnGpMk3E02WGmn2z/L +chG6f5+eBU8kAXn1DGdNV3fIa/R3c/81NLk5sJA84LrAAtCZDMBfTLQVz/5lyDL1 +x9bRBQYRVm3w0RtjUesRkWMjaLpfVWElSTiuQJkut6c9g1xi5QnpIlrh9XCnv8v1 +D5dwTexLgzkXg/CyPtG15D8G156YR6IQRhqa3G66FZJ0wYS9XcNZ4uvPCXHqGc83 +vgjehyIwE9mTcJTsAJ+cYVwcmeEp2eD25zqJMTvXEuRdlG2Uu+GhboWT9YLqANs5 +WIjc1vloRRSAOgmL6jtgtu8l7Urr7oOamoK8zt+N6iIHfBDeEQYvOGxHQXZOQ0xr +ln5OBqwCCmkZIy+lP+4ETvRf0XzvGVPZPT1cVYQ9cXmNd/r7m4m2OaPEo+e4bqGa +18nInY8gUERCKCa55wsPl89QRSIFojRQ/0WAF95ZZpBFE2JsOoDb4qG73RYK+NVe +S2HZdBlVU+AwtLNE+471ek1ybZ8CS8ptokrGLqb3h2I/Lm/YPSUJgnV5a6fYHDid +nDjlPw7dRWQF32+ZVtlfgi/ONfm8AWGrpcBKr2hkWbn/khhpyH2eVJGvKxxKvztT +i5dNYup0gQBsCLyypBZZZ57dmcQ7P7FBqjCD2bc792sI3EwNMI3KP7eWfi+NzS+f +muEbE3KrYWQn/9aN7ezocq5rfs140zccEqOhbipVBUs5WDxf5z6oTDaOKOipFBnt +lClLg6OyZVoSgi3GGMv3hcmcycejQOndPJhxMgFJhqHXtC7T/E+L8/l6lRvONOdF +/qjpGI14rdjMsZX5GG2rH/AzXxpfOtSvtm4hYKIp7OnhyA5dlA3NDRbMGW1sO4fE +XAFG7hyqdO7cJKRklMAt4zod7v8ebRbO7vll0PCnjftOpGD4e9AxS5MfKiCEZ+Ep +9Ky/7vXcjAdznAeDpvZT1SC/YSBdZLL0cnUYf2RN2LhDpK8NBKTDPLxzFYRrXSIT +ADeFK+bfWPZ/pSzFccmHoADDxtCXN7Xpp//KJpdW7gKfZLzvSuff4HiymwjyH58e +VY++z6k0j30r9o1SWk/tqtPewB4zKqmsQFJ1GC0zqb6UEzyBq9IwSuKIVTgCOGif +Nimo8tMHBvCJCGTtnQD9bKStbqztgV3ppbmnc0ewufGPlTpNHxh+GqgteXwG+T6p +4yVo2k5cT5P4yzcKpO6w6W92VywuXw3VSCtX+LbIcXRGspxbUy6J4/xRTlBgldR0 +NTPa/HokYrv3qVXVrWHrfVYe0pNvZVpU6lNhp5cwhQ97/ByX8BFPj/WVsytHMdLE +LV0cRoHveIK26G9PAR8WDAzVb7UpFJ8NB+94PZnlPjj1g1DC7oieRx2WfXCQUtZW +XlHC6uTTBA0+WU1eT5geN7Gt+lqD2TUZ3GtM6D6m26FaO3sXWmDFYy8VcXpS1aKj ++ARLqLjmCh/Z1KqHDGfVznXCzZdWx7A/iuV63Zwe2vXRYh2SMCqof3ytHrbEHxKm +XCR/uy/0OmMgZp5LglWaWM5KGAPBzMK/U/oUDls0tGIIOC8VXJZZj6CsIpmZbSeB +bAAQX+grDgkV1phHrClF8t6FDU3/cRtBXbL+ea1OxShulZoAftuGjuFqdirdj8bC +e7s6gufGMja0Fj3EKltLPatp9EeZfncyltgOC983bstHq52906FOg57O+lsXN8Dj +DWR/ZK4pz56F+zRPDENVbK8qEXBtyAqeKtpE22sRKn42c3ILeOlCQyO65mWgv5K0 ++cVXigNWVTo4so5QU0V8KgyNaBFEerUwvoZ83M/XbwRpLeoss3CdZY+btDudqdu0 +l6CZm0YCyv2SaEvTAc6HHWvq+wE9jDsQQqjK2ZEfah52L4tzFHptv9WCxB5reR5S +RjeUXos3TIipVnRMoqP1rBMsGilHTvDPQl7zfuyYshGP30/dndjgFuaL2gqY13VF +8LJTbFrKlkvjDZFUYo163b9IGJaAhTEyn+Q2PejBddxUP//V+cDV+QNEt4tl6ylY +O6LKfVg/O22GoG7QRkTwPLkkbH7C+/ZzXFo16DN/r7oFXcd7PtLugMkDNLjEnpkS +YDj7CkXaUG2ROGxs65HsZWZDW20KQcCcEVcOT92LsZOo/ly9mTr31qwt/+1gMBWi +bX4DhfHHjT3iN2x1+AWclo9uaPHdEPykKhy+AYyeEmw8+jKzx+XDg0c/21k5jQBB +qwfDMClvcyvYMw/dxshbTDTkLWYsLIjoSmcznlJ9rrnU/y3DV2hgKpzVAawj9Wgt +pfzA5QTmiOR/jh9qrIhkGXjVyR/WdtXKkrWIU5Vb+0WXWEcrxjGlJIyhPfgNyn/B +YTc2GeiFFFe2VZz722LGNTJUXT069Upy+bLC1K72vorJugUYvNe7XyYx0TcbvLP5 +f/TRuLVhImF56J2mtUpcGIvIy+KbdIHodsWmK/BUl4L4EXhW+ei1zpPcMqnRq8RN +TufDGfWQaSLUd2rQ/TbxyNZGNRSii2NadxB0YdHPzN2gA9XhWvtOKl2RZYgkij6h +TtU3tiVdnl9ypv9M7tPEqS8pozxQijuYnLs20hXxZCHLTCxtHlSEiOPxh2UHR3Uu +Omcipi6/74ZkzfOEtolzL6kDmMmZ7zIHQmlAEZfBFwxdvJ8PJkP550AlZomyfc67 +Z04+JeTd4xupr1POl/n5qSMOhE4f1ZQQb/56lCVHiM3B2Uhi63T/jgjsF9Qj9GH/ +ROJk7G6QcglfAJSnYuj1aU7KQfrhfNqtQmF4YwLbYCjHyfQrRFQiDMrEFK1uYhY3 +ppP5/6g/WeSWzDZCGYtxkExy/BmVFdyELTy8aA3HOwaFi3PyPBU8WLb1VJFUfcMI +rfwuDqDf+LKFnFnwSxP477SylZZAVjytSSV1CMwYNEDIjaseRh5MRO7qL26g85PS +ENpBGE0nA/1MnlTu2zxDDbKC6xGRPzaOoadfy9bSQ9X4OP2yS02Z8Oyg7f4CmTJ8 +W1e1+wi8eBd+tsxHDxEiLUVGaHuCiIqOp8HF1eDj6CMsOUCRtLzM5vL5Hyw0PU5P +XGNljpuerq/X5+n3+gUKExgdHic6REdTX3+ItrjI0Nbb8vX3/wAAAAAAAAATHjFJ +BYH9WQICDO2ZXyh152BEcmBPXl4LR7dL569Oq9jMsY/2RV81gAe1Rw/eXVpVGcqJ +6pWa9c0/Lb57VGElvoyue9gHFIOoIPE+z/mf31DyrhfwaxHvORDGoDTJIz+NsFxF +Srmxzu68GmtWe3YfglXjpNkI7CpnirTziz0xX8463EteLth5ACihqGOzSanq0a2P +mgvuEZzBbyEO7jZIojbbRM1SuJGT3KezFmZXYBw8mnCBRJsl80TYGlhQjZdkanuu +79e5OfsHiDmD5V/k9I2K9TlaiSrIZDBcNhyFcvsSjFLe83pZXcrk3VvELljbMakt +tpe4ELGft3HGxMWH2MymWr18TpjK2wdF6TlmFnyq2TM/avjzAZ5v62kNrdojSanO +encJWLPzqr2XcMZ9M3mK3jtNWMc/lPqXhtZCUMDow5PKVVXwbYjkRSr65XNj/Uys +K03aHYZ1+MRIzFiqQhaX2by+97Dmv6iyEl6sfkOghJoRRwBbsO0nS0KCse90cmM3 +zLEP/f0F1es9Fnso+2xqEQOCCU7+SYC1J43zQ+NfAGHCdREGI+cdLcTjGo15eV7Z +d/N66SwyLZ2licgbir774Kh52f9fTtKHAlUOZdcLLHujjVZALeYaPDCbtlSKb+wN +swEDF8DcjBseHDTmn8l2mXcAfSAvjnX4zoZVd2N0k41zOs5Dz0Uik2TdJl8J/7Mf +F06ASas3YGJjc1U7jEnDtW6WVEGXmd3NMOAVApm+R26XsVHk53ZQuCgV2mBC2NYL +t39maLF4MxYeayd4PcO37Kdcj4QzYmc1gLr3F9Kbn3rgIJWUbz6itpfTGjuJWqYE +4DtWEstB+vMLkS2L11S0FE/dUJN+IWhSKyW/rkV/gucfRmxhkFfpImArv8FQZaxc +uGBr7qmnglaOCiBcM2qmMsEP7cpzSqUBxWaOZ3v+HCTBVSoPJ0jqyZ6aNlKnEgN+ +/BZPD2VANRpSyegO+85lI5DIdFrM8k9oRDHgb9NMZKSbzdWPaY7QT4IVx7FOX6iZ +tjhJkNeltrPP5dN6aOdximgVAtZ4myrkGIPgUcpruafv9+FkeKyzkHsil3PehWCc +RuZjoJ63+xk7wBW+VSwnwcVS0IZnwq9pHzui85FaBHcdB05/8+EGS+TOn47MmtE5 +T5APC1PSnJw4Xya519xhAgI+SsG7uGiSkmunQeDRZ7JrWBcNWwPCqyAnn/KuCxFT +8B92WQiDr5HbZJbA6B1VFV8+Hp943lRMNtHROQ9l7IGk5bIroaUpK3mhOPJRURPp +A6S0HvyeuKN+6LfwEu8XzRvtosZmJuMqqPvPJ2QIzSQyG+cqQY4h56s517LHs/wi +sU4KD9HHWvT5uWln5Vz05/bHnEjB2GOJdpiQqwe1ZLXJtUfmKZEese0itjViUm7E +aKLa4T9HI19nKlcSXy+TWh+VEtPF7vr8GsyxS7kcJe4gFOco/23pGvw3urNcCaY5 +SF1zufBLDgffWyDwl2kkxV0V7zKuW99G/xA5z2uw3GV9Gl1xYYLxQ95KLOSfvIY6 +SyEb4DveoPCuurzIR3V0G+7LnazBEouSLjh9hW/AYmF3gdJUvYkyn6M7LNcchY0b +2KKhUdDeoTIiljGbkaEaG5e/axn4C6o1rxUNEf6EycdA5lhLeU1uEa+A/7bChV+B +Gn2ao2LZrUoPZ9mBacFm3UbB8PyMFGeUYQT6LW6KifPYDnlTf24gzF9h46JhW+v1 +nP7FB14BzWHpeWANUYunnKaoXD1o6hGjCu1ui7T6VmiPgR8jfn6RgYdCYZzGGBid +PXvlXfaRMM40nN9szJ4PWVkTQ/7HgohWGcKXSqEhUu9PrWnaBLP7/bPcETLlADQQ +4JazXAoSuUy5/NS9pOBnZMCTNmIxXFTqV2xRAj4Tbqc5Gh4y9yP849Z/iT2pBJNZ +2MgS1p1j4P9I3GBD5JXmOI250Oyq5DlhLRKPaRfy51BLdTzMGspHAgOBcW9JmyE8 +NQv8iU4YlM40KamO2ejvopTTXzQoNetzsJYlKyVco5nzNTULGvRd9k2HDQgyFK38 +NPh+bGnfg/fz2gM8fSo26DppV7MO4SfeDnMQunJj+LgVSwL8jo6tSZJgCWJJ5C7z +hr00CP35V+j2Zj7SuZf/ZhSSgHhitY4SkNk/2WUJvUYhW7v5g3Q4sjJrIULYLyo/ +E6nSLRG+SRyHoM/LPBoSBCJSGwm602zyraRnwQYlt8Oq2t51NQ9VH168nEF9mc3A +xUBLaKTodqkd0xAk52yhbjycYabpphRtigrhKRFMXw0/2mp3z9m2315KgENQufe5 +XCGGRMltw7h2QNV+jFejZdrIt+52Xx2zE/0EVWydyerUBAnoljE5XLbwOw2QwIdw +5S9t5lHFO3+xlEpv9KNbXO1Z78ELfpkadhPwgQG5AdE+NkMvkIwI+MmzMK0Iwwqd +l+MaU6cNBfwTOqe8KS/BP4cVCnNwNsg1uXj+nOba9pH4Ujrf/rqSFlsoOGL8O10k ++QTb2IUAeTGNZ3k2HWzN3Tm8P83tY3ekVDKtP6LEXuoz8dUrojOuONOwjQFXXeBU +XXu5Pzr4KON5bCVhgkEFmpZLVaNY2TawZm/EeYKJYegKgw8gbexNNxyvV7LWIY1y +fwizXglIN3TaHjZKxuMqHtLCkpYQm0hM99/JBxfW6HDJpkIZJWG/fq48WukY6/9a +HmS5lhFRn91ilNbzqJogAPrxYnf2zMLT+beXDDxIEemO1N9Pntg3SsuL7Svpu+8q +Jz7qO+HyRh5NcLPZBxdjM9wlXVY7zUHXVH9sj7Qy5yMFyyU0IqyKgEVs+HBQOh8A +8CvMoAJhaYkK0IKMcwY1rA2wQkV5RfRCFs+dSpDOluNKwCgKrRRr+I0EOQyQ8oZF +zhQrT5b7DDDOrxZEbDN/Guyg7OVAcQeDXEqkLTYTJDDl9ZhfkRSRKz12SaubrI6l +R9aIcnNcBcjfCJMxAfI0EPgCDqA+T8f8W7+aWN106CqzLl+yrDO/W37ZwjwuCgKV +c3ZK3DOYP+LmjsI0Sl7lPaNdH103UQQrSXGwZnEfy8BbfyJPrBKkkl5wQ33tHNIu +zi/fQKil4J7SAc5sQUjheT/weNJbP+lMWXWuM+00Z2cb1Ynn14bXRnNrM9RQOqze +y57KdSGKVkppI+a/EWZ5ANg3xSxcepzeWtEDrysZyTlKLEbp38d0XLs95JWJp7at +vDPJzTqJVJqlfCvNtocVK0kL8oH6MBZSPLO4T2J4TwysJ8XYEt5wJ84Nor5+q+vb +9kKjDqyU0kzzXypU6e27ozeaameY7NjYO0rHFoNP+wKmpyNIJhsxkA/D00p829qL +sMC35Xn6drZ/i9w+87CH1B3ICdbfV2pKiKAE6eBrACEbUtf2om1wZvpvYtHBsnbB +FVN/dXruKxi1QUWlFen415RDQxmf3SZoWjFlqlISSPXACZ6ll9Laqj4yCwWsqMB8 +XhUTWOW6el1FSzWk1D3FT9C2UE16F65CZ8uQJOQtlImJJgfbPJjkrapwi/8WWGeB +dBhUxfodDUOtqizT1fcbpMDacs86JXPjStUXNJFSejOf9YlErsyttgjI8osXWxhz +RC2kLrqdRnyywhvZZjT/zjjot5yvBaM87fWAsogtXlf5EiDhraieyfHSFg3zrnLU +5NB4QCjNmMUOlt1qYzrtwIVUkabC2GuFRR5GCxEbfAImlJyZxAgJOaZ5FDGbP9uN +XXCjhunkoFZXqTtCTHl+dqwq31SJDMCj68UZqYwAs2Z2uRZiq+dg+r6IlvvBuNZ1 +YY0i8y6+DP27xpFM6tYKAFJ8Hyttpsh5YZwkILIqs2E5kCe38KVkLysNMzKoDSg5 +oQ7+1ybKekad7dZ/CGc7MPP8G8RJN/uyvgcJLjBbufOasYEix9GkR4vJtQq/H9JN +3Gs/6PElNBKPtEgd2tEElry8zEZmJ8MBk5IkG8SZCA5cdXmN8/lwp0xGWNE12Vph +VBWZXd0IGYVczm8Uijd2zwuVasJtsZaYNEQTP3pZe0zizsa4jptTGWQmPaETtw8S +YbmTVbF4YlD0XN3/LyqWHI8w/FkoEFh2E5azp9ZckXJ09XIQnA0pSOLkVbX00NZe +xJFqJnoNQSXslQj3rAP0B0TeFiK8EDMOx1G0twnisxOlxHYDHyIX+AJf5OTKMfAm +MS5rN2USdzD6+nFbjhU99pJL3kHpuZacMAENjqMZtB6zLaLYEHD4CdKZq8LNC5eq +3SVRm77bAiqNdkP5NEwfvxfrkDJhu4EsSmx53pySD8LtVe70MDqZA1qoGsq3dh0g +YU10p6O8nt0BvtekM98wAzN1Xm3XTrdERvI0CIgVJtlj5zXz6x2NzBcmSlpr3+fq +GH6pWWV2fpLF4AgrQ2R6jfRbz9jrNFZaYoWjuM/h/AAAAAAAAAAAAAAAAAAAAAAI +CxIZHScFgf1ZAgIM7deu5oa5yLBnnlKL6aux0rnNJzy6sX/LeSgVeLI2SbhUdtOm +0QiYf/l5YO47URHee5w+djqAdK6WJOXs3WctTdCF+buntgM/eYVcqikqtI0SQwik +FUIUo5Scag4IdTVbpfW0RDMn5IsczyqyCcgz8cS5nHakbAKvIpm6Rn/F312Rrh+A +xqWkLsKNxzYV6v828lUGVRLDThWiAiz5eXV48l4rNnssYL5mdNMlOAgfg2KgZPUR +Y7eAb2IMT9tsHRMgtlnsNKs7/JTO50+zEmCeCJYmDF5X/L7FrOefYEuLMd62vMIR +gi+HIlI0RNrBvS6/3V5OXPzN/9BafPpjGoqP0xhAzriiAohEafe9XQvBewt/g4fS +SJO+GUEtG586cSEPKoNKraSss1f6xihjGX70xC/cczB2jvwoyhYMj0QqEz7VfzSu +lRSEIqOvAqYdQ5ARVvq1Xd+gdNoHqvPnEacZpKqX1oXqY1S+7XhdQxREOqZQ4ZMN +PvvkdHxRJBdYV9JJpcqdunkPs90iov/VZ7yBPqQNiu79ta/A1kaG5GPtU3OV5QYI +bIR/ro8QgMHpmYJhDnNV0W4ALDVXWCC9Kq7waiLVTNPdIqMg8ZWwZo668XhkGb0a +5XR3NAxuGbI0Ez2Nn/8EvsxbkeEoCpZau4tZAW2nxy1btuzTJ0swICnLWyY/7x9q +DrCXBb6vVTpOZkA+vN5sSBd5F+Ymu7s9g0QNwcV7qexQi2avSTn+AbsULd6GP2y8 +rPHbHshC1ZMNhSIKxW18P9lgFJwQgb5e9eSZDzLScZ/mssvhnN5kG3p7BSwWeOTn +ZYDEerhqNRw/Q3didisuN30NSqEFLeyP339wRu96kX0zTg6fSMX6dsFTIMIwofNu +pA57th5d0MKZqq3td5ezVz/XU1lWgJjJG8WPe27lmFk6GTC1hZW2pVSQmiQ4FTcb +KQTcYeqX1S+92mojhq64iKxerxK874FqLRwWkkJxADlz/0ex4sJ30Dpb9h4x4ng7 +4bC5ypidgFMNeKD9TSQNHc4VSjf+Nlq0eJogfl9pJZw12tSvggoaTrPrn6qPqH9S +S2WtQpbZX3QX1MCj/fjWXJsZQ3vZcZYzUZRxnTkh+O5zodoiyd8jLfnjSAeCkbY/ +S8FFqdOAD3PHYsJ1t5AzIMRTotGKSvyEkfZFmWSCqyA4o5OJYdN1AMEd+LhDvMI/ +cJqWU26WrwzRqSW5HZtZLbPGvLlFQuPMsWy813D1CdeeaY3Z8cvW/W6LF/v1Yn+j +B1fE8bNZO0z1AQjjvnOa2k+3GJ3WGd/xOrczCwAMZUtlcJ1TUyyMRI5vS31nqjRK +SAhA94n7MmwUdQDrzxuefZZPuxL8Awu5BS+1UHxcWVJMIoEM9PFoGbyaN5ndCNPk +TYQ0Ur0DkRHIyWC6+/z+TeO5EOsNB5bzEm1tcNsvADm0a2TFsrVcMyvjpmaho5ln +lD5mXGpgHRdHn1Id/8i10NgaMK4AA9oRDecPrV7mziKoE0OjdTSIkLmbWRij3Lip +NAgxrbSHhQxrQ0Qcsd9JWHfEBc+fVqBrHJSl9w06qLaaRZUnbT5sSw94yap0NGfY +aeB8ZLvPcZJ4THgyuzqoIoVa3DoypZFQaRybbamy+x6NIw46/EYfZ3Pm4xcTOsfZ +5xMEzlGsSqf2c8DdfPoRxoQTxk3rgmdY/C6bRzNA/TJQqmD4+tbPlfB6/mvmjgrW +zfD/A0OP2mBizT8KeuSeTclCUy7jwVrXkNuNoc8PdC6gYxZjJd6VJp+4WUbqsZtA +AZBpzyryR7XrlE2WVUJYlPWw4bbVmT6u3ikvKGedKpP2u6L7+itbUDEFNNlmdE7f +YjMdlYSkWxkJ7ckh1XU1jP4tWX5CWuaMxum6tIzeidXnzRqKUPWv9Heoi+4Jxvr7 +8zLraoyhOGnXB5GcIWYE+eKDzPUuc6XA6tauRFLONKLzEaBCrmead9xfnUeGAnPV +ieAwydMpyLp0OwQ/UvWfW1HxIx2jcuJX+nCDbH1bvNY5YjOt0Vve7kIAxPLg6LVy +5t3DWPegwz8ZxEwgtXUgkgWmrP7x4hBl5z7ukwCxabfatUNhcd7fsA8x3MnOnz7Q +3tNquaPe5HiW9pqG8b3hk7kdgwW6R1pzdfCxlPqfqVCB9sQfHfZAMrxw0/6mhGiw +jkAkcR6TIwHfw+A6HXCyjHG627icQ843PsVIUgNn+39BPo4Z4q9KwkFyd992uHBE +/p0eF0fbODHRdA4oJFF98OFJrjS98uYdwPaBnFDT+A0VigffttFqz+ogtLbaQedY +fSLNehuzOow5qggUGhxa6wJRH7dmQDTvuHqIxlXGDALD35B+geq+ZHGWGXJG1hlI +kizPEnRNoI1+lh59+IWxiOxwSJBZnHXgLBggLFBJ6RQ2JYONjPtu2nGT2715fcCZ +Hrjgj9SZFZ7J1C0IsOTFvSdoc/WTpUrZhPuBaduUr/M120Nh93i8rolqYO7bhKU8 +oeXXEev18mvC8MPnDNi0n6Y+Ou2JnXVFwsgxP0pyVCdQJIOOvECOZTldpWZb9bsu +SDlxD5OyKt/AsP7Cf6e4JiD4KLwTklPXAZhqcoJ/WkO7I6aSenh9Y/ltqJkjZWoa +/G43nTxIYUhQ5Jvy4l8OqZUe83iABZb5rAvZ3/OFRCAPhjNhOe240b7zAdgNVZR1 +gXHTkUqM2tTGSN0M9QZN9GA1Et8QoQT5yrpA5AAnkeI/1KCW6oRZOs6zu4Da2zxJ +PKRyeFYCV6JbLJ0SpcK++aZ2FG6J879Gn6w+Zf87btxFq2pUWjxvHacjPF5UtpxZ +V/D96QWSKiNSJ/7g5jusiJBI9iu7rHFGtBrK0Qo4n5lB+P9AIue0GubUtJzy6Axc +ndRu7KHTS9C2iR0Y2vOWCdryn91kLK5/KEcbGK7911sk9m8eKCoIQgWCqq7ZtTqu +4Ztz4sZ2lxiDQC06AYlg39q4zX/JYIHw7jboNlVCjhEXekWuXf6ohKs24Y87MC9u +Swfj+eifZrjtWSdSVC0kXtukF6MROENwwzu5AgEYxK9+IKEeoXsvLaIMZ/7Mnx82 +3ONjcXAZlCziW8EWmyuRdB580qJJHXSm/+fbv6JVPcB6fJb3JdgbN42H2EdOhSuS +MN6IXeoePstsxAb5kG8t8BUkqaKeQs4i1BglUsToLcS3NjQ2fvVrSPUv37kv5cfx +U+afVZ411QUFCDTahWtkeEi4jfCajI0/UTEfW+B1uBYS7Ohx43Aprf088/9d98JJ +LohjrUwHdafCD+LEDS5bfRO7eHFaox+D4sc6hw8sUu6ed37tTghF+KUZv2+T554G +JbSLGlmG4lF2jTbP+anl9sSxk/dVLncyuV71rHUzHruStDJVWmoeCA8IrdltScpI +7CquRpI78FUhL/RTrYHtAG9g+Ms3Xa16k/OFjvVMJYjE924ZGAS6c3ApkAiB5syx +z16elyYzfn7RbfdAfc/Oa94uoDmy0Owyvt/PgcUf+D/44LNxjwCsTDlduVrpgeOL +K8IZs8U4ksOBJeXgnR16Eq2FV3e1R4YIJawtkq9XE/6hCA9kotXmcHQeZvPJDdCY +vvNzQiepqlJ41rNdhnHdHJxRimYPZ9KZ6I9tT91f9hRI4J0+51ypB5pfZzvcXsie +v3zatBoOfGMXnob1GTLovAE7QIOBfnBzyL8/KEgRl4wgG7aPTBBi9S9CDDnUW7vG +GpNzAX58j3O2HLOMYl0HO+uvIUB8rVO1fvNbmv476hDLFsU8ehlbppWk/zNDKFc5 +t90IpYFSvstc7Rh+T7e6eBl+yNo+5wermwuw6R3qO/vfqaA58Fuv1RpIZ8pjLE4S +To/bK+bbLzd2qp9m4iV5NMYjg37kuxIBpIisyBkIr9zl+7GOCwx8VfMRdrWzhRm0 +w+JtX8lHV+46UhLK5UM5WPySIH+RWt5mTh/Svy4V5cWn+8X5Ch8cld0jj/LxeNh1 +R/SEj7u4tSRUaKmGU+ej4aLE6P9AZARCwO3wCWp0tp5bTpDtQpUXjJUOTKCsVIwG +NQjmYNX+eld6CjJMGdyoLFQd3nSZ8c/cjApI/7HjYvgHvbwfQD+W+MFgYLvWCKZU +liTts8ufvA57xKiEiP9hslNg3kxa6pqRMcpLkARjSVcfbMkTKeZifLzVO0oKEeED +sTZJ+O3GrhXnnRG/nlBulqM0MXRzV9xGFAanDbj47kxRPcDgyXHstzgYunrmngn3 +TRdRLC/pHA7PwgEroyL5bMJuTiZYlvm5oJF2Xmo4vGLTVGSr3h7058ZrDlKzvz8W +tr/z05UKEZN9aMRuA3iOeHxT5H/1ydR6BoDN59WYFVYuaNJShYqWuO7Sl8lCDmV1 +fpTT/gFMUVylqs8LLkmazM8zWnJzkbXYGiktUGmbo83R0hYdUrnxAAAAAAAAAAAA +AAAAAAcOFBslKg== +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_8.pem b/crypto/x509/test/mtc/cert_33_8.pem new file mode 100644 index 0000000..9dcf2f7 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_8.pem
@@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_33_9.pem b/crypto/x509/test/mtc/cert_33_9.pem new file mode 100644 index 0000000..e4f4707 --- /dev/null +++ b/crypto/x509/test/mtc/cert_33_9.pem
@@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/cert_5036_0.pem b/crypto/x509/test/mtc/cert_5036_0.pem new file mode 100644 index 0000000..05a3793 --- /dev/null +++ b/crypto/x509/test/mtc/cert_5036_0.pem
@@ -0,0 +1,63 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE-----
diff --git a/crypto/x509/test/mtc/mtc_testdata_config.json b/crypto/x509/test/mtc/mtc_testdata_config.json new file mode 100644 index 0000000..ac39cf8 --- /dev/null +++ b/crypto/x509/test/mtc/mtc_testdata_config.json
@@ -0,0 +1,177 @@ +{ + "Version": "plants-05", + "ID": "32473.1", + "LogNumber": 1, + "Cosigners": [ + { + "CosignerID": "32473.1", + "SignatureAlgorithm": "mldsa44", + "PrivateKey": "MDQCAQAwCwYJYIZIAWUDBAMRBCKAIAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4f" + }, + { + "CosignerID": "32473.2.1", + "SignatureAlgorithm": "ecdsa_p256_sha256", + "PrivateKey": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgthrguld6LZNJw6UMbhyTkML7u3BMcdEyomQIwB+N2o6hRANCAAR6nKeTu+M2OxL7HCjH/i0+lnIx7OE0b3DnXWVue+5TBVDq8aG6KqFq+xprV5ll6QtPJb+TTBp+Kv1IRpDxMpxt" + }, + { + "CosignerID": "32473.2.2", + "SignatureAlgorithm": "mldsa65", + "PrivateKey": "MDQCAQAwCwYJYIZIAWUDBAMSBCKAIAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4f" + } + ], + "CACert": { + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "IsCA": true, + "KeyUsage": ["CertSign"], + "//0": "MinSerial and MaxSerial are set to exclude some of the certs specified below, to exercise serial number checking.", + "MinSerial": {"Log": 1, "Index": 8}, + "MaxSerial": {"Log": 1, "Index": 4096} + }, + "Entries": [ + { + "Repeat": 2, + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["a.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"] + }, + { + "//0": "This cert is invalid because it falls under minSerial for the CA.", + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["z.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"], + "Certificates": [ + {"SubtreeStart": 0, "SubtreeEnd": 4, "Cosigners": ["32473.1"]} + ] + }, + { + "Repeat": 7, + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["a.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"] + }, + { + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["b.example", "*.blah.b.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"], + "Checkpoints": ["fast"], + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1", "32473.2.1", "32473.2.2"]}, + {"SubtreeStart": 8, "SubtreeEnd": 16, "Cosigners": ["32473.1", "32473.2.2"]} + ] + }, + { + "Null": true + }, + { + "Repeat": 10, + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["c.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"] + }, + { + "Repeat": 10, + "Null": true + }, + { + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "Subject": {"CommonName": "No extensions and a common name"}, + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1", "32473.2.1", "32473.2.2"]} + ] + }, + { + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["d.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"], + "Checkpoints": ["fast"], + "//0": "Only the first two certs specified below are valid. The rest exercise various error cases.", + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1", "32473.2.1", "32473.2.2"]}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1"]}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1"], "BitFlipProof": true}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1"], "UnusedBit": true}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.2.2"]}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.2.2", "32473.1"], "DontSortCosigners": true}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1", "32473.1", "32473.2.2"], "DontSortCosigners": true}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1", "32473.2.2", "32473.2.2"], "DontSortCosigners": true}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1"], "OverrideSignatureAlgorithm": "MAsGCWCGSAFlAwQDEQ=="}, + {"SubtreeStart": 32, "SubtreeEnd": 64, "Cosigners": ["32473.1"], "OverrideTBSSignatureAlgorithm": "MAsGCWCGSAFlAwQDEQ=="} + ] + }, + { + "Repeat": 2000, + "Subject": {"CommonName": "Some more filler certificates"}, + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z" + }, + { + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "Subject": { + "CommonName": "https://github.com/ietf-plants-wg/merkle-tree-certs/issues/146" + }, + "DNSNames": ["e.example"], + "KeyUsage": ["CertSign"], + "IsCA": true, + "MaxPathLen": 5, + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1", "32473.2.1", "32473.2.2"]} + ] + }, + { + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["e.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"], + "Checkpoints": ["fast"], + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1", "32473.2.1", "32473.2.2"]} + ] + }, + { + "Repeat": 3000, + "Subject": {"CommonName": "Some more filler certificates"}, + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z" + }, + { + "//0": "This cert is invalid because it falls above maxSerial for the CA.", + "PublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyxiC16lts+SOL87OwHhGDzK9/dyUd7sM80jAf53VL+AV38HoHKpmA7LJoYLf4yVhcVleNcxufsAfcPueTLX0Vg==", + "NotBefore": "2020-01-01T00:00:00Z", + "NotAfter": "2030-12-31T23:59:59Z", + "DNSNames": ["f.example"], + "KeyUsage": ["DigitalSignature"], + "ExtKeyUsage": ["ServerAuth"], + "Checkpoints": ["fast"], + "Certificates": [ + {"Checkpoint": "fast", "Cosigners": ["32473.1"]} + ] + } + ] +}
diff --git a/crypto/x509/v3_purp.cc b/crypto/x509/v3_purp.cc index c330eb8..d832c5b 100644 --- a/crypto/x509/v3_purp.cc +++ b/crypto/x509/v3_purp.cc
@@ -142,7 +142,8 @@ nid == NID_policy_constraints || // nid == NID_name_constraints || // nid == NID_policy_mappings || // - nid == NID_inhibit_any_policy; + nid == NID_inhibit_any_policy || + nid == NID_pe_mtcCertificationAuthority_draft; } static int setup_dp(X509 *x, DIST_POINT *dp) {
diff --git a/crypto/x509/x509_mtc.cc b/crypto/x509/x509_mtc.cc index 9838a0c..989dd42 100644 --- a/crypto/x509/x509_mtc.cc +++ b/crypto/x509/x509_mtc.cc
@@ -12,14 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <openssl/asn1.h> #include <openssl/base.h> #include <openssl/bytestring.h> #include <openssl/digest.h> +#include <openssl/err.h> #include <openssl/evp.h> +#include <openssl/nid.h> #include <openssl/span.h> +#include <openssl/x509.h> #include <assert.h> +#include <algorithm> +#include <optional> + +#include "../bytestring/internal.h" #include "../internal.h" #include "./internal.h" @@ -27,8 +35,38 @@ BSSL_NAMESPACE_BEGIN namespace { -// Prefix for domain separation to denote a Merkle Tree interior node. -const uint8_t kMtcNodeDomainSeparator[] = {0x01}; +// Prefix for domain separation to denote a Merkle Tree leaf or interior node. +constexpr uint8_t kMTCLeafDomainSeparator[] = {0x00}; +constexpr uint8_t kMTCNodeDomainSeparator[] = {0x01}; +// DER encoding of AlgorithmIdentifier for alg-mtcProof-draft with absent +// parameters. +// SEQUENCE (12 bytes) { +// OBJECT IDENTIFIER 1.3.6.1.4.1.44363.47.0 (10 bytes) +// } +constexpr uint8_t kMTCAlgorithmIdentifier[] = { + 0x30, // SEQUENCE tag + 12, // tag + len + OID bytes + 0x06, // OBJECT tag + 10, // OID length + OBJ_ENC_alg_mtcProof_draft, +}; +// MTCLogEntryType enum value for tbs_cert_entry. +constexpr uint8_t kMTCLogEntryTypeTBSCertEntry[] = {0x00, 0x01}; +// ASN.1 tag for encoded OCTET STRING. +constexpr uint8_t kEncodedOctetStringTag[] = {0x04}; +// Prefix for domain separation used in CosignedMessage. +constexpr uint8_t kCosignedMessageLabel[12] = {'s', 'u', 'b', 't', 'r', 'e', + 'e', '/', 'v', '1', '\n', '\0'}; +// String prefix used to construct ASCII representation of trust anchor IDs for +// CosignedMessage fields. +constexpr uint8_t kASCIIOIDPrefix[16] = {'o', 'i', 'd', '/', '1', '.', + '3', '.', '6', '.', '1', '.', + '4', '.', '1', '.'}; +// DER encoded OID component found in trust anchor IDs for issuance logs. +constexpr uint8_t kEncOIDLogs = 0x00; + +constexpr CBS_ASN1_TAG kTBSVersionTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; // HashNode executes one hashing step in the evaluation of an inclusion proof. void HashNode(Span<uint8_t> out, const EVP_MD *log_hash, @@ -38,8 +76,8 @@ assert(right_child.size() == EVP_MD_size(log_hash)); ScopedEVP_MD_CTX ctx; EVP_DigestInit_ex(ctx.get(), log_hash, nullptr); - EVP_DigestUpdate(ctx.get(), kMtcNodeDomainSeparator, - sizeof(kMtcNodeDomainSeparator)); + EVP_DigestUpdate(ctx.get(), kMTCNodeDomainSeparator, + sizeof(kMTCNodeDomainSeparator)); EVP_DigestUpdate(ctx.get(), left_child.data(), left_child.size()); EVP_DigestUpdate(ctx.get(), right_child.data(), right_child.size()); EVP_DigestFinal_ex(ctx.get(), out.data(), nullptr); @@ -48,6 +86,12 @@ // lsb returns whether the least-significant bit of `n` is set. inline bool lsb(uint64_t n) { return n & 1; } +// is_mtc_proof returns whether `algor` is an mtcProof AlgorithmIdentifier. +bool is_mtc_proof(const X509_ALGOR *algor) { + return OBJ_obj2nid(algor->algorithm) == NID_alg_mtcProof_draft && + algor->parameter == nullptr; +} + // Returns the first hash value (of size `log_hash_size`) remaining in // `inclusion_proof` and advances `inclusion_proof` past the returned value. // Returns an empty span if there are no more hash values of the appropriate @@ -62,8 +106,219 @@ return value; } +// Writes `data` to the digest in `ctx`, prepending an 8-bit length prefix. +bool DigestUpdateWithU8LengthPrefix(EVP_MD_CTX *ctx, Span<const uint8_t> data) { + BSSL_CHECK(data.size() < (1u << 8)); + const uint8_t length_prefix = static_cast<uint8_t>(data.size()); + return EVP_DigestUpdate(ctx, &length_prefix, sizeof(length_prefix)) && + EVP_DigestUpdate(ctx, data.data(), data.size()); +} + +// Writes `data` to the digest in `ctx`, prepending a 16-bit length prefix. +bool DigestUpdateWithU16LengthPrefix(EVP_MD_CTX *ctx, + Span<const uint8_t> data) { + BSSL_CHECK(data.size() < (1u << 16)); + const uint8_t length_prefix[2] = {static_cast<uint8_t>(data.size() >> 8), + static_cast<uint8_t>(data.size())}; + return EVP_DigestUpdate(ctx, length_prefix, sizeof(length_prefix)) && + EVP_DigestUpdate(ctx, data.data(), data.size()); +} + +// Reads the next ASN.1 element from `cbs` and writes it as-is to the digest in +// `ctx`, including ASN.1 header bytes. +bool DigestUpdateNextASN1Element(EVP_MD_CTX *ctx, CBS *cbs) { + CBS element; + if (!CBS_get_any_asn1_element(cbs, &element, /*out_tag=*/nullptr, + /*out_header_len=*/nullptr)) { + return false; + } + return EVP_DigestUpdate(ctx, CBS_data(&element), CBS_len(&element)); +} + +// MTCCACosigner represents a Merkle Tree CA and its corresponding CA cosigner +// (see draft-ietf-plants-merkle-tree-certs, section 5.5). +class MTCCACosigner { + public: + MTCCACosigner() = default; + ~MTCCACosigner() = default; + + // Init() must be called before this object can be used. + // Init parses parameters defining an MTC CA cosigner from `x509`, including + // its MTCCertificationAuthority extension. `pkey` is the public key + // previously parsed from `x509`. Returns true if successfully initialized an + // MTCCACosigner representing a valid MTC CA, or false on error. + bool Init(const X509 *x509, const EVP_PKEY *pkey) { + // Get and parse the MTCCertificationAuthority extension (see section 5.5). + int ext_index = + X509_get_ext_by_NID(x509, NID_pe_mtcCertificationAuthority_draft, -1); + const X509_EXTENSION *ext = X509_get_ext(x509, ext_index); + if (ext == nullptr || !X509_EXTENSION_get_critical(ext)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_CA); + return false; + } + const ASN1_STRING *value = X509_EXTENSION_get_data(ext); + CBS ext_value; + CBS_init(&ext_value, ASN1_STRING_get0_data(value), + ASN1_STRING_length(value)); + + CBS seq, log_hash; + if (!CBS_get_asn1(&ext_value, &seq, CBS_ASN1_SEQUENCE) || // + !CBS_get_asn1_element(&seq, &log_hash, CBS_ASN1_SEQUENCE) || // + !x509_parse_algorithm(&seq, cosign_sigalg_.get()) || // + !CBS_get_asn1_uint64(&seq, &min_serial_) || // + !CBS_get_asn1_uint64(&seq, &max_serial_) || // + CBS_len(&seq) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return false; + } + log_hash_ = EVP_parse_digest_algorithm(&log_hash); + if (log_hash_ == nullptr) { + return false; + } + if (CBS_len(&log_hash) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return false; + } + + // Extract the CA ID from the subject (see section 5.1). + const X509_NAME *subject = X509_get_subject_name(x509); + int tai_index = + X509_NAME_get_index_by_NID(subject, NID_rdna_trustAnchorID_draft, -1); + if (tai_index < 0 || X509_NAME_entry_count(subject) != 1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_CA); + return false; + } + // For initial experimentation, the attribute's value is a UTF8String + // containing the trust anchor ID's ASCII representation. + const ASN1_STRING *tai_ascii = + X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, tai_index)); + if (ASN1_STRING_type(tai_ascii) != V_ASN1_UTF8STRING) { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE); + return false; + } + std::string_view tai_ascii_str = BytesAsStringView( + Span(ASN1_STRING_get0_data(tai_ascii), ASN1_STRING_length(tai_ascii))); + ScopedCBB ca_id_enc; + if (!CBB_init(ca_id_enc.get(), 64) || + !CBB_add_asn1_relative_oid_from_text( + ca_id_enc.get(), tai_ascii_str.data(), tai_ascii_str.size())) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return false; + } + if (!CBBFinishArray(ca_id_enc.get(), &ca_id_enc_oid_)) { + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return false; + } + + cosign_pubkey_.reset(EVP_PKEY_dup_ref(pkey)); + return true; + } + + bool IsSerialInRange(uint64_t serial) const { + return min_serial_ <= serial && serial <= max_serial_; + } + + // Constructs CosignedMessage and computes signature. + bool VerifyCACosignature(Span<const uint8_t> ca_cosignature, + uint64_t log_number, uint64_t subtree_start, + uint64_t subtree_end, + Span<const uint8_t> expected_subtree_hash) const { + ScopedCBB cosigned_message; + if (!CBB_init(cosigned_message.get(), 256) || + !CBB_add_bytes(cosigned_message.get(), kCosignedMessageLabel, + sizeof(kCosignedMessageLabel)) || + !WriteCosignerName(cosigned_message.get()) || + !CBB_add_u64(cosigned_message.get(), 0u) || // timestamp + !WriteLogOrigin(cosigned_message.get(), log_number) || + !CBB_add_u64(cosigned_message.get(), subtree_start) || + !CBB_add_u64(cosigned_message.get(), subtree_end) || + !CBB_add_bytes(cosigned_message.get(), expected_subtree_hash.data(), + expected_subtree_hash.size())) { + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return false; + } + return x509_verify_signature_bytes(cosign_sigalg_.get(), ca_cosignature, + CBBAsSpan(cosigned_message.get()), + cosign_pubkey_.get()); + } + + // IsCACosigner returns whether `trust_anchor_id` equals the cosigner ID + // of this CA's CA cosigner. + bool IsCACosigner(Span<const uint8_t> trust_anchor_id) const { + return trust_anchor_id == ca_id_enc_oid_; + } + + const EVP_MD *log_hash() const { return log_hash_; } + + private: + // WriteTaiAscii concatenates the trust anchor ID prefix with the CA ID as a + // relative OID to get the CA ID as a full OID, then appends any additional + // OID components from `oid_suffix`, and writes the ASCII string + // representation of the full trust anchor ID to `out`. + bool WriteTaiAscii(CBB *out, Span<const uint64_t> oid_suffix = {}) const { + // Trust anchor IDs are constrained to 256 bytes by spec (and are typically + // much shorter). + uint8_t id[256]; + CBB id_cbb; + if (!CBB_init_fixed(&id_cbb, id, sizeof(id)) || + !CBB_add_bytes(&id_cbb, ca_id_enc_oid_.data(), ca_id_enc_oid_.size())) { + return false; + } + for (const uint64_t component : oid_suffix) { + if (!CBB_add_asn1_oid_component(&id_cbb, component)) { + return false; + } + } + return CBB_add_asn1_relative_oid_from_der_to_text(out, CBB_data(&id_cbb), + CBB_len(&id_cbb)); + } + + // WriteCosignerName writes the `cosigner_name` field for a CosignedMessage (a + // prefixed ASCII representation of the CA ID) to `out`. + bool WriteCosignerName(CBB *out) const { + CBB cosigner_name; + return CBB_add_u8_length_prefixed(out, &cosigner_name) && + CBB_add_bytes(&cosigner_name, kASCIIOIDPrefix, + sizeof(kASCIIOIDPrefix)) && + WriteTaiAscii(&cosigner_name) && // + CBB_flush(out); + } + + // WriteLogOrigin writes the `log_origin` field for a CosignedMessage (a + // prefixed ASCII representation of the CA's log ID for a given `log_number`) + // to `out`. + bool WriteLogOrigin(CBB *out, uint64_t log_number) const { + const uint64_t log_number_relative_oid[2] = {kEncOIDLogs, log_number}; + CBB log_origin; + return CBB_add_u8_length_prefixed(out, &log_origin) && + CBB_add_bytes(&log_origin, kASCIIOIDPrefix, + sizeof(kASCIIOIDPrefix)) && + WriteTaiAscii(&log_origin, Span(log_number_relative_oid)) && + CBB_flush(out); + } + + // The CA ID, which is equal to the CA cosigner's cosigner ID (see sections + // 5.1 and 5.4), in the form of a DER-encoded relative OID. This does not + // include any framing, only the element's contents. + Array<uint8_t> ca_id_enc_oid_; + // Log hash algorithm. + const EVP_MD *log_hash_ = nullptr; + // Public key of the CA cosigner. + UniquePtr<EVP_PKEY> cosign_pubkey_; + // Signature algorithm for CA cosigner signatures. + ScopedX509Algor cosign_sigalg_; + // Min and max allowed serial number, (0..2^64-1). + uint64_t min_serial_ = 0u; + uint64_t max_serial_ = 0u; +}; + } // namespace +bool x509_is_merkle_tree_ca(const X509 *x509) { + return X509_get_ext_by_NID(x509, NID_pe_mtcCertificationAuthority_draft, + -1) >= 0; +} + bool x509_evaluate_mtc_subtree_inclusion_proof( Span<uint8_t> out, const EVP_MD *log_hash, Span<const uint8_t> inclusion_proof, uint64_t index, @@ -82,6 +337,8 @@ // must not exceed the largest power of 2 that divides the start index. const uint64_t subtree_size = subtree_end - subtree_start; if (subtree_start != 0 && + // The expression `subtree_start & (~subtree_start + 1)` isolates the + // lowest set bit of `subtree_start`. subtree_size > (subtree_start & (~subtree_start + 1))) { return false; } @@ -130,4 +387,212 @@ return true; } +int x509_verify_mtc(const X509 *x509, const EVP_PKEY *pkey, + const X509 *issuer) { + MTCCACosigner issuer_mtc_ca; + if (!issuer_mtc_ca.Init(issuer, pkey)) { + return 0; + } + + auto *impl = FromOpaque(x509); + if (!is_mtc_proof(impl->sig_alg.get())) { + OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (X509_ALGOR_cmp(impl->sig_alg.get(), impl->tbs_sig_alg.get())) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); + return 0; + } + + if (impl->signature->type == V_ASN1_BIT_STRING && + ASN1_BIT_STRING_unused_bits(impl->signature.get()) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; + } + + CBS mtc_proof; + CBS_init(&mtc_proof, ASN1_STRING_get0_data(impl->signature.get()), + ASN1_STRING_length(impl->signature.get())); + + CBS extensions, inclusion_proof, signatures; + uint64_t subtree_start, subtree_end; + if (!CBS_get_u16_length_prefixed(&mtc_proof, &extensions) || + !CBS_get_u48(&mtc_proof, &subtree_start) || + !CBS_get_u48(&mtc_proof, &subtree_end) || + !CBS_get_u16_length_prefixed(&mtc_proof, &inclusion_proof) || + !CBS_get_u16_length_prefixed(&mtc_proof, &signatures) || + CBS_len(&mtc_proof) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // Iterate through the subtree signatures array to check that they conform to + // spec, and identify the subtree signature from the CA cosigner. + CBS cosigner_id, signature; + std::optional<Span<const uint8_t>> prev_cosigner_id; + std::optional<Span<const uint8_t>> ca_cosignature; + while (CBS_len(&signatures) > 0) { + if (!CBS_get_u8_length_prefixed(&signatures, &cosigner_id) || + CBS_len(&cosigner_id) == 0 || + !CBS_get_u16_length_prefixed(&signatures, &signature) || + CBS_len(&signature) == 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + Span<const uint8_t> cosigner_id_span = cosigner_id; + // Cosignatures must be ordered by increasing cosigner ID length + // (lexicographical order if same length), and must not contain duplicate + // cosigner IDs. + if (prev_cosigner_id.has_value()) { + if (prev_cosigner_id->size() > cosigner_id_span.size()) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_PROOF); + return 0; + } + if (prev_cosigner_id->size() == cosigner_id_span.size() && + !std::lexicographical_compare( + prev_cosigner_id->begin(), prev_cosigner_id->end(), + cosigner_id_span.begin(), cosigner_id_span.end())) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_PROOF); + return 0; + } + } + prev_cosigner_id = cosigner_id_span; + if (issuer_mtc_ca.IsCACosigner(cosigner_id_span)) { + ca_cosignature = signature; + } + } + if (!ca_cosignature.has_value()) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_PROOF); + return 0; + } + + CBS tbs_seq, tbs; + Array<uint8_t> tbs_scratch; + if (!x509_get_or_marshal_tbs_cert(&tbs_seq, &tbs_scratch, x509) || + !CBS_get_asn1(&tbs_seq, &tbs, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + CBS version_field; + if (CBS_peek_asn1_tag(&tbs, kTBSVersionTag)) { + if (!CBS_get_asn1_element(&tbs, &version_field, kTBSVersionTag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + } else { + CBS_init(&version_field, nullptr, 0); + } + + // Check serial number is well-formed and within CA's range. (Caller is + // responsible for checking serial number against other revoked ranges.) + uint64_t serial; + if (!CBS_get_asn1_uint64(&tbs, &serial)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!issuer_mtc_ca.IsSerialInRange(serial)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + // `index` is the least significant 48 bits of `serial`. + uint64_t index = serial & ((uint64_t{1} << 48) - 1); + uint64_t log_number = serial >> 48; + if (log_number == 0) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + + // The TBSCertificate's `signature` field must match the expected MTC + // signature algorithm identifier. + CBS tbs_sigalg; + if (!CBS_get_asn1_element(&tbs, &tbs_sigalg, CBS_ASN1_SEQUENCE) || + !CBS_mem_equal(&tbs_sigalg, kMTCAlgorithmIdentifier, + sizeof(kMTCAlgorithmIdentifier))) { + OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); + return 0; + } + + // Compute `entry_hash` in a single pass without storing the full + // TBSCertificateLogEntry or MTCLogEntry. + ScopedEVP_MD_CTX entry_hash_ctx; + if (!EVP_DigestInit_ex(entry_hash_ctx.get(), issuer_mtc_ca.log_hash(), + nullptr) || + !EVP_DigestUpdate(entry_hash_ctx.get(), kMTCLeafDomainSeparator, + sizeof(kMTCLeafDomainSeparator)) || + // MTCLogEntry `extensions` field (comes directly from the MTCProof). + !DigestUpdateWithU16LengthPrefix(entry_hash_ctx.get(), extensions) || + // MTCLogEntryType enum value for a tbs_cert_entry. + !EVP_DigestUpdate(entry_hash_ctx.get(), kMTCLogEntryTypeTBSCertEntry, + sizeof(kMTCLogEntryTypeTBSCertEntry)) || + // Contents of TBSCertificateLogEntry follow (excluding the initial + // identifier and length octets): + !EVP_DigestUpdate(entry_hash_ctx.get(), CBS_data(&version_field), + CBS_len(&version_field)) || + !DigestUpdateNextASN1Element(entry_hash_ctx.get(), &tbs) || // issuer + !DigestUpdateNextASN1Element(entry_hash_ctx.get(), &tbs) || // validity + !DigestUpdateNextASN1Element(entry_hash_ctx.get(), &tbs)) { // subject + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Hash the TBSCertificate's `subjectPublicKeyInfo` field. + CBS spki; + if (!CBS_get_asn1_element(&tbs, &spki, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + uint8_t spki_digest[EVP_MAX_MD_SIZE]; + unsigned int spki_digest_len; + if (!EVP_Digest(CBS_data(&spki), CBS_len(&spki), spki_digest, + &spki_digest_len, issuer_mtc_ca.log_hash(), nullptr) || + spki_digest_len == 0 || spki_digest_len > 0xff) { + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Add the AlgorithmIdentifier from the subjectPublicKeyInfo. + CBS spki_contents; + if (!CBS_get_asn1(&spki, &spki_contents, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!DigestUpdateNextASN1Element(entry_hash_ctx.get(), &spki_contents) || + //`subjectPublicKeyInfoHash` field. + !EVP_DigestUpdate(entry_hash_ctx.get(), &kEncodedOctetStringTag, + sizeof(kEncodedOctetStringTag)) || + !DigestUpdateWithU8LengthPrefix(entry_hash_ctx.get(), + Span(spki_digest, spki_digest_len)) || + // Write the remainder of the TBSCertificate contents octets to the hash. + // This includes the optional fields `issuerUniqueID`, `subjectUniqueID`, + // and `extensions`. + !EVP_DigestUpdate(entry_hash_ctx.get(), CBS_data(&tbs), CBS_len(&tbs))) { + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + + uint8_t entry_hash[EVP_MAX_MD_SIZE]; + unsigned entry_hash_len; + if (!EVP_DigestFinal_ex(entry_hash_ctx.get(), entry_hash, &entry_hash_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + + InplaceVector<uint8_t, EVP_MAX_MD_SIZE> expected_subtree_hash; + expected_subtree_hash.ResizeForOverwrite( + EVP_MD_size(issuer_mtc_ca.log_hash())); + + if (!x509_evaluate_mtc_subtree_inclusion_proof( + Span(expected_subtree_hash), issuer_mtc_ca.log_hash(), + inclusion_proof, index, Span(entry_hash, entry_hash_len), + subtree_start, subtree_end)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_MTC_PROOF); + return 0; + } + + return issuer_mtc_ca.VerifyCACosignature(ca_cosignature.value(), log_number, + subtree_start, subtree_end, + Span(expected_subtree_hash)); +} + BSSL_NAMESPACE_END
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index c126f14..6170895 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc
@@ -1368,13 +1368,17 @@ return stack; } +// Timestamp to use with X509VerifyMTCTest. +static const int64_t kVerifyMtcReferenceTime = 1735689600 /* Jan 1st, 2025 */; +// Timestamp that works with the rest of the tests. static const int64_t kReferenceTime = 1474934400 /* Sep 27th, 2016 */; static int Verify( X509 *leaf, const std::vector<X509 *> &roots, const std::vector<X509 *> &intermediates, const std::vector<X509_CRL *> &crls, unsigned long flags = 0, - std::function<void(X509_STORE_CTX *)> configure_callback = nullptr) { + std::function<void(X509_STORE_CTX *)> configure_callback = nullptr, + int64_t time_posix = kReferenceTime) { UniquePtr<STACK_OF(X509)> roots_stack(CertsToStack(roots)); UniquePtr<STACK_OF(X509)> intermediates_stack(CertsToStack(intermediates)); UniquePtr<STACK_OF(X509_CRL)> crls_stack(CRLsToStack(crls)); @@ -1401,7 +1405,7 @@ X509_STORE_CTX_set0_crls(ctx.get(), crls_stack.get()); X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx.get()); - X509_VERIFY_PARAM_set_time_posix(param, kReferenceTime); + X509_VERIFY_PARAM_set_time_posix(param, time_posix); if (configure_callback) { configure_callback(ctx.get()); } @@ -11388,5 +11392,276 @@ #endif // !defined (BORINGSSL_SHARED_LIBRARY) +// Tests for verifying Merkle Tree Certificates. Test data was obtained by +// running the demo tool github.com/ietf-plants-wg/merkle-tree-certs/demo +// at revision d7362d6c441463b4e9c7064fa8bb48ee65929585 with the custom config +// at crypto/x509/test/mtc/mtc_testdata_config.json. +class X509VerifyMTCTest : public ::testing::Test { + public: + X509VerifyMTCTest() = default; + + void SetUp() override { + mtc_ca_cert_ = CertFromPEM(GetTestData("crypto/x509/test/mtc/ca_cert.pem")); + ASSERT_TRUE(mtc_ca_cert_); + + mtc_10_subtree_8_11_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_10_0.pem")); + ASSERT_TRUE(mtc_10_subtree_8_11_); + mtc_10_subtree_8_16_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_10_1.pem")); + ASSERT_TRUE(mtc_10_subtree_8_16_); + + mtc_32_subtree_32_34_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_32_0.pem")); + ASSERT_TRUE(mtc_32_subtree_32_34_); + + mtc_33_subtree_32_34_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_0.pem")); + ASSERT_TRUE(mtc_33_subtree_32_34_); + mtc_33_subtree_32_64_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_1.pem")); + ASSERT_TRUE(mtc_33_subtree_32_64_); + + mtc_2034_subtree_1024_2036_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_2034_0.pem")); + ASSERT_TRUE(mtc_2034_subtree_1024_2036_); + + mtc_2035_subtree_1024_2036_ = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_2035_0.pem")); + ASSERT_TRUE(mtc_2035_subtree_1024_2036_); + } + + std::vector<X509 *> GetValidTestMTCs() const { + return { + mtc_10_subtree_8_11_.get(), mtc_10_subtree_8_16_.get(), + mtc_32_subtree_32_34_.get(), mtc_33_subtree_32_34_.get(), + mtc_33_subtree_32_64_.get(), mtc_2034_subtree_1024_2036_.get(), + mtc_2035_subtree_1024_2036_.get(), + }; + } + + int VerifyMTC(X509 *mtc, + unsigned long flags = X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05, + X509 *mtc_ca = nullptr) { + if (!mtc_ca) { + mtc_ca = mtc_ca_cert_.get(); + } + return Verify( + mtc, /*roots=*/{mtc_ca}, /*intermediates=*/{}, + /*crls=*/{}, + /*flags=*/flags, + /*configure_callback=*/ + [mtc_ca](X509_STORE_CTX *ctx) { + ASSERT_TRUE(X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER)); + ASSERT_TRUE( + X509_add1_trust_object(mtc_ca, OBJ_nid2obj(NID_server_auth))); + }, + /*time_posix=*/kVerifyMtcReferenceTime); + } + + protected: + UniquePtr<X509> mtc_ca_cert_; + UniquePtr<X509> mtc_10_subtree_8_11_; + UniquePtr<X509> mtc_10_subtree_8_16_; + UniquePtr<X509> mtc_32_subtree_32_34_; + UniquePtr<X509> mtc_33_subtree_32_34_; + UniquePtr<X509> mtc_33_subtree_32_64_; + UniquePtr<X509> mtc_2034_subtree_1024_2036_; + UniquePtr<X509> mtc_2035_subtree_1024_2036_; +}; + +TEST_F(X509VerifyMTCTest, VerifyMTC) { + for (X509 *mtc : GetValidTestMTCs()) { + EXPECT_EQ(X509_V_OK, + VerifyMTC(mtc, /*flags=*/X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05)); + + // The flag is required to enable MTC verification. + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, VerifyMTC(mtc, /*flags=*/0)); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_ASN1, + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM)); + ERR_clear_error(); + + // X509_verify does not work directly on MTCs. + EXPECT_EQ(X509_verify(mtc, X509_get0_pubkey(mtc_ca_cert_.get())), 0); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_ASN1, + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM)); + ERR_clear_error(); + } +} + +TEST_F(X509VerifyMTCTest, InvalidBitFlipProof) { + // This cert has an inclusion proof with a bitflip that still has the right + // form to be processed, but fails the signature check because the + // CosignedMessage will be incorrect. + UniquePtr<X509> mtc_33_bitflip_proof = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_2.pem")); + ASSERT_TRUE(mtc_33_bitflip_proof); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_bitflip_proof.get())); +} + +TEST_F(X509VerifyMTCTest, InvalidUnusedBit) { + // This cert erroneously encodes the last bit in the signatureValue as unused, + // making it a non-whole number of bytes. + UniquePtr<X509> mtc_33_unused_bit = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_3.pem")); + ASSERT_TRUE(mtc_33_unused_bit); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_unused_bit.get())); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_X509, + X509_R_INVALID_BIT_STRING_BITS_LEFT)); +} + +TEST_F(X509VerifyMTCTest, InvalidCosignaturesArray) { + UniquePtr<X509> mtc_33_no_ca_cosignature = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_4.pem")); + ASSERT_TRUE(mtc_33_no_ca_cosignature); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_no_ca_cosignature.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_PROOF)); + ERR_clear_error(); + + UniquePtr<X509> mtc_33_cosignatures_misordered = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_5.pem")); + ASSERT_TRUE(mtc_33_cosignatures_misordered); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_cosignatures_misordered.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_PROOF)); + ERR_clear_error(); + + UniquePtr<X509> mtc_33_duplicate_ca_cosignatures = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_6.pem")); + ASSERT_TRUE(mtc_33_duplicate_ca_cosignatures); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_duplicate_ca_cosignatures.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_PROOF)); + ERR_clear_error(); + + UniquePtr<X509> mtc_33_duplicate_non_ca_cosignatures = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_7.pem")); + ASSERT_TRUE(mtc_33_duplicate_non_ca_cosignatures); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_duplicate_non_ca_cosignatures.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_PROOF)); + ERR_clear_error(); +} + +TEST_F(X509VerifyMTCTest, InvalidSerial) { + // This cert with index 2 is below the minSerial for the CA, which is: + // {"Log": 1, "Index": 8}. + UniquePtr<X509> mtc_2 = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_2_0.pem")); + ASSERT_TRUE(mtc_2); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, VerifyMTC(mtc_2.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER)); + ERR_clear_error(); + + // This cert with index 5036 is above the maxSerial for the CA, which is: + // {"Log": 1, "Index": 4096}. + UniquePtr<X509> mtc_5036 = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_5036_0.pem")); + ASSERT_TRUE(mtc_5036); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, VerifyMTC(mtc_5036.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER)); + ERR_clear_error(); +} + +TEST_F(X509VerifyMTCTest, MismatchedSignatureAlgorithm) { + // This cert erroneously has an outer sigalg for ML-DSA-44. + UniquePtr<X509> mtc_33_wrong_sigalg = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_8.pem")); + ASSERT_TRUE(mtc_33_wrong_sigalg); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_wrong_sigalg.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM)); + ERR_clear_error(); + + // This cert erroneously has an inner sigalg for ML-DSA-44. + UniquePtr<X509> mtc_33_wrong_tbs_sigalg = + CertFromPEM(GetTestData("crypto/x509/test/mtc/cert_33_9.pem")); + ASSERT_TRUE(mtc_33_wrong_tbs_sigalg); + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_33_wrong_tbs_sigalg.get())); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_X509, + X509_R_SIGNATURE_ALGORITHM_MISMATCH)); + ERR_clear_error(); +} + +// If the CA lacks the MTCCertificationAuthority extension, it is treated as a +// standard CA and fails because standard verification does not support MTCs. +TEST_F(X509VerifyMTCTest, InvalidMTCCANoExtension) { + UniquePtr<X509> bad_ca(X509_dup(mtc_ca_cert_.get())); + ASSERT_TRUE(bad_ca); + int ext_index = X509_get_ext_by_NID( + bad_ca.get(), NID_pe_mtcCertificationAuthority_draft, -1); + ASSERT_GE(ext_index, 0); + UniquePtr<X509_EXTENSION> ext(X509_delete_ext(bad_ca.get(), ext_index)); + ASSERT_TRUE(ext); + + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_10_subtree_8_11_.get(), + /*flags=*/X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05, + /*mtc_ca=*/bad_ca.get())); + EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_ASN1, + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM)); +} + +// If the CA's MTCCertificationAuthority extension is not marked critical, +// it is not recognized as an MTC CA (per draft-ietf-plants-merkle-tree-certs +// section 5.5). MTC verification is attempted and fails. +TEST_F(X509VerifyMTCTest, InvalidMTCCAExtensionNotCritical) { + UniquePtr<X509> bad_ca_non_critical(X509_dup(mtc_ca_cert_.get())); + ASSERT_TRUE(bad_ca_non_critical); + int ext_index = X509_get_ext_by_NID( + bad_ca_non_critical.get(), NID_pe_mtcCertificationAuthority_draft, -1); + ASSERT_GE(ext_index, 0); + X509_EXTENSION *ext = X509_get_ext(bad_ca_non_critical.get(), ext_index); + ASSERT_TRUE(ext); + ASSERT_TRUE(X509_EXTENSION_set_critical(ext, /*crit=*/0)); + + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc_10_subtree_8_11_.get(), + /*flags=*/X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05, + /*mtc_ca=*/bad_ca_non_critical.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_CA)); +} + +// If the CA has the MTCCertificationAuthority extension but an invalid +// subject name (e.g. missing trust anchor ID), MTC CA initialization fails. +TEST_F(X509VerifyMTCTest, InvalidMTCCABadSubject) { + UniquePtr<X509> bad_ca_no_trust_anchor(X509_dup(mtc_ca_cert_.get())); + ASSERT_TRUE(bad_ca_no_trust_anchor); + + X509_NAME *subject = X509_get_subject_name(bad_ca_no_trust_anchor.get()); + int name_index = + X509_NAME_get_index_by_NID(subject, NID_rdna_trustAnchorID_draft, -1); + ASSERT_GE(name_index, 0); + UniquePtr<X509_NAME_ENTRY> entry(X509_NAME_delete_entry(subject, name_index)); + ASSERT_TRUE(entry); + ASSERT_TRUE(X509_NAME_add_entry_by_txt( + subject, "CN", MBSTRING_ASC, reinterpret_cast<const uint8_t *>("Bad CA"), + -1, -1, 0)); + + // Make the leaf cert match. + UniquePtr<X509> mtc(X509_dup(mtc_10_subtree_8_11_.get())); + ASSERT_TRUE(mtc); + ASSERT_TRUE(X509_set_issuer_name(mtc.get(), subject)); + + EXPECT_EQ(X509_V_ERR_CERT_SIGNATURE_FAILURE, + VerifyMTC(mtc.get(), + /*flags=*/X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05, + /*mtc_ca=*/bad_ca_no_trust_anchor.get())); + EXPECT_TRUE( + ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_MTC_CA)); +} + } // namespace BSSL_NAMESPACE_END
diff --git a/crypto/x509/x509_vfy.cc b/crypto/x509/x509_vfy.cc index 2b071bc..eef00b5 100644 --- a/crypto/x509/x509_vfy.cc +++ b/crypto/x509/x509_vfy.cc
@@ -1243,6 +1243,18 @@ return 1; } +static int verify_signature(X509_STORE_CTX *ctx, const X509 *x509, + const X509 *issuer, EVP_PKEY *pkey) { + int ret; + if ((ctx->param->flags & X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05) && + x509_is_merkle_tree_ca(issuer)) { + ret = x509_verify_mtc(x509, pkey, issuer); + } else { + ret = X509_verify(x509, pkey); + } + return ret ? X509_V_OK : X509_V_ERR_CERT_SIGNATURE_FAILURE; +} + static int internal_verify(X509_STORE_CTX *ctx) { // TODO(davidben): This logic is incredibly confusing. Rewrite this: // @@ -1289,8 +1301,9 @@ if (!call_verify_cb(0, ctx)) { return 0; } - } else if (X509_verify(xs, pkey) <= 0) { - ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + } else if (int err = verify_signature(ctx, xs, xi, pkey); + err != X509_V_OK) { + ctx->error = err; ctx->current_cert = xs; if (!call_verify_cb(0, ctx)) { return 0;
diff --git a/gen/crypto/err_data.cc b/gen/crypto/err_data.cc index 006aa94..954eb30 100644 --- a/gen/crypto/err_data.cc +++ b/gen/crypto/err_data.cc
@@ -218,39 +218,41 @@ 0x2c36833a, 0x2c373597, 0x2c37b5c3, - 0x2c383601, - 0x2c38b618, - 0x2c393636, - 0x2c39b646, - 0x2c3a3658, - 0x2c3ab66c, - 0x2c3b367d, - 0x2c3bb69c, + 0x2c383622, + 0x2c38b639, + 0x2c393657, + 0x2c39b667, + 0x2c3a3679, + 0x2c3ab68d, + 0x2c3b369e, + 0x2c3bb6bd, 0x2c3c1455, 0x2c3c946b, - 0x2c3d36e1, + 0x2c3d3702, 0x2c3d9484, - 0x2c3e370b, - 0x2c3eb719, - 0x2c3f3731, - 0x2c3fb749, - 0x2c403773, + 0x2c3e372c, + 0x2c3eb73a, + 0x2c3f3752, + 0x2c3fb76a, + 0x2c403794, 0x2c409330, - 0x2c413784, - 0x2c41b797, + 0x2c4137a5, + 0x2c41b7b8, 0x2c4212f6, - 0x2c42b7a8, + 0x2c42b7c9, 0x2c43076d, - 0x2c43b68e, - 0x2c4435d6, - 0x2c44b756, + 0x2c43b6af, + 0x2c4435f7, + 0x2c44b777, 0x2c45356d, 0x2c45b5a9, - 0x2c463626, - 0x2c46b6b0, - 0x2c4736c5, - 0x2c47b6fe, - 0x2c4835e8, + 0x2c463647, + 0x2c46b6d1, + 0x2c4736e6, + 0x2c47b71f, + 0x2c483609, + 0x2c48b5d6, + 0x2c4935e5, 0x30320000, 0x30328015, 0x3033001f, @@ -714,71 +716,71 @@ 0x4c41954d, 0x4c4216b6, 0x4c429495, - 0x503237ba, - 0x5032b7c9, - 0x503337d4, - 0x5033b7e4, - 0x503437fd, - 0x5034b817, - 0x50353825, - 0x5035b83b, - 0x5036384d, - 0x5036b863, - 0x5037387c, - 0x5037b88f, - 0x503838a7, - 0x5038b8b8, - 0x503938cd, - 0x5039b8e1, - 0x503a3901, - 0x503ab917, - 0x503b392f, - 0x503bb941, - 0x503c395d, - 0x503cb974, - 0x503d398d, - 0x503db9a3, - 0x503e39b0, - 0x503eb9c6, - 0x503f39d8, + 0x503237db, + 0x5032b7ea, + 0x503337f5, + 0x5033b805, + 0x5034381e, + 0x5034b838, + 0x50353846, + 0x5035b85c, + 0x5036386e, + 0x5036b884, + 0x5037389d, + 0x5037b8b0, + 0x503838c8, + 0x5038b8d9, + 0x503938ee, + 0x5039b902, + 0x503a3922, + 0x503ab938, + 0x503b3950, + 0x503bb962, + 0x503c397e, + 0x503cb995, + 0x503d39ae, + 0x503db9c4, + 0x503e39d1, + 0x503eb9e7, + 0x503f39f9, 0x503f83b3, - 0x504039eb, - 0x5040b9fb, - 0x50413a15, - 0x5041ba24, - 0x50423a3e, - 0x5042ba5b, - 0x50433a6b, - 0x5043ba7b, - 0x50443a98, + 0x50403a0c, + 0x5040ba1c, + 0x50413a36, + 0x5041ba45, + 0x50423a5f, + 0x5042ba7c, + 0x50433a8c, + 0x5043ba9c, + 0x50443ab9, 0x50448469, - 0x50453aac, - 0x5045baca, - 0x50463add, - 0x5046baf3, - 0x50473b05, - 0x5047bb1a, - 0x50483b40, - 0x5048bb4e, - 0x50493b61, - 0x5049bb76, - 0x504a3b8c, - 0x504abb9c, - 0x504b3bbc, - 0x504bbbcf, - 0x504c3bf2, - 0x504cbc20, - 0x504d3c4d, - 0x504dbc6a, - 0x504e3c85, - 0x504ebca1, - 0x504f3cb3, - 0x504fbcca, - 0x50503cd9, + 0x50453acd, + 0x5045baeb, + 0x50463afe, + 0x5046bb14, + 0x50473b26, + 0x5047bb3b, + 0x50483b61, + 0x5048bb6f, + 0x50493b82, + 0x5049bb97, + 0x504a3bad, + 0x504abbbd, + 0x504b3bdd, + 0x504bbbf0, + 0x504c3c13, + 0x504cbc41, + 0x504d3c6e, + 0x504dbc8b, + 0x504e3ca6, + 0x504ebcc2, + 0x504f3cd4, + 0x504fbceb, + 0x50503cfa, 0x50508729, - 0x50513cec, - 0x5051ba8a, - 0x50523c32, + 0x50513d0d, + 0x5051baab, + 0x50523c53, 0x58321011, 0x68320fd3, 0x68328d2b, @@ -1473,6 +1475,8 @@ "INVALID_DIRECTORY\0" "INVALID_FIELD_FOR_VERSION\0" "INVALID_FIELD_NAME\0" + "INVALID_MTC_CA\0" + "INVALID_MTC_PROOF\0" "INVALID_PARAMETER\0" "INVALID_POLICY_EXTENSION\0" "INVALID_PSS_PARAMETERS\0"
diff --git a/gen/sources.bzl b/gen/sources.bzl index 6f82243..58f2047 100644 --- a/gen/sources.bzl +++ b/gen/sources.bzl
@@ -999,6 +999,24 @@ "crypto/x509/test/many_names1.pem", "crypto/x509/test/many_names2.pem", "crypto/x509/test/many_names3.pem", + "crypto/x509/test/mtc/ca_cert.pem", + "crypto/x509/test/mtc/cert_10_0.pem", + "crypto/x509/test/mtc/cert_10_1.pem", + "crypto/x509/test/mtc/cert_2034_0.pem", + "crypto/x509/test/mtc/cert_2035_0.pem", + "crypto/x509/test/mtc/cert_2_0.pem", + "crypto/x509/test/mtc/cert_32_0.pem", + "crypto/x509/test/mtc/cert_33_0.pem", + "crypto/x509/test/mtc/cert_33_1.pem", + "crypto/x509/test/mtc/cert_33_2.pem", + "crypto/x509/test/mtc/cert_33_3.pem", + "crypto/x509/test/mtc/cert_33_4.pem", + "crypto/x509/test/mtc/cert_33_5.pem", + "crypto/x509/test/mtc/cert_33_6.pem", + "crypto/x509/test/mtc/cert_33_7.pem", + "crypto/x509/test/mtc/cert_33_8.pem", + "crypto/x509/test/mtc/cert_33_9.pem", + "crypto/x509/test/mtc/cert_5036_0.pem", "crypto/x509/test/policy_intermediate.pem", "crypto/x509/test/policy_intermediate_any.pem", "crypto/x509/test/policy_intermediate_duplicate.pem",
diff --git a/gen/sources.cmake b/gen/sources.cmake index 195d6f3..3e98e1e 100644 --- a/gen/sources.cmake +++ b/gen/sources.cmake
@@ -1031,6 +1031,24 @@ crypto/x509/test/many_names1.pem crypto/x509/test/many_names2.pem crypto/x509/test/many_names3.pem + crypto/x509/test/mtc/ca_cert.pem + crypto/x509/test/mtc/cert_10_0.pem + crypto/x509/test/mtc/cert_10_1.pem + crypto/x509/test/mtc/cert_2034_0.pem + crypto/x509/test/mtc/cert_2035_0.pem + crypto/x509/test/mtc/cert_2_0.pem + crypto/x509/test/mtc/cert_32_0.pem + crypto/x509/test/mtc/cert_33_0.pem + crypto/x509/test/mtc/cert_33_1.pem + crypto/x509/test/mtc/cert_33_2.pem + crypto/x509/test/mtc/cert_33_3.pem + crypto/x509/test/mtc/cert_33_4.pem + crypto/x509/test/mtc/cert_33_5.pem + crypto/x509/test/mtc/cert_33_6.pem + crypto/x509/test/mtc/cert_33_7.pem + crypto/x509/test/mtc/cert_33_8.pem + crypto/x509/test/mtc/cert_33_9.pem + crypto/x509/test/mtc/cert_5036_0.pem crypto/x509/test/policy_intermediate.pem crypto/x509/test/policy_intermediate_any.pem crypto/x509/test/policy_intermediate_duplicate.pem
diff --git a/gen/sources.gni b/gen/sources.gni index 0dd7a88..5f30e9f 100644 --- a/gen/sources.gni +++ b/gen/sources.gni
@@ -999,6 +999,24 @@ "crypto/x509/test/many_names1.pem", "crypto/x509/test/many_names2.pem", "crypto/x509/test/many_names3.pem", + "crypto/x509/test/mtc/ca_cert.pem", + "crypto/x509/test/mtc/cert_10_0.pem", + "crypto/x509/test/mtc/cert_10_1.pem", + "crypto/x509/test/mtc/cert_2034_0.pem", + "crypto/x509/test/mtc/cert_2035_0.pem", + "crypto/x509/test/mtc/cert_2_0.pem", + "crypto/x509/test/mtc/cert_32_0.pem", + "crypto/x509/test/mtc/cert_33_0.pem", + "crypto/x509/test/mtc/cert_33_1.pem", + "crypto/x509/test/mtc/cert_33_2.pem", + "crypto/x509/test/mtc/cert_33_3.pem", + "crypto/x509/test/mtc/cert_33_4.pem", + "crypto/x509/test/mtc/cert_33_5.pem", + "crypto/x509/test/mtc/cert_33_6.pem", + "crypto/x509/test/mtc/cert_33_7.pem", + "crypto/x509/test/mtc/cert_33_8.pem", + "crypto/x509/test/mtc/cert_33_9.pem", + "crypto/x509/test/mtc/cert_5036_0.pem", "crypto/x509/test/policy_intermediate.pem", "crypto/x509/test/policy_intermediate_any.pem", "crypto/x509/test/policy_intermediate_duplicate.pem",
diff --git a/gen/sources.json b/gen/sources.json index 408cf7f..8c1b187 100644 --- a/gen/sources.json +++ b/gen/sources.json
@@ -978,6 +978,24 @@ "crypto/x509/test/many_names1.pem", "crypto/x509/test/many_names2.pem", "crypto/x509/test/many_names3.pem", + "crypto/x509/test/mtc/ca_cert.pem", + "crypto/x509/test/mtc/cert_10_0.pem", + "crypto/x509/test/mtc/cert_10_1.pem", + "crypto/x509/test/mtc/cert_2034_0.pem", + "crypto/x509/test/mtc/cert_2035_0.pem", + "crypto/x509/test/mtc/cert_2_0.pem", + "crypto/x509/test/mtc/cert_32_0.pem", + "crypto/x509/test/mtc/cert_33_0.pem", + "crypto/x509/test/mtc/cert_33_1.pem", + "crypto/x509/test/mtc/cert_33_2.pem", + "crypto/x509/test/mtc/cert_33_3.pem", + "crypto/x509/test/mtc/cert_33_4.pem", + "crypto/x509/test/mtc/cert_33_5.pem", + "crypto/x509/test/mtc/cert_33_6.pem", + "crypto/x509/test/mtc/cert_33_7.pem", + "crypto/x509/test/mtc/cert_33_8.pem", + "crypto/x509/test/mtc/cert_33_9.pem", + "crypto/x509/test/mtc/cert_5036_0.pem", "crypto/x509/test/policy_intermediate.pem", "crypto/x509/test/policy_intermediate_any.pem", "crypto/x509/test/policy_intermediate_duplicate.pem",
diff --git a/gen/sources.mk b/gen/sources.mk index 89b3df1..02e21fc 100644 --- a/gen/sources.mk +++ b/gen/sources.mk
@@ -984,6 +984,24 @@ crypto/x509/test/many_names1.pem \ crypto/x509/test/many_names2.pem \ crypto/x509/test/many_names3.pem \ + crypto/x509/test/mtc/ca_cert.pem \ + crypto/x509/test/mtc/cert_10_0.pem \ + crypto/x509/test/mtc/cert_10_1.pem \ + crypto/x509/test/mtc/cert_2034_0.pem \ + crypto/x509/test/mtc/cert_2035_0.pem \ + crypto/x509/test/mtc/cert_2_0.pem \ + crypto/x509/test/mtc/cert_32_0.pem \ + crypto/x509/test/mtc/cert_33_0.pem \ + crypto/x509/test/mtc/cert_33_1.pem \ + crypto/x509/test/mtc/cert_33_2.pem \ + crypto/x509/test/mtc/cert_33_3.pem \ + crypto/x509/test/mtc/cert_33_4.pem \ + crypto/x509/test/mtc/cert_33_5.pem \ + crypto/x509/test/mtc/cert_33_6.pem \ + crypto/x509/test/mtc/cert_33_7.pem \ + crypto/x509/test/mtc/cert_33_8.pem \ + crypto/x509/test/mtc/cert_33_9.pem \ + crypto/x509/test/mtc/cert_5036_0.pem \ crypto/x509/test/policy_intermediate.pem \ crypto/x509/test/policy_intermediate_any.pem \ crypto/x509/test/policy_intermediate_duplicate.pem \
diff --git a/include/openssl/nid.h b/include/openssl/nid.h index 6b3bb45..216c066 100644 --- a/include/openssl/nid.h +++ b/include/openssl/nid.h
@@ -5511,6 +5511,26 @@ #define SN_X_Wing "X-Wing" #define NID_X_Wing 972 +#define SN_alg_mtcProof_draft "alg-mtcProof-draft" +#define NID_alg_mtcProof_draft 976 +#define OBJ_alg_mtcProof_draft 1L, 3L, 6L, 1L, 4L, 1L, 44363L, 47L, 0L +#define OBJ_ENC_alg_mtcProof_draft \ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xda, 0x4b, 0x2f, 0x00 + +#define SN_rdna_trustAnchorID_draft "rdna-trustAnchorID-draft" +#define NID_rdna_trustAnchorID_draft 977 +#define OBJ_rdna_trustAnchorID_draft 1L, 3L, 6L, 1L, 4L, 1L, 44363L, 47L, 1L +#define OBJ_ENC_rdna_trustAnchorID_draft \ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xda, 0x4b, 0x2f, 0x01 + +#define SN_pe_mtcCertificationAuthority_draft \ + "pe-mtcCertificationAuthority-draft" +#define NID_pe_mtcCertificationAuthority_draft 978 +#define OBJ_pe_mtcCertificationAuthority_draft \ + 1L, 3L, 6L, 1L, 4L, 1L, 44363L, 47L, 2L +#define OBJ_ENC_pe_mtcCertificationAuthority_draft \ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xda, 0x4b, 0x2f, 0x02 + #if defined(__cplusplus) } /* extern C */
diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 75ada6c..0ef08e6 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h
@@ -3289,6 +3289,9 @@ // X509_V_FLAG_ALLOW_TIMEZONE_OFFSET allows `notBefore` and `notAfter` fields // to contain a time zone offset. #define X509_V_FLAG_ALLOW_TIMEZONE_OFFSET 0x1000000 +// X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05 enables the verification of Merkle Tree +// Certificates as specified in draft-ietf-plants-merkle-tree-certs-05. +#define X509_V_FLAG_USE_MTC_DRAFT_PLANTS_05 0x400000 // X509_VERIFY_PARAM_set_flags enables all values in `flags` in `param`'s // verification flags and returns one. `flags` should be a combination of @@ -5395,5 +5398,7 @@ #define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 142 #define X509_R_NO_CRL_FOUND 143 #define X509_R_INVALID_POLICY_EXTENSION 144 +#define X509_R_INVALID_MTC_CA 145 +#define X509_R_INVALID_MTC_PROOF 146 #endif // OPENSSL_HEADER_X509_H