/* * Copyright (c) 2011 ICM Uniwersytet Warszawski All rights reserved. * See LICENCE file for licensing information. */ package eu.emi.security.authn.x509.helpers; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; /** * Extends BC's {@link PEMParser} class so it can read correctly also * PEM files with a garbage at the beginning * and minor syntax violations which occur more then often in the wild. * * TODO - probably we can remove this class - BC seems to be fixed. * * @author K. Benedyczak */ public class FlexiblePEMReader extends PEMParser { /** * Creates a new {@link FlexiblePEMReader} object. * @param reader input source */ public FlexiblePEMReader(Reader reader) { super(reader); } /** * Generate BC's PemObject * @return the parsed PEM object * @throws IOException IO exception */ @Override public PemObject readPemObject() throws IOException { Pattern starter = Pattern.compile("^---[-]+BEGIN [^-]+---[-]+$"); Pattern end = Pattern.compile("^---[-]+END [^-]+---[-]+$"); String line; boolean startFound = false; while ((line=readLine()) != null) { Matcher m = starter.matcher(line); if (m.find()) { startFound = true; break; } } if (!startFound) return null; int pos = line.indexOf("BEGIN ") + 6; int endPos = line.indexOf('-', pos); String type = line.substring(pos, endPos); boolean endFound = false; StringBuilder sb = new StringBuilder(); List<PemHeader> headers = new ArrayList<PemHeader>(); while ((line=readLine()) != null) { Matcher m = end.matcher(line); if (m.find()) throw new IOException("The supplied data is not in PEM format, end line found before getting any contents."); if (line.indexOf(":") >= 0) { int index = line.indexOf(':'); String hdr = line.substring(0, index); String value = line.substring(index + 1).trim(); headers.add(new PemHeader(hdr, value)); } else { sb.append(line.trim()); break; } } while ((line=readLine()) != null) { Matcher m = end.matcher(line); if (m.find()) { endFound = true; break; } else sb.append(line.trim()); } if (!endFound) throw new IOException("The supplied data is not in PEM format, no ending line found."); return new PemObject(type, headers, Base64.decode(sb.toString())); } }