001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.util; 019 020 021import java.io.ByteArrayInputStream; 022import java.security.cert.Certificate; 023import java.security.cert.CertificateException; 024import java.security.cert.CertificateFactory; 025import java.security.cert.X509Certificate; 026 027import com.nimbusds.jose.util.Base64; 028 029 030/** 031 * X.509 certificate utilities. 032 * 033 * @author Vladimir Dzhuvinov 034 * @version 2015-11-16 035 */ 036public class X509CertUtils { 037 038 039 /** 040 * The PEM start marker. 041 */ 042 private static final String PEM_BEGIN_MARKER = "-----BEGIN CERTIFICATE-----"; 043 044 045 /** 046 * The PEM end marker. 047 */ 048 private static final String PEM_END_MARKER = "-----END CERTIFICATE-----"; 049 050 051 /** 052 * Parses a DER-encoded X.509 certificate. 053 * 054 * @param derEncodedCert The DER-encoded X.509 certificate, as a byte 055 * array. May be {@code null}. 056 * 057 * @return The X.509 certificate, {@code null} if parsing failed. 058 */ 059 public static X509Certificate parse(final byte[] derEncodedCert) { 060 061 if (derEncodedCert == null || derEncodedCert.length == 0) { 062 return null; 063 } 064 065 final Certificate cert; 066 try { 067 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 068 cert = cf.generateCertificate(new ByteArrayInputStream(derEncodedCert)); 069 } catch (CertificateException e) { 070 return null; 071 } 072 073 if (! (cert instanceof X509Certificate)) { 074 return null; 075 } 076 077 return (X509Certificate)cert; 078 } 079 080 081 /** 082 * Parses a PEM-encoded X.509 certificate. 083 * 084 * @param pemEncodedCert The PEM-encoded X.509 certificate, as a 085 * string. May be {@code null}. 086 * 087 * @return The X.509 certificate, {@code null} if parsing failed. 088 */ 089 public static X509Certificate parse(final String pemEncodedCert) { 090 091 if (pemEncodedCert == null || pemEncodedCert.isEmpty()) { 092 return null; 093 } 094 095 final int markerStart = pemEncodedCert.indexOf(PEM_BEGIN_MARKER); 096 097 if (markerStart < 0) { 098 return null; 099 } 100 101 String buf = pemEncodedCert.substring(markerStart + PEM_BEGIN_MARKER.length()); 102 103 final int markerEnd = buf.indexOf(PEM_END_MARKER); 104 105 if (markerEnd < 0) { 106 return null; 107 } 108 109 buf = buf.substring(0, markerEnd); 110 111 buf = buf.replaceAll("\\s", ""); 112 113 return parse(new Base64(buf).decode()); 114 } 115}