diff --git a/panda/src/express/zipArchive.cxx b/panda/src/express/zipArchive.cxx index 06bd4f9e28..02e501349f 100644 --- a/panda/src/express/zipArchive.cxx +++ b/panda/src/express/zipArchive.cxx @@ -571,11 +571,11 @@ add_jar_signature(X509 *cert, EVP_PKEY *pkey, const std::string &alias) { const std::string header_digest = "VmrRqAIgAm0FCZViZFzpaP8OfDbN4iY0MyYFuzTMPv8="; std::stringstream manifest; - SHA256_CTX manifest_ctx; - SHA256_Init(&manifest_ctx); + EVP_MD_CTX *manifest_ctx = EVP_MD_CTX_new(); + EVP_DigestInit_ex(manifest_ctx, EVP_sha256(), nullptr); manifest << header; - SHA256_Update(&manifest_ctx, header.data(), header.size()); + EVP_DigestUpdate(manifest_ctx, header.data(), header.size()); std::ostringstream sigfile_body; @@ -594,20 +594,21 @@ add_jar_signature(X509 *cert, EVP_PKEY *pkey, const std::string &alias) { { std::istream *stream = open_read_subfile(subfile); - SHA256_CTX subfile_ctx; - SHA256_Init(&subfile_ctx); + EVP_MD_CTX *subfile_ctx = EVP_MD_CTX_new(); + EVP_DigestInit_ex(subfile_ctx, EVP_sha256(), nullptr); char buffer[4096]; stream->read(buffer, sizeof(buffer)); size_t count = stream->gcount(); while (count > 0) { - SHA256_Update(&subfile_ctx, buffer, count); + EVP_DigestUpdate(subfile_ctx, buffer, count); stream->read(buffer, sizeof(buffer)); count = stream->gcount(); } delete stream; - SHA256_Final(digest, &subfile_ctx); + EVP_DigestFinal_ex(subfile_ctx, digest, nullptr); + EVP_MD_CTX_free(subfile_ctx); } // Encode to base64. @@ -616,24 +617,21 @@ add_jar_signature(X509 *cert, EVP_PKEY *pkey, const std::string &alias) { // Encode what we just wrote to the manifest file as well. { unsigned char digest[SHA256_DIGEST_LENGTH]; - - SHA256_CTX section_ctx; - SHA256_Init(§ion_ctx); - SHA256_Update(§ion_ctx, section.data(), section.size()); - SHA256_Final(digest, §ion_ctx); + EVP_Digest(section.data(), section.size(), digest, nullptr, EVP_sha256(), nullptr); sigfile_body << "SHA-256-Digest: " << base64_encode(digest, SHA256_DIGEST_LENGTH) << "\r\n\r\n"; } manifest << section; - SHA256_Update(&manifest_ctx, section.data(), section.size()); + EVP_DigestUpdate(manifest_ctx, section.data(), section.size()); } // The hash for the whole manifest file goes at the beginning of the .SF file. std::stringstream sigfile; { unsigned char digest[SHA256_DIGEST_LENGTH]; - SHA256_Final(digest, &manifest_ctx); + EVP_DigestFinal_ex(manifest_ctx, digest, nullptr); + EVP_MD_CTX_free(manifest_ctx); sigfile << "Signature-Version: 1.0\r\n"; sigfile << "SHA-256-Digest-Manifest-Main-Attributes: " << header_digest << "\r\n"; sigfile << "SHA-256-Digest-Manifest: " << base64_encode(digest, SHA256_DIGEST_LENGTH) << "\r\n\r\n"; diff --git a/tests/express/cert.pem b/tests/express/cert.pem new file mode 100644 index 0000000000..33a3a9f151 --- /dev/null +++ b/tests/express/cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIULuBiiqTjDq8eK6pCRMLMTtV5tRUwDQYJKoZIhvcNAQEL +BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE +CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yNTEwMTUwOTA3MDhaFw0yNjEwMTUw +OTA3MDhaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa +BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCjCpKGVRGDaAkdb+Fl7NYv6/d3QEp3HDDN0I8Ns5xBPRlvsnUm +uPcv+VZRtgM8DXFyypqmbknHeayWBwcAdvEor3JsRLYpB+buZl48Sr7rOQMbP3xG +da0XYMA3JNW4MSf7VfNbq9tBcXM+JGHZgyEFkmKPxxdwjJC0g90zOBRlTmmOjI1H +Aus1hTQXeCxkbkTIjggxU5e6ptx4EOpaWotLLIWbuFx9rLTcbuQVx4Pwu+DuRcCp +eXsnWcS/wcGQSUF1586zu6oAFBgv8XPmskzOphK0Ei8eDwyfIHxqF/ej0NAJei1Q +hePOh+fX2eLh6kH4sAc2mFtLbnURxwz3b03tAgMBAAGjUzBRMB0GA1UdDgQWBBT7 +KryYClrgtH/oF518izizsMfX1DAfBgNVHSMEGDAWgBT7KryYClrgtH/oF518iziz +sMfX1DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA+JH1el4P8 +ofA5Us4LBJNS82KJY96dSITKE3W7R6IZj0TZPYgE244eeN/wdbu1QsFrXXS7jYYY +npLlVouiC26aMNIrNoRa0rHqJA7shR4+1iT3hawu8zYH55kooOgZwn8mRe1G7XD+ +TrvFYvgjNi5AgISqkmfuXyzcOfSZ7jt/mv7rVSSs9N1ZVrNOAGDnFN1YLAVXD9eh +cH2i0SrtmFYnK+xYvK/eT1EGngtTdsBwD/GGoaPuuGU9sWVswcR9Gp/FgQBB31ZK +Edeyh2IdydBlHRSzpJkhnUtyJBN29+/P3WW27XUYDyfSma+0X7G8qAWsyBG7qWXi +fIU+/gpvLoNC +-----END CERTIFICATE----- diff --git a/tests/express/private.pem b/tests/express/private.pem new file mode 100644 index 0000000000..3f6759b81c --- /dev/null +++ b/tests/express/private.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjCpKGVRGDaAkd +b+Fl7NYv6/d3QEp3HDDN0I8Ns5xBPRlvsnUmuPcv+VZRtgM8DXFyypqmbknHeayW +BwcAdvEor3JsRLYpB+buZl48Sr7rOQMbP3xGda0XYMA3JNW4MSf7VfNbq9tBcXM+ +JGHZgyEFkmKPxxdwjJC0g90zOBRlTmmOjI1HAus1hTQXeCxkbkTIjggxU5e6ptx4 +EOpaWotLLIWbuFx9rLTcbuQVx4Pwu+DuRcCpeXsnWcS/wcGQSUF1586zu6oAFBgv +8XPmskzOphK0Ei8eDwyfIHxqF/ej0NAJei1QhePOh+fX2eLh6kH4sAc2mFtLbnUR +xwz3b03tAgMBAAECggEAR8txCFxPcPkQAnlw3Mw06TdUapvR7q9oQklTpSnxZbz9 +BXWlJt8OYn6+Zw7qT7hvu6fCAAXS0VcgC5SenbLCsTLJBSoguOK060gCuTQE7FnX +p1kGZZSOGxxMqDu9LPXgcEnB9x0vWJsXr0agHAMlOGnkowF9rd8IHaVvc41/VbhD +kH9mWSlX8jSFZnN3pTJUygpA3/m2fBzs+WWacGukF0c3TNgbXpmf2ODxrqCWsf0e +kv7CW1X64g9T/UPoIXCaaAFwM6AzfykEHvty5Yac2WRavTSSxw619vtNGK6Sw7se +SJo9tykxXa1emhEl+AlHkOz4AqPJ+BXZv3IVBiswtQKBgQDlzPKdNPlIQlEsJXrE +3evmOL8ACqnSQG2kof2ouEBE6Z09e4Wm2VA6SBV4soPiVyOcKZp58ZNiU9MIHVl2 +OKvT1AhsKID2cIYjGYvmr7+IpHqqklAMy3K+EtT6oUGu/Js3wlmxG9KJnCtxGwIH +QjizqaUoAZKwj/j5ZWQPxLYdUwKBgQC1oSlTTVvd+tGtEKXyeG5/xTpQpjyRnKWp +bof2Apj6zaWKx6EWAdmLB7uIk4J1rQqCdEVSbUZ+PGcl1flKoSfSWFOtnb0pdU91 +70WS4hz2ABgMuRlOh1xCk0YaoIpR5My+KsoHQngAqChj5rlcLTS2hJTUcQjItSB3 +tuQf8Ug/vwKBgEaA8bKvzQeRaSwdN6Rs3fJdWKRfoSijocAP/y4jkXxTHG3/lsrR +A59N/GByjKoFyCQiU4W0S16wjx9/ObJewsET3Z2pc5+oeE8OiHC3XRFEPWpVx3+V +b9fHGVbn4KoaUFj0JOaEvbyAkId8HMwzUgg1NTmn+eR315BUvjVkSeeHAoGBALUV +ZNpEul7qfroJayn/oEuLG8TkuGaEwzXVmYBQvqzu8ykWNyh116qhnvtf9iXUzDGc +MrEneazKFBzI5K7fVZCFt4fVSI9ZAkwWrkrvXOh214N32B9PHVDS/IX3oXBcqTS/ +/ISYZIRjI0HW+t9HwtJmBOx5dcSFsUUp9u9R5DKJAoGBAMWEsK5lMz0FFr9g9OLD +lARC8iYtFSgL2klINxeMT3lzhB/7baIoEYbgWNcHWw/qB+li3QGpDn+tlilNHIzU +Y1LTEJFMjoHLanA7qskhkziyVIL5z4VCsguArUHamGajT3ZQ03814rG0OUk7wHfk +9ZN06G0/Ot4cPZEc5Jy6E4pS +-----END PRIVATE KEY----- diff --git a/tests/express/test_zip.py b/tests/express/test_zip.py index 89b869ff69..ee433845d4 100644 --- a/tests/express/test_zip.py +++ b/tests/express/test_zip.py @@ -2,6 +2,7 @@ from panda3d.core import ZipArchive, IStreamWrapper, StringStream, Filename from direct.stdpy.file import StreamIOWrapper import zipfile from io import BytesIO +import os EMPTY_ZIP = b'PK\x05\x06' + b'\x00' * 18 @@ -181,3 +182,18 @@ def test_zip_repack(tmp_path): assert zf.read("test1.txt") == b"contents of first file" assert "test2.txt" not in zf.namelist() assert zf.read("test3.txt") == b"contents of third file" + + +def test_zip_jar_signature(): + cur_dir = Filename.from_os_specific(os.path.dirname(__file__)) + + stream = StringStream() + zip = ZipArchive() + zip.open_read_write(stream) + zip.add_subfile("test.txt", StringStream(b"contents of test file"), 6) + zip.add_jar_signature(Filename(cur_dir, "cert.pem"), Filename(cur_dir, "private.pem")) + zip.close() + + with zipfile.ZipFile(StreamIOWrapper(stream), 'r') as zf: + assert zf.read("META-INF/MANIFEST.MF") == b'Manifest-Version: 1.0\r\n\r\nName: test.txt\r\nSHA-256-Digest: k5XWgStAZvRlNWIcz67qLSzso8Mc+OUG1QOlAwysyhE=\r\n\r\n' + assert zf.read("META-INF/CERT.SF") == b'Signature-Version: 1.0\r\nSHA-256-Digest-Manifest-Main-Attributes: VmrRqAIgAm0FCZViZFzpaP8OfDbN4iY0MyYFuzTMPv8=\r\nSHA-256-Digest-Manifest: 9R83KbhgHCBaYGXhJ/bV2MofgjRU254oUx+YilOvRcE=\r\n\r\nName: test.txt\r\nSHA-256-Digest: q8FmiLsrdoC5XQRaN9KmaPCcd2revsR0NzDul9cK6bk=\r\n\r\n'