Pārlūkot izejas kodu

express: Update SHA256 code in ZipArchive for OpenSSL v3

rdb 2 mēneši atpakaļ
vecāks
revīzija
25ef6112de

+ 12 - 14
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(&section_ctx);
-      SHA256_Update(&section_ctx, section.data(), section.size());
-      SHA256_Final(digest, &section_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";

+ 21 - 0
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-----

+ 28 - 0
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-----

+ 16 - 0
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'