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