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

com.unboundid.util.ssl.cert.X509PEMFileReader Maven / Gradle / Ivy

Go to download

The UnboundID LDAP SDK for Java is a fast, comprehensive, and easy-to-use Java API for communicating with LDAP directory servers and performing related tasks like reading and writing LDIF, encoding and decoding data using base64 and ASN.1 BER, and performing secure communication. This package contains the Standard Edition of the LDAP SDK, which is a complete, general-purpose library for communicating with LDAPv3 directory servers.

There is a newer version: 7.0.1
Show newest version
/*
 * Copyright 2021-2023 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2021-2023 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2021-2023 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.util.ssl.cert;



import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.unboundid.util.Base64;
import com.unboundid.util.Debug;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;

import static com.unboundid.util.ssl.cert.CertMessages.*;



/**
 * This class provides a mechanism for reading PEM-encoded X.509 certificates
 * from a specified file.  The PEM file may contain zero or more certificates.
 * Each certificate should consist of the following:
 * 
    *
  • A line containing only the string "-----BEGIN CERTIFICATE-----".
  • *
  • One or more lines representing the base64-encoded representation of the * bytes that comprise the X.509 certificate.
  • *
  • A line containing only the string "-----END CERTIFICATE-----".
  • *
*

* Any spaces that appear at the beginning or end of each line will be ignored. * Empty lines and lines that start with the octothorpe (#) character will also * be ignored. */ @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) public final class X509PEMFileReader implements Closeable { /** * The header string that should appear on a line by itself before the * base64-encoded representation of the bytes that comprise an X.509 * certificate. */ @NotNull public static final String BEGIN_CERTIFICATE_HEADER = "-----BEGIN CERTIFICATE-----"; /** * The footer string that should appear on a line by itself after the * base64-encoded representation of the bytes that comprise an X.509 * certificate. */ @NotNull public static final String END_CERTIFICATE_FOOTER = "-----END CERTIFICATE-----"; // The reader that will be used to consume data from the PEM file. @NotNull private final BufferedReader reader; /** * Creates a new X.509 PEM file reader that will read certificate information * from the specified file. * * @param pemFilePath The path to the PEM file from which the certificates * should be read. This must not be {@code null} and the * file must exist. * * @throws IOException If a problem occurs while attempting to open the file * for reading. */ public X509PEMFileReader(@NotNull final String pemFilePath) throws IOException { this(new File(pemFilePath)); } /** * Creates a new X.509 PEM file reader that will read certificate information * from the specified file. * * @param pemFile The PEM file from which the certificates should be read. * This must not be {@code null} and the file must * exist. * * @throws IOException If a problem occurs while attempting to open the file * for reading. */ public X509PEMFileReader(@NotNull final File pemFile) throws IOException { this(new FileInputStream(pemFile)); } /** * Creates a new X.509 PEM file reader that will read certificate information * from the provided input stream. * * @param inputStream The input stream from which the certificates should * be read. This must not be {@code null} and it must be * open for reading. */ public X509PEMFileReader(@NotNull final InputStream inputStream) { reader = new BufferedReader(new InputStreamReader(inputStream)); } /** * Reads the next certificate from the PEM file. * * @return The certificate that was read, or {@code null} if the end of the * file has been reached. * * @throws IOException If a problem occurs while trying to read data from * the PEM file. * * @throws CertException If a problem occurs while trying to interpret data * read from the PEM file as an X.509 certificate. */ @Nullable() public X509Certificate readCertificate() throws IOException, CertException { boolean beginFound = false; final StringBuilder base64Buffer = new StringBuilder(); while (true) { final String line = reader.readLine(); if (line == null) { // We hit the end of the file. If we read a begin header, then that's // an error. if (beginFound) { throw new CertException(ERR_X509_PEM_READER_EOF_WITHOUT_END.get( END_CERTIFICATE_FOOTER, BEGIN_CERTIFICATE_HEADER)); } return null; } final String trimmedLine = line.trim(); if (trimmedLine.isEmpty() || trimmedLine.startsWith("#")) { continue; } final String upperLine = StaticUtils.toUpperCase(trimmedLine); if (BEGIN_CERTIFICATE_HEADER.equals(upperLine)) { if (beginFound) { throw new CertException(ERR_X509_PEM_READER_REPEATED_BEGIN.get( BEGIN_CERTIFICATE_HEADER)); } else { beginFound = true; } } else if (END_CERTIFICATE_FOOTER.equals(upperLine)) { if (! beginFound) { throw new CertException(ERR_X509_PEM_READER_END_WITHOUT_BEGIN.get( END_CERTIFICATE_FOOTER, BEGIN_CERTIFICATE_HEADER)); } else if (base64Buffer.length() == 0) { throw new CertException(ERR_X509_PEM_READER_END_WITHOUT_DATA.get( END_CERTIFICATE_FOOTER, BEGIN_CERTIFICATE_HEADER)); } else { final byte[] x509Bytes; try { x509Bytes = Base64.decode(base64Buffer.toString()); } catch (final Exception e) { Debug.debugException(e); throw new CertException( ERR_X509_PEM_READER_CANNOT_BASE64_DECODE.get(), e); } return new X509Certificate(x509Bytes); } } else { if (! beginFound) { throw new CertException(ERR_X509_PEM_READER_DATA_WITHOUT_BEGIN.get( BEGIN_CERTIFICATE_HEADER)); } base64Buffer.append(trimmedLine); } } } /** * Closes this X.509 PEM file reader. * * @throws IOException If a problem is encountered while attempting to close * the reader. */ @Override() public void close() throws IOException { reader.close(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy