use of com.unboundid.util.ByteStringBuffer in project ldapsdk by pingidentity.
the class ManageCertificatesTestCase method testGetKeystore.
/**
* Provides test coverage for the {@code getKeystore} method.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testGetKeystore() throws Exception {
// Test the behavior with an unsupported keystore type.
try {
ManageCertificates.getKeystore("unsupported", new File(emptyKeyStorePath), "password".toCharArray());
fail("Expected an exception when trying to instantiate a keystore of " + "an unsupported type.");
} catch (final LDAPException le) {
// This was expected.
}
// Test the behavior with a file that the server believes to be a PKCS #12
// keystore, but isn't valid.
File ksFile = createTempFile();
assertTrue(ksFile.exists());
assertTrue(ksFile.delete());
assertFalse(ksFile.exists());
try (FileOutputStream outputStream = new FileOutputStream(ksFile)) {
new ASN1Sequence(new ASN1OctetString("Not a valid PKCS #12 keystore")).writeTo(outputStream);
}
try {
ManageCertificates.getKeystore("PKCS12", ksFile, "password".toCharArray());
fail("Expected an exception when trying to load a keystore from a " + "malformed PKCS #12 file.");
} catch (final LDAPException le) {
// This was expected.
}
// Test the behavior with a file that the server believes to be a JKS
// keystore, but isn't valid.
assertTrue(ksFile.exists());
assertTrue(ksFile.delete());
assertFalse(ksFile.exists());
try (FileOutputStream outputStream = new FileOutputStream(ksFile)) {
final ByteStringBuffer buffer = new ByteStringBuffer();
buffer.append(StaticUtils.byteArray(0xFE, 0xED, 0xFE, 0xED));
buffer.append("This is not a valid JKS keystore.");
buffer.write(outputStream);
}
try {
ManageCertificates.getKeystore("JKS", ksFile, "password".toCharArray());
fail("Expected an exception when trying to load a keystore from a " + "malformed JKS file.");
} catch (final LDAPException le) {
// This was expected.
}
}
use of com.unboundid.util.ByteStringBuffer in project ldapsdk by pingidentity.
the class Base64Tool method doEncode.
/**
* Performs the necessary work for base64 encoding.
*
* @param p The argument parser for the encode subcommand.
*
* @return A result code that indicates whether the processing completed
* successfully.
*/
@NotNull()
private ResultCode doEncode(@NotNull final ArgumentParser p) {
// Get the data to encode.
final ByteStringBuffer rawDataBuffer = new ByteStringBuffer();
final StringArgument dataArg = p.getStringArgument(ARG_NAME_DATA);
if ((dataArg != null) && dataArg.isPresent()) {
rawDataBuffer.append(dataArg.getValue());
} else {
try {
final InputStream inputStream;
final FileArgument inputFileArg = p.getFileArgument(ARG_NAME_INPUT_FILE);
if ((inputFileArg != null) && inputFileArg.isPresent()) {
inputStream = new FileInputStream(inputFileArg.getValue());
} else {
inputStream = in;
}
final byte[] buffer = new byte[8192];
while (true) {
final int bytesRead = inputStream.read(buffer);
if (bytesRead <= 0) {
break;
}
rawDataBuffer.append(buffer, 0, bytesRead);
}
inputStream.close();
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, WRAP_COLUMN, "An error occurred while attempting to read the data to encode: ", StaticUtils.getExceptionMessage(e));
return ResultCode.LOCAL_ERROR;
}
}
// If we should ignore any trailing end-of-line markers, then do that now.
final BooleanArgument ignoreEOLArg = p.getBooleanArgument(ARG_NAME_IGNORE_TRAILING_LINE_BREAK);
if ((ignoreEOLArg != null) && ignoreEOLArg.isPresent()) {
stripEOLLoop: while (rawDataBuffer.length() > 0) {
switch(rawDataBuffer.getBackingArray()[rawDataBuffer.length() - 1]) {
case '\n':
case '\r':
rawDataBuffer.delete(rawDataBuffer.length() - 1, 1);
break;
default:
break stripEOLLoop;
}
}
}
// Base64-encode the data.
final byte[] rawDataArray = rawDataBuffer.toByteArray();
final ByteStringBuffer encodedDataBuffer = new ByteStringBuffer(4 * rawDataBuffer.length() / 3 + 3);
final BooleanArgument urlArg = p.getBooleanArgument(ARG_NAME_URL);
if ((urlArg != null) && urlArg.isPresent()) {
Base64.urlEncode(rawDataArray, 0, rawDataArray.length, encodedDataBuffer, false);
} else {
Base64.encode(rawDataArray, encodedDataBuffer);
}
// Write the encoded data.
final FileArgument outputFileArg = p.getFileArgument(ARG_NAME_OUTPUT_FILE);
if ((outputFileArg != null) && outputFileArg.isPresent()) {
try {
final FileOutputStream outputStream = new FileOutputStream(outputFileArg.getValue(), false);
encodedDataBuffer.write(outputStream);
outputStream.write(StaticUtils.EOL_BYTES);
outputStream.flush();
outputStream.close();
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, WRAP_COLUMN, "An error occurred while attempting to write the base64-encoded " + "data to output file ", outputFileArg.getValue().getAbsolutePath(), ": ", StaticUtils.getExceptionMessage(e));
err("Base64-encoded data:");
err(encodedDataBuffer.toString());
return ResultCode.LOCAL_ERROR;
}
} else {
out(encodedDataBuffer.toString());
}
return ResultCode.SUCCESS;
}
use of com.unboundid.util.ByteStringBuffer in project ldapsdk by pingidentity.
the class DNsOnlyLDAPResultWriterTestCase method testByteArrayOutputStream.
/**
* Test with a tool that has a byte array output stream.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testByteArrayOutputStream() throws Exception {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final DNsOnlyLDAPResultWriter writer = new DNsOnlyLDAPResultWriter(out);
writer.writeHeader();
writer.writeSearchResultEntry(new SearchResultEntry(new Entry("dn: dc=example,dc=com", "dc: example")));
writer.writeSearchResultReference(null);
writer.writeResult(null);
writer.writeUnsolicitedNotification(null, null);
final ByteStringBuffer expectedOutputBuffer = new ByteStringBuffer();
expectedOutputBuffer.append("dc=example,dc=com");
expectedOutputBuffer.append(StaticUtils.EOL_BYTES);
assertEquals(out.toByteArray(), expectedOutputBuffer.toByteArray());
}
use of com.unboundid.util.ByteStringBuffer in project ldapsdk by pingidentity.
the class TransformLDIF method doToolProcessing.
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public ResultCode doToolProcessing() {
final Schema schema;
try {
schema = getSchema();
} catch (final LDAPException le) {
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, le.getMessage());
return le.getResultCode();
}
// If an encryption passphrase file is provided, then get the passphrase
// from it.
String encryptionPassphrase = null;
if (encryptionPassphraseFile.isPresent()) {
try {
encryptionPassphrase = ToolUtils.readEncryptionPassphraseFromFile(encryptionPassphraseFile.getValue());
} catch (final LDAPException e) {
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, e.getMessage());
return e.getResultCode();
}
}
// Create the translators to use to apply the transformations.
final ArrayList<LDIFReaderEntryTranslator> entryTranslators = new ArrayList<>(10);
final ArrayList<LDIFReaderChangeRecordTranslator> changeRecordTranslators = new ArrayList<>(10);
final AtomicLong excludedEntryCount = new AtomicLong(0L);
createTranslators(entryTranslators, changeRecordTranslators, schema, excludedEntryCount);
final AggregateLDIFReaderEntryTranslator entryTranslator = new AggregateLDIFReaderEntryTranslator(entryTranslators);
final AggregateLDIFReaderChangeRecordTranslator changeRecordTranslator = new AggregateLDIFReaderChangeRecordTranslator(changeRecordTranslators);
// Determine the path to the target file to be written.
final File targetFile;
if (targetLDIF.isPresent()) {
targetFile = targetLDIF.getValue();
} else if (targetToStandardOutput.isPresent()) {
targetFile = null;
} else {
targetFile = new File(sourceLDIF.getValue().getAbsolutePath() + ".scrambled");
}
// Create the LDIF reader.
final LDIFReader ldifReader;
try {
final InputStream inputStream;
if (sourceLDIF.isPresent()) {
final ObjectPair<InputStream, String> p = ToolUtils.getInputStreamForLDIFFiles(sourceLDIF.getValues(), encryptionPassphrase, getOut(), getErr());
inputStream = p.getFirst();
if ((encryptionPassphrase == null) && (p.getSecond() != null)) {
encryptionPassphrase = p.getSecond();
}
} else {
inputStream = System.in;
}
ldifReader = new LDIFReader(inputStream, numThreads.getValue(), entryTranslator, changeRecordTranslator);
if (schema != null) {
ldifReader.setSchema(schema);
}
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_ERROR_CREATING_LDIF_READER.get(StaticUtils.getExceptionMessage(e)));
return ResultCode.LOCAL_ERROR;
}
ResultCode resultCode = ResultCode.SUCCESS;
OutputStream outputStream = null;
processingBlock: try {
// Create the output stream to use to write the transformed data.
try {
if (targetFile == null) {
outputStream = getOut();
} else {
outputStream = new FileOutputStream(targetFile, appendToTargetLDIF.isPresent());
}
if (encryptTarget.isPresent()) {
if (encryptionPassphrase == null) {
encryptionPassphrase = ToolUtils.promptForEncryptionPassphrase(false, true, getOut(), getErr());
}
outputStream = new PassphraseEncryptedOutputStream(encryptionPassphrase, outputStream);
}
if (compressTarget.isPresent()) {
outputStream = new GZIPOutputStream(outputStream);
}
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_ERROR_CREATING_OUTPUT_STREAM.get(targetFile.getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
resultCode = ResultCode.LOCAL_ERROR;
break processingBlock;
}
// Read the source data one record at a time. The transformations will
// automatically be applied by the LDIF reader's translators, and even if
// there are multiple reader threads, we're guaranteed to get the results
// in the right order.
long entriesWritten = 0L;
while (true) {
final LDIFRecord ldifRecord;
try {
ldifRecord = ldifReader.readLDIFRecord();
} catch (final LDIFException le) {
Debug.debugException(le);
if (le.mayContinueReading()) {
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_RECOVERABLE_MALFORMED_RECORD.get(StaticUtils.getExceptionMessage(le)));
if (resultCode == ResultCode.SUCCESS) {
resultCode = ResultCode.PARAM_ERROR;
}
continue;
} else {
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_UNRECOVERABLE_MALFORMED_RECORD.get(StaticUtils.getExceptionMessage(le)));
if (resultCode == ResultCode.SUCCESS) {
resultCode = ResultCode.PARAM_ERROR;
}
break processingBlock;
}
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_UNEXPECTED_READ_ERROR.get(StaticUtils.getExceptionMessage(e)));
resultCode = ResultCode.LOCAL_ERROR;
break processingBlock;
}
// done.
if (ldifRecord == null) {
break;
}
// Write the record to the output stream.
try {
if (ldifRecord instanceof PreEncodedLDIFEntry) {
outputStream.write(((PreEncodedLDIFEntry) ldifRecord).getLDIFBytes());
} else {
final ByteStringBuffer buffer = getBuffer();
if (wrapColumn.isPresent()) {
ldifRecord.toLDIF(buffer, wrapColumn.getValue());
} else {
ldifRecord.toLDIF(buffer, 0);
}
buffer.append(StaticUtils.EOL_BYTES);
buffer.write(outputStream);
}
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_WRITE_ERROR.get(targetFile.getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
resultCode = ResultCode.LOCAL_ERROR;
break processingBlock;
}
// If we've written a multiple of 1000 entries, print a progress
// message.
entriesWritten++;
if ((!targetToStandardOutput.isPresent()) && ((entriesWritten % 1000L) == 0)) {
final long numExcluded = excludedEntryCount.get();
if (numExcluded > 0L) {
wrapOut(0, MAX_OUTPUT_LINE_LENGTH, INFO_TRANSFORM_LDIF_WROTE_ENTRIES_WITH_EXCLUDED.get(entriesWritten, numExcluded));
} else {
wrapOut(0, MAX_OUTPUT_LINE_LENGTH, INFO_TRANSFORM_LDIF_WROTE_ENTRIES_NONE_EXCLUDED.get(entriesWritten));
}
}
}
if (!targetToStandardOutput.isPresent()) {
final long numExcluded = excludedEntryCount.get();
if (numExcluded > 0L) {
wrapOut(0, MAX_OUTPUT_LINE_LENGTH, INFO_TRANSFORM_LDIF_COMPLETE_WITH_EXCLUDED.get(entriesWritten, numExcluded));
} else {
wrapOut(0, MAX_OUTPUT_LINE_LENGTH, INFO_TRANSFORM_LDIF_COMPLETE_NONE_EXCLUDED.get(entriesWritten));
}
}
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (final Exception e) {
Debug.debugException(e);
wrapErr(0, MAX_OUTPUT_LINE_LENGTH, ERR_TRANSFORM_LDIF_ERROR_CLOSING_OUTPUT_STREAM.get(targetFile.getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
if (resultCode == ResultCode.SUCCESS) {
resultCode = ResultCode.LOCAL_ERROR;
}
}
}
try {
ldifReader.close();
} catch (final Exception e) {
Debug.debugException(e);
// We can ignore this.
}
}
return resultCode;
}
use of com.unboundid.util.ByteStringBuffer in project ldapsdk by pingidentity.
the class AES256EncodedPassword method encode.
/**
* Encodes a password using the provided information.
*
* @param secretKey
* The secret key that should be used to encrypt the password.
* It must not be {@code null}. The secret key can be reused
* when
* @param initializationVector
* The initialization vector used to randomize the cipher output.
* It must not be [@code null} and it must have a length of
* exactly 16 bytes.
* @param clearTextPassword
* The bytes that comprise the clear-text password to encode.
* It must not be {@code null} or empty.
*
* @return An object with all of the encoded password details.
*
* @throws GeneralSecurityException If a problem occurs while attempting to
* perform any of the cryptographic
* processing.
*/
@NotNull()
public static AES256EncodedPassword encode(@NotNull final AES256EncodedPasswordSecretKey secretKey, @NotNull final byte[] initializationVector, @NotNull final byte[] clearTextPassword) throws GeneralSecurityException {
// Validate all of the provided parameters.
Validator.ensureNotNull(secretKey, "AES256EncodedPassword.encode.secretKey must not be null.");
Validator.ensureNotNull(initializationVector, "AES256EncodedPassword.encode.initializationVector must not be null.");
if (initializationVector.length != ENCODING_VERSION_0_IV_LENGTH_BYTES) {
Validator.violation("AES256EncodedPassword.encode.initializationVector " + "must have a length of exactly " + ENCODING_VERSION_0_IV_LENGTH_BYTES + " bytes. The provided " + "initialization vector had a length of " + initializationVector.length + " bytes.");
}
Validator.ensureNotNullOrEmpty(clearTextPassword, "AES256EncodedPassword.encode.clearTextPassword must not be null or " + "empty.");
// Generate a padded representation of the password.
final byte[] paddedClearTextPassword;
final int paddingBytesNeeded;
final int clearTextPasswordLengthModulus = clearTextPassword.length % ENCODING_VERSION_0_PADDING_MODULUS;
if (clearTextPasswordLengthModulus == 0) {
paddedClearTextPassword = clearTextPassword;
paddingBytesNeeded = 0;
} else {
paddingBytesNeeded = ENCODING_VERSION_0_PADDING_MODULUS - clearTextPasswordLengthModulus;
paddedClearTextPassword = new byte[clearTextPassword.length + paddingBytesNeeded];
Arrays.fill(paddedClearTextPassword, (byte) 0x00);
System.arraycopy(clearTextPassword, 0, paddedClearTextPassword, 0, clearTextPassword.length);
}
// Create and initialize the cipher and use it to encrypt the padded
// password.
final Cipher cipher = CryptoHelper.getCipher(ENCODING_VERSION_0_CIPHER_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey.getSecretKey(), new GCMParameterSpec(ENCODING_VERSION_0_GCM_TAG_LENGTH_BITS, initializationVector));
final byte[] encryptedPaddedPassword = cipher.doFinal(paddedClearTextPassword);
// Generate the raw encoded representation of the password.
final ByteStringBuffer buffer = new ByteStringBuffer();
// The first byte will combine the encoding version (the upper four bits)
// and the number of padding bytes (the lower four bits).
buffer.append((byte) ((ENCODING_VERSION_0_MASK & 0xF0) | (paddingBytesNeeded & 0x0F)));
// The next 16 bytes will be the salt.
final byte[] keyFactorySalt = secretKey.getKeyFactorySalt();
buffer.append(keyFactorySalt);
// The next 16 bytes will be the initialization vector.
buffer.append(initializationVector);
// The next byte will be the number of bytes in the raw encryption settings
// definition ID, followed by the encoded ID.
final byte[] encryptionSettingsDefinitionID = secretKey.getEncryptionSettingsDefinitionID();
buffer.append((byte) (encryptionSettingsDefinitionID.length & 0xFF));
buffer.append(encryptionSettingsDefinitionID);
// The remainder of the encoded representation will be the encrypted
// padded password.
buffer.append(encryptedPaddedPassword);
// Create and return an object with all of the encoded password details.
return new AES256EncodedPassword(buffer.toByteArray(), ENCODING_VERSION_0, paddingBytesNeeded, keyFactorySalt, initializationVector, encryptionSettingsDefinitionID, encryptedPaddedPassword);
}
Aggregations