All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rt.storage.api.client.util.PemReader Maven / Gradle / Ivy

package com.rt.storage.api.client.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * {@link Beta} 
* PEM file reader. * *

Supports reading any PEM stream that contains Base64 encoded content stored inside {@code * "-----BEGIN ...-----"} and {@code "-----END ...-----"} tags. Each call to {@link * #readNextSection()} parses the next section in the PEM file. If you need a section of a certain * title use {@link #readNextSection(String)}, for example {@code readNextSection("PRIVATE KEY")}. * To ensure that the stream is closed properly, call {@link #close()} in a finally block. * *

As a convenience, use {@link #readFirstSectionAndClose(Reader)} or {@link * #readFirstSectionAndClose(Reader, String)} for the common case of only a single section in a PEM * file (or only a single section of a given title). * *

Limitations: * *

* *

    *
  • Assumes the PEM file section content is not encrypted and cannot handle the case of any * headers inside the BEGIN and END tag. *
  • It also ignores any attributes associated with any PEM file section. *
* * @since 1.14 * @author Yaniv Inbar */ @Beta public final class PemReader { private static final Pattern BEGIN_PATTERN = Pattern.compile("-----BEGIN ([A-Z ]+)-----"); private static final Pattern END_PATTERN = Pattern.compile("-----END ([A-Z ]+)-----"); /** Reader. */ private BufferedReader reader; /** @param reader reader */ public PemReader(Reader reader) { this.reader = new BufferedReader(reader); } /** Reads the next section in the PEM file or {@code null} for end of file. */ public Section readNextSection() throws IOException { return readNextSection(null); } /** * Reads the next section in the PEM file, optionally based on a title to look for. * * @param titleToLookFor title to look for or {@code null} for any title * @return next section or {@code null} for end of file */ public Section readNextSection(String titleToLookFor) throws IOException { String title = null; StringBuilder keyBuilder = null; while (true) { String line = reader.readLine(); if (line == null) { Preconditions.checkArgument(title == null, "missing end tag (%s)", title); return null; } if (keyBuilder == null) { Matcher m = BEGIN_PATTERN.matcher(line); if (m.matches()) { String curTitle = m.group(1); if (titleToLookFor == null || curTitle.equals(titleToLookFor)) { keyBuilder = new StringBuilder(); title = curTitle; } } } else { Matcher m = END_PATTERN.matcher(line); if (m.matches()) { String endTitle = m.group(1); Preconditions.checkArgument( endTitle.equals(title), "end tag (%s) doesn't match begin tag (%s)", endTitle, title); return new Section(title, Base64.decodeBase64(keyBuilder.toString())); } keyBuilder.append(line); } } } /** * Reads the first section in the PEM file, and then closes the reader. * * @param reader reader * @return first section found or {@code null} for none found */ public static Section readFirstSectionAndClose(Reader reader) throws IOException { return readFirstSectionAndClose(reader, null); } /** * Reads the first section in the PEM file, optionally based on a title to look for, and then * closes the reader. * * @param titleToLookFor title to look for or {@code null} for any title * @param reader reader * @return first section found or {@code null} for none found */ public static Section readFirstSectionAndClose(Reader reader, String titleToLookFor) throws IOException { PemReader pemReader = new PemReader(reader); try { return pemReader.readNextSection(titleToLookFor); } finally { pemReader.close(); } } /** * Closes the reader. * *

To ensure that the stream is closed properly, call {@link #close()} in a finally block. */ public void close() throws IOException { reader.close(); } /** Section in the PEM file. */ public static final class Section { /** Title. */ private final String title; /** Base64-decoded bytes. */ private final byte[] base64decodedBytes; /** * @param title title * @param base64decodedBytes base64-decoded bytes */ Section(String title, byte[] base64decodedBytes) { this.title = Preconditions.checkNotNull(title); this.base64decodedBytes = Preconditions.checkNotNull(base64decodedBytes); } /** Returns the title. */ public String getTitle() { return title; } /** Returns the base64-decoded bytes (modifiable array). */ public byte[] getBase64DecodedBytes() { return base64decodedBytes; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy