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