io.cloudslang.lang.entities.bindings.values.SensitiveValue Maven / Gradle / Ivy
/*******************************************************************************
* (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License v2.0 which accompany this distribution.
*
* The Apache License is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
*******************************************************************************/
package io.cloudslang.lang.entities.bindings.values;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.cloudslang.lang.entities.SensitivityLevel;
import io.cloudslang.lang.entities.encryption.EncryptionProvider;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import io.cloudslang.lang.spi.encryption.Encryption;
import javassist.util.proxy.ProxyObjectInputStream;
import javassist.util.proxy.ProxyObjectOutputStream;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
/**
* Sensitive InOutParam value
*
* Created by Ifat Gavish on 19/04/2016
*/
public class SensitiveValue implements Value {
private static final long serialVersionUID = -1494652686913646816L;
public static final String SENSITIVE_VALUE_MASK = "********";
private String content = null;
/**
* This variable only used when passing sensitive data between application components which use
* different encryption key
* Json serialization in database should not deal with it
*/
@JsonIgnore
private Serializable originalContent = null;
private SensitivityLevel sensitivityLevel = SensitivityLevel.ENCRYPTED;
@SuppressWarnings("unused")
protected SensitiveValue() {
}
protected SensitiveValue(Serializable content) {
originalContent = content;
encrypt();
}
protected SensitiveValue(Serializable content, SensitivityLevel sensitivityLevel) {
this.sensitivityLevel = sensitivityLevel;
originalContent = content;
encrypt();
}
protected SensitiveValue(String content, boolean preEncrypted) {
if (preEncrypted) {
this.content = content;
} else {
originalContent = content;
encrypt();
}
}
public void encrypt() {
if (originalContent != null) {
content = encrypt(originalContent);
originalContent = null;
}
}
protected String encrypt(Serializable originalContent) {
byte[] serialized = serialize(originalContent);
String serializedAsString = Base64.encodeBase64String(serialized);
Encryption encryption = EncryptionProvider.get();
if (SensitivityLevel.OBFUSCATED == sensitivityLevel) {
return encryption.obfuscate(serializedAsString);
} else {
return encryption.encrypt(serializedAsString.toCharArray());
}
}
public void decrypt() {
if (content != null) {
originalContent = decrypt(content);
content = null;
}
}
protected Serializable decrypt(String content) {
Encryption encryption = EncryptionProvider.get();
char[] decrypted;
if (SensitivityLevel.OBFUSCATED == sensitivityLevel) {
decrypted = encryption.deobfuscate(content);
} else {
decrypted = encryption.decrypt(content);
}
String serializedAsString = new String(decrypted);
byte[] serialized = Base64.decodeBase64(serializedAsString);
return deserialize(serialized);
}
public String getContent() {
return (content != null) ? content : ((originalContent != null) ? originalContent.toString() : null);
}
public void setContent(String content) {
this.content = content;
}
public Serializable getOriginalContent() {
return originalContent;
}
public SensitivityLevel getSensitivityLevel() {
return sensitivityLevel;
}
@Override
public Serializable get() {
return (originalContent != null) ? originalContent : ((content == null) ? null : decrypt(content));
}
@JsonIgnore
@Override
public boolean isSensitive() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SensitiveValue that = (SensitiveValue) o;
if (content != null ? !content.equals(that.content) : that.content != null) {
return false;
}
return originalContent != null ? originalContent.equals(that.originalContent) : that.originalContent == null;
}
@Override
public int hashCode() {
int result = content != null ? content.hashCode() : 0;
result = 31 * result + (originalContent != null ? originalContent.hashCode() : 0);
return result;
}
@Override
public String toString() {
return SENSITIVE_VALUE_MASK;
}
private byte[] serialize(Serializable data) {
ObjectOutputStream oos = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
oos = new ProxyObjectOutputStream(baos);
oos.writeObject(data);
return baos.toByteArray();
} catch (Exception e) {
throw new RuntimeException("Failed to serialize object", e);
} finally {
if (oos != null) {
IOUtils.closeQuietly(oos);
}
}
}
private Serializable deserialize(byte[] data) {
ObjectInputStream ois = null;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ois = new ProxyObjectInputStream(bais);
return (Serializable) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("Failed to deserialize object", e);
} finally {
if (ois != null) {
IOUtils.closeQuietly(ois);
}
}
}
}