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-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.server.types;
018
019import org.forgerock.opendj.config.server.ConfigException;
020import org.opends.server.crypto.CryptoSuite;
021
022import javax.crypto.Mac;
023import javax.crypto.CipherOutputStream;
024import javax.crypto.CipherInputStream;
025import javax.net.ssl.SSLContext;
026import java.security.MessageDigest;
027import java.security.NoSuchAlgorithmException;
028import java.security.GeneralSecurityException;
029import java.io.InputStream;
030import java.io.IOException;
031import java.io.OutputStream;
032import java.util.zip.DataFormatException;
033import java.util.SortedSet;
034
035/**
036 This interface defines the methods to call to access cryptographic
037 services including encryption and hashing; in particular, when the
038 ciphertext or HMAC is produced on one directory server instance and
039 is to be consumed on another.
040 */
041@org.opends.server.types.PublicAPI(
042     stability=org.opends.server.types.StabilityLevel.VOLATILE,
043     mayInstantiate=false,
044     mayExtend=false,
045     mayInvoke=true)public interface CryptoManager {
046  /**
047   * Retrieves the name of the preferred message digest algorithm.
048   *
049   * @return  The name of the preferred message digest algorithm
050   */
051  String getPreferredMessageDigestAlgorithm();
052
053  /**
054   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
055   * generate digests using the preferred digest algorithm.
056   *
057   * @return  A <CODE>MessageDigest</CODE> object that may be used to
058   *          generate digests using the preferred digest algorithm.
059   *
060   * @throws java.security.NoSuchAlgorithmException  If the requested
061   * algorithm is not supported or is unavailable.
062   */
063  MessageDigest getPreferredMessageDigest()
064         throws NoSuchAlgorithmException;
065
066  /**
067   * Retrieves a <CODE>MessageDigest</CODE> object that may be used to
068   * generate digests using the specified algorithm.
069   *
070   * @param  digestAlgorithm  The algorithm to use to generate the
071   *                          message digest.
072   *
073   * @return  A <CODE>MessageDigest</CODE> object that may be used to
074   *          generate digests using the specified algorithm.
075   *
076   * @throws  java.security.NoSuchAlgorithmException  If the requested
077   * algorithm is not supported or is unavailable.
078   */
079  MessageDigest getMessageDigest(String digestAlgorithm)
080         throws NoSuchAlgorithmException;
081
082  /**
083   * Retrieves a byte array containing a message digest based on the
084   * provided data, using the preferred digest algorithm.
085   *
086   * @param  data  The data to be digested.
087   *
088   * @return  A byte array containing the generated message digest.
089   *
090   * @throws  java.security.NoSuchAlgorithmException  If the requested
091   * algorithm is not supported or is unavailable.
092   */
093  byte[] digest(byte[] data)
094         throws NoSuchAlgorithmException;
095
096  /**
097   * Retrieves a byte array containing a message digest based on the
098   * provided data, using the requested digest algorithm.
099   *
100   * @param  digestAlgorithm  The algorithm to use to generate the
101   *                          message digest.
102   * @param  data             The data to be digested.
103   *
104   * @return  A byte array containing the generated message digest.
105   *
106   * @throws  java.security.NoSuchAlgorithmException  If the requested
107   * algorithm is not supported or is unavailable.
108   */
109  byte[] digest(String digestAlgorithm, byte[] data)
110         throws NoSuchAlgorithmException;
111
112  /**
113   * Retrieves a byte array containing a message digest based on the
114   * data read from the provided input stream, using the preferred
115   * digest algorithm.  Data will be read until the end of the stream
116   * is reached.
117   *
118   * @param  inputStream  The input stream from which the data is to
119   *                      be read.
120   *
121   * @return  A byte array containing the generated message digest.
122   *
123   * @throws java.io.IOException  If a problem occurs while reading
124   * data from the provided stream.
125   *
126   * @throws  java.security.NoSuchAlgorithmException  If the requested
127   * algorithm is not supported or is unavailable.
128   */
129  byte[] digest(InputStream inputStream)
130         throws IOException, NoSuchAlgorithmException;
131
132  /**
133   * Retrieves a byte array containing a message digest based on the
134   * data read from the provided input stream, using the requested
135   * digest algorithm.  Data will be read until the end of the stream
136   * is reached.
137   *
138   * @param  digestAlgorithm  The algorithm to use to generate the
139   *                          message digest.
140   * @param  inputStream      The input stream from which the data is
141   *                          to be read.
142   *
143   * @return  A byte array containing the generated message digest.
144   *
145   * @throws  java.io.IOException  If a problem occurs while reading
146   * data from the provided stream.
147   *
148   * @throws  java.security.NoSuchAlgorithmException  If the requested
149   * algorithm is not supported or is unavailable.
150   */
151  byte[] digest(String digestAlgorithm,
152                       InputStream inputStream)
153         throws IOException, NoSuchAlgorithmException;
154
155  /**
156   * For the current preferred MAC algorithm and key length, return
157   * the identifier of the corresponding key entry. Note: the result
158   * (key identifier) might change across invocations, due to either
159   * of the perferred parameters changing, or because the original
160   * key was marked compromised and a replacement key generated.
161   *
162   * @return A String representation of the identifier of a key entry
163   * corresponding to the preferred MAC algorithm and key length.
164   *
165   * @throws CryptoManagerException In case one or more of the key
166   * parameters is invalid, or there is a problem instantiating the
167   * key entry in case it does not already exist.
168   */
169  String getMacEngineKeyEntryID()
170          throws CryptoManagerException;
171
172  /**
173   * For the specified MAC algorithm and key length, return
174   * the identifier of the corresponding key entry. Note: the result
175   * (key identifier) might change across invocations, due to either
176   * of the perferred parameters changing, or because the original
177   * key was marked compromised and a replacement key generated.
178   *
179   * @param  macAlgorithm  The algorithm to use for the MAC engine.
180   *
181   * @param  keyLengthBits  The key length in bits to use with the
182   *         specified algorithm.
183   *
184   * @return A String representation of the identifier of a key entry
185   * corresponding to the specified MAC algorithm and key length.
186   *
187   * @throws CryptoManagerException In case one or more of the key
188   * parameters is invalid, or there is a problem instantiating the
189   * key entry in case it does not already exist.
190   */
191  String getMacEngineKeyEntryID(String macAlgorithm,
192                                       int keyLengthBits)
193         throws CryptoManagerException;
194
195  /**
196   * For the specified key entry identifier, instantiate a MAC engine.
197   *
198   * @param keyEntryID The identifier of the key entry containing the
199   * desired MAC algorithm name and key length.
200   *
201   * @return The MAC engine instantiated with the parameters from the
202   * referenced key entry, or null if no such entry exists.
203   *
204   * @throws CryptoManagerException  In case the key entry identifier
205   * is invalid or there is a problem instantiating the MAC engine
206   * from the parameters in the referenced key entry.
207   */
208  Mac getMacEngine(String keyEntryID)
209          throws CryptoManagerException;
210
211  /**
212   * Encrypts the data in the provided byte array using the preferred
213   * cipher transformation.
214   *
215   * @param  data  The plain-text data to be encrypted.
216   *
217   * @return  A byte array containing the encrypted representation of
218   *          the provided data.
219   *
220   * @throws java.security.GeneralSecurityException  If a problem
221   * occurs while encrypting the data.
222   *
223   * @throws  CryptoManagerException  If a problem occurs managing the
224   *          encryption key or producing the cipher.
225   */
226  byte[] encrypt(byte[] data)
227         throws GeneralSecurityException, CryptoManagerException;
228
229  /**
230   * Encrypts the data in the provided byte array using the requested
231   * cipher algorithm.
232   *
233   * @param  cipherTransformation  The algorithm/mode/padding to use
234   *         for the cipher.
235   *
236   * @param  keyLengthBits  The length in bits of the encryption key
237   *         this method is to use. Note the specified key length and
238   *         transformation must be compatible.
239   *
240   * @param  data  The plain-text data to be encrypted.
241   *
242   * @return  A byte array containing the encrypted representation of
243   *          the provided data.
244   *
245   * @throws  java.security.GeneralSecurityException  If a problem
246   * occurs while encrypting the data.
247   *
248   * @throws  CryptoManagerException  If a problem occurs managing the
249   *          encryption key or producing the cipher.
250   */
251  byte[] encrypt(String cipherTransformation,
252                        int keyLengthBits,
253                        byte[] data)
254         throws GeneralSecurityException, CryptoManagerException;
255
256  /**
257   * Writes encrypted data to the provided output stream using the
258   * preferred cipher transformation.
259   *
260   * @param  outputStream The output stream to be wrapped by the
261   *         returned cipher output stream.
262   *
263   * @return  The output stream wrapped with a CipherOutputStream.
264   *
265   * @throws  CryptoManagerException  If a problem occurs managing the
266   *          encryption key or producing the cipher.
267   */
268  CipherOutputStream getCipherOutputStream(
269          OutputStream outputStream) throws CryptoManagerException;
270
271  /**
272   * Writes encrypted data to the provided output stream using the
273   * requested cipher transformation.
274   *
275   * @param  cipherTransformation  The algorithm/mode/padding to use
276   *         for the cipher.
277   *
278   * @param  keyLengthBits  The length in bits of the encryption key
279   *         this method will generate. Note the specified key length
280   *         must be compatible with the transformation.
281   *
282   * @param  outputStream The output stream to be wrapped by the
283   *         returned cipher output stream.
284   *
285   * @return  The output stream wrapped with a CipherOutputStream.
286   *
287   * @throws  CryptoManagerException  If a problem occurs managing the
288   *          encryption key or producing the cipher.
289   */
290  CipherOutputStream getCipherOutputStream(
291          String cipherTransformation, int keyLengthBits,
292          OutputStream outputStream)
293         throws CryptoManagerException;
294
295  /**
296   * Decrypts the data in the provided byte array using cipher
297   * specified by the key identifier prologue to the data.
298   * cipher.
299   *
300   * @param  data  The cipher-text data to be decrypted.
301   *
302   * @return  A byte array containing the clear-text representation of
303   *          the provided data.
304   *
305   * @throws  java.security.GeneralSecurityException  If a problem
306   * occurs while encrypting the data.
307   *
308   * @throws  CryptoManagerException  If a problem occurs reading the
309   *          key identifier or initialization vector from the data
310   *          prologue, or using these values to initialize a Cipher.
311   */
312  byte[] decrypt(byte[] data)
313         throws GeneralSecurityException,
314                CryptoManagerException;
315
316  /**
317   * Returns a CipherInputStream instantiated with a cipher
318   * corresponding to the key identifier prologue to the data.
319   *
320   * @param  inputStream The input stream be wrapped with the
321   *         CipherInputStream.
322   *
323   * @return The CiperInputStream instantiated as specified.
324   *
325   * @throws  CryptoManagerException If there is a problem reading the
326   *          key ID or initialization vector from the input stream,
327   *          or using these values to inititalize a Cipher.
328   */
329  CipherInputStream getCipherInputStream(
330          InputStream inputStream) throws CryptoManagerException;
331
332  /**
333   * Attempts to compress the data in the provided source array into
334   * the given destination array.  If the compressed data will fit
335   * into the destination array, then this method will return the
336   * number of bytes of compressed data in the array.  Otherwise, it
337   * will return -1 to indicate that the compression was not
338   * successful.  Note that if -1 is returned, then the data in the
339   * destination array should be considered invalid.
340   *
341   * @param  src  The array containing the raw data to compress.
342   * @param  srcOff The start offset of the source data.
343   * @param  srcLen The maximum number of source data bytes to
344   *                compress.
345   * @param  dst  The array into which the compressed data should be
346   *              written.
347   * @param  dstOff The start offset of the compressed data.
348   * @param  dstLen The maximum number of bytes of compressed data.
349   *
350   * @return  The number of bytes of compressed data, or -1 if it was
351   *          not possible to actually compress the data.
352   */
353  int compress(byte[] src, int srcOff, int srcLen,
354               byte[] dst, int dstOff, int dstLen);
355
356  /**
357   * Attempts to uncompress the data in the provided source array into
358   * the given destination array.  If the uncompressed data will fit
359   * into the given destination array, then this method will return
360   * the number of bytes of uncompressed data written into the
361   * destination buffer.  Otherwise, it will return a negative value
362   * to indicate that the destination buffer was not large enough.
363   * The absolute value of that negative return value will indicate
364   * the buffer size required to fully decompress the data.  Note that
365   * if a negative value is returned, then the data in the destination
366   * array should be considered invalid.
367   *
368   * @param  src  The array containing the raw data to compress.
369   * @param  srcOff The start offset of the source data.
370   * @param  srcLen The maximum number of source data bytes to
371   *                compress.
372   * @param  dst  The array into which the compressed data should be
373   *              written.
374   * @param  dstOff The start offset of the compressed data.
375   * @param  dstLen The maximum number of bytes of compressed data.
376   *
377   * @return  A positive value containing the number of bytes of
378   *          uncompressed data written into the destination buffer,
379   *          or a negative value whose absolute value is the size of
380   *          the destination buffer required to fully decompress the
381   *          provided data.
382   *
383   * @throws java.util.zip.DataFormatException  If a problem occurs
384   * while attempting to uncompress the data.
385   */
386  int uncompress(byte[] src, int srcOff, int srcLen,
387                 byte[] dst, int dstOff, int dstLen)
388         throws DataFormatException;
389
390  /**
391   * Create an SSL context that may be used for communication to
392   * another ADS component.
393   *
394   * @param componentName    Name of the component to which is associated this SSL Context.
395   * @param sslCertNicknames The names of the local certificates to use,
396   *                         or null if none is specified.
397   * @return A new SSL Context.
398   * @throws ConfigException If the context
399   * could not be created.
400   */
401  SSLContext getSslContext(String componentName, SortedSet<String> sslCertNicknames) throws ConfigException;
402
403  /**
404   * Get the names of the local certificates to use for SSL.
405   * @return The names of the local certificates to use for SSL.
406   */
407  SortedSet<String> getSslCertNicknames();
408
409  /**
410   * Determine whether SSL encryption is enabled.
411   * @return true if SSL encryption is enabled.
412   */
413  boolean isSslEncryption();
414
415  /**
416   * Get the set of enabled SSL protocols.
417   * @return The set of enabled SSL protocols.
418   */
419  SortedSet<String> getSslProtocols();
420
421  /**
422   * Get the set of enabled SSL cipher suites.
423   * @return The set of enabled SSL cipher suites.
424   */
425  SortedSet<String> getSslCipherSuites();
426
427  /**
428   * Return a new {@link CryptoSuite} for the cipher and key.
429   *
430   * @return a new {@link CryptoSuite} for the cipher and key
431   * @param cipherTransformation cipher transformation string specification
432   * @param cipherKeyLength length of key in bits
433   * @param encrypt true if the user of the crypto suite needs encryption
434   */
435  CryptoSuite newCryptoSuite(String cipherTransformation, int cipherKeyLength, boolean encrypt);
436
437  /**
438   * Ensures that a key exists for the provided cipher transformation and key length.
439   * If none exists, a new one will be created.
440   *<p>
441   * Newly created keys will be published and propagated to the replication topology.
442   *
443   * @param cipherTransformation cipher transformation string specification
444   * @param cipherKeyLength length of key in bits
445   * @throws CryptoManagerException  If a problem occurs managing the encryption key
446   */
447  void ensureCipherKeyIsAvailable(String cipherTransformation, int cipherKeyLength) throws CryptoManagerException;
448
449}