132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root/* 232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * Copyright (C) 2012 The Android Open Source Project 332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * 432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * you may not use this file except in compliance with the License. 632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * You may obtain a copy of the License at 732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * 832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * http://www.apache.org/licenses/LICENSE-2.0 932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * 1032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * Unless required by applicable law or agreed to in writing, software 1132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 1232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * See the License for the specific language governing permissions and 1432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * limitations under the License. 1532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 1632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 1832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 1932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.io.IOException; 2032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.io.InputStream; 2132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.io.PushbackInputStream; 2232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.security.cert.CRL; 2332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.security.cert.CRLException; 24e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.CertPath; 2532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.security.cert.Certificate; 2632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.security.cert.CertificateException; 2732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.security.cert.CertificateFactorySpi; 28e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.security.cert.X509Certificate; 2932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.util.ArrayList; 3032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.util.Arrays; 3132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.util.Collection; 3232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.util.Collections; 33e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Rootimport java.util.Iterator; 3432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootimport java.util.List; 3532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 3632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Rootpublic class OpenSSLX509CertificateFactory extends CertificateFactorySpi { 373e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root private static final byte[] PKCS7_MARKER = new byte[] { 383e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root '-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7' 393e46e4ee56c8e37158f46941dedd5b436d724baaKenny Root }; 4032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 4132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root private static final int PUSHBACK_SIZE = 64; 4232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 4332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root static class ParsingException extends Exception { 4432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root private static final long serialVersionUID = 8390802697728301325L; 4532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 4632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public ParsingException(String message) { 4732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root super(message); 4832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 4932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 5032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public ParsingException(Exception cause) { 5132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root super(cause); 5232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 5332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 5432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public ParsingException(String message, Exception cause) { 5532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root super(message, cause); 5632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 5732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 5832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 5932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /** 6032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * The code for X509 Certificates and CRL is pretty much the same. We use 6132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * this abstract class to share the code between them. This makes it ugly, 6232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * but it's already written in this language anyway. 6332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 6432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root private static abstract class Parser<T> { 6532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public T generateItem(InputStream inStream) throws ParsingException { 66eb1df6f347f30dc40815f3776b47632a10216660Kenny Root if (inStream == null) { 67eb1df6f347f30dc40815f3776b47632a10216660Kenny Root throw new ParsingException("inStream == null"); 68eb1df6f347f30dc40815f3776b47632a10216660Kenny Root } 69eb1df6f347f30dc40815f3776b47632a10216660Kenny Root 7032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final boolean markable = inStream.markSupported(); 7132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 7232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.mark(PKCS7_MARKER.length); 7332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 7432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 7532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE); 7632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 7732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final byte[] buffer = new byte[PKCS7_MARKER.length]; 7832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 7932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final int len = pbis.read(buffer); 8032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (len < 0) { 8132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* No need to reset here. The stream was empty or EOF. */ 8232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new ParsingException("inStream is empty"); 8332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 8432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root pbis.unread(buffer, 0, len); 8532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 8632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (buffer[0] == '-') { 8732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) { 8832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root List<? extends T> items = fromPkcs7PemInputStream(pbis); 8932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (items.size() == 0) { 9032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return null; 9132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 9232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root items.get(0); 9332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } else { 9432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return fromX509PemInputStream(pbis); 9532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 9632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 9732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 9832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */ 9932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (buffer[4] == 0x06) { 10032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root List<? extends T> certs = fromPkcs7DerInputStream(pbis); 10132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (certs.size() == 0) { 10232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return null; 10332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 10432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return certs.get(0); 10532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } else { 10632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return fromX509DerInputStream(pbis); 10732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 10832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (Exception e) { 10932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 11032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 11132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.reset(); 11232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (IOException ignored) { 11332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 11432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 11532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new ParsingException(e); 11632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 11732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 11832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 11932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public Collection<? extends T> generateItems(InputStream inStream) 12032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 121881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (inStream == null) { 1226faa71701f8f8a985db5e914369c97d511532886Kenny Root throw new ParsingException("inStream == null"); 123881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 12432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 125881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (inStream.available() == 0) { 12632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return Collections.emptyList(); 12732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 12832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (IOException e) { 12932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new ParsingException("Problem reading input stream", e); 13032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 13132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 13232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final boolean markable = inStream.markSupported(); 13332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 13432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.mark(PUSHBACK_SIZE); 13532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 13632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 13732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* Attempt to see if this is a PKCS#7 bag. */ 13832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE); 13932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 14032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final byte[] buffer = new byte[PKCS7_MARKER.length]; 14132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 14232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final int len = pbis.read(buffer); 14332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (len < 0) { 14432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* No need to reset here. The stream was empty or EOF. */ 14532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new ParsingException("inStream is empty"); 14632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 14732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root pbis.unread(buffer, 0, len); 14832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 14932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) { 15032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return fromPkcs7PemInputStream(pbis); 15132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 15232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 15332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */ 15432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (buffer[4] == 0x06) { 15532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return fromPkcs7DerInputStream(pbis); 15632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 15732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (Exception e) { 15832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 15932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 16032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.reset(); 16132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (IOException ignored) { 16232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 16332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 16432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new ParsingException(e); 16532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 16632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 16732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* 16832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * It wasn't, so just try to keep grabbing certificates until we 16932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * can't anymore. 17032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 17132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root final List<T> coll = new ArrayList<T>(); 17232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root T c = null; 17332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root do { 17432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* 17532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * If this stream supports marking, try to mark here in case 17632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * there is an error during certificate generation. 17732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 17832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 17932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.mark(PUSHBACK_SIZE); 18032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 18132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 18232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 18332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root c = generateItem(pbis); 18432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root coll.add(c); 18532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (ParsingException e) { 18632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root /* 18732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * If this stream supports marking, attempt to reset it to 18832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root * the mark before the failure. 18932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root */ 19032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root if (markable) { 19132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 19232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root inStream.reset(); 19332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (IOException ignored) { 19432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 19532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 19632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 19732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root c = null; 19832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 19932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } while (c != null); 20032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 20132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return coll; 20232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 20332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 20432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root protected abstract T fromX509PemInputStream(InputStream pbis) throws ParsingException; 20532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 20632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root protected abstract T fromX509DerInputStream(InputStream pbis) throws ParsingException; 20732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 20832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root protected abstract List<? extends T> fromPkcs7PemInputStream(InputStream is) 20932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException; 21032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 21132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root protected abstract List<? extends T> fromPkcs7DerInputStream(InputStream is) 21232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException; 21332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 21432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 21532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root private Parser<OpenSSLX509Certificate> certificateParser = 21632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root new Parser<OpenSSLX509Certificate>() { 21732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 21832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public OpenSSLX509Certificate fromX509PemInputStream(InputStream is) 21932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 22032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509Certificate.fromX509PemInputStream(is); 22132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 22232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 22332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 22432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public OpenSSLX509Certificate fromX509DerInputStream(InputStream is) 22532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 22632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509Certificate.fromX509DerInputStream(is); 22732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 22832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 22932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 23032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public List<? extends OpenSSLX509Certificate> 23132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root fromPkcs7PemInputStream(InputStream is) throws ParsingException { 23232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509Certificate.fromPkcs7PemInputStream(is); 23332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 23432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 23532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 23632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public List<? extends OpenSSLX509Certificate> 23732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root fromPkcs7DerInputStream(InputStream is) throws ParsingException { 23832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509Certificate.fromPkcs7DerInputStream(is); 23932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 24032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root }; 24132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 24232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root private Parser<OpenSSLX509CRL> crlParser = 24332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root new Parser<OpenSSLX509CRL>() { 24432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 24532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public OpenSSLX509CRL fromX509PemInputStream(InputStream is) 24632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 24732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509CRL.fromX509PemInputStream(is); 24832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 24932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 25032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 25132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public OpenSSLX509CRL fromX509DerInputStream(InputStream is) 25232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 25332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509CRL.fromX509DerInputStream(is); 25432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 25532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 25632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 25732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is) 25832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 25932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509CRL.fromPkcs7PemInputStream(is); 26032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 26132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 26232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 26332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is) 26432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throws ParsingException { 26532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return OpenSSLX509CRL.fromPkcs7DerInputStream(is); 26632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 26732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root }; 26832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 26932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 27032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException { 27132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 27232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return certificateParser.generateItem(inStream); 27332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (ParsingException e) { 27432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new CertificateException(e); 27532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 27632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 27732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 27832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 27932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public Collection<? extends Certificate> engineGenerateCertificates( 28032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root InputStream inStream) throws CertificateException { 28132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 28232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return certificateParser.generateItems(inStream); 28332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (ParsingException e) { 28432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new CertificateException(e); 28532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 28632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 28732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 28832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 28932850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public CRL engineGenerateCRL(InputStream inStream) throws CRLException { 29032850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 29132850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return crlParser.generateItem(inStream); 29232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (ParsingException e) { 29332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new CRLException(e); 29432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 29532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 29632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root 29732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root @Override 29832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException { 299881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root if (inStream == null) { 300881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root return Collections.emptyList(); 301881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root } 302881c794faa5fd0a4498a5f331c2fc92dd23b26a2Kenny Root 30332850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root try { 30432850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root return crlParser.generateItems(inStream); 30532850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } catch (ParsingException e) { 30632850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root throw new CRLException(e); 30732850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 30832850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root } 309e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 310e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 311e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public Iterator<String> engineGetCertPathEncodings() { 312e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return OpenSSLX509CertPath.getEncodingsIterator(); 313e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 314e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 315e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 316e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException { 317e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return OpenSSLX509CertPath.fromEncoding(inStream); 318e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 319e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 320e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 321e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public CertPath engineGenerateCertPath(InputStream inStream, String encoding) 322e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 323e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return OpenSSLX509CertPath.fromEncoding(inStream, encoding); 324e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 325e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 326e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root @Override 327e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root public CertPath engineGenerateCertPath(List<? extends Certificate> certificates) 328e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throws CertificateException { 329e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final List<X509Certificate> filtered = new ArrayList<X509Certificate>(certificates.size()); 330e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root for (int i = 0; i < certificates.size(); i++) { 331e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root final Certificate c = certificates.get(i); 332e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 333e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root if (!(c instanceof X509Certificate)) { 334e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root throw new CertificateException("Certificate not X.509 type at index " + i); 335e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 336e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 337e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root filtered.add((X509Certificate) c); 338e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 339e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root 340e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root return new OpenSSLX509CertPath(filtered); 341e1429740ee37db9422d7622d11d32a29a4bc4301Kenny Root } 34232850b6ce29c70150cfe01c4ce2a1b353d92e6feKenny Root} 343