1 package org.bouncycastle.jcajce.provider.keystore.util;
2 
3 import java.io.BufferedInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.security.Key;
8 import java.security.KeyStore;
9 import java.security.KeyStoreException;
10 import java.security.KeyStoreSpi;
11 import java.security.NoSuchAlgorithmException;
12 import java.security.UnrecoverableKeyException;
13 import java.security.cert.Certificate;
14 import java.security.cert.CertificateException;
15 import java.util.Date;
16 import java.util.Enumeration;
17 
18 import org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
19 import org.bouncycastle.jcajce.util.JcaJceHelper;
20 import org.bouncycastle.util.Properties;
21 
22 /**
23  * Implements a certificate only JKS key store.
24  */
25 public class AdaptingKeyStoreSpi
26     extends KeyStoreSpi
27 {
28     public static final String COMPAT_OVERRIDE = "keystore.type.compat";
29 
30     private final JKSKeyStoreSpi jksStore;
31     private final KeyStoreSpi primaryStore;
32 
33     private KeyStoreSpi keyStoreSpi;
34 
AdaptingKeyStoreSpi(JcaJceHelper helper, KeyStoreSpi primaryStore)35     public AdaptingKeyStoreSpi(JcaJceHelper helper, KeyStoreSpi primaryStore)
36     {
37         this.jksStore = new JKSKeyStoreSpi(helper);
38         this.primaryStore = primaryStore;
39         this.keyStoreSpi = primaryStore;
40     }
41 
engineProbe(InputStream stream)42     public boolean engineProbe(InputStream stream)
43         throws IOException
44     {
45         if (keyStoreSpi instanceof PKCS12KeyStoreSpi)
46         {
47             return ((PKCS12KeyStoreSpi)keyStoreSpi).engineProbe(stream);
48         }
49         return false;
50     }
51 
engineGetKey(String alias, char[] password)52     public Key engineGetKey(String alias, char[] password)
53         throws NoSuchAlgorithmException, UnrecoverableKeyException
54     {
55         return keyStoreSpi.engineGetKey(alias, password);
56     }
57 
engineGetCertificateChain(String alias)58     public Certificate[] engineGetCertificateChain(String alias)
59     {
60         return keyStoreSpi.engineGetCertificateChain(alias);
61     }
62 
engineGetCertificate(String alias)63     public Certificate engineGetCertificate(String alias)
64     {
65         return keyStoreSpi.engineGetCertificate(alias);
66     }
67 
engineGetCreationDate(String alias)68     public Date engineGetCreationDate(String alias)
69     {
70         return keyStoreSpi.engineGetCreationDate(alias);
71     }
72 
engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)73     public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
74         throws KeyStoreException
75     {
76         keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
77     }
78 
engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)79     public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
80         throws KeyStoreException
81     {
82         keyStoreSpi.engineSetKeyEntry(alias, key, chain);
83     }
84 
engineSetCertificateEntry(String alias, Certificate cert)85     public void engineSetCertificateEntry(String alias, Certificate cert)
86         throws KeyStoreException
87     {
88         keyStoreSpi.engineSetCertificateEntry(alias, cert);
89     }
90 
engineDeleteEntry(String alias)91     public void engineDeleteEntry(String alias)
92         throws KeyStoreException
93     {
94         keyStoreSpi.engineDeleteEntry(alias);
95     }
96 
engineAliases()97     public Enumeration<String> engineAliases()
98     {
99         return keyStoreSpi.engineAliases();
100     }
101 
engineContainsAlias(String alias)102     public boolean engineContainsAlias(String alias)
103     {
104         return keyStoreSpi.engineContainsAlias(alias);
105     }
106 
engineSize()107     public int engineSize()
108     {
109         return keyStoreSpi.engineSize();
110     }
111 
engineIsKeyEntry(String alias)112     public boolean engineIsKeyEntry(String alias)
113     {
114         return keyStoreSpi.engineIsKeyEntry(alias);
115     }
116 
engineIsCertificateEntry(String alias)117     public boolean engineIsCertificateEntry(String alias)
118     {
119         return keyStoreSpi.engineIsCertificateEntry(alias);
120     }
121 
engineGetCertificateAlias(Certificate cert)122     public String engineGetCertificateAlias(Certificate cert)
123     {
124         return keyStoreSpi.engineGetCertificateAlias(cert);
125     }
126 
engineStore(OutputStream stream, char[] password)127     public void engineStore(OutputStream stream, char[] password)
128         throws IOException, NoSuchAlgorithmException, CertificateException
129     {
130         keyStoreSpi.engineStore(stream, password);
131     }
132 
engineStore(KeyStore.LoadStoreParameter parameter)133     public void engineStore(KeyStore.LoadStoreParameter parameter)
134         throws IOException, NoSuchAlgorithmException, CertificateException
135     {
136         keyStoreSpi.engineStore(parameter);
137     }
138 
engineLoad(InputStream stream, char[] password)139     public void engineLoad(InputStream stream, char[] password)
140         throws IOException, NoSuchAlgorithmException, CertificateException
141     {
142         if (stream == null)
143         {
144             keyStoreSpi = primaryStore;
145             keyStoreSpi.engineLoad(null, password);
146         }
147         else
148         {
149             // the FIPS BCFKS/JKS compatibility is explicit and doesn't use the override.
150             if (Properties.isOverrideSet(COMPAT_OVERRIDE) || !(primaryStore instanceof PKCS12KeyStoreSpi))
151             {
152                 if (!stream.markSupported())
153                 {
154                     stream = new BufferedInputStream(stream);
155                 }
156 
157                 stream.mark(8);
158                 if (jksStore.engineProbe(stream))
159                 {
160                     keyStoreSpi = jksStore;
161                 }
162                 else
163                 {
164                     keyStoreSpi = primaryStore;
165                 }
166 
167                 stream.reset();
168             }
169             else
170             {
171                 keyStoreSpi = primaryStore;
172             }
173 
174             keyStoreSpi.engineLoad(stream, password);
175         }
176     }
177 
engineLoad(KeyStore.LoadStoreParameter parameter)178     public void engineLoad(KeyStore.LoadStoreParameter parameter)
179         throws IOException, NoSuchAlgorithmException, CertificateException
180     {
181         keyStoreSpi.engineLoad(parameter);
182     }
183 }
184 
185