001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2015 ForgeRock AS
026 */
027package org.opends.quicksetup;
028
029import java.util.Arrays;
030import java.util.Collection;
031import java.util.Set;
032import java.util.TreeSet;
033
034/**
035 * Class used to describe the Security Options specified by the user.
036 *
037 */
038public class SecurityOptions
039{
040  private boolean enableSSL;
041  private boolean enableStartTLS;
042
043  private int sslPort = 636;
044
045  /** Alias of a self-signed certificate. */
046  public static final String SELF_SIGNED_CERT_ALIAS = "server-cert";
047  /** Alias of a self-signed certificate using elliptic curve. */
048  public static final String SELF_SIGNED_EC_CERT_ALIAS = SELF_SIGNED_CERT_ALIAS + "-ec";
049
050  /**
051   * The different type of security options that we can have.
052   */
053  public enum CertificateType
054  {
055    /**
056     * No certificate to be used (and so no SSL and no Start TLS).
057     */
058    NO_CERTIFICATE,
059    /**
060     * Use a newly created Self Signed Certificate.
061     */
062    SELF_SIGNED_CERTIFICATE,
063    /**
064     * Use an existing JKS key store.
065     */
066    JKS,
067    /**
068     * Use an existing JCEKS key store.
069     */
070    JCEKS,
071    /**
072     * Use an existing PKCS#11 key store.
073     */
074    PKCS11,
075    /**
076     * Use an existing PKCS#12 key store.
077     */
078    PKCS12
079  }
080
081  private CertificateType certificateType;
082  private String keyStorePath;
083  private String keyStorePassword;
084  private Set<String> aliasesToUse = new TreeSet<>();
085
086  private SecurityOptions()
087  {
088  }
089
090  /**
091   * Creates a new instance of a SecurityOptions representing for no certificate
092   * (no SSL or Start TLS).
093   *
094   * @return a new instance of a SecurityOptions representing for no certificate
095   *         (no SSL or Start TLS).
096   */
097  public static SecurityOptions createNoCertificateOptions()
098  {
099    SecurityOptions ops = new SecurityOptions();
100    ops.setCertificateType(CertificateType.NO_CERTIFICATE);
101    ops.setEnableSSL(false);
102    ops.setEnableStartTLS(false);
103    return ops;
104  }
105
106  /**
107   * Creates a new instance of a SecurityOptions using a self-signed
108   * certificate.
109   *
110   * @param enableSSL
111   *          whether SSL is enabled or not.
112   * @param enableStartTLS
113   *          whether Start TLS is enabled or not.
114   * @param sslPort
115   *          the value of the LDAPS port.
116   * @return a new instance of a SecurityOptions using a self-signed
117   *         certificate.
118   */
119  public static SecurityOptions createSelfSignedCertificateOptions(
120          boolean enableSSL, boolean enableStartTLS, int sslPort)
121  {
122    return createSelfSignedCertificateOptions(enableSSL, enableStartTLS, sslPort,
123        Arrays.asList(SELF_SIGNED_CERT_ALIAS));
124  }
125
126  /**
127   * Creates a new instance of a SecurityOptions using a self-signed
128   * certificate.
129   *
130   * @param enableSSL
131   *          whether SSL is enabled or not.
132   * @param enableStartTLS
133   *          whether Start TLS is enabled or not.
134   * @param sslPort
135   *          the value of the LDAPS port.
136   * @param aliasesToUse
137   *          the aliases of the certificates in the key store to be used.
138   * @return a new instance of a SecurityOptions using a self-signed
139   *         certificate.
140   */
141  public static SecurityOptions createSelfSignedCertificateOptions(boolean enableSSL, boolean enableStartTLS,
142      int sslPort, Collection<String> aliasesToUse)
143  {
144      return createOptionsForCertificatType(
145              CertificateType.SELF_SIGNED_CERTIFICATE, null, null, enableSSL, enableStartTLS, sslPort, aliasesToUse);
146  }
147
148  /**
149   * Creates a new instance of a SecurityOptions using a Java Key Store.
150   *
151   * @param keystorePath
152   *          the path of the key store.
153   * @param keystorePwd
154   *          the password of the key store.
155   * @param enableSSL
156   *          whether SSL is enabled or not.
157   * @param enableStartTLS
158   *          whether Start TLS is enabled or not.
159   * @param sslPort
160   *          the value of the LDAPS port.
161   * @param aliasesToUse
162   *          the aliases of the certificates in the key store to be used.
163   * @return a new instance of a SecurityOptions using a Java Key Store.
164   */
165  public static SecurityOptions createJKSCertificateOptions(String keystorePath, String keystorePwd, boolean enableSSL,
166      boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
167  {
168    return createOptionsForCertificatType(
169            CertificateType.JKS, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasesToUse);
170  }
171
172  /**
173   * Creates a new instance of a SecurityOptions using a JCE Key Store.
174   *
175   * @param keystorePath
176   *          the path of the key store.
177   * @param keystorePwd
178   *          the password of the key store.
179   * @param enableSSL
180   *          whether SSL is enabled or not.
181   * @param enableStartTLS
182   *          whether Start TLS is enabled or not.
183   * @param sslPort
184   *          the value of the LDAPS port.
185   * @param aliasesToUse
186   *          the aliases of the certificates in the keystore to be used.
187   * @return a new instance of a SecurityOptions using a JCE Key Store.
188   */
189  public static SecurityOptions createJCEKSCertificateOptions(String keystorePath, String keystorePwd,
190      boolean enableSSL, boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
191  {
192    return createOptionsForCertificatType(
193            CertificateType.JCEKS, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasesToUse);
194  }
195
196
197  /**
198   * Creates a new instance of a SecurityOptions using a PKCS#11 Key Store.
199   *
200   * @param keystorePwd
201   *          the password of the key store.
202   * @param enableSSL
203   *          whether SSL is enabled or not.
204   * @param enableStartTLS
205   *          whether Start TLS is enabled or not.
206   * @param sslPort
207   *          the value of the LDAPS port.
208   * @param aliasesToUse
209   *          the aliases of the certificates in the keystore to be used.
210   * @return a new instance of a SecurityOptions using a PKCS#11 Key Store.
211   */
212  public static SecurityOptions createPKCS11CertificateOptions(String keystorePwd, boolean enableSSL,
213      boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
214  {
215    return createOptionsForCertificatType(
216            CertificateType.PKCS11, null, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasesToUse);
217  }
218
219  /**
220   * Creates a new instance of a SecurityOptions using a PKCS#12 Key Store.
221   *
222   * @param keystorePath
223   *          the path of the key store.
224   * @param keystorePwd
225   *          the password of the key store.
226   * @param enableSSL
227   *          whether SSL is enabled or not.
228   * @param enableStartTLS
229   *          whether Start TLS is enabled or not.
230   * @param sslPort
231   *          the value of the LDAPS port.
232   * @param aliasesToUse
233   *          the aliases of the certificates in the keystore to be used.
234   * @return a new instance of a SecurityOptions using a PKCS#12 Key Store.
235   */
236  public static SecurityOptions createPKCS12CertificateOptions( String keystorePath, String keystorePwd,
237          boolean enableSSL, boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
238  {
239    return createOptionsForCertificatType(
240            CertificateType.PKCS12, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasesToUse);
241  }
242
243  /**
244   * Creates a new instance of a SecurityOptions using the provided type Key
245   * Store.
246   *
247   * @param certType
248   *          The Key Store type.
249   * @param keystorePath
250   *          The path of the key store (may be @null).
251   * @param keystorePwd
252   *          The password of the key store.
253   * @param enableSSL
254   *          Whether SSL is enabled or not.
255   * @param enableStartTLS
256   *          Whether Start TLS is enabled or not.
257   * @param sslPort
258   *          The value of the LDAPS port.
259   * @param aliasesToUse
260   *          The aliases of the certificates in the keystore to be used.
261   * @return a new instance of a SecurityOptions.
262   */
263  public static SecurityOptions createOptionsForCertificatType(CertificateType certType, String keystorePath,
264      String keystorePwd, boolean enableSSL, boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
265  {
266      if (certType == CertificateType.NO_CERTIFICATE)
267      {
268        return createNoCertificateOptions();
269      }
270      else if ( certType.equals(CertificateType.SELF_SIGNED_CERTIFICATE) && aliasesToUse.isEmpty() )
271      {
272        aliasesToUse = Arrays.asList(SELF_SIGNED_CERT_ALIAS);
273      }
274
275      SecurityOptions ops = new SecurityOptions();
276      if (keystorePath != null)
277      {
278        ops.setKeyStorePath(keystorePath);
279      }
280      if (keystorePwd != null)
281      {
282        ops.setKeyStorePassword(keystorePwd);
283      }
284      ops.setCertificateType(certType);
285      updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort, aliasesToUse);
286      return ops;
287  }
288
289  /**
290   * Returns the CertificateType for this instance.
291   * @return the CertificateType for this instance.
292   */
293  public CertificateType getCertificateType()
294  {
295    return certificateType;
296  }
297
298  /**
299   * Sets the CertificateType for this instance.
300   * @param certificateType the CertificateType for this instance.
301   */
302  private void setCertificateType(CertificateType certificateType)
303  {
304    this.certificateType = certificateType;
305  }
306
307  /**
308   * Returns whether SSL is enabled or not.
309   * @return <CODE>true</CODE> if SSL is enabled and <CODE>false</CODE>
310   * otherwise.
311   */
312  public boolean getEnableSSL()
313  {
314    return enableSSL;
315  }
316
317  /**
318   * Sets whether SSL is enabled or not.
319   * @param enableSSL whether SSL is enabled or not.
320   */
321  private void setEnableSSL(boolean enableSSL)
322  {
323    this.enableSSL = enableSSL;
324  }
325
326  /**
327   * Returns whether StartTLS is enabled or not.
328   * @return <CODE>true</CODE> if StartTLS is enabled and <CODE>false</CODE>
329   * otherwise.
330   */
331  public boolean getEnableStartTLS()
332  {
333    return enableStartTLS;
334  }
335
336  /**
337   * Sets whether StartTLS is enabled or not.
338   * @param enableStartTLS whether StartTLS is enabled or not.
339   */
340  private void setEnableStartTLS(boolean enableStartTLS)
341  {
342    this.enableStartTLS = enableStartTLS;
343  }
344
345  /**
346   * Returns the key store password.
347   * @return the key store password.
348   */
349  public String getKeystorePassword()
350  {
351    return keyStorePassword;
352  }
353
354  /**
355   * Sets the key store password.
356   * @param keyStorePassword the new key store password.
357   */
358  private void setKeyStorePassword(String keyStorePassword)
359  {
360    this.keyStorePassword = keyStorePassword;
361  }
362
363  /**
364   * Returns the key store path.
365   * @return the key store path.
366   */
367  public String getKeystorePath()
368  {
369    return keyStorePath;
370  }
371
372  /**
373   * Sets the key store path.
374   * @param keyStorePath the new key store path.
375   */
376  private void setKeyStorePath(String keyStorePath)
377  {
378    this.keyStorePath = keyStorePath;
379  }
380
381  /**
382   * Updates the provided certificate options object with some parameters.
383   * @param ops the SecurityOptions object to be updated.
384   * @param enableSSL whether to enable SSL or not.
385   * @param enableStartTLS whether to enable StartTLS or not.
386   * @param sslPort the LDAPS port number.
387   * @param aliasToUse the name of the alias to be used.
388   */
389  private static void updateCertificateOptions(SecurityOptions ops,
390      boolean enableSSL, boolean enableStartTLS, int sslPort, Collection<String> aliasesToUse)
391  {
392    if (!enableSSL && !enableStartTLS)
393    {
394      throw new IllegalArgumentException(
395          "You must enable SSL or StartTLS to use a certificate.");
396    }
397    ops.setEnableSSL(enableSSL);
398    ops.setEnableStartTLS(enableStartTLS);
399    ops.setSslPort(sslPort);
400    ops.setAliasToUse(aliasesToUse);
401  }
402
403  /**
404   * Returns the SSL port.
405   * @return the SSL port.
406   */
407  public int getSslPort()
408  {
409    return sslPort;
410  }
411
412  /**
413   * Sets the SSL port.
414   * @param sslPort the new SSL port.
415   */
416  void setSslPort(int sslPort)
417  {
418    this.sslPort = sslPort;
419  }
420
421  /**
422   * Returns the alias of the certificate in the key store to be used.
423   * @return the alias of the certificate in the key store to be used.
424   */
425  public Set<String> getAliasesToUse()
426  {
427    return aliasesToUse;
428  }
429
430  /**
431   * Sets the certificates aliases name.
432   * @param aliasesToUse the certificates aliases name.
433   */
434  void setAliasToUse(Collection<String> aliasesToUse)
435  {
436    this.aliasesToUse.clear();
437    this.aliasesToUse.addAll(aliasesToUse);
438  }
439
440}