1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /**
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  */
23 package com.sun.org.apache.xml.internal.security.keys.storage.implementations;
24 
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.nio.file.Files;
30 import java.nio.file.Paths;
31 import java.security.cert.Certificate;
32 import java.security.cert.CertificateException;
33 import java.security.cert.CertificateExpiredException;
34 import java.security.cert.CertificateFactory;
35 import java.security.cert.CertificateNotYetValidException;
36 import java.security.cert.X509Certificate;
37 import java.util.ArrayList;
38 import java.util.Iterator;
39 import java.util.List;
40 
41 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverException;
42 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi;
43 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
44 
45 /**
46  * This {@link StorageResolverSpi} makes all raw (binary) {@link X509Certificate}s
47  * which reside as files in a single directory available to the
48  * {@link com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver}.
49  */
50 public class CertsInFilesystemDirectoryResolver extends StorageResolverSpi {
51 
52     private static final com.sun.org.slf4j.internal.Logger LOG =
53         com.sun.org.slf4j.internal.LoggerFactory.getLogger(
54             CertsInFilesystemDirectoryResolver.class
55         );
56 
57     /** Field merlinsCertificatesDir */
58     private String merlinsCertificatesDir;
59 
60     /** Field certs */
61     private List<X509Certificate> certs = new ArrayList<>();
62 
63     /**
64      * @param directoryName
65      * @throws StorageResolverException
66      */
CertsInFilesystemDirectoryResolver(String directoryName)67     public CertsInFilesystemDirectoryResolver(String directoryName)
68         throws StorageResolverException {
69         this.merlinsCertificatesDir = directoryName;
70 
71         this.readCertsFromHarddrive();
72     }
73 
74     /**
75      * Method readCertsFromHarddrive
76      *
77      * @throws StorageResolverException
78      */
readCertsFromHarddrive()79     private void readCertsFromHarddrive() throws StorageResolverException {
80 
81         File certDir = new File(this.merlinsCertificatesDir);
82         List<String> al = new ArrayList<>();
83         String[] names = certDir.list();
84 
85         if (names != null) {
86             for (int i = 0; i < names.length; i++) {
87                 String currentFileName = names[i];
88 
89                 if (currentFileName.endsWith(".crt")) {
90                     al.add(names[i]);
91                 }
92             }
93         }
94 
95         CertificateFactory cf = null;
96 
97         try {
98             cf = CertificateFactory.getInstance("X.509");
99         } catch (CertificateException ex) {
100             throw new StorageResolverException(ex);
101         }
102 
103         for (int i = 0; i < al.size(); i++) {
104             String filename = certDir.getAbsolutePath() + File.separator + al.get(i);
105             boolean added = false;
106             String dn = null;
107 
108             try (InputStream inputStream = Files.newInputStream(Paths.get(filename))) {
109                 X509Certificate cert =
110                     (X509Certificate) cf.generateCertificate(inputStream);
111 
112                 //add to ArrayList
113                 cert.checkValidity();
114                 this.certs.add(cert);
115 
116                 dn = cert.getSubjectX500Principal().getName();
117                 added = true;
118             } catch (FileNotFoundException ex) {
119                 if (LOG.isDebugEnabled()) {
120                     LOG.debug("Could not add certificate from file " + filename, ex);
121                 }
122             } catch (CertificateNotYetValidException ex) {
123                 if (LOG.isDebugEnabled()) {
124                     LOG.debug("Could not add certificate from file " + filename, ex);
125                 }
126             } catch (CertificateExpiredException ex) {
127                 if (LOG.isDebugEnabled()) {
128                     LOG.debug("Could not add certificate from file " + filename, ex);
129                 }
130             } catch (CertificateException ex) {
131                 if (LOG.isDebugEnabled()) {
132                     LOG.debug("Could not add certificate from file " + filename, ex);
133                 }
134             } catch (IOException ex) {
135                 if (LOG.isDebugEnabled()) {
136                     LOG.debug("Could not add certificate from file " + filename, ex);
137                 }
138             }
139 
140             if (added) {
141                 LOG.debug("Added certificate: {}", dn);
142             }
143         }
144     }
145 
146     /** {@inheritDoc} */
getIterator()147     public Iterator<Certificate> getIterator() {
148         return new FilesystemIterator(this.certs);
149     }
150 
151     /**
152      * Class FilesystemIterator
153      */
154     private static class FilesystemIterator implements Iterator<Certificate> {
155 
156         /** Field certs */
157         private List<X509Certificate> certs;
158 
159         /** Field i */
160         private int i;
161 
162         /**
163          * Constructor FilesystemIterator
164          *
165          * @param certs
166          */
FilesystemIterator(List<X509Certificate> certs)167         public FilesystemIterator(List<X509Certificate> certs) {
168             this.certs = certs;
169             this.i = 0;
170         }
171 
172         /** {@inheritDoc} */
hasNext()173         public boolean hasNext() {
174             return this.i < this.certs.size();
175         }
176 
177         /** {@inheritDoc} */
next()178         public Certificate next() {
179             return this.certs.get(this.i++);
180         }
181 
182         /**
183          * Method remove
184          *
185          */
remove()186         public void remove() {
187             throw new UnsupportedOperationException("Can't remove keys from KeyStore");
188         }
189     }
190 
191     /**
192      * Method main
193      *
194      * @param unused
195      * @throws Exception
196      */
main(String unused[])197     public static void main(String unused[]) throws Exception {
198 
199         CertsInFilesystemDirectoryResolver krs =
200             new CertsInFilesystemDirectoryResolver(
201                 "data/ie/baltimore/merlin-examples/merlin-xmldsig-eighteen/certs");
202 
203         for (Iterator<Certificate> i = krs.getIterator(); i.hasNext(); ) {
204             X509Certificate cert = (X509Certificate) i.next();
205             byte[] ski =
206                 com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509SKI.getSKIBytesFromCert(cert);
207 
208             System.out.println();
209             System.out.println("Base64(SKI())=                 \""
210                                + XMLUtils.encodeToString(ski) + "\"");
211             System.out.println("cert.getSerialNumber()=        \""
212                                + cert.getSerialNumber().toString() + "\"");
213             System.out.println("cert.getSubjectX500Principal().getName()= \""
214                                + cert.getSubjectX500Principal().getName() + "\"");
215             System.out.println("cert.getIssuerX500Principal().getName()=  \""
216                                + cert.getIssuerX500Principal().getName() + "\"");
217         }
218     }
219 }
220