From f9469a099e74c366734869d13afcee19534bece7 Mon Sep 17 00:00:00 2001 From: Appu Goundan Date: Wed, 1 Nov 2023 11:37:49 -0400 Subject: [PATCH] Use stricter PEMParser instead of PemReader https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61015&q=label%3AProj-sigstore-java Signed-off-by: Appu Goundan --- .../encryption/certificates/Certificates.java | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/sigstore-java/src/main/java/dev/sigstore/encryption/certificates/Certificates.java b/sigstore-java/src/main/java/dev/sigstore/encryption/certificates/Certificates.java index 6688df6f..e7891d06 100644 --- a/sigstore-java/src/main/java/dev/sigstore/encryption/certificates/Certificates.java +++ b/sigstore-java/src/main/java/dev/sigstore/encryption/certificates/Certificates.java @@ -15,7 +15,6 @@ */ package dev.sigstore.encryption.certificates; -import com.google.api.client.util.PemReader; import com.google.common.collect.ImmutableList; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -27,7 +26,11 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.bouncycastle.util.encoders.DecoderException; public class Certificates { @@ -96,36 +99,34 @@ public static byte[] toPemBytes(CertPath certs) throws IOException { /** Convert a PEM encoded certificate chain to a {@link CertPath}. */ public static CertPath fromPemChain(String certs) throws CertificateException { - PemReader pemReader = null; - try { - pemReader = new PemReader(new StringReader(certs)); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); + try (PEMParser pemParser = new PEMParser(new StringReader(certs))) { ArrayList certList = new ArrayList<>(); while (true) { try { - PemReader.Section section = pemReader.readNextSection(); + var section = pemParser.readObject(); // throws DecoderException if (section == null) { break; } - byte[] certBytes = section.getBase64DecodedBytes(); - certList.add( - (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certBytes))); - } catch (IOException | IllegalArgumentException ioe) { - throw new CertificateParsingException("Error reading PEM section in cert chain", ioe); + if (section instanceof X509CertificateHolder) { + var certificate = + new JcaX509CertificateConverter().getCertificate((X509CertificateHolder) section); + certList.add(certificate); + } else { + throw new CertificateException( + "Unsupported pem section: " + + section.getClass().toString() + + " is not an X509Certificate"); + } + } catch (IOException | DecoderException e) { + throw new CertificateException("failed to parse PEM object to certificate", e); } } if (certList.isEmpty()) { - throw new CertificateParsingException("no valid PEM certificates were found"); - } - return cf.generateCertPath(certList); - } finally { - if (pemReader != null) { - try { - pemReader.close(); - } catch (IOException e) { - // ignored - } + throw new CertificateException("no valid PEM certificates were found"); } + return CertificateFactory.getInstance("X.509").generateCertPath(certList); + } catch (IOException e) { + throw new CertificateException("failed to close PEM parser", e); } }