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