2
2
3
3
import com .acuity .iot .dsa .dslink .sys .cert .HostnameWhitelist .WhitelistValue ;
4
4
import java .io .File ;
5
+ import java .io .FileOutputStream ;
5
6
import java .io .IOException ;
7
+ import java .io .InputStream ;
6
8
import java .security .cert .CertificateEncodingException ;
7
9
import java .security .cert .X509Certificate ;
8
10
import javax .net .ssl .HostnameVerifier ;
@@ -50,6 +52,7 @@ public class SysCertService extends DSNode {
50
52
private static final String GENERATE_SELF_SIGNED = "Generate Self-Signed Certificate" ;
51
53
private static final String DELETE_KS_ENTRY = "Delete Keystore Entry" ;
52
54
private static final String GET_KS_ENTRY = "Get Keystore Entry" ;
55
+ private static final String DEFAULT_CERTFILE = "dslink.jks" ;
53
56
54
57
// Fields
55
58
// ------
@@ -60,6 +63,12 @@ public class SysCertService extends DSNode {
60
63
private DSInfo keystorePath = getInfo (CERTFILE );
61
64
private DSInfo keystorePass = getInfo (CERTFILE_PASS );
62
65
private DSInfo keystoreType = getInfo (CERTFILE_TYPE );
66
+ private DSInfo generateCsr = getInfo (GENERATE_CSR );
67
+ private DSInfo importCaCert = getInfo (IMPORT_CA_CERT );
68
+ private DSInfo importPrimaryCert = getInfo (IMPORT_PRIMARY_CERT );
69
+ private DSInfo generateSSCert = getInfo (GENERATE_SELF_SIGNED );
70
+ private DSInfo getKSEntry = getInfo (GET_KS_ENTRY );
71
+ private DSInfo deleteKSEntry = getInfo (DELETE_KS_ENTRY );
63
72
private CertCollection localTruststore ;
64
73
private CertCollection quarantine ;
65
74
private HostnameWhitelist whitelist ;
@@ -128,7 +137,7 @@ public void declareDefaults() {
128
137
declareDefault (ALLOW_SERVERS , DSBool .TRUE );
129
138
declareDefault (VERIFY_HOSTNAMES , DSBool .TRUE );
130
139
declareDefault (HOSTNAME_WHITELIST , new HostnameWhitelist ());
131
- declareDefault (CERTFILE , DSString .valueOf ("dslink.jks" ));
140
+ declareDefault (CERTFILE , DSString .valueOf (DEFAULT_CERTFILE ));
132
141
declareDefault (CERTFILE_TYPE , DSString .valueOf ("JKS" ));
133
142
declareDefault (CERTFILE_PASS , DSPasswordAes128 .valueOf ("dsarocks" ));
134
143
declareDefault (LOCAL_TRUSTSTORE , new CertCollection ());
@@ -153,17 +162,23 @@ public void prepareParameter(DSInfo info, DSMap parameter) {
153
162
154
163
@ Override
155
164
public ActionResult invoke (DSInfo info , ActionInvocation invocation ) {
156
- String csr = ((SysCertService ) info .getParent ()).generateCSR ();
157
- return csr != null ? new DSActionValues (info .getAction ())
158
- .addResult (DSString .valueOf (csr )) : null ;
165
+ String [] results = ((SysCertService ) info .getParent ()).generateCSR ();
166
+ if (results != null && results .length > 1 ) {
167
+ return new DSActionValues (info .getAction ())
168
+ .addResult (DSString .valueOf (results [0 ]))
169
+ .addResult (DSString .valueOf (results [1 ]));
170
+ } else {
171
+ return null ;
172
+ }
159
173
}
160
174
};
161
175
act .setResultType (ResultType .VALUES );
176
+ act .addValueResult ("Result" , DSValueType .STRING );
162
177
act .addValueResult ("CSR" , DSValueType .STRING ).setEditor ("textarea" );
163
178
return act ;
164
179
}
165
180
166
- private String generateCSR () {
181
+ private String [] generateCSR () {
167
182
try {
168
183
return KeyToolUtil .generateCSR (getKeystorePath (), getCertFilePass ());
169
184
} catch (IOException e ) {
@@ -182,22 +197,25 @@ public void prepareParameter(DSInfo info, DSMap parameter) {
182
197
@ Override
183
198
public ActionResult invoke (DSInfo info , ActionInvocation invocation ) {
184
199
DSMap parameters = invocation .getParameters ();
185
- ((SysCertService ) info .getParent ()).importCACert (parameters );
186
- return null ;
200
+ String result = ((SysCertService ) info .getParent ()).importCACert (parameters );
201
+ return new DSActionValues ( info . getAction ()). addResult ( DSString . valueOf ( result )) ;
187
202
}
188
203
};
189
204
act .addParameter ("Alias" , DSValueType .STRING , null );
190
205
act .addParameter ("Certificate" , DSValueType .STRING , null ).setEditor ("textarea" );
206
+ act .setResultType (ResultType .VALUES );
207
+ act .addValueResult ("Result" , DSValueType .STRING );
191
208
return act ;
192
209
}
193
210
194
- private void importCACert (DSMap parameters ) {
211
+ private String importCACert (DSMap parameters ) {
195
212
String alias = parameters .getString ("Alias" );
196
213
String certStr = parameters .getString ("Certificate" );
197
214
try {
198
- KeyToolUtil .importCACert (getKeystorePath (), certStr , alias , getCertFilePass ());
215
+ return KeyToolUtil .importCACert (getKeystorePath (), certStr , alias , getCertFilePass ());
199
216
} catch (IOException e ) {
200
217
DSException .throwRuntime (e );
218
+ return null ;
201
219
}
202
220
}
203
221
@@ -211,20 +229,23 @@ public void prepareParameter(DSInfo info, DSMap parameter) {
211
229
@ Override
212
230
public ActionResult invoke (DSInfo info , ActionInvocation invocation ) {
213
231
DSMap parameters = invocation .getParameters ();
214
- ((SysCertService ) info .getParent ()).importPrimaryCert (parameters );
215
- return null ;
232
+ String result = ((SysCertService ) info .getParent ()).importPrimaryCert (parameters );
233
+ return new DSActionValues ( info . getAction ()). addResult ( DSString . valueOf ( result )) ;
216
234
}
217
235
};
218
236
act .addParameter ("Certificate" , DSValueType .STRING , null ).setEditor ("textarea" );
237
+ act .setResultType (ResultType .VALUES );
238
+ act .addValueResult ("Result" , DSValueType .STRING );
219
239
return act ;
220
240
}
221
241
222
- private void importPrimaryCert (DSMap parameters ) {
242
+ private String importPrimaryCert (DSMap parameters ) {
223
243
String certStr = parameters .getString ("Certificate" );
224
244
try {
225
- KeyToolUtil .importPrimaryCert (getKeystorePath (), certStr , getCertFilePass ());
245
+ return KeyToolUtil .importPrimaryCert (getKeystorePath (), certStr , getCertFilePass ());
226
246
} catch (IOException e ) {
227
247
DSException .throwRuntime (e );
248
+ return null ;
228
249
}
229
250
}
230
251
@@ -237,10 +258,12 @@ public void prepareParameter(DSInfo info, DSMap parameter) {
237
258
238
259
@ Override
239
260
public ActionResult invoke (DSInfo info , ActionInvocation invocation ) {
240
- ((SysCertService ) info .getParent ()).keytoolGenkey ();
241
- return null ;
261
+ String result = ((SysCertService ) info .getParent ()).keytoolGenkey ();
262
+ return new DSActionValues ( info . getAction ()). addResult ( DSString . valueOf ( result )) ;
242
263
}
243
264
};
265
+ act .setResultType (ResultType .VALUES );
266
+ act .addValueResult ("Result" , DSValueType .STRING );
244
267
return act ;
245
268
}
246
269
@@ -275,15 +298,17 @@ public void prepareParameter(DSInfo info, DSMap parameter) {
275
298
276
299
@ Override
277
300
public ActionResult invoke (DSInfo info , ActionInvocation invocation ) {
278
- ((SysCertService ) info .getParent ()).deleteKSEntry ();
279
- return null ;
301
+ String result = ((SysCertService ) info .getParent ()).deleteKSEntry ();
302
+ return new DSActionValues ( info . getAction ()). addResult ( DSString . valueOf ( result )) ;
280
303
}
281
304
};
305
+ act .setResultType (ResultType .VALUES );
306
+ act .addValueResult ("Result" , DSValueType .STRING );
282
307
return act ;
283
308
}
284
309
285
- private void deleteKSEntry () {
286
- KeyToolUtil .deleteEntry (getKeystorePath (), getCertFilePass ());
310
+ private String deleteKSEntry () {
311
+ return KeyToolUtil .deleteEntry (getKeystorePath (), getCertFilePass ());
287
312
}
288
313
289
314
private String getCertFilePass () {
@@ -298,19 +323,66 @@ private String getKeystorePath() {
298
323
/**
299
324
* Executes the java keytool to generate a new self signed cert.
300
325
*/
301
- private void keytoolGenkey () {
302
- KeyToolUtil .generateSelfSigned (getKeystorePath (), getCertFilePass ());
326
+ private String keytoolGenkey () {
327
+ return KeyToolUtil .generateSelfSigned (getKeystorePath (), getCertFilePass ());
328
+ }
329
+
330
+ private boolean isKeytoolAvailable () {
331
+ String result = KeyToolUtil .help ();
332
+ return result != null && !result .isEmpty ();
303
333
}
304
334
305
335
@ Override
306
336
public void onStarted () {
307
337
inst = this ;
308
338
AnonymousTrustFactory .init (this );
309
- String keystore = this . keystorePath . getElement (). toString ();
339
+ String keystore = getKeystorePath ();
310
340
File f = new File (keystore );
311
- if (!f .exists ()) {
312
- keytoolGenkey ();
341
+ if (isKeytoolAvailable ()) {
342
+ if (!f .exists ()) {
343
+ keytoolGenkey ();
344
+ }
345
+ } else {
346
+ info ("Keytool not available. Disabling keytool functionality and attempting to use existing keystore" );
347
+ if (!f .exists ()) {
348
+ InputStream inpStream = null ;
349
+ FileOutputStream outStream = null ;
350
+ try {
351
+ inpStream = SysCertService .class .getResourceAsStream (DEFAULT_CERTFILE );
352
+ if (inpStream != null ) {
353
+ int readBytes ;
354
+ byte [] buffer = new byte [4096 ];
355
+ outStream = new FileOutputStream (f );
356
+ while ((readBytes = inpStream .read (buffer )) > 0 ) {
357
+ outStream .write (buffer , 0 , readBytes );
358
+ }
359
+ }
360
+ } catch (Exception e ) {
361
+ debug ("" , e );
362
+ } finally {
363
+ try {
364
+ if (inpStream != null ) {
365
+ inpStream .close ();
366
+ }
367
+ if (outStream != null ) {
368
+ outStream .close ();
369
+ }
370
+ } catch (Exception e ) {
371
+ debug ("" , e );
372
+ }
373
+ }
374
+ if (!f .exists ()) {
375
+ error ("Existing keystore not found and new one could not be generated" );
376
+ }
377
+ }
378
+ generateCsr .setHidden (true );
379
+ importCaCert .setHidden (true );
380
+ importPrimaryCert .setHidden (true );
381
+ generateSSCert .setHidden (true );
382
+ getKSEntry .setHidden (true );
383
+ deleteKSEntry .setHidden (true );
313
384
}
385
+
314
386
try {
315
387
System .setProperty ("javax.net.ssl.keyStore" , keystore );
316
388
System .setProperty ("javax.net.ssl.keyStoreType" ,
@@ -321,6 +393,18 @@ public void onStarted() {
321
393
}
322
394
HttpsURLConnection .setDefaultHostnameVerifier (hostnameVerifier );
323
395
}
396
+
397
+ @ Override
398
+ protected void onChildChanged (DSInfo info ) {
399
+ if (info == keystorePath ) {
400
+ System .setProperty ("javax.net.ssl.keyStore" , getKeystorePath ());
401
+ } else if (info == keystoreType ) {
402
+ System .setProperty ("javax.net.ssl.keyStoreType" ,
403
+ keystoreType .getElement ().toString ());
404
+ } else if (info == keystorePass ) {
405
+ System .setProperty ("javax.net.ssl.keyStorePassword" , getCertFilePass ());
406
+ }
407
+ }
324
408
325
409
public boolean isInTrustStore (X509Certificate cert ) {
326
410
return getLocalTruststore ().containsCertificate (cert );
0 commit comments