com.savl.ripple.client.blobvault.BlobVault Maven / Gradle / Ivy
package com.savl.ripple.client.blobvault;
import com.savl.ripple.crypto.sjcljson.JSONEncrypt;
import com.savl.ripple.encodings.common.B16;
import org.json.JSONObject;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.util.encoders.Base64;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
public class BlobVault {
String baseUrl;
public JSONEncrypt sjcl = new JSONEncrypt();
/**
* @param baseUrl eg. "https://blobvault.payward.com/"
*/
public BlobVault(String baseUrl) {
this.baseUrl = baseUrl;
}
public static class BlobNotFound extends RuntimeException {
public BlobNotFound(String msg) {
super(msg);
}
}
public JSONObject getBlob(String user, String pass) throws IOException,
InvalidCipherTextException {
// Everywhere, this is expected to be lower cased.
user = user.toLowerCase();
String userPassUrl = userPassHash(user, pass);
URL blobUrl = new URL(baseUrl + userPassUrl);
HttpURLConnection getRequest = createGETRequestConnection(blobUrl);
int responseCode = getRequest.getResponseCode();
String data = readAllFromConnection(getRequest);
if (responseCode == 404 || data.length() == 0) {
// We won't log the pass
throw new BlobNotFound("No blob found for user: " + user);
}
String utf8 = base64decodeUTF8(data);
String decryptionKey;
try {
decryptionKey = userPassDerivedDecryptionKey(user, pass);
return sjcl.decrypt(decryptionKey, utf8);
} catch (InvalidCipherTextException e) {
decryptionKey = userPassDerivedDecryptionKeyOLD(user, pass);
return sjcl.decrypt(decryptionKey, utf8);
}
}
/**
* @param user Username already lower cased
*/
private String userPassDerivedDecryptionKey(String user, String pass) {
return user.length() + "|" + user + pass;
}
/**
* @param user Username already lower cased
*/
private String userPassDerivedDecryptionKeyOLD(String user, String pass) {
return user + pass;
}
/**
* @param user Username already lower cased
*/
public String userPassHash(String user, String pass) {
String toHash = user + pass;
try {
byte[] toHashBytes = toHash.getBytes("utf8");
byte[] sha256 = MessageDigest.getInstance("SHA-256").digest(toHashBytes);
return B16.toString(sha256);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private HttpURLConnection createGETRequestConnection(URL website) throws IOException {
HttpURLConnection connection = (HttpURLConnection) website.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
return connection;
}
private String readAllFromConnection(HttpURLConnection connection) throws IOException {
BufferedReader buf = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder text = new StringBuilder();
while ((line = buf.readLine()) != null)
text.append(line);
return text.toString();
}
private String base64decodeUTF8(String data) throws UnsupportedEncodingException {
return new String(Base64.decode(data), "utf8");
}
}