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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.types;
028    
029    import org.opends.server.config.ConfigException;
030    
031    import javax.crypto.Mac;
032    import javax.crypto.CipherOutputStream;
033    import javax.crypto.CipherInputStream;
034    import javax.net.ssl.SSLContext;
035    import java.security.MessageDigest;
036    import java.security.NoSuchAlgorithmException;
037    import java.security.GeneralSecurityException;
038    import java.io.InputStream;
039    import java.io.IOException;
040    import java.io.OutputStream;
041    import java.util.zip.DataFormatException;
042    import 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  dst  The array into which the compressed data should be
352       *              written.
353       *
354       * @return  The number of bytes of compressed data, or -1 if it was
355       *          not possible to actually compress the data.
356       */
357      int compress(byte[] src, byte[] dst);
358    
359      /**
360       * Attempts to uncompress the data in the provided source array into
361       * the given destination array.  If the uncompressed data will fit
362       * into the given destination array, then this method will return
363       * the number of bytes of uncompressed data written into the
364       * destination buffer.  Otherwise, it will return a negative value
365       * to indicate that the destination buffer was not large enough.
366       * The absolute value of that negative return value will indicate
367       * the buffer size required to fully decompress the data.  Note that
368       * if a negative value is returned, then the data in the destination
369       * array should be considered invalid.
370       *
371       * @param  src  The array containing the compressed data.
372       * @param  dst  The array into which the uncompressed data should be
373       *              written.
374       *
375       * @return  A positive value containing the number of bytes of
376       *          uncompressed data written into the destination buffer,
377       *          or a negative value whose absolute value is the size of
378       *          the destination buffer required to fully decompress the
379       *          provided data.
380       *
381       * @throws java.util.zip.DataFormatException  If a problem occurs
382       * while attempting to uncompress the data.
383       */
384      int uncompress(byte[] src, byte[] dst)
385             throws DataFormatException;
386    
387      /**
388       * Create an SSL context that may be used for communication to
389       * another ADS component.
390       *
391       * @param sslCertNickname The name of the local certificate to use,
392       *                        or null if none is specified.
393       * @return A new SSL Context.
394       * @throws org.opends.server.config.ConfigException If the context
395       * could not be created.
396       */
397      SSLContext getSslContext(String sslCertNickname)
398           throws ConfigException;
399    
400      /**
401       * Get the name of the local certificate to use for SSL.
402       * @return The name of the local certificate to use for SSL.
403       */
404      String getSslCertNickname();
405    
406      /**
407       * Determine whether SSL encryption is enabled.
408       * @return true if SSL encryption is enabled.
409       */
410      boolean isSslEncryption();
411    
412      /**
413       * Get the set of enabled SSL protocols.
414       * @return The set of enabled SSL protocols.
415       */
416      SortedSet<String> getSslProtocols();
417    
418      /**
419       * Get the set of enabled SSL cipher suites.
420       * @return The set of enabled SSL cipher suites.
421       */
422      SortedSet<String> getSslCipherSuites();
423    }