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}