001/*
002 * Copyright 2020-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2020-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2020-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.util;
037
038
039
040import java.io.Serializable;
041
042
043
044/**
045 * This class provides a set of properties that will be used when creating a
046 * {@link PassphraseEncryptedOutputStream}.  The default settings that will be
047 * used for properties that are not required in the constructor are:
048 * <UL>
049 *   <LI>
050 *     The header will be written to the beginning of the output stream.
051 *   </LI>
052 *   <LI>
053 *     The cipher type's key factory iteration count will be used.
054 *   </LI>
055 *   <LI>
056 *     No key identifier will be included in the encryption header.
057 *   </LI>
058 * </UL>
059 */
060@Mutable()
061@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
062public final class PassphraseEncryptedOutputStreamProperties
063       implements Serializable
064{
065  /**
066   * The serial version UID for this serializable class.
067   */
068  private static final long serialVersionUID = 2778471308512283705L;
069
070
071
072  // Indicates whether to write the encryption header to the beginning of the
073  // output stream.
074  private boolean writeHeaderToStream;
075
076  // The iteration count that will be used when generating the encryption key
077  // from the passphrase.
078  private int keyFactoryIterationCount;
079
080  // The cipher type value that will be used to obtain settings when encrypting
081  // data.
082  @NotNull private final PassphraseEncryptionCipherType cipherType;
083
084  // An optional identifier that may be used to associate the encryption details
085  // with information in another system.
086  @Nullable private String keyIdentifier;
087
088
089
090  /**
091   * Creates a new {@code PassphraseEncryptedOutputStreamProperties} instance
092   * with the provided cipher type value.
093   *
094   * @param  cipherType  The cipher type value that will be used to obtain
095   *                     settings when encrypting data.
096   */
097  public PassphraseEncryptedOutputStreamProperties(
098       @NotNull final PassphraseEncryptionCipherType cipherType)
099  {
100    this.cipherType = cipherType;
101
102    writeHeaderToStream = true;
103    keyFactoryIterationCount = cipherType.getKeyFactoryIterationCount();
104    keyIdentifier = null;
105  }
106
107
108
109  /**
110   * Retrieves the cipher type value that will be used to obtain settings when
111   * encrypting data.
112   *
113   * @return  The cipher type value that will be used to obtain settings when
114   *          encrypting data.
115   */
116  @NotNull()
117  public PassphraseEncryptionCipherType getCipherType()
118  {
119    return cipherType;
120  }
121
122
123
124  /**
125   * Indicates whether the {@link PassphraseEncryptedOutputStream} should write
126   * the generated {@link PassphraseEncryptedStreamHeader} to the wrapped output
127   * stream before starting the encrypted data so that a
128   * {@link PassphraseEncryptedInputStream} can read it to obtain the necessary
129   * information for decrypting the data.
130   *
131   * @return  {@code true} if the {@code PassphraseEncryptedOutputStream} should
132   *          write a {@code PassphraseEncryptedStreamHeader} to the wrapped
133   *          output stream before any encrypted data, or {@code false} if not.
134   */
135  public boolean writeHeaderToStream()
136  {
137    return writeHeaderToStream;
138  }
139
140
141
142  /**
143   * Specifies whether the {@link PassphraseEncryptedOutputStream} should write
144   * the generated {@link PassphraseEncryptedStreamHeader} to the wrapped output
145   * stream before starting the encrypted data so that a
146   * {@link PassphraseEncryptedInputStream} can read it to obtain the necessary
147   * information for decrypting the data.  If this is {@code false}, then the
148   * necessary metadata should be stored elsewhere so that it can be used to
149   * decrypt the data.
150   *
151   * @param  writeHeaderToStream  Indicates whether the
152   *                              {@code PassphraseEncryptedOutputStream} should
153   *                              write the generated
154   *                              {@code PassphraseEncryptedStreamHeader} to the
155   *                              wrapped output stream before starting the
156   *                              encrypted data.
157   */
158  public void setWriteHeaderToStream(final boolean writeHeaderToStream)
159  {
160    this.writeHeaderToStream = writeHeaderToStream;
161  }
162
163
164
165  /**
166   * Retrieves the iteration count that will be used when generating the
167   * encryption key from the passphrase.
168   *
169   * @return  The iteration count that will be used when generating the
170   *          encryption key from the passphrase.
171   */
172  public int getKeyFactoryIterationCount()
173  {
174    return keyFactoryIterationCount;
175  }
176
177
178
179  /**
180   * Specifies the iteration count that will be used when generating the
181   * encryption key from the passphrase.
182   *
183   * @param  keyFactoryIterationCount  The iteration count that will be used
184   *                                   when generating the encryption key from
185   *                                   the passphrase.  If this is {@code null},
186   *                                   then the cipher type's key factory
187   *                                   iteration count will be used.
188   */
189  public void setKeyFactoryIterationCount(
190                   @Nullable final Integer keyFactoryIterationCount)
191  {
192    if (keyFactoryIterationCount == null)
193    {
194      this.keyFactoryIterationCount = cipherType.getKeyFactoryIterationCount();
195    }
196    else
197    {
198      this.keyFactoryIterationCount = keyFactoryIterationCount;
199    }
200  }
201
202
203
204  /**
205   * Retrieves a key identifier that may be used to associate the encryption
206   * details with information in another system.  This is primarily intended for
207   * use in conjunction with the UnboundID/Ping Identity server products, but it
208   * may be useful in other systems as well.
209   *
210   * @return  A key identifier that may be used to associate the encryption
211   *          details with information in another system, or {@code null} if no
212   *          key identifier should be used.
213   */
214  @Nullable()
215  public String getKeyIdentifier()
216  {
217    return keyIdentifier;
218  }
219
220
221
222  /**
223   * Specifies a key identifier that may be used to associate the encryption
224   * details with information in another system.  This is primarily intended for
225   * use in conjunction with the UnboundID/Ping Identity server products, but it
226   * may be useful in other systems as well.
227   *
228   * @param  keyIdentifier  A key identifier that may be used to associate the
229   *                        encryption details with information in another
230   *                        system.  It may be {@code null} if no key identifier
231   *                        should be used.
232   */
233  public void setKeyIdentifier(@Nullable final String keyIdentifier)
234  {
235    this.keyIdentifier = keyIdentifier;
236  }
237
238
239
240  /**
241   * Retrieves a string representation of these properties.
242   *
243   * @return  A string representation of these properties.
244   */
245  @Override()
246  @NotNull()
247  public String toString()
248  {
249    final StringBuilder buffer = new StringBuilder();
250    toString(buffer);
251    return buffer.toString();
252  }
253
254
255
256  /**
257   * Appends a string representation of these properties to the provided buffer.
258   *
259   * @param  buffer  The buffer to which the properties should be appended.
260   */
261  public void toString(@NotNull final StringBuilder buffer)
262  {
263    buffer.append("PassphraseEncryptedOutputStreamProperties(cipherType=");
264    cipherType.toString(buffer);
265    buffer.append(", writeHeaderToStream=");
266    buffer.append(writeHeaderToStream);
267
268    if (keyFactoryIterationCount != cipherType.getKeyFactoryIterationCount())
269    {
270      buffer.append(", keyFactoryIterationCount=");
271      buffer.append(keyFactoryIterationCount);
272    }
273
274    if (keyIdentifier != null)
275    {
276      buffer.append(", keyIdentifier='");
277      buffer.append(keyIdentifier);
278      buffer.append('\'');
279    }
280
281
282    buffer.append(')');
283  }
284}