From 1a2cdfb5cf5f89348e8fee7ceeaa699d4aa54cea Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Thu, 21 Apr 2016 15:17:15 +0000
Subject: [PATCH] OPENDJ-2616 Support protection of pluggable backend data at rest
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryIDSet.java | 66 +++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryIDSet.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryIDSet.java
index 62f7ff1..3066154 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryIDSet.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryIDSet.java
@@ -19,6 +19,7 @@
import static org.forgerock.util.Reject.*;
import static org.opends.server.util.StaticUtils.*;
+import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@@ -31,6 +32,8 @@
import org.forgerock.util.Reject;
import com.forgerock.opendj.util.Iterators;
+import org.opends.server.types.CryptoManagerException;
+import org.opends.server.crypto.CryptoSuite;
/**
* Represents a set of Entry IDs. It can represent a set where the IDs are not defined, for example when the index entry
@@ -535,6 +538,69 @@
}
}
+ /**
+ * Decorate a V1 or V2 codec with encryption. When writing EntryIDSets to disk,
+ * prepend two bytes, {0, 1} to mark them as encrypted.
+ * The first is tag zero (unused in other encodings), followed by a byte
+ * indicating version 1 of encryption.
+ */
+ static class EntryIDSetCodecV3 implements EntryIDSetCodec
+ {
+ private static final byte CODEC_V3_TAG = 0x00;
+ private static final byte CODEC_V3_VERSION = 0x01;
+ private final EntryIDSetCodec delegate;
+ private final CryptoSuite cryptoSuite;
+ EntryIDSetCodecV3(EntryIDSetCodec delegate, CryptoSuite cryptoSuite)
+ {
+ this.delegate = delegate;
+ this.cryptoSuite = cryptoSuite;
+ }
+
+ @Override
+ public ByteString encode(EntryIDSet idSet)
+ {
+ ByteString encodedValue = delegate.encode(idSet);
+ ByteStringBuilder builder = new ByteStringBuilder(encodedValue.length());
+ builder.appendByte(CODEC_V3_TAG);
+ builder.appendByte(CODEC_V3_VERSION);
+ try
+ {
+ builder.appendBytes(cryptoSuite.encrypt(encodedValue.toByteArray()));
+ return builder.toByteString();
+ }
+ catch (GeneralSecurityException | CryptoManagerException e)
+ {
+ // Only if the underlying crypto provider has serious problems.
+ throw new IllegalStateException();
+ }
+ }
+
+ @Override
+ public EntryIDSet decode(ByteSequence key, ByteString value)
+ {
+ checkNotNull(value, "value must not be null");
+ if (value.byteAt(0) == CODEC_V3_TAG)
+ {
+ try
+ {
+ return delegate.decode(key,
+ ByteString.wrap(cryptoSuite.decrypt(value.subSequence(2, value.length()).toByteArray())));
+ }
+ catch (GeneralSecurityException | CryptoManagerException e)
+ {
+ // Only if data is completely corrupted.
+ throw new IllegalStateException();
+ }
+ }
+ return delegate.decode(key, value);
+ }
+ }
+
+ static EntryIDSetCodec newEntryIDSetCodecV3(EntryIDSetCodec codec, CryptoSuite cs)
+ {
+ return new EntryIDSetCodecV3(codec, cs);
+ }
+
static EntryIDSet newUndefinedSet()
{
return newUndefinedSetWithKey(NO_KEY);
--
Gitblit v1.10.0