From 2f4740450892fd893a62f99b97d4114244e634d4 Mon Sep 17 00:00:00 2001 From: Kai Kramer Date: Thu, 2 Dec 2021 23:52:22 +0100 Subject: [PATCH] Fixed further issues in file type detection --- kse/src/org/kse/crypto/x509/X509CertUtil.java | 42 +++++++++++++------ .../crypto/filetype/CryptoFileUtilTest.java | 3 ++ .../CryptoFileUtilTest/cert.base64.txt | 29 +++++++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 kse/test/testdata/CryptoFileUtilTest/cert.base64.txt diff --git a/kse/src/org/kse/crypto/x509/X509CertUtil.java b/kse/src/org/kse/crypto/x509/X509CertUtil.java index cb09b44df..75163fe87 100644 --- a/kse/src/org/kse/crypto/x509/X509CertUtil.java +++ b/kse/src/org/kse/crypto/x509/X509CertUtil.java @@ -41,7 +41,7 @@ import java.security.cert.X509Certificate; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; @@ -97,13 +97,15 @@ public static X509Certificate[] loadCertificates(byte[] certsBytes) throws Crypt // try to parse data as PEM encoded List loadedCerts = loadAsPEM(certsBytes, cf); + // might be Base64 encoded but without the PEM header + if (loadedCerts.isEmpty()) { + loadedCerts = loadAsBase64(certsBytes, cf); + } + // try to parse as DER encoded if (loadedCerts.isEmpty()) { Collection certs = cf.generateCertificates(new ByteArrayInputStream(certsBytes)); - - if (!certs.isEmpty()) { - return convertCertificates(certs); - } + loadedCerts = convertCertificates(certs); } return loadedCerts.toArray(new X509Certificate[0]); @@ -119,6 +121,18 @@ public static X509Certificate[] loadCertificates(byte[] certsBytes) throws Crypt } } + private static List loadAsBase64(byte[] certsBytes, CertificateFactory cf) { + try { + byte[] base64Decoded = Base64.getMimeDecoder().decode(certsBytes); + + Collection certs = cf.generateCertificates(new ByteArrayInputStream(base64Decoded)); + + return convertCertificates(certs); + } catch (Exception e) { + return new ArrayList<>(); + } + } + private static X509Certificate[] loadCertificatesPkiPath(InputStream is) throws CryptoException { try { CertificateFactory cf = CertificateFactory.getInstance(X509_CERT_TYPE, BOUNCY_CASTLE.jce()); @@ -166,8 +180,8 @@ private static List loadAsPEM(byte[] bytes, CertificateFactory cf.generateCertificates(new ByteArrayInputStream(contentInfo.getEncoded())); if (!certsFromPkcs7.isEmpty()) { - X509Certificate[] x509Certificates = convertCertificates(certsFromPkcs7); - certs.addAll(Arrays.asList(x509Certificates)); + List x509Certificates = convertCertificates(certsFromPkcs7); + certs.addAll(x509Certificates); } } pemObject = pemParser.readObject(); @@ -226,6 +240,7 @@ public static X509Certificate[] convertCertificates(Certificate[] certsIn) throw return certsOut; } + /** * Convert the supplied array of certificate objects into X509Certificate * objects. @@ -236,19 +251,20 @@ public static X509Certificate[] convertCertificates(Certificate[] certsIn) throw * @throws CryptoException * A problem occurred during the conversion */ - public static X509Certificate[] convertCertificates(Collection certs) throws CryptoException { + public static List convertCertificates(Collection certs) + throws CryptoException { + + ArrayList convertedCerts = new ArrayList<>(); if (certs == null) { - return new X509Certificate[0]; + return convertedCerts; } - X509Certificate[] certsOut = new X509Certificate[certs.size()]; - int i = 0; for (Certificate cert : certs) { - certsOut[i++] = convertCertificate(cert); + convertedCerts.add(convertCertificate(cert)); } - return certsOut; + return convertedCerts; } /** diff --git a/kse/test/org/kse/crypto/filetype/CryptoFileUtilTest.java b/kse/test/org/kse/crypto/filetype/CryptoFileUtilTest.java index 36a0f49b9..f7d842579 100644 --- a/kse/test/org/kse/crypto/filetype/CryptoFileUtilTest.java +++ b/kse/test/org/kse/crypto/filetype/CryptoFileUtilTest.java @@ -31,6 +31,9 @@ class CryptoFileUtilTest { "cert.p7, CERT", "cert.p7b, CERT", + // base64 encoded cert file, but no PEM header/footer + "cert.base64.txt, CERT", + // certificate signing request formats "csr.p10, PKCS10_CSR", "csr.spkac, SPKAC_CSR", diff --git a/kse/test/testdata/CryptoFileUtilTest/cert.base64.txt b/kse/test/testdata/CryptoFileUtilTest/cert.base64.txt new file mode 100644 index 000000000..6db6dc8ab --- /dev/null +++ b/kse/test/testdata/CryptoFileUtilTest/cert.base64.txt @@ -0,0 +1,29 @@ +MIIFYjCCBEqgAwIBAgIQd70NbNs2+RrqIQ/E8FjTDTANBgkqhkiG9w0BAQsFADBX +MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UE +CxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTIwMDYx +OTAwMDA0MloXDTI4MDEyODAwMDA0MlowRzELMAkGA1UEBhMCVVMxIjAgBgNVBAoT +GUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBMTEMxFDASBgNVBAMTC0dUUyBSb290IFIx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63 +ladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS +iV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k +KSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ +DrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk +j5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5 +cuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW +CruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499 +iYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei +Eua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap +sZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b +9f6BQdgAmD06yK56mDcYBZUCAwEAAaOCATgwggE0MA4GA1UdDwEB/wQEAwIBhjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkrysmcRorSCeFL1JmLO/wiRNxPjAf +BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzBgBggrBgEFBQcBAQRUMFIw +JQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnBraS5nb29nL2dzcjEwKQYIKwYBBQUH +MAKGHWh0dHA6Ly9wa2kuZ29vZy9nc3IxL2dzcjEuY3J0MDIGA1UdHwQrMCkwJ6Al +oCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMS9nc3IxLmNybDA7BgNVHSAENDAy +MAgGBmeBDAECATAIBgZngQwBAgIwDQYLKwYBBAHWeQIFAwIwDQYLKwYBBAHWeQIF +AwMwDQYJKoZIhvcNAQELBQADggEBADSkHrEoo9C0dhemMXoh6dFSPsjbdBZBiLg9 +NR3t5P+T4Vxfq7vqfM/b5A3Ri1fyJm9bvhdGaJQ3b2t6yMAYN/olUazsaL+yyEn9 +WprKASOshIArAoyZl+tJaox118fessmXn1hIVw41oeQa1v1vg4Fv74zPl6/AhSrw +9U5pCZEt4Wi4wStz6dTZ/CLANx8LZh1J7QJVj2fhMtfTJr9w4z30Z209fOU0iOMy ++qduBmpvvYuR7hZL6Dupszfnw0Skfths18dG9ZKb59UhvmaSGZRVbNQpsg3BZlvi +d0lIKO2d1xozclOzgjXPYovJJIultzkMu34qQb9Sz/yilrbCgj8= \ No newline at end of file