From e5aa912f1d824ba4d3f9d0091a356a0da183dd4d Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 3 Jul 2020 10:46:08 +0200 Subject: add EAAF specific serializer that supports whitelisting of classes --- .../core/impl/utils/EaafObjectInputStream.java | 39 ++++++++++++ .../core/impl/utils/EaafSerializationUtils.java | 69 ++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafObjectInputStream.java create mode 100644 eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafSerializationUtils.java diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafObjectInputStream.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafObjectInputStream.java new file mode 100644 index 00000000..e15c7a37 --- /dev/null +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafObjectInputStream.java @@ -0,0 +1,39 @@ +package at.gv.egiz.eaaf.core.impl.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.util.List; + +import javax.annotation.Nonnull; + +public class EaafObjectInputStream extends ObjectInputStream { + + private List allowedClassNames; + + /** + * Object input-stream with internal class validation. + * + * @param is Inputstream to deserialize. + * @param classNames Whitelisted classnames + * @throws IOException In case of an error + */ + public EaafObjectInputStream(@Nonnull InputStream is, @Nonnull List classNames) throws IOException { + super(is); + this.allowedClassNames = classNames; + + } + + //Only deserialize instances of our expected class + @Override + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + if (!allowedClassNames.contains(desc.getName())) { + throw new InvalidClassException("Unauthorized deserialization attempt: {}",desc.getName()); + + } + return super.resolveClass(desc); + } +} diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafSerializationUtils.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafSerializationUtils.java new file mode 100644 index 00000000..e15c6800 --- /dev/null +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/EaafSerializationUtils.java @@ -0,0 +1,69 @@ +package at.gv.egiz.eaaf.core.impl.utils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.List; + +import org.springframework.lang.Nullable; + +public class EaafSerializationUtils { + + private EaafSerializationUtils() { + + } + + /** + * Serialize a given Java object into a byte array. + * + * @param object Java object to serialize. + * @return Serialized Java object + */ + @Nullable + public static byte[] serialize(@Nullable Object object) { + if (object == null) { + return null; + + } + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(object); + oos.flush(); + + } catch (final IOException ex) { + throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex); + + } + + return baos.toByteArray(); + } + + /** + * Deserialize the byte array into an object. + * + * @param bytes a serialized object + * @param allowedClassName List of classnames that are allowed for deserialization + * @return the result of deserializing the bytes + */ + @Nullable + public static Object deserialize(@Nullable byte[] bytes, List allowedClassName) { + if (bytes == null) { + return null; + + } + + try (ObjectInputStream ois = new EaafObjectInputStream(new ByteArrayInputStream(bytes), allowedClassName)) { + return ois.readObject(); + + } catch (final IOException ex) { + throw new IllegalArgumentException("Failed to deserialize object", ex); + + } catch (final ClassNotFoundException ex) { + throw new IllegalStateException("Failed to deserialize object type", ex); + + } + } +} -- cgit v1.2.3