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