1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.security;
21
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.security.Key;
27 import java.security.KeyStore;
28 import java.security.KeyStoreException;
29 import java.security.KeyStoreSpi;
30 import java.security.NoSuchAlgorithmException;
31 import java.security.UnrecoverableKeyException;
32 import java.security.cert.Certificate;
33 import java.security.cert.CertificateException;
34 import java.security.cert.X509Certificate;
35 import java.util.Date;
36 import java.util.Enumeration;
37 import java.util.Objects;
38
39 import org.apache.directory.api.ldap.model.entry.Entry;
40 import org.apache.directory.api.ldap.model.exception.LdapException;
41 import org.apache.directory.api.ldap.model.name.Dn;
42 import org.apache.directory.api.util.SingletonEnumeration;
43 import org.apache.directory.api.util.exception.NotImplementedException;
44 import org.apache.directory.server.constants.ServerDNConstants;
45 import org.apache.directory.server.core.api.DirectoryService;
46 import org.apache.directory.server.i18n.I18n;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54
55
56
57
58 public class CoreKeyStoreSpi extends KeyStoreSpi
59 {
60 private static final String APACHEDS_ALIAS = "apacheds";
61
62 private static final Logger LOG = LoggerFactory.getLogger( CoreKeyStoreSpi.class );
63
64 private DirectoryService directoryService;
65 private KeyStore keyStore;
66
67
68
69
70
71
72 public CoreKeyStoreSpi( DirectoryService directoryService )
73 {
74 LOG.debug( "Constructor called." );
75 this.directoryService = directoryService;
76 }
77
78
79 public void setKeyStore( KeyStore keyStore )
80 {
81 this.keyStore = keyStore;
82 }
83
84
85 private Entry getTlsEntry() throws LdapException
86 {
87 Dn adminDn = directoryService.getDnFactory().create( ServerDNConstants.ADMIN_SYSTEM_DN );
88
89 return directoryService.getAdminSession().lookup( adminDn );
90 }
91
92
93
94
95
96 @Override
97 public Enumeration<String> engineAliases()
98 {
99 LOG.debug( "engineAliases() called." );
100 return new SingletonEnumeration<>( APACHEDS_ALIAS );
101 }
102
103
104
105
106
107 @Override
108 public boolean engineContainsAlias( String alias )
109 {
110 LOG.debug( "engineContainsAlias({}) called.", alias );
111
112 return alias.equalsIgnoreCase( APACHEDS_ALIAS );
113 }
114
115
116
117
118
119 @Override
120 public void engineDeleteEntry( String alias ) throws KeyStoreException
121 {
122 LOG.debug( "engineDeleteEntry({}) called.", alias );
123 throw new UnsupportedOperationException();
124 }
125
126
127
128
129
130 @Override
131 public Certificate engineGetCertificate( String alias )
132 {
133 LOG.debug( "engineGetCertificate({}) called.", alias );
134 if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
135 {
136 try
137 {
138 return keyStore.getCertificate( alias );
139
140
141 }
142 catch ( Exception e )
143 {
144 LOG.error( I18n.err( I18n.ERR_65 ), e );
145 }
146 }
147
148 return null;
149 }
150
151
152
153
154
155 @Override
156 public String engineGetCertificateAlias( Certificate cert )
157 {
158 LOG.debug( "engineGetCertificateAlias({}) called.", cert );
159
160 if ( cert instanceof X509Certificate )
161 {
162 LOG.debug( "Certificate in alias request is X.509 based." );
163 X509Certificate xcert = ( X509Certificate ) cert;
164
165 if ( xcert.getIssuerDN().toString().equals( TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN ) )
166 {
167 return APACHEDS_ALIAS;
168 }
169 }
170
171 try
172 {
173 Certificate certificate = keyStore.getCertificate( APACHEDS_ALIAS );
174
175 if ( Objects.deepEquals( cert.getEncoded(), certificate.getEncoded() ) )
176 {
177 return APACHEDS_ALIAS;
178 }
179
180
181
182
183
184
185
186
187 }
188 catch ( Exception e )
189 {
190 LOG.error( I18n.err( I18n.ERR_66 ), e );
191 }
192
193 return null;
194 }
195
196
197
198
199
200 @Override
201 public Certificate[] engineGetCertificateChain( String alias )
202 {
203 LOG.debug( "engineGetCertificateChain({}) called.", alias );
204 try
205 {
206 Entry entry = getTlsEntry();
207 LOG.debug( "Entry:\n{}", entry );
208 return new Certificate[]
209 {
210 keyStore.getCertificate( alias )
211 };
212
213 }
214 catch ( Exception e )
215 {
216 LOG.error( I18n.err( I18n.ERR_66 ), e );
217 }
218
219 return new Certificate[0];
220 }
221
222
223
224
225
226 @Override
227 public Date engineGetCreationDate( String alias )
228 {
229 LOG.debug( "engineGetCreationDate({}) called.", alias );
230 return new Date();
231 }
232
233
234
235
236
237 @Override
238 public Key engineGetKey( String alias, char[] password ) throws NoSuchAlgorithmException, UnrecoverableKeyException
239 {
240 LOG.debug( "engineGetKey({}, {}) called.", alias, password );
241
242 try
243 {
244 return keyStore.getKey( alias, password );
245
246
247
248
249
250 }
251 catch ( Exception e )
252 {
253 LOG.error( I18n.err( I18n.ERR_68 ), e );
254 }
255
256 return null;
257 }
258
259
260
261
262
263 @Override
264 public boolean engineIsCertificateEntry( String alias )
265 {
266 LOG.debug( "engineIsCertificateEntry({}) called.", alias );
267 return false;
268 }
269
270
271
272
273
274 @Override
275 public boolean engineIsKeyEntry( String alias )
276 {
277 LOG.debug( "engineIsKeyEntry({}) called.", alias );
278 return true;
279 }
280
281
282
283
284
285 @Override
286 public void engineLoad( InputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
287 CertificateException
288 {
289 LOG.debug( "engineLoad({}, {}) called.", stream, password );
290 }
291
292
293
294
295
296 @Override
297 public void engineSetCertificateEntry( String alias, Certificate cert ) throws KeyStoreException
298 {
299 LOG.debug( "engineSetCertificateEntry({}, {}) called.", alias, cert );
300 throw new NotImplementedException();
301 }
302
303
304
305
306
307 @Override
308 public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain ) throws KeyStoreException
309 {
310 LOG.debug( "engineSetKeyEntry({}, key, {}) called.", alias, chain );
311 throw new NotImplementedException();
312 }
313
314
315
316
317
318 @Override
319 public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain )
320 throws KeyStoreException
321 {
322 if ( LOG.isDebugEnabled() )
323 {
324 LOG.debug( "engineSetKeyEntry({}, key, {}, chain) called.", alias, new String( password ) );
325 }
326
327 throw new NotImplementedException();
328 }
329
330
331
332
333
334 @Override
335 public int engineSize()
336 {
337 if ( LOG.isDebugEnabled() )
338 {
339 LOG.debug( "engineSize() called." );
340 }
341
342 return 1;
343 }
344
345
346
347
348
349 @Override
350 public void engineStore( OutputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
351 CertificateException
352 {
353 if ( LOG.isDebugEnabled() )
354 {
355 LOG.debug( "engineStore(stream, {}) called.", new String( password ) );
356 }
357 }
358 }