refactored encryption service and exposed sha256 routine

This commit is contained in:
Adrian Cole 2010-07-06 18:21:11 -07:00
parent 2dda46696a
commit 204c093753
49 changed files with 374 additions and 588 deletions

View File

@ -53,7 +53,7 @@ public class BindAtmosObjectToPayloadAndMetadataToHeaders implements Binder {
if (object.getContentMetadata().getContentMD5() != null) { if (object.getContentMetadata().getContentMD5() != null) {
request.getHeaders().put("Content-MD5", request.getHeaders().put("Content-MD5",
encryptionService.toBase64String(object.getContentMetadata().getContentMD5())); encryptionService.base64(object.getContentMetadata().getContentMD5()));
} }
metaBinder.bindToRequest(request, object.getUserMetadata()); metaBinder.bindToRequest(request, object.getUserMetadata());
} }

View File

@ -77,7 +77,7 @@ public class SignRequest implements HttpRequestFilter {
@TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) { @TimeStamp Provider<String> timeStampProvider, EncryptionService encryptionService) {
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.uid = uid; this.uid = uid;
this.key = encryptionService.fromBase64String(encodedKey); this.key = encryptionService.fromBase64(encodedKey);
this.timeStampProvider = timeStampProvider; this.timeStampProvider = timeStampProvider;
this.encryptionService = encryptionService; this.encryptionService = encryptionService;
} }
@ -119,7 +119,7 @@ public class SignRequest implements HttpRequestFilter {
public String signString(String toSign) { public String signString(String toSign) {
String signature; String signature;
try { try {
signature = encryptionService.hmacSha1Base64(toSign, key); signature = encryptionService.base64(encryptionService.hmacSha1(toSign, key));
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -60,7 +60,7 @@ public class ParseSystemMetadataFromHeaders implements Function<HttpResponse, Sy
metaMap.put(entrySplit[0], entrySplit[1]); metaMap.put(entrySplit[0], entrySplit[1]);
} }
assert metaMap.size() >= 12 : String.format("Should be 12 entries in %s", metaMap); assert metaMap.size() >= 12 : String.format("Should be 12 entries in %s", metaMap);
byte[] md5 = metaMap.containsKey("content-md5") ? encryptionService.fromHexString(metaMap byte[] md5 = metaMap.containsKey("content-md5") ? encryptionService.fromHex(metaMap
.get("content-md5")) : null; .get("content-md5")) : null;
return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap return new SystemMetadata(md5, dateService.iso8601SecondsDateParse(checkNotNull(metaMap
.get("atime"), "atime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap .get("atime"), "atime")), dateService.iso8601SecondsDateParse(checkNotNull(metaMap

View File

@ -73,7 +73,7 @@ public class AtmosStorageUtils {
deleteAndEnsureGone(sync, path); deleteAndEnsureGone(sync, path);
if (blob.getMetadata().getContentMD5() != null) if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5", blob.getMetadata().getUserMetadata().put("content-md5",
encryptionService.toHexString(blob.getMetadata().getContentMD5())); encryptionService.hex(blob.getMetadata().getContentMD5()));
sync.createFile(container, blob2Object.apply(blob)); sync.createFile(container, blob2Object.apply(blob));
return path; return path;
} }

View File

@ -55,7 +55,7 @@ public class ParseSystemMetadataFromHeadersTest {
+ "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, " + "gid=rootr, objectid=4980cdb2b010109b04a44f7bb83f5f04ad354c638ae5, "
+ "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default"); + "objname=e913e09366364e9ba384b8fead643d43, size=4096, nlink=1, policyname=default");
SystemMetadata expected = new SystemMetadata(encryptionService SystemMetadata expected = new SystemMetadata(encryptionService
.fromHexString("1f3870be274f6c49b3e31a0c6728957f"), .fromHex("1f3870be274f6c49b3e31a0c6728957f"),
dateService.iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService dateService.iso8601SecondsDateParse("2009-10-12T16:09:42Z"), dateService
.iso8601SecondsDateParse("2009-10-19T04:37:00Z"), "rootr", dateService .iso8601SecondsDateParse("2009-10-19T04:37:00Z"), "rootr", dateService

View File

@ -47,6 +47,6 @@ public class ConvertUnencodedBytesToBase64EncodedString implements Function<Obje
byte[] unencodedData = (byte[]) from; byte[] unencodedData = (byte[]) from;
checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024, checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024,
"userData cannot be larger than 16kb"); "userData cannot be larger than 16kb");
return encryptionService.toBase64String(unencodedData); return encryptionService.base64(unencodedData);
} }
} }

View File

@ -37,7 +37,7 @@ public class UnencodeStringValueHandler extends StringValueHandler {
@Override @Override
public String getResult() { public String getResult() {
return super.getResult() == null ? null : new String(encryptionService.fromBase64String(super return super.getResult() == null ? null : new String(encryptionService.fromBase64(super
.getResult()), Charsets.UTF_8); .getResult()), Charsets.UTF_8);
} }
} }

View File

@ -151,7 +151,8 @@ public class FormSigner implements HttpRequestFilter, RequestSigner {
public String sign(String stringToSign) { public String sign(String stringToSign) {
String signature; String signature;
try { try {
signature = encryptionService.hmacSha256Base64(stringToSign, secretKey.getBytes()); signature = encryptionService.base64(encryptionService.hmacSha256(stringToSign,
secretKey.getBytes()));
if (signatureWire.enabled()) if (signatureWire.enabled())
signatureWire.input(Utils.toInputStream(signature)); signatureWire.input(Utils.toInputStream(signature));
} catch (Exception e) { } catch (Exception e) {

View File

@ -128,7 +128,8 @@ public class RequestAuthorizeSignature implements HttpRequestFilter, RequestSign
public String sign(String toSign) { public String sign(String toSign) {
String signature; String signature;
try { try {
signature = encryptionService.hmacSha1Base64(toSign, secretKey.getBytes()); signature = encryptionService.base64(encryptionService.hmacSha1(toSign, secretKey
.getBytes()));
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -64,7 +64,7 @@ public class ParseObjectMetadataFromHeaders implements
BlobMetadata base = blobMetadataParser.apply(from); BlobMetadata base = blobMetadataParser.apply(from);
MutableObjectMetadata to = blobToObjectMetadata.apply(base); MutableObjectMetadata to = blobToObjectMetadata.apply(base);
addETagTo(from, to); addETagTo(from, to);
to.setContentMD5(encryptionService.fromHexString(Utils.replaceAll(to.getETag(), '"', ""))); to.setContentMD5(encryptionService.fromHex(Utils.replaceAll(to.getETag(), '"', "")));
to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL)); to.setCacheControl(from.getFirstHeaderOrNull(HttpHeaders.CACHE_CONTROL));
to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition")); to.setContentDisposition(from.getFirstHeaderOrNull("Content-Disposition"));
to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING)); to.setContentEncoding(from.getFirstHeaderOrNull(HttpHeaders.CONTENT_ENCODING));

View File

@ -72,8 +72,8 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
} }
public ListBucketResponse getResult() { public ListBucketResponse getResult() {
return new ListBucketResponseImpl(bucketName, contents, prefix, marker, nextMarker, maxResults, return new ListBucketResponseImpl(bucketName, contents, prefix, marker, nextMarker,
delimiter, isTruncated, commonPrefixes); maxResults, delimiter, isTruncated, commonPrefixes);
} }
private boolean inCommonPrefixes; private boolean inCommonPrefixes;
@ -102,7 +102,7 @@ public class ListBucketHandler extends ParseSax.HandlerWithResult<ListBucketResp
currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim()); currentLastModified = dateParser.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("ETag")) { } else if (qName.equals("ETag")) {
currentETag = currentText.toString().trim(); currentETag = currentText.toString().trim();
currentMD5 = encryptionService.fromHexString(Utils.replaceAll(currentETag,'"', "")); currentMD5 = encryptionService.fromHex(Utils.replaceAll(currentETag, '"', ""));
} else if (qName.equals("Size")) { } else if (qName.equals("Size")) {
currentSize = new Long(currentText.toString().trim()); currentSize = new Long(currentText.toString().trim());
} else if (qName.equals("Owner")) { } else if (qName.equals("Owner")) {

View File

@ -48,7 +48,7 @@ public class MD5Handler extends ParseSax.HandlerWithResult<byte[]> {
public void endElement(String uri, String name, String qName) { public void endElement(String uri, String name, String qName) {
if (qName.equals("MD5OfMessageBody")) { if (qName.equals("MD5OfMessageBody")) {
String md5Hex = currentText.toString().trim(); String md5Hex = currentText.toString().trim();
this.md5 = encryptionService.fromHexString(md5Hex); this.md5 = encryptionService.fromHex(md5Hex);
} }
currentText = new StringBuilder(); currentText = new StringBuilder();
} }

View File

@ -54,7 +54,7 @@ public class RegexMD5Handler implements Function<HttpResponse, byte[]> {
try { try {
Matcher matcher = pattern.matcher(Utils.toStringAndClose(response.getContent())); Matcher matcher = pattern.matcher(Utils.toStringAndClose(response.getContent()));
if (matcher.find()) { if (matcher.find()) {
value = encryptionService.fromHexString(matcher.group(1)); value = encryptionService.fromHex(matcher.group(1));
} }
} catch (IOException e) { } catch (IOException e) {
Throwables.propagate(e); Throwables.propagate(e);

View File

@ -104,7 +104,7 @@ public class ParseObjectMetadataFromHeadersTest {
expects.setCacheControl("cacheControl"); expects.setCacheControl("cacheControl");
expects.setContentDisposition("contentDisposition"); expects.setContentDisposition("contentDisposition");
expects.setContentEncoding("encoding"); expects.setContentEncoding("encoding");
expects.setContentMD5(encryptionService.fromHexString("abc")); expects.setContentMD5(encryptionService.fromHex("abc"));
expects.setContentType("type"); expects.setContentType("type");
expects.setETag("\"abc\""); expects.setETag("\"abc\"");
expects.setKey("key"); expects.setKey("key");

View File

@ -65,54 +65,54 @@ public class ListBucketHandlerTest extends BaseHandlerTest {
(ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/0", dateService
.iso8601DateParse("2009-05-07T18:27:08.000Z"), .iso8601DateParse("2009-05-07T18:27:08.000Z"),
"\"c82e6a0025c31c5de5947fda62ac51ab\"", encryptionService "\"c82e6a0025c31c5de5947fda62ac51ab\"", encryptionService
.fromHexString("c82e6a0025c31c5de5947fda62ac51ab"), 8, .fromHex("c82e6a0025c31c5de5947fda62ac51ab"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/1", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService "\"944fab2c5a9a6bacf07db5e688310d7a\"", encryptionService
.fromHexString("944fab2c5a9a6bacf07db5e688310d7a"), 8, .fromHex("944fab2c5a9a6bacf07db5e688310d7a"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/2", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"a227b8888045c8fd159fb495214000f0\"", encryptionService "\"a227b8888045c8fd159fb495214000f0\"", encryptionService
.fromHexString("a227b8888045c8fd159fb495214000f0"), 8, .fromHex("a227b8888045c8fd159fb495214000f0"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/3", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService "\"c9caa76c3dec53e2a192608ce73eef03\"", encryptionService
.fromHexString("c9caa76c3dec53e2a192608ce73eef03"), 8, .fromHex("c9caa76c3dec53e2a192608ce73eef03"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/4", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"1ce5d0dcc6154a647ea90c7bdf82a224\"", encryptionService "\"1ce5d0dcc6154a647ea90c7bdf82a224\"", encryptionService
.fromHexString("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, .fromHex("1ce5d0dcc6154a647ea90c7bdf82a224"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/5", dateService
.iso8601DateParse("2009-05-07T18:27:09.000Z"), .iso8601DateParse("2009-05-07T18:27:09.000Z"),
"\"79433524d87462ee05708a8ef894ed55\"", encryptionService "\"79433524d87462ee05708a8ef894ed55\"", encryptionService
.fromHexString("79433524d87462ee05708a8ef894ed55"), 8, .fromHex("79433524d87462ee05708a8ef894ed55"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/6", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"dd00a060b28ddca8bc5a21a49e306f67\"", encryptionService "\"dd00a060b28ddca8bc5a21a49e306f67\"", encryptionService
.fromHexString("dd00a060b28ddca8bc5a21a49e306f67"), 8, .fromHex("dd00a060b28ddca8bc5a21a49e306f67"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/7", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"8cd06eca6e819a927b07a285d750b100\"", encryptionService "\"8cd06eca6e819a927b07a285d750b100\"", encryptionService
.fromHexString("8cd06eca6e819a927b07a285d750b100"), 8, .fromHex("8cd06eca6e819a927b07a285d750b100"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/8", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"174495094d0633b92cbe46603eee6bad\"", encryptionService "\"174495094d0633b92cbe46603eee6bad\"", encryptionService
.fromHexString("174495094d0633b92cbe46603eee6bad"), 8, .fromHex("174495094d0633b92cbe46603eee6bad"), 8, owner,
owner, StorageClass.STANDARD), StorageClass.STANDARD),
(ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService (ObjectMetadata) new BucketListObjectMetadata("apps/9", dateService
.iso8601DateParse("2009-05-07T18:27:10.000Z"), .iso8601DateParse("2009-05-07T18:27:10.000Z"),
"\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService "\"cd8a19b26fea8a827276df0ad11c580d\"", encryptionService
.fromHexString("cd8a19b26fea8a827276df0ad11c580d"), 8, .fromHex("cd8a19b26fea8a827276df0ad11c580d"), 8, owner,
owner, StorageClass.STANDARD)), "apps/", null, null, 1000, null, StorageClass.STANDARD)), "apps/", null, null, 1000, null, false,
false, new TreeSet<String>()); new TreeSet<String>());
ListBucketResponse result = (ListBucketResponse) factory.create( ListBucketResponse result = (ListBucketResponse) factory.create(
injector.getInstance(ListBucketHandler.class)).parse(is); injector.getInstance(ListBucketHandler.class)).parse(is);

View File

@ -35,6 +35,7 @@ import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.util.Utils;
import org.testng.annotations.AfterTest; import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -61,8 +62,10 @@ public class SQSClientLiveTest {
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws IOException { public void setupClient() throws IOException {
String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); String identity = checkNotNull(System.getProperty("jclouds.test.identity"),
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); "jclouds.test.identity");
String credential = checkNotNull(System.getProperty("jclouds.test.credential"),
"jclouds.test.credential");
context = new RestContextFactory().createContext("sqs", identity, credential, ImmutableSet context = new RestContextFactory().createContext("sqs", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule())); .<Module> of(new Log4JLoggingModule()));
@ -126,7 +129,7 @@ public class SQSClientLiveTest {
@Test(dependsOnMethods = "testCreateQueue") @Test(dependsOnMethods = "testCreateQueue")
void testSendMessage() throws InterruptedException { void testSendMessage() throws InterruptedException {
String message = "hardyharhar"; String message = "hardyharhar";
byte[] md5 = encryptionService.md5(message.getBytes()); byte[] md5 = encryptionService.md5(Utils.toInputStream(message));
for (Queue queue : queues) { for (Queue queue : queues) {
assertEquals(client.sendMessage(queue, message), md5); assertEquals(client.sendMessage(queue, message), md5);
} }

View File

@ -78,7 +78,7 @@ public class BindAzureBlobToPayload implements Binder {
if (object.getProperties().getContentMD5() != null) { if (object.getProperties().getContentMD5() != null) {
request.getHeaders().put("Content-MD5", request.getHeaders().put("Content-MD5",
encryptionService.toBase64String(object.getProperties().getContentMD5())); encryptionService.base64(object.getProperties().getContentMD5()));
} }
if (object.getProperties().getContentLanguage() != null) { if (object.getProperties().getContentLanguage() != null) {
request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE, request.getHeaders().put(HttpHeaders.CONTENT_LANGUAGE,

View File

@ -166,7 +166,7 @@ public class ContainerNameEnumerationResultsHandler extends
currentSize = Long.parseLong(currentText.toString().trim()); currentSize = Long.parseLong(currentText.toString().trim());
} else if (qName.equals("Content-MD5")) { } else if (qName.equals("Content-MD5")) {
if (!currentText.toString().trim().equals("")) if (!currentText.toString().trim().equals(""))
currentContentMD5 = encryptionService.fromBase64String(currentText.toString().trim()); currentContentMD5 = encryptionService.fromBase64(currentText.toString().trim());
} else if (qName.equals("Content-Type")) { } else if (qName.equals("Content-Type")) {
currentContentType = currentText.toString().trim(); currentContentType = currentText.toString().trim();
} else if (qName.equals("Content-Encoding")) { } else if (qName.equals("Content-Encoding")) {

View File

@ -74,7 +74,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
this.encryptionService = encryptionService; this.encryptionService = encryptionService;
this.signatureWire = signatureWire; this.signatureWire = signatureWire;
this.identity = identity; this.identity = identity;
this.key = encryptionService.fromBase64String(encodedKey); this.key = encryptionService.fromBase64(encodedKey);
this.timeStampProvider = timeStampProvider; this.timeStampProvider = timeStampProvider;
} }
@ -110,7 +110,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
public String signString(String toSign) { public String signString(String toSign) {
String signature; String signature;
try { try {
signature = encryptionService.hmacSha256Base64(toSign, key); signature = encryptionService.base64(encryptionService.hmacSha256(toSign, key));
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -74,7 +74,8 @@ public class AzureBlobClientLiveTest {
identity = System.getProperty("jclouds.test.identity"); identity = System.getProperty("jclouds.test.identity");
String credential = System.getProperty("jclouds.test.credential"); String credential = System.getProperty("jclouds.test.credential");
client = (AzureBlobClient) new BlobStoreContextFactory().createContext("azureblob", identity, client = (AzureBlobClient) new BlobStoreContextFactory().createContext("azureblob", identity,
credential, ImmutableSet.<Module> of(new Log4JLoggingModule())).getProviderSpecificContext().getApi(); credential, ImmutableSet.<Module> of(new Log4JLoggingModule()))
.getProviderSpecificContext().getApi();
} }
@Test @Test
@ -236,8 +237,8 @@ public class AzureBlobClientLiveTest {
object.getProperties().getMetadata().put("mykey", "metadata-value"); object.getProperties().getMetadata().put("mykey", "metadata-value");
byte[] md5 = object.getProperties().getContentMD5(); byte[] md5 = object.getProperties().getContentMD5();
String newEtag = client.putBlob(privateContainer, object); String newEtag = client.putBlob(privateContainer, object);
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
.getProperties().getContentMD5())); .getContentMD5()));
// Test HEAD of missing object // Test HEAD of missing object
assert client.getBlobProperties(privateContainer, "non-existent-object") == null; assert client.getBlobProperties(privateContainer, "non-existent-object") == null;
@ -254,8 +255,8 @@ public class AzureBlobClientLiveTest {
// assertEquals(metadata.getSize(), data.length()); // assertEquals(metadata.getSize(), data.length());
assertEquals(metadata.getContentType(), "text/plain"); assertEquals(metadata.getContentType(), "text/plain");
// Azure doesn't return the Content-MD5 on head request... // Azure doesn't return the Content-MD5 on head request...
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object assertEquals(encryptionService.hex(md5), encryptionService.hex(object.getProperties()
.getProperties().getContentMD5())); .getContentMD5()));
assertEquals(metadata.getETag(), newEtag); assertEquals(metadata.getETag(), newEtag);
assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().entrySet().size(), 1);
assertEquals(metadata.getMetadata().get("mykey"), "metadata-value"); assertEquals(metadata.getMetadata().get("mykey"), "metadata-value");
@ -276,8 +277,8 @@ public class AzureBlobClientLiveTest {
// TODO assertEquals(getBlob.getName(), object.getProperties().getName()); // TODO assertEquals(getBlob.getName(), object.getProperties().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length())); assertEquals(getBlob.getContentLength(), new Long(data.length()));
assertEquals(getBlob.getProperties().getContentType(), "text/plain"); assertEquals(getBlob.getProperties().getContentType(), "text/plain");
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
.getProperties().getContentMD5())); .getContentMD5()));
assertEquals(newEtag, getBlob.getProperties().getETag()); assertEquals(newEtag, getBlob.getProperties().getETag());
// wait until we can update metadata // wait until we can update metadata
// assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2); // assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2);
@ -318,8 +319,8 @@ public class AzureBlobClientLiveTest {
object.setPayload(bais); object.setPayload(bais);
object.setContentLength(new Long(data.getBytes().length)); object.setContentLength(new Long(data.getBytes().length));
newEtag = client.putBlob(privateContainer, object); newEtag = client.putBlob(privateContainer, object);
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob.getProperties()
.getProperties().getContentMD5())); .getContentMD5()));
// Test GET with options // Test GET with options
// Non-matching ETag // Non-matching ETag

View File

@ -20,15 +20,26 @@ package org.jclouds.blobstore;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.getCausalChain;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.size;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.partition;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.filter;
import static com.google.common.collect.Sets.newTreeSet;
import static com.google.common.io.ByteStreams.toByteArray;
import static com.google.common.io.Closeables.closeQuietly;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.http.Payloads.newByteArrayPayload;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput; import java.io.ObjectInput;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutput; import java.io.ObjectOutput;
@ -74,17 +85,12 @@ import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.http.Payload;
import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.http.options.HttpRequestOptions;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.internal.Nullable; import com.google.inject.internal.Nullable;
@ -125,27 +131,6 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
getContainerToBlobs().put("stub", new ConcurrentHashMap<String, Blob>()); getContainerToBlobs().put("stub", new ConcurrentHashMap<String, Blob>());
} }
/**
* @throws java.io.IOException
*/
public static byte[] toByteArray(Object data) throws IOException {
checkNotNull(data, "data must be set before calling generateETag()");
byte[] bytes = null;
if (data == null || data instanceof byte[]) {
bytes = (byte[]) data;
} else if (data instanceof String) {
bytes = ((String) data).getBytes();
} else if (data instanceof File || data instanceof InputStream) {
InputStream io = (data instanceof InputStream) ? (InputStream) data : new FileInputStream(
(File) data);
bytes = ByteStreams.toByteArray(io);
Closeables.closeQuietly(io);
} else {
throw new UnsupportedOperationException("Content not supported " + data.getClass());
}
return bytes;
}
/** /**
* default maxResults is 1000 * default maxResults is 1000
*/ */
@ -157,8 +142,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
if (realContents == null) if (realContents == null)
return immediateFailedFuture(cnfe(container)); return immediateFailedFuture(cnfe(container));
SortedSet<StorageMetadata> contents = Sets.newTreeSet(Iterables.transform(realContents SortedSet<StorageMetadata> contents = newTreeSet(transform(realContents.keySet(),
.keySet(), new Function<String, StorageMetadata>() { new Function<String, StorageMetadata>() {
public StorageMetadata apply(String key) { public StorageMetadata apply(String key) {
Blob oldBlob = realContents.get(key); Blob oldBlob = realContents.get(key);
checkState(oldBlob != null, "blob " + key checkState(oldBlob != null, "blob " + key
@ -177,8 +162,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
if (options.getMarker() != null) { if (options.getMarker() != null) {
final String finalMarker = options.getMarker(); final String finalMarker = options.getMarker();
StorageMetadata lastMarkerMetadata = Iterables.find(contents, StorageMetadata lastMarkerMetadata = find(contents, new Predicate<StorageMetadata>() {
new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata metadata) { public boolean apply(StorageMetadata metadata) {
return metadata.getName().equals(finalMarker); return metadata.getName().equals(finalMarker);
} }
@ -189,7 +173,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
final String prefix = options.getDir(); final String prefix = options.getDir();
if (prefix != null) { if (prefix != null) {
contents = Sets.newTreeSet(Iterables.filter(contents, new Predicate<StorageMetadata>() { contents = newTreeSet(filter(contents, new Predicate<StorageMetadata>() {
public boolean apply(StorageMetadata o) { public boolean apply(StorageMetadata o) {
return (o != null && o.getName().startsWith(prefix) && !o.getName().equals(prefix)); return (o != null && o.getName().startsWith(prefix) && !o.getName().equals(prefix));
} }
@ -212,15 +196,15 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
final String delimiter = options.isRecursive() ? null : "/"; final String delimiter = options.isRecursive() ? null : "/";
if (delimiter != null) { if (delimiter != null) {
SortedSet<String> commonPrefixes = null; SortedSet<String> commonPrefixes = null;
Iterable<String> iterable = Iterables.transform(contents, new CommonPrefixes( Iterable<String> iterable = transform(contents, new CommonPrefixes(prefix != null ? prefix
prefix != null ? prefix : null, delimiter)); : null, delimiter));
commonPrefixes = iterable != null ? Sets.newTreeSet(iterable) : new TreeSet<String>(); commonPrefixes = iterable != null ? newTreeSet(iterable) : new TreeSet<String>();
commonPrefixes.remove(CommonPrefixes.NO_PREFIX); commonPrefixes.remove(CommonPrefixes.NO_PREFIX);
contents = Sets.newTreeSet(Iterables.filter(contents, new DelimiterFilter( contents = newTreeSet(filter(contents, new DelimiterFilter(prefix != null ? prefix : null,
prefix != null ? prefix : null, delimiter))); delimiter)));
Iterables.<StorageMetadata> addAll(contents, Iterables.transform(commonPrefixes, Iterables.<StorageMetadata> addAll(contents, transform(commonPrefixes,
new Function<String, StorageMetadata>() { new Function<String, StorageMetadata>() {
public StorageMetadata apply(String o) { public StorageMetadata apply(String o) {
MutableStorageMetadata md = new MutableStorageMetadataImpl(); MutableStorageMetadata md = new MutableStorageMetadataImpl();
@ -258,14 +242,14 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
convertUserMetadataKeysToLowercase(metadata); convertUserMetadataKeysToLowercase(metadata);
return metadata; return metadata;
} catch (Exception e) { } catch (Exception e) {
Throwables.propagate(e); propagate(e);
assert false : "exception should have propagated: " + e; assert false : "exception should have propagated: " + e;
return null; return null;
} }
} }
private static void convertUserMetadataKeysToLowercase(MutableBlobMetadata metadata) { private static void convertUserMetadataKeysToLowercase(MutableBlobMetadata metadata) {
Map<String, String> lowerCaseUserMetadata = Maps.newHashMap(); Map<String, String> lowerCaseUserMetadata = newHashMap();
for (Entry<String, String> entry : metadata.getUserMetadata().entrySet()) { for (Entry<String, String> entry : metadata.getUserMetadata().entrySet()) {
lowerCaseUserMetadata.put(entry.getKey().toLowerCase(), entry.getValue()); lowerCaseUserMetadata.put(entry.getKey().toLowerCase(), entry.getValue());
} }
@ -333,8 +317,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
*/ */
@Override @Override
public ListenableFuture<? extends PageSet<? extends StorageMetadata>> list() { public ListenableFuture<? extends PageSet<? extends StorageMetadata>> list() {
return immediateFuture(new PageSetImpl<StorageMetadata>(Iterables.transform( return immediateFuture(new PageSetImpl<StorageMetadata>(transform(getContainerToBlobs()
getContainerToBlobs().keySet(), new Function<String, StorageMetadata>() { .keySet(), new Function<String, StorageMetadata>() {
public StorageMetadata apply(String name) { public StorageMetadata apply(String name) {
MutableStorageMetadata cmd = create(); MutableStorageMetadata cmd = create();
cmd.setName(name); cmd.setName(name);
@ -423,8 +407,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
public static <T extends Comparable<?>> SortedSet<T> firstSliceOfSize(Iterable<T> elements, public static <T extends Comparable<?>> SortedSet<T> firstSliceOfSize(Iterable<T> elements,
int size) { int size) {
List<List<T>> slices = Lists.partition(Lists.newArrayList(elements), size); List<List<T>> slices = partition(newArrayList(elements), size);
return Sets.newTreeSet(slices.get(0)); return newTreeSet(slices.get(0));
} }
public static HttpResponseException returnResponseException(int code) { public static HttpResponseException returnResponseException(int code) {
@ -472,24 +456,32 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public ListenableFuture<String> putBlob(final String containerName, final Blob object) { public ListenableFuture<String> putBlob(String containerName, Blob object) {
Map<String, Blob> container = getContainerToBlobs().get(containerName); Map<String, Blob> container = getContainerToBlobs().get(containerName);
if (container == null) { if (container == null) {
new RuntimeException("containerName not found: " + containerName); new RuntimeException("containerName not found: " + containerName);
} }
Payload payload = object.getPayload();
if (!payload.isRepeatable()) {
try { try {
byte[] data = toByteArray(object.getPayload().getRawContent()); payload = newByteArrayPayload(toByteArray(payload.getInput()));
object.getMetadata().setSize(data.length); } catch (IOException e) {
propagate(e);
} finally {
closeQuietly(payload.getInput());
}
}
object.getMetadata().setSize(payload.calculateSize());
MutableBlobMetadata newMd = copy(object.getMetadata()); MutableBlobMetadata newMd = copy(object.getMetadata());
newMd.setLastModified(new Date()); newMd.setLastModified(new Date());
final byte[] md5 = encryptionService.md5(data); byte[] md5 = encryptionService.md5(payload.getInput());
final String eTag = encryptionService.toHexString(md5); String eTag = encryptionService.hex(md5);
newMd.setETag(eTag); newMd.setETag(eTag);
newMd.setContentMD5(md5); newMd.setContentMD5(md5);
newMd.setContentType(object.getMetadata().getContentType()); newMd.setContentType(object.getMetadata().getContentType());
Blob blob = blobFactory.create(newMd); Blob blob = blobFactory.create(newMd);
blob.setPayload(data); blob.setPayload(payload);
container.put(blob.getMetadata().getName(), blob); container.put(blob.getMetadata().getName(), blob);
// Set HTTP headers to match metadata // Set HTTP headers to match metadata
@ -502,10 +494,6 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
blob.getAllHeaders().put(userMD.getKey(), userMD.getValue()); blob.getAllHeaders().put(userMD.getKey(), userMD.getValue());
} }
return immediateFuture(eTag); return immediateFuture(eTag);
} catch (IOException e) {
return immediateFailedFuture(new RuntimeException(e));
}
} }
/** /**
@ -567,7 +555,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
if (options.getRanges() != null && options.getRanges().size() > 0) { if (options.getRanges() != null && options.getRanges().size() > 0) {
byte[] data; byte[] data;
try { try {
data = ByteStreams.toByteArray(returnVal.getPayload().getInput()); data = toByteArray(returnVal.getPayload().getInput());
} catch (IOException e) { } catch (IOException e) {
return immediateFailedFuture(new RuntimeException(e)); return immediateFailedFuture(new RuntimeException(e));
} }
@ -608,8 +596,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
Blob blob = getBlob(container, key).get(); Blob blob = getBlob(container, key).get();
return immediateFuture(blob != null ? (BlobMetadata) copy(blob.getMetadata()) : null); return immediateFuture(blob != null ? (BlobMetadata) copy(blob.getMetadata()) : null);
} catch (Exception e) { } catch (Exception e) {
if (Iterables.size(Iterables.filter(Throwables.getCausalChain(e), if (size(filter(getCausalChain(e), KeyNotFoundException.class)) >= 1)
KeyNotFoundException.class)) >= 1)
return immediateFuture(null); return immediateFuture(null);
return immediateFailedFuture(e); return immediateFailedFuture(e);
} }

View File

@ -53,7 +53,7 @@ public class BindBlobToPayload implements Binder {
if (object.getMetadata().getContentMD5() != null) { if (object.getMetadata().getContentMD5() != null) {
request.getHeaders().put("Content-MD5", request.getHeaders().put("Content-MD5",
encryptionService.toBase64String(object.getMetadata().getContentMD5())); encryptionService.base64(object.getMetadata().getContentMD5()));
} }
} }
} }

View File

@ -1,33 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.functions;
import org.jclouds.blobstore.functions.impl.JCEGenerateMD5;
import com.google.common.base.Function;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*/
@ImplementedBy(JCEGenerateMD5.class)
public interface GenerateMD5 extends Function<Object, byte[]> {
}

View File

@ -1,36 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.functions;
import java.io.InputStream;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.impl.JCEGenerateMD5Result;
import com.google.common.base.Function;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*/
@ImplementedBy(JCEGenerateMD5Result.class)
public interface GenerateMD5Result extends Function<InputStream, MD5InputStreamResult> {
}

View File

@ -114,7 +114,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements
protected void addContentMD5To(HttpResponse from, MutableBlobMetadata metadata) { protected void addContentMD5To(HttpResponse from, MutableBlobMetadata metadata) {
String contentMD5 = from.getFirstHeaderOrNull("Content-MD5"); String contentMD5 = from.getFirstHeaderOrNull("Content-MD5");
if (contentMD5 != null) { if (contentMD5 != null) {
metadata.setContentMD5(encryptionService.fromBase64String(contentMD5)); metadata.setContentMD5(encryptionService.fromBase64(contentMD5));
} }
} }

View File

@ -1,39 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.functions.impl;
import javax.inject.Singleton;
import org.jclouds.blobstore.functions.GenerateMD5;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.JCEEncryptionService;
/**
*
* @author Adrian Cole
*/
@Singleton
public class JCEGenerateMD5 implements GenerateMD5 {
private static final EncryptionService encryptionService = new JCEEncryptionService();
public byte[] apply(Object from) {
return encryptionService.md5(from);
}
}

View File

@ -1,43 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.blobstore.functions.impl;
import java.io.InputStream;
import javax.inject.Singleton;
import org.jclouds.blobstore.domain.MD5InputStreamResult;
import org.jclouds.blobstore.functions.GenerateMD5Result;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.encryption.internal.JCEEncryptionService;
/**
*
* @author Adrian Cole
*/
@Singleton
public class JCEGenerateMD5Result implements GenerateMD5Result {
private static final EncryptionService encryptionService = new JCEEncryptionService();
public MD5InputStreamResult apply(InputStream toEncode) {
org.jclouds.encryption.EncryptionService.MD5InputStreamResult result = encryptionService
.generateMD5Result(toEncode);
return new MD5InputStreamResult(result.data, result.md5, result.length);
}
}

View File

@ -83,7 +83,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
@Override @Override
public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception { public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception {
encryptionService = Guice.createInjector().getInstance(EncryptionService.class); encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
MD5InputStreamResult result = encryptionService.generateMD5Result(getTestDataSupplier() MD5InputStreamResult result = encryptionService.md5Result(getTestDataSupplier()
.getInput()); .getInput());
oneHundredOneConstitutions = result.data; oneHundredOneConstitutions = result.data;
oneHundredOneConstitutionsMD5 = result.md5; oneHundredOneConstitutionsMD5 = result.md5;
@ -440,7 +440,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
// providers. // providers.
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
object.getMetadata().setContentMD5(new JCEEncryptionService().md5(TEST_STRING.getBytes())); object.getMetadata().setContentMD5(
new JCEEncryptionService().md5(Utils.toInputStream(TEST_STRING)));
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff")); assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff"));
@ -469,7 +470,8 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType(); assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
assertEquals(metadata.getSize(), new Long(TEST_STRING.length())); assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
assertEquals(metadata.getContentMD5(), new JCEEncryptionService().md5(TEST_STRING.getBytes())); assertEquals(metadata.getContentMD5(), new JCEEncryptionService().md5(Utils
.toInputStream(TEST_STRING)));
} }
} }

View File

@ -59,7 +59,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest {
String key = "hello"; String key = "hello";
URL url = new URL(httpStreamUrl); URL url = new URL(httpStreamUrl);
byte[] md5 = new JCEEncryptionService().fromHexString(httpStreamETag); byte[] md5 = new JCEEncryptionService().fromHex(httpStreamETag);
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
int length = connection.getContentLength(); int length = connection.getContentLength();

View File

@ -18,9 +18,12 @@
*/ */
package org.jclouds.blobstore.integration.internal; package org.jclouds.blobstore.integration.internal;
import static com.google.common.base.Throwables.propagateIfPossible;
import static com.google.common.collect.Iterables.get;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.afterMarker;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults;
import static org.jclouds.util.Utils.toInputStream;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -37,9 +40,6 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.encryption.internal.JCEEncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -80,7 +80,8 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
// providers. // providers.
object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); object.getMetadata().getUserMetadata().put("Adrian", "powderpuff");
object.getMetadata().setContentMD5(new JCEEncryptionService().md5(TEST_STRING.getBytes())); object.getMetadata()
.setContentMD5(new JCEEncryptionService().md5(toInputStream(TEST_STRING)));
String containerName = getContainerName(); String containerName = getContainerName();
try { try {
addBlobToContainer(containerName, object); addBlobToContainer(containerName, object);
@ -89,13 +90,13 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
PageSet<? extends StorageMetadata> container = context.getBlobStore().list(containerName, PageSet<? extends StorageMetadata> container = context.getBlobStore().list(containerName,
maxResults(1).withDetails()); maxResults(1).withDetails());
BlobMetadata metadata = BlobMetadata.class.cast(Iterables.get(container, 0)); BlobMetadata metadata = BlobMetadata.class.cast(get(container, 0));
assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType(); assert metadata.getContentType().startsWith("text/plain") : metadata.getContentType();
assertEquals(metadata.getSize(), new Long(TEST_STRING.length())); assertEquals(metadata.getSize(), new Long(TEST_STRING.length()));
assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff");
assertEquals(metadata.getContentMD5(), new JCEEncryptionService().md5(TEST_STRING assertEquals(metadata.getContentMD5(), new JCEEncryptionService()
.getBytes())); .md5(toInputStream(TEST_STRING)));
} finally { } finally {
returnContainer(containerName); returnContainer(containerName);
} }
@ -304,7 +305,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest {
assert !context.getBlobStore().containerExists(containerName) : "container " assert !context.getBlobStore().containerExists(containerName) : "container "
+ containerName + " still exists"; + containerName + " still exists";
} catch (Exception e) { } catch (Exception e) {
Throwables.propagateIfPossible(e); propagateIfPossible(e);
} }
} }
}); });

View File

@ -134,7 +134,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
@VisibleForTesting @VisibleForTesting
String hashPath(String path) { String hashPath(String path) {
try { try {
return encryptionService.sha1Base64(Utils.toInputStream(canonicalPath(path))); return encryptionService.base64(encryptionService.sha1(Utils
.toInputStream(canonicalPath(path))));
} catch (Exception e) { } catch (Exception e) {
Throwables.propagateIfPossible(e); Throwables.propagateIfPossible(e);
throw new HttpException("error creating sigature for path: " + path, e); throw new HttpException("error creating sigature for path: " + path, e);
@ -159,7 +160,7 @@ public class SignedHeaderAuth implements HttpRequestFilter {
checkArgument(payload != null, "payload was null"); checkArgument(payload != null, "payload was null");
checkArgument(payload.isRepeatable(), "payload must be repeatable: " + payload); checkArgument(payload.isRepeatable(), "payload must be repeatable: " + payload);
try { try {
return encryptionService.sha1Base64(payload.getInput()); return encryptionService.base64(encryptionService.sha1(payload.getInput()));
} catch (Exception e) { } catch (Exception e) {
Throwables.propagateIfPossible(e); Throwables.propagateIfPossible(e);
throw new HttpException("error creating sigature for payload: " + payload, e); throw new HttpException("error creating sigature for payload: " + payload, e);
@ -187,8 +188,8 @@ public class SignedHeaderAuth implements HttpRequestFilter {
public String sign(String toSign) { public String sign(String toSign) {
try { try {
byte[] encrypted = encryptionService.rsaPrivateEncrypt(toSign, privateKey); byte[] encrypted = encryptionService.rsaSign(toSign, privateKey);
return encryptionService.toBase64String(encrypted); return encryptionService.base64(encrypted);
} catch (Exception e) { } catch (Exception e) {
throw new HttpException("error signing request", e); throw new HttpException("error signing request", e);
} }

View File

@ -28,6 +28,7 @@ import static org.testng.Assert.assertNotNull;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -36,7 +37,6 @@ import org.jclouds.chef.domain.Resource;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.util.Utils;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -135,7 +135,13 @@ public class ChefClientLiveTest {
cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll( cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(
cookbookO.getRootFiles()).addAll(cookbookO.getTemplates()).build()) { cookbookO.getRootFiles()).addAll(cookbookO.getTemplates()).build()) {
try { try {
Utils.toStringAndClose(adminConnection.utils().http().get(resource.getUrl()));
InputStream stream = adminConnection.utils().http().get(resource.getUrl());
byte[] md5 = adminConnection.utils().encryption().sha256(stream);
String md5Hex = adminConnection.utils().encryption().hex(md5);
assert md5Hex.equals(resource.getChecksum()) : String.format(
"hex for %s was: %s should be %s ", resource, md5Hex, resource
.getChecksum());
} catch (NullPointerException e) { } catch (NullPointerException e) {
assert false : "resource not found: " + resource; assert false : "resource not found: " + resource;
} }

View File

@ -24,15 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.jclouds.encryption.internal.JCEEncryptionService; import org.jclouds.encryption.internal.JCEEncryptionService;
@ -44,35 +36,27 @@ import com.google.inject.ImplementedBy;
*/ */
@ImplementedBy(JCEEncryptionService.class) @ImplementedBy(JCEEncryptionService.class)
public interface EncryptionService { public interface EncryptionService {
String base64(byte[] toEncode);
String toHexString(byte[] raw); byte[] fromBase64(String encoded);
byte[] fromHexString(String hex); String hex(byte[] toEncode);
String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, byte[] fromHex(String encoded);
NoSuchProviderException, InvalidKeyException;
String sha1Base64(InputStream toEncode) throws NoSuchAlgorithmException, NoSuchProviderException, byte[] rsaSign(String toSign, Key privateKey);
InvalidKeyException;
String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, byte[] hmacSha256(String toEncode, byte[] key);
NoSuchProviderException, InvalidKeyException;
String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException, byte[] hmacSha1(String toEncode, byte[] key);
InvalidKeyException, UnsupportedEncodingException;
String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException, byte[] sha1(InputStream toEncode);
InvalidKeyException;
byte[] md5(byte[] plainBytes); byte[] sha256(InputStream toEncode);
byte[] md5(InputStream toEncode); byte[] md5(InputStream toEncode);
String toBase64String(byte[] resBuf); MD5InputStreamResult md5Result(InputStream toEncode);
byte[] md5(Object data);
MD5InputStreamResult generateMD5Result(InputStream toEncode);
MD5OutputStream md5OutputStream(OutputStream out); MD5OutputStream md5OutputStream(OutputStream out);
@ -89,19 +73,13 @@ public interface EncryptionService {
public final byte[] md5; public final byte[] md5;
public final long length; public final long length;
public MD5InputStreamResult(byte[] data, byte[] eTag, long length) { public MD5InputStreamResult(byte[] data, byte[] md5, long length) {
this.data = checkNotNull(data, "data"); this.data = checkNotNull(data, "data");
this.md5 = checkNotNull(eTag, "eTag"); this.md5 = checkNotNull(md5, "md5");
checkArgument(length >= 0, "length cannot me negative"); checkArgument(length >= 0, "length cannot me negative");
this.length = length; this.length = length;
} }
} }
byte[] fromBase64String(String encoded);
byte[] rsaPrivateEncrypt(String toSign, Key privateKey) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException;
} }

View File

@ -18,22 +18,10 @@
*/ */
package org.jclouds.encryption.internal; package org.jclouds.encryption.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.jclouds.encryption.EncryptionService; import org.jclouds.encryption.EncryptionService;
import com.google.common.base.Throwables;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -44,7 +32,8 @@ public abstract class BaseEncryptionService implements EncryptionService {
(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
(byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
public String toHexString(byte[] raw) { @Override
public String hex(byte[] raw) {
byte[] hex = new byte[2 * raw.length]; byte[] hex = new byte[2 * raw.length];
int index = 0; int index = 0;
@ -60,7 +49,8 @@ public abstract class BaseEncryptionService implements EncryptionService {
} }
} }
public byte[] fromHexString(String hex) { @Override
public byte[] fromHex(String hex) {
if (hex.startsWith("0x")) if (hex.startsWith("0x"))
hex = hex.substring(2); hex = hex.substring(2);
byte[] bytes = new byte[hex.length() / 2]; byte[] bytes = new byte[hex.length() / 2];
@ -70,42 +60,4 @@ public abstract class BaseEncryptionService implements EncryptionService {
return bytes; return bytes;
} }
public String md5Hex(byte[] toEncode) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, UnsupportedEncodingException {
byte[] resBuf = md5(toEncode);
return toHexString(resBuf);
}
public String md5Base64(byte[] toEncode) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException {
byte[] resBuf = md5(toEncode);
return toBase64String(resBuf);
}
/**
* @throws IOException
*/
public byte[] md5(Object data) {
checkNotNull(data, "data must be set before calling generateETag()");
byte[] md5 = null;
if (data == null) {
} else if (data instanceof byte[]) {
md5 = md5((byte[]) data);
} else if (data instanceof String) {
md5 = md5(((String) data).getBytes());
} else if (data instanceof File) {
try {
md5 = md5(new FileInputStream((File) data));
} catch (FileNotFoundException e) {
Throwables.propagate(e);
}
} else if (data instanceof InputStream) {
md5 = md5(((InputStream) data));
} else {
throw new UnsupportedOperationException("Content not supported " + data.getClass());
}
return md5;
}
} }

View File

@ -27,15 +27,12 @@ import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
/** /**
@ -44,14 +41,14 @@ import com.google.common.io.Closeables;
*/ */
public class JCEEncryptionService extends BaseEncryptionService { public class JCEEncryptionService extends BaseEncryptionService {
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, @Override
NoSuchProviderException, InvalidKeyException { public byte[] hmacSha256(String toEncode, byte[] key) {
return hmacBase64(toEncode, key, "HmacSHA256"); return hmac(toEncode, key, "HmacSHA256");
} }
private String hmacBase64(String toEncode, byte[] key, String algorithm) { @Override
byte[] resBuf = hmac(toEncode, key, algorithm); public byte[] hmacSha1(String toEncode, byte[] key) {
return toBase64String(resBuf); return hmac(toEncode, key, "HmacSHA1");
} }
public byte[] hmac(String toEncode, byte[] key, String algorithm) { public byte[] hmac(String toEncode, byte[] key, String algorithm) {
@ -71,17 +68,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
return mac.doFinal(toEncode.getBytes()); return mac.doFinal(toEncode.getBytes());
} }
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, @Override
NoSuchProviderException, InvalidKeyException {
return hmacBase64(toEncode, key, "HmacSHA1");
}
public byte[] md5(byte[] plainBytes) {
MessageDigest eTag = getDigest();
eTag.update(plainBytes, 0, plainBytes.length);
return eTag.digest();
}
public byte[] md5(InputStream toEncode) { public byte[] md5(InputStream toEncode) {
MessageDigest eTag = getDigest(); MessageDigest eTag = getDigest();
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
@ -101,11 +88,18 @@ public class JCEEncryptionService extends BaseEncryptionService {
return eTag.digest(); return eTag.digest();
} }
public String toBase64String(byte[] resBuf) { @Override
public String base64(byte[] resBuf) {
return Base64.encodeBytes(resBuf, Base64.DONT_BREAK_LINES); return Base64.encodeBytes(resBuf, Base64.DONT_BREAK_LINES);
} }
public MD5InputStreamResult generateMD5Result(InputStream toEncode) { @Override
public byte[] fromBase64(String encoded) {
return Base64.decode(encoded);
}
@Override
public MD5InputStreamResult md5Result(InputStream toEncode) {
MessageDigest eTag = getDigest(); MessageDigest eTag = getDigest();
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -129,7 +123,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
return new MD5InputStreamResult(out.toByteArray(), eTag.digest(), length); return new MD5InputStreamResult(out.toByteArray(), eTag.digest(), length);
} }
public static MessageDigest getDigest() { private static MessageDigest getDigest() {
MessageDigest eTag; MessageDigest eTag;
try { try {
eTag = MessageDigest.getInstance("MD5"); eTag = MessageDigest.getInstance("MD5");
@ -139,16 +133,12 @@ public class JCEEncryptionService extends BaseEncryptionService {
return eTag; return eTag;
} }
public byte[] fromBase64String(String encoded) {
return Base64.decode(encoded);
}
@Override @Override
public MD5OutputStream md5OutputStream(OutputStream out) { public MD5OutputStream md5OutputStream(OutputStream out) {
return new JCEMD5OutputStream(out); return new JCEMD5OutputStream(out);
} }
public static class JCEMD5OutputStream extends MD5OutputStream { private static class JCEMD5OutputStream extends MD5OutputStream {
public JCEMD5OutputStream(OutputStream out) { public JCEMD5OutputStream(OutputStream out) {
super(new DigestOutputStream(out, getDigest())); super(new DigestOutputStream(out, getDigest()));
} }
@ -161,9 +151,23 @@ public class JCEEncryptionService extends BaseEncryptionService {
} }
@Override @Override
public String sha1Base64(InputStream plainBytes) throws NoSuchAlgorithmException, public byte[] sha1(InputStream plainBytes) {
NoSuchProviderException, InvalidKeyException { return digest(plainBytes, "SHA1");
MessageDigest sha1 = MessageDigest.getInstance("SHA1"); }
@Override
public byte[] sha256(InputStream plainBytes) {
return digest(plainBytes, "SHA256");
}
private byte[] digest(InputStream plainBytes, String algorithm) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e1) {
Throwables.propagate(e1);
return null;
}
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
long length = 0; long length = 0;
int numRead = -1; int numRead = -1;
@ -172,7 +176,7 @@ public class JCEEncryptionService extends BaseEncryptionService {
numRead = plainBytes.read(buffer); numRead = plainBytes.read(buffer);
if (numRead > 0) { if (numRead > 0) {
length += numRead; length += numRead;
sha1.update(buffer, 0, numRead); digest.update(buffer, 0, numRead);
} }
} while (numRead != -1); } while (numRead != -1);
} catch (IOException e) { } catch (IOException e) {
@ -181,15 +185,20 @@ public class JCEEncryptionService extends BaseEncryptionService {
Closeables.closeQuietly(plainBytes); Closeables.closeQuietly(plainBytes);
} }
return toBase64String(sha1.digest()); return digest.digest();
} }
@Override @Override
public byte[] rsaPrivateEncrypt(String toSign, Key key) throws NoSuchAlgorithmException, public byte[] rsaSign(String toSign, Key key) {
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, Cipher cipher;
BadPaddingException { try {
Cipher cipher = Cipher.getInstance("RSA"); cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key); cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(toSign.getBytes()); return cipher.doFinal(toSign.getBytes());
} catch (Exception e) {
Throwables.propagate(e);
return null;
} }
}
} }

View File

@ -54,9 +54,8 @@ public class BasicAuthentication implements HttpRequestFilter {
@Named(PROPERTY_CREDENTIAL) String password, EncryptionService encryptionService) @Named(PROPERTY_CREDENTIAL) String password, EncryptionService encryptionService)
throws UnsupportedEncodingException { throws UnsupportedEncodingException {
this.credentialList = ImmutableSet.of("Basic " this.credentialList = ImmutableSet.of("Basic "
+ encryptionService.toBase64String(String.format("%s:%s", + encryptionService.base64(String.format("%s:%s", checkNotNull(user, "user"),
checkNotNull(user, "user"), checkNotNull(password, "password")).getBytes( checkNotNull(password, "password")).getBytes("UTF-8")));
"UTF-8")));
} }
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {

View File

@ -31,7 +31,6 @@ import org.jclouds.encryption.EncryptionService.MD5InputStreamResult;
import org.jclouds.http.Payload; import org.jclouds.http.Payload;
import org.jclouds.http.PayloadEnclosing; import org.jclouds.http.PayloadEnclosing;
import org.jclouds.http.Payloads; import org.jclouds.http.Payloads;
import org.jclouds.http.payloads.InputStreamPayload;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
@ -55,14 +54,13 @@ public abstract class BasePayloadEnclosingImpl implements PayloadEnclosing {
@Override @Override
public void generateMD5() { public void generateMD5() {
checkState(payload != null, "payload"); checkState(payload != null, "payload");
if (payload instanceof InputStreamPayload) { if (!payload.isRepeatable()) {
MD5InputStreamResult result = encryptionService MD5InputStreamResult result = encryptionService.md5Result(payload.getInput());
.generateMD5Result(((InputStreamPayload) payload).getInput());
setContentMD5(result.md5); setContentMD5(result.md5);
setContentLength(result.length); setContentLength(result.length);
setPayload(result.data); setPayload(result.data);
} else { } else {
setContentMD5(encryptionService.md5(payload.getRawContent())); setContentMD5(encryptionService.md5(payload.getInput()));
} }
} }

View File

@ -20,6 +20,7 @@ package org.jclouds.encryption;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -84,7 +85,7 @@ public class EncryptionServiceTest extends PerformanceTest {
@Test(dataProvider = "hmacsha1") @Test(dataProvider = "hmacsha1")
public void testHmacSha1Base64(byte[] key, String message, String base64Digest) public void testHmacSha1Base64(byte[] key, String message, String base64Digest)
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
String b64 = encryptionService.hmacSha1Base64(message, key); String b64 = encryptionService.base64(encryptionService.hmacSha1(message, key));
assertEquals(b64, base64Digest); assertEquals(b64, base64Digest);
} }
@ -126,14 +127,15 @@ public class EncryptionServiceTest extends PerformanceTest {
@Test(dataProvider = "eTag") @Test(dataProvider = "eTag")
public void testMD5Digest(String message, String hexMD5Digest) throws NoSuchProviderException, public void testMD5Digest(String message, String hexMD5Digest) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException, IOException { NoSuchAlgorithmException, InvalidKeyException, IOException {
String b64 = encryptionService.md5Hex(message.getBytes()); String b64 = encryptionService.hex(encryptionService.md5(new ByteArrayInputStream(message
.getBytes())));
assertEquals(hexMD5Digest, b64); assertEquals(hexMD5Digest, b64);
MD5OutputStream outputStream = encryptionService.md5OutputStream(new ByteArrayOutputStream()); MD5OutputStream outputStream = encryptionService.md5OutputStream(new ByteArrayOutputStream());
ByteStreams.copy(ByteStreams.newInputStreamSupplier(message.getBytes()).getInput(), ByteStreams.copy(ByteStreams.newInputStreamSupplier(message.getBytes()).getInput(),
outputStream); outputStream);
assertEquals(encryptionService.fromHexString(hexMD5Digest), outputStream.getMD5()); assertEquals(encryptionService.fromHex(hexMD5Digest), outputStream.getMD5());
} }
@ -141,14 +143,14 @@ public class EncryptionServiceTest extends PerformanceTest {
String hex = "0001020408102040"; String hex = "0001020408102040";
public void testHexStringEncode() throws UnsupportedEncodingException { public void testHexStringEncode() throws UnsupportedEncodingException {
assertEquals(encryptionService.toHexString(bytes), hex); assertEquals(encryptionService.hex(bytes), hex);
} }
public void testHexStringDecode() throws UnsupportedEncodingException { public void testHexStringDecode() throws UnsupportedEncodingException {
assertEquals(encryptionService.fromHexString(hex), bytes); assertEquals(encryptionService.fromHex(hex), bytes);
} }
public void testHexStringDecodeOx() throws UnsupportedEncodingException { public void testHexStringDecodeOx() throws UnsupportedEncodingException {
assertEquals(encryptionService.fromHexString("0x" + hex), bytes); assertEquals(encryptionService.fromHex("0x" + hex), bytes);
} }
} }

View File

@ -29,11 +29,11 @@ import java.io.OutputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.encryption.internal.JCEEncryptionService;
import org.jclouds.http.options.GetOptions; import org.jclouds.http.options.GetOptions;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
@ -43,80 +43,77 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
/** /**
* Tests for functionality all HttpCommandExecutorServices must express. These * Tests for functionality all HttpCommandExecutorServices must express. These tests will operate
* tests will operate against an in-memory http engine, so as to ensure * against an in-memory http engine, so as to ensure end-to-end functionality works.
* end-to-end functionality works.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(threadPoolSize = 10, groups = "integration", sequential = true) @Test(threadPoolSize = 10, groups = "integration", sequential = true)
public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends BaseJettyTest {
BaseJettyTest {
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testRequestFilter() throws MalformedURLException, public void testRequestFilter() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.downloadFilter("", "filterme").trim(), "test"); assertEquals(client.downloadFilter("", "filterme").trim(), "test");
} }
// TODO: filtering redirect test // TODO: filtering redirect test
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetStringWithHeader() throws MalformedURLException, public void testGetStringWithHeader() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.download("", "test").trim(), "test"); assertEquals(client.download("", "test").trim(), "test");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetString() throws MalformedURLException, public void testGetString() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.download("").trim(), XML); assertEquals(client.download("").trim(), XML);
} }
@DataProvider(name = "gets") @DataProvider(name = "gets")
public Object[][] createData() { public Object[][] createData() {
return new Object[][] { { "object" }, { "/path" }, { "sp ace" }, return new Object[][] { { "object" }, { "/path" }, { "sp ace" }, { "unic₪de" },
{ "unic₪de" }, { "qu?stion" } }; { "qu?stion" } };
} }
@Test(invocationCount = 25, timeOut = 5000, dataProvider = "gets") @Test(invocationCount = 25, timeOut = 5000, dataProvider = "gets")
public void testGetStringSynch(String uri) throws MalformedURLException, public void testGetStringSynch(String uri) throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
// TODO why need trim? // TODO why need trim?
assertEquals(client.synch(uri).trim(), XML); assertEquals(client.synch(uri).trim(), XML);
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetException() throws MalformedURLException, public void testGetException() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.downloadException("", GetOptions.Builder.tail(1)) assertEquals(client.downloadException("", GetOptions.Builder.tail(1)).trim(), "foo");
.trim(), "foo");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetSynchException() throws MalformedURLException, public void testGetSynchException() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.synchException("", "").trim(), "foo"); assertEquals(client.synchException("", "").trim(), "foo");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetStringRedirect() throws MalformedURLException, public void testGetStringRedirect() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.download("redirect").trim(), XML2); assertEquals(client.download("redirect").trim(), XML2);
} }
@Test(invocationCount = 100, timeOut = 5000) @Test(invocationCount = 100, timeOut = 5000)
public void testGetBigFile() throws MalformedURLException, public void testGetBigFile() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(encryptionService.toBase64String(encryptionService assertEquals(
.md5(context.utils().http().get( encryptionService.base64(encryptionService.md5(context.utils().http().get(
URI.create(String.format("http://localhost:%d/%s", testPort, URI.create(String.format("http://localhost:%d/%s", testPort,
"101constitutions"))))), md5); "101constitutions"))))), md5);
} }
@Test(enabled = false, invocationCount = 25, timeOut = 5000) @Test(enabled = false, invocationCount = 25, timeOut = 5000)
public void testGetStringPermanentRedirect() throws MalformedURLException, public void testGetStringPermanentRedirect() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
// GetString get = factory.createGetString("permanentredirect"); // GetString get = factory.createGetString("permanentredirect");
// assert get != null; // assert get != null;
// client.submit(get); // client.submit(get);
@ -126,14 +123,14 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testPost() throws MalformedURLException, ExecutionException, public void testPost() throws MalformedURLException, ExecutionException, InterruptedException,
InterruptedException, TimeoutException { TimeoutException {
assertEquals(client.post("", "foo").trim(), "fooPOST"); assertEquals(client.post("", "foo").trim(), "fooPOST");
} }
@Test(invocationCount = 25, timeOut = 10000) @Test(invocationCount = 25, timeOut = 10000)
public void testPostAsInputStream() throws MalformedURLException, public void testPostAsInputStream() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
try { try {
assertEquals(client.postAsInputStream("", "foo").trim(), "fooPOST"); assertEquals(client.postAsInputStream("", "foo").trim(), "fooPOST");
} catch (Exception e) { } catch (Exception e) {
@ -142,8 +139,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
} }
/** /**
* Tests sending a big file to the server. Note: this is a heavy test, takes * Tests sending a big file to the server. Note: this is a heavy test, takes several minutes to
* several minutes to finish. * finish.
* *
* @throws java.io.IOException * @throws java.io.IOException
*/ */
@ -157,10 +154,14 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
f = File.createTempFile(filename, "tmp"); f = File.createTempFile(filename, "tmp");
f.deleteOnExit(); f.deleteOnExit();
long length = (long) (Runtime.getRuntime().freeMemory() * 1.1); long length = (long) (Runtime.getRuntime().freeMemory() * 1.1);
os = new BufferedOutputStream( os = new BufferedOutputStream(new FileOutputStream(f.getAbsolutePath()));
new FileOutputStream(f.getAbsolutePath())); MessageDigest eTag;
try {
eTag = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Could not find the MD5 algorithm", e);
}
MessageDigest eTag = JCEEncryptionService.getDigest();
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
try { try {
for (long i = 0; i < length; i++) { for (long i = 0; i < length; i++) {
@ -175,9 +176,8 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
} }
// upload and verify the response // upload and verify the response
assertEquals(client.postWithMd5("fileso", assertEquals(client.postWithMd5("fileso", this.encryptionService.base64(eTag.digest()),
this.encryptionService.toBase64String(eTag.digest()), f).trim(), f).trim(), "created");
"created");
} finally { } finally {
if (os != null) if (os != null)
@ -201,40 +201,39 @@ public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testPostBinder() throws MalformedURLException, public void testPostBinder() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.postJson("", "foo").trim(), "{\"key\":\"foo\"}POST"); assertEquals(client.postJson("", "foo").trim(), "{\"key\":\"foo\"}POST");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testPut() throws MalformedURLException, ExecutionException, public void testPut() throws MalformedURLException, ExecutionException, InterruptedException,
InterruptedException, TimeoutException { TimeoutException {
assertEquals(client.upload("", "foo").trim(), "fooPUT"); assertEquals(client.upload("", "foo").trim(), "fooPUT");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testPutRedirect() throws MalformedURLException, public void testPutRedirect() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.upload("redirect", "foo").trim(), "fooPUTREDIRECT"); assertEquals(client.upload("redirect", "foo").trim(), "fooPUTREDIRECT");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testKillRobotSlowly() throws MalformedURLException, public void testKillRobotSlowly() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.action("robot", "kill", assertEquals(client.action("robot", "kill", ImmutableMap.of("death", "slow")).trim(),
ImmutableMap.of("death", "slow")).trim(),
"robot->kill:{death=slow}"); "robot->kill:{death=slow}");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testHead() throws MalformedURLException, ExecutionException, public void testHead() throws MalformedURLException, ExecutionException, InterruptedException,
InterruptedException, TimeoutException { TimeoutException {
assert client.exists(""); assert client.exists("");
} }
@Test(invocationCount = 25, timeOut = 5000) @Test(invocationCount = 25, timeOut = 5000)
public void testGetAndParseSax() throws MalformedURLException, public void testGetAndParseSax() throws MalformedURLException, ExecutionException,
ExecutionException, InterruptedException, TimeoutException { InterruptedException, TimeoutException {
assertEquals(client.downloadAndParse(""), "whoppers"); assertEquals(client.downloadAndParse(""), "whoppers");
} }
} }

View File

@ -85,8 +85,8 @@ public abstract class BaseJettyTest {
encryptionService = Guice.createInjector().getInstance(EncryptionService.class); encryptionService = Guice.createInjector().getInstance(EncryptionService.class);
md5 = encryptionService.md5Base64(ByteStreams.toByteArray(oneHundredOneConstitutions md5 = encryptionService
.getInput())); .base64(encryptionService.md5(oneHundredOneConstitutions.getInput()));
Handler server1Handler = new AbstractHandler() { Handler server1Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, public void handle(String target, HttpServletRequest request,

View File

@ -65,7 +65,7 @@ public class WireLiveTest {
ByteStreams.copy(in, out); ByteStreams.copy(in, out);
byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray())); byte[] compare = encryptionService.md5(new ByteArrayInputStream(out.toByteArray()));
Thread.sleep(100); Thread.sleep(100);
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5, assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5)); sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
return null; return null;
@ -145,7 +145,7 @@ public class WireLiveTest {
InputStream in = wire.input(connection.getInputStream()); InputStream in = wire.input(connection.getInputStream());
byte[] compare = encryptionService.md5(in); byte[] compare = encryptionService.md5(in);
Thread.sleep(100); Thread.sleep(100);
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5, assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5)); sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
} }
@ -168,7 +168,7 @@ public class WireLiveTest {
InputStream in = wire.input(connection.getInputStream()); InputStream in = wire.input(connection.getInputStream());
byte[] compare = encryptionService.md5(in); byte[] compare = encryptionService.md5(in);
Thread.sleep(100); Thread.sleep(100);
assertEquals(encryptionService.toHexString(compare), checkNotNull(sysHttpStreamMd5, assertEquals(encryptionService.hex(compare), checkNotNull(sysHttpStreamMd5,
sysHttpStreamMd5)); sysHttpStreamMd5));
assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484); assertEquals(((BufferLogger) wire.getWireLog()).buff.toString().getBytes().length, 3331484);
} }

View File

@ -22,15 +22,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Digest;
@ -44,6 +38,7 @@ import org.bouncycastle.util.encoders.Base64;
import org.jclouds.encryption.internal.BaseEncryptionService; import org.jclouds.encryption.internal.BaseEncryptionService;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables; import com.google.common.io.Closeables;
/** /**
@ -52,15 +47,15 @@ import com.google.common.io.Closeables;
*/ */
@Singleton @Singleton
public class BouncyCastleEncryptionService extends BaseEncryptionService { public class BouncyCastleEncryptionService extends BaseEncryptionService {
public String hmacSha256Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException { @Override
Digest digest = new SHA256Digest(); public byte[] hmacSha256(String toEncode, byte[] key) {
return hmacBase64(toEncode, key, digest); return hmac(toEncode, key, new SHA256Digest());
} }
private String hmacBase64(String toEncode, byte[] key, Digest digest) { @Override
byte[] resBuf = hmac(toEncode, key, digest); public byte[] hmacSha1(String toEncode, byte[] key) {
return toBase64String(resBuf); return hmac(toEncode, key, new SHA1Digest());
} }
public byte[] hmac(String toEncode, byte[] key, Digest digest) { public byte[] hmac(String toEncode, byte[] key, Digest digest) {
@ -74,20 +69,7 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
return resBuf; return resBuf;
} }
public String hmacSha1Base64(String toEncode, byte[] key) throws NoSuchAlgorithmException, @Override
NoSuchProviderException, InvalidKeyException {
Digest digest = new SHA1Digest();
return hmacBase64(toEncode, key, digest);
}
public byte[] md5(byte[] plainBytes) {
MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()];
eTag.update(plainBytes, 0, plainBytes.length);
eTag.doFinal(resBuf, 0);
return resBuf;
}
public byte[] md5(InputStream toEncode) { public byte[] md5(InputStream toEncode) {
MD5Digest eTag = new MD5Digest(); MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()]; byte[] resBuf = new byte[eTag.getDigestSize()];
@ -109,11 +91,13 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
return resBuf; return resBuf;
} }
public String toBase64String(byte[] resBuf) { @Override
public String base64(byte[] resBuf) {
return new String(Base64.encode(resBuf)); return new String(Base64.encode(resBuf));
} }
public MD5InputStreamResult generateMD5Result(InputStream toEncode) { @Override
public MD5InputStreamResult md5Result(InputStream toEncode) {
MD5Digest eTag = new MD5Digest(); MD5Digest eTag = new MD5Digest();
byte[] resBuf = new byte[eTag.getDigestSize()]; byte[] resBuf = new byte[eTag.getDigestSize()];
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
@ -139,7 +123,8 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
return new MD5InputStreamResult(out.toByteArray(), resBuf, length); return new MD5InputStreamResult(out.toByteArray(), resBuf, length);
} }
public byte[] fromBase64String(String encoded) { @Override
public byte[] fromBase64(String encoded) {
return Base64.decode(encoded); return Base64.decode(encoded);
} }
@ -148,7 +133,7 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
return new BouncyCastleMD5OutputStream(out); return new BouncyCastleMD5OutputStream(out);
} }
public static class BouncyCastleMD5OutputStream extends MD5OutputStream { private static class BouncyCastleMD5OutputStream extends MD5OutputStream {
public BouncyCastleMD5OutputStream(OutputStream out) { public BouncyCastleMD5OutputStream(OutputStream out) {
super(new DigestOutputStream(out, new MD5Digest())); super(new DigestOutputStream(out, new MD5Digest()));
} }
@ -163,9 +148,16 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
} }
@Override @Override
public String sha1Base64(InputStream plainBytes) throws NoSuchAlgorithmException, public byte[] sha256(InputStream plainBytes) {
NoSuchProviderException, InvalidKeyException { return sha(plainBytes, new SHA256Digest());
Digest digest = new SHA1Digest(); }
@Override
public byte[] sha1(InputStream plainBytes) {
return sha(plainBytes, new SHA1Digest());
}
private byte[] sha(InputStream plainBytes, Digest digest) {
byte[] resBuf = new byte[digest.getDigestSize()]; byte[] resBuf = new byte[digest.getDigestSize()];
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
long length = 0; long length = 0;
@ -184,16 +176,20 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService {
Closeables.closeQuietly(plainBytes); Closeables.closeQuietly(plainBytes);
} }
digest.doFinal(resBuf, 0); digest.doFinal(resBuf, 0);
return toBase64String(resBuf); return resBuf;
} }
@Override @Override
public byte[] rsaPrivateEncrypt(String toSign, Key key) throws NoSuchAlgorithmException, public byte[] rsaSign(String toSign, Key key) {
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
BadPaddingException {
// TODO convert this to BC code // TODO convert this to BC code
try {
Cipher cipher = Cipher.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key); cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(toSign.getBytes()); return cipher.doFinal(toSign.getBytes());
} catch (Exception e) {
Throwables.propagate(e);
return null;
} }
}
} }

View File

@ -42,6 +42,7 @@ import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.Utils;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@ -95,7 +96,7 @@ public class SharedKeyLiteAuthentication implements HttpRequestFilter {
private String getMd5For(String stringToHash) { private String getMd5For(String stringToHash) {
try { try {
return encryptionService.md5Hex(stringToHash.getBytes()); return encryptionService.hex(encryptionService.md5(Utils.toInputStream(stringToHash)));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -58,7 +58,7 @@ public class BindCFObjectToPayload extends BindBlobToPayloadAndUserMetadataToHea
super.bindToRequest(request, object2Blob.apply(object)); super.bindToRequest(request, object2Blob.apply(object));
if (object.getInfo().getHash() != null) { if (object.getInfo().getHash() != null) {
request.getHeaders().put(HttpHeaders.ETAG, request.getHeaders().put(HttpHeaders.ETAG,
encryptionService.toHexString(object.getInfo().getHash())); encryptionService.hex(object.getInfo().getHash()));
request.getHeaders().removeAll("Content-MD5"); request.getHeaders().removeAll("Content-MD5");
} }

View File

@ -54,7 +54,7 @@ public class ObjectToBlobMetadata implements Function<ObjectInfo, MutableBlobMet
if (from.getContentType() != null) if (from.getContentType() != null)
to.setContentType(from.getContentType()); to.setContentType(from.getContentType());
if (from.getHash() != null) if (from.getHash() != null)
to.setETag(encryptionService.toHexString(from.getHash())); to.setETag(encryptionService.hex(from.getHash()));
to.setName(from.getName()); to.setName(from.getName());
if (from.getBytes() != null) if (from.getBytes() != null)
to.setSize(from.getBytes()); to.setSize(from.getBytes());

View File

@ -56,7 +56,7 @@ public class ResourceToObjectInfo implements
to.setContentType("application/directory"); to.setContentType("application/directory");
} }
if (from.getETag() != null && to.getHash() == null) if (from.getETag() != null && to.getHash() == null)
to.setHash(encryptionService.fromHexString(from.getETag())); to.setHash(encryptionService.fromHex(from.getETag()));
to.setName(from.getName()); to.setName(from.getName());
to.setLastModified(from.getLastModified()); to.setLastModified(from.getLastModified());
if (from.getSize() != null) if (from.getSize() != null)

View File

@ -60,7 +60,7 @@ public class ParseObjectInfoFromHeaders implements
String eTagHeader = from.getFirstHeaderOrNull("Etag"); String eTagHeader = from.getFirstHeaderOrNull("Etag");
if (eTagHeader != null) { if (eTagHeader != null) {
String hashString = Utils.replaceAll(eTagHeader, '"', ""); String hashString = Utils.replaceAll(eTagHeader, '"', "");
to.setHash(encryptionService.fromHexString(hashString)); to.setHash(encryptionService.fromHex(hashString));
} }
return to; return to;
} }

View File

@ -82,7 +82,7 @@ public class ParseObjectInfoListFromJsonResponse extends ParseJson<PageSet<Objec
} }
public byte[] getHash() { public byte[] getHash() {
return encryptionService.fromHexString(hash); return encryptionService.fromHex(hash);
} }
public Date getLastModified() { public Date getLastModified() {

View File

@ -304,7 +304,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
CFObject object = newCFObject(data, key); CFObject object = newCFObject(data, key);
byte[] md5 = object.getInfo().getHash(); byte[] md5 = object.getInfo().getHash();
String newEtag = getApi().putObject(containerName, object); String newEtag = getApi().putObject(containerName, object);
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object assertEquals(encryptionService.hex(md5), encryptionService.hex(object
.getInfo().getHash())); .getInfo().getHash()));
// Test HEAD of missing object // Test HEAD of missing object
@ -316,9 +316,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// TODO assertEquals(metadata.getName(), object.getMetadata().getName()); // TODO assertEquals(metadata.getName(), object.getMetadata().getName());
assertEquals(metadata.getBytes(), new Long(data.length())); assertEquals(metadata.getBytes(), new Long(data.length()));
assertEquals(metadata.getContentType(), "text/plain"); assertEquals(metadata.getContentType(), "text/plain");
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(object assertEquals(encryptionService.hex(md5), encryptionService.hex(object
.getInfo().getHash())); .getInfo().getHash()));
assertEquals(metadata.getHash(), encryptionService.fromHexString(newEtag)); assertEquals(metadata.getHash(), encryptionService.fromHex(newEtag));
assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().entrySet().size(), 1);
assertEquals(metadata.getMetadata().get("metadata"), "metadata-value"); assertEquals(metadata.getMetadata().get("metadata"), "metadata-value");
@ -336,9 +336,9 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// TODO assertEquals(getBlob.getName(), object.getMetadata().getName()); // TODO assertEquals(getBlob.getName(), object.getMetadata().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length())); assertEquals(getBlob.getContentLength(), new Long(data.length()));
assertEquals(getBlob.getInfo().getContentType(), "text/plain"); assertEquals(getBlob.getInfo().getContentType(), "text/plain");
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob
.getInfo().getHash())); .getInfo().getHash()));
assertEquals(encryptionService.fromHexString(newEtag), getBlob.getInfo().getHash()); assertEquals(encryptionService.fromHex(newEtag), getBlob.getInfo().getHash());
assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2); assertEquals(getBlob.getInfo().getMetadata().entrySet().size(), 2);
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1"); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-1"), "value-1");
assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2"); assertEquals(getBlob.getInfo().getMetadata().get("new-metadata-2"), "value-2");
@ -346,7 +346,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// Test PUT with invalid ETag (as if object's data was corrupted in transit) // Test PUT with invalid ETag (as if object's data was corrupted in transit)
String correctEtag = newEtag; String correctEtag = newEtag;
String incorrectEtag = "0" + correctEtag.substring(1); String incorrectEtag = "0" + correctEtag.substring(1);
object.getInfo().setHash(encryptionService.fromHexString(incorrectEtag)); object.getInfo().setHash(encryptionService.fromHex(incorrectEtag));
try { try {
getApi().putObject(containerName, object); getApi().putObject(containerName, object);
} catch (HttpResponseException e) { } catch (HttpResponseException e) {
@ -359,7 +359,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
blob.getInfo().setName("chunked-object"); blob.getInfo().setName("chunked-object");
blob.setPayload(bais); blob.setPayload(bais);
newEtag = getApi().putObject(containerName, blob); newEtag = getApi().putObject(containerName, blob);
assertEquals(encryptionService.toHexString(md5), encryptionService.toHexString(getBlob assertEquals(encryptionService.hex(md5), encryptionService.hex(getBlob
.getInfo().getHash())); .getInfo().getHash()));
// Test GET with options // Test GET with options
@ -374,7 +374,7 @@ public class CloudFilesClientLiveTest extends BaseBlobStoreIntegrationTest {
// Matching ETag // Matching ETag
getBlob = getApi().getObject(containerName, object.getInfo().getName(), getBlob = getApi().getObject(containerName, object.getInfo().getName(),
GetOptions.Builder.ifETagMatches(newEtag)); GetOptions.Builder.ifETagMatches(newEtag));
assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHexString(newEtag)); assertEquals(getBlob.getInfo().getHash(), encryptionService.fromHex(newEtag));
getBlob = getApi().getObject(containerName, object.getInfo().getName(), getBlob = getApi().getObject(containerName, object.getInfo().getName(),
GetOptions.Builder.startAt(8)); GetOptions.Builder.startAt(8));
assertEquals(Utils.toStringAndClose(getBlob.getContent()), data.substring(8)); assertEquals(Utils.toStringAndClose(getBlob.getContent()), data.substring(8));