You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2012/01/06 08:07:57 UTC
svn commit: r1227991 - in /abdera/abdera2:
activities/src/main/java/org/apache/abdera2/activities/extra/
common/src/main/java/org/apache/abdera2/common/http/
common/src/main/java/org/apache/abdera2/common/iri/
common/src/main/java/org/apache/abdera2/co...
Author: jmsnell
Date: Fri Jan 6 07:07:57 2012
New Revision: 1227991
URL: http://svn.apache.org/viewvc?rev=1227991&view=rev
Log:
a few fixes and experimental items...
Added:
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java (with props)
Modified:
abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ClientSecrets.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/iri/IRI.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/security/HashHelper.java
Modified: abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ClientSecrets.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ClientSecrets.java?rev=1227991&r1=1227990&r2=1227991&view=diff
==============================================================================
--- abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ClientSecrets.java (original)
+++ abdera/abdera2/activities/src/main/java/org/apache/abdera2/activities/extra/ClientSecrets.java Fri Jan 6 07:07:57 2012
@@ -70,6 +70,10 @@ public final class ClientSecrets extends
}
}
+ public boolean has(Type type) {
+ return has(type.label());
+ }
+
public ASBase getType(Type type) {
return has(type.label()) ? this.<ASBase>getProperty(type.label()) : null;
}
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java?rev=1227991&r1=1227990&r2=1227991&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java Fri Jan 6 07:07:57 2012
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -41,9 +42,11 @@ import org.apache.commons.codec.binary.B
import org.apache.commons.codec.binary.StringUtils;
import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
@@ -135,6 +138,18 @@ public class Authentication implements I
return new Authentication(this);
}
+ public Builder params(Map<String,String> map) {
+ params.putAll(map);
+ return this;
+ }
+
+ public Builder params(
+ Map<String,String> map,
+ Predicate<Map.Entry<String,String>> predicate) {
+ params.putAll(Maps.filterEntries(map, predicate));
+ return this;
+ }
+
public Builder param(String name, String val) {
params.put(name, val);
return this;
Added: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java?rev=1227991&view=auto
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java (added)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java Fri Jan 6 07:07:57 2012
@@ -0,0 +1,612 @@
+package org.apache.abdera2.common.http;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.abdera2.activities.extra.ClientSecrets;
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.abdera2.common.security.HashHelper;
+import org.apache.abdera2.common.text.CharUtils;
+import org.apache.abdera2.common.text.UrlEncoding;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.Hex;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * This is largely experimental... it implements a number of
+ * OAuth related Authentication header builders for OAuth 1.0,
+ * Bearer and MAC style WWW-Authenticate/Authorization headers
+ */
+public final class OAuthUtil {
+
+ private static final int NONCE_SIZE = ((23 * 5) / 8) + 1;
+ private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+ static final Predicate<Map.Entry<String,String>> is_oauth_param =
+ new Predicate<Map.Entry<String,String>>() {
+ public boolean apply(Entry<String, String> input) {
+ return input.getKey()
+ .toLowerCase(Locale.US)
+ .startsWith("oauth_") ||
+ input.getKey().equalsIgnoreCase("realm");
+ }
+ };
+
+ static long getTimestamp() {
+ return DateTimes.now().getMillis() / 1000;
+ }
+
+ static String getNonce() {
+ byte[] nonce = new byte[NONCE_SIZE];
+ SECURE_RANDOM.nextBytes(nonce);
+ return Hex.encodeHexString(nonce);
+ }
+
+ public static OAuth1HeaderBuilder makeOAuth1Header() {
+ return new OAuth1HeaderBuilder();
+ }
+
+ public static enum OAuth1SignatureMethod {
+ PLAINTEXT,
+ RSA_SHA1,
+ HMAC_SHA1;
+
+ public String label() {
+ return name().replace('_','-');
+ }
+ }
+
+ public static class OAuth1HeaderBuilder
+ implements Supplier<Authentication> {
+
+ private OAuth1SignatureMethod method;
+ private String httpMethod;
+ private IRI requestUri;
+ private PrivateKey sigKey;
+ private String consumer_secret;
+ private String token_secret;
+ private boolean include_additional = false;
+ private ImmutableMap.Builder<String,String> builder =
+ ImmutableMap.<String,String>builder()
+ .put("oauth_version", "1.0");
+
+ public OAuth1HeaderBuilder includeAdditional() {
+ this.include_additional = true;
+ return this;
+ }
+
+ public OAuth1HeaderBuilder doNotIncludeAdditional() {
+ this.include_additional = false;
+ return this;
+ }
+
+ public OAuth1HeaderBuilder consumerDetails(
+ ClientSecrets secrets,
+ ClientSecrets.Type type) {
+ checkNotNull(secrets);
+ if (secrets.has(type)) {
+ consumerKey(secrets.getClientId(type));
+ consumerSecret(secrets.getClientSecret(type));
+ }
+ return this;
+ }
+
+ public OAuth1HeaderBuilder consumerSecret(String secret) {
+ this.consumer_secret = secret;
+ return this;
+ }
+
+ public OAuth1HeaderBuilder tokenSecret(String secret) {
+ this.token_secret = secret;
+ return this;
+ }
+
+ private static final ImmutableSet<String> reserved =
+ ImmutableSet.of(
+ "realm",
+ "oauth_consumer_key",
+ "oauth_signature_method",
+ "oauth_signature",
+ "oauth_timestamp",
+ "oauth_nonce",
+ "oauth_version",
+ "oauth_token",
+ "oauth_token_secret",
+ "oauth_callback",
+ "oauth_consumer_secret");
+
+ public OAuth1HeaderBuilder additional(String key, String val) {
+ key = checkNotNull(key).toLowerCase(Locale.US);
+ checkArgument(!reserved.contains(key));
+ builder.put(key,val);
+ return this;
+ }
+
+ public OAuth1HeaderBuilder requestUri(IRI uri) {
+ this.requestUri = uri.base();
+ return this;
+ }
+
+ public OAuth1HeaderBuilder requestUri(String uri) {
+ return requestUri(new IRI(uri));
+ }
+
+ public OAuth1HeaderBuilder httpMethod(String method) {
+ this.httpMethod = method;
+ return this;
+ }
+
+ public OAuth1HeaderBuilder realm(String val) {
+ builder.put("realm", val);
+ return this;
+ }
+
+ public OAuth1HeaderBuilder consumerKey(String key) {
+ builder.put("oauth_consumer_key", key);
+ return this;
+ }
+
+ public OAuth1HeaderBuilder token(String token) {
+ builder.put("oauth_token", token);
+ return this;
+ }
+
+ public OAuth1HeaderBuilder plainText() {
+ this.method = OAuth1SignatureMethod.PLAINTEXT;
+ return signatureMethod(this.method.label());
+ }
+
+ public OAuth1HeaderBuilder hmacSha1() {
+ this.method = OAuth1SignatureMethod.HMAC_SHA1;
+ return signatureMethod(this.method.label());
+ }
+
+ public OAuth1HeaderBuilder rsaSha1(PrivateKey key) {
+ this.sigKey = key;
+ this.method = OAuth1SignatureMethod.RSA_SHA1;
+ return signatureMethod(this.method.label());
+ }
+
+ private OAuth1HeaderBuilder signatureMethod(String method) {
+ builder.put("oauth_signature_method", method);
+ return this;
+ }
+
+ public OAuth1HeaderBuilder timestampNow() {
+ return timestamp(getTimestamp());
+ }
+
+ public OAuth1HeaderBuilder timestamp(long timestamp) {
+ builder.put("oauth_timestamp", Long.toString(timestamp));
+ return this;
+ }
+
+ public OAuth1HeaderBuilder nonce() {
+ return nonce(getNonce());
+ }
+
+ public OAuth1HeaderBuilder nonce(String nonce) {
+ builder.put("oauth_nonce", nonce);
+ return this;
+ }
+
+ public Authentication getPlaintext() {
+ return plainText().get();
+ }
+
+ public Authentication getHmacSha1() {
+ return hmacSha1().get();
+ }
+
+ public Authentication getRsaSha1(PrivateKey key) {
+ return rsaSha1(key).get();
+ }
+
+ public Authentication get() {
+ ImmutableMap<String,String> map =
+ this.builder.build();
+ String signature = null;
+ if (method != null) {
+ switch(method) {
+ case PLAINTEXT:
+ signature = generatePlainTextSignature(map);
+ break;
+ case HMAC_SHA1:
+ byte[] base = generateSignatureBaseString(httpMethod,requestUri,map);
+ signature = hmac(hmacKey(consumer_secret,token_secret), base);
+ break;
+ case RSA_SHA1:
+ base = generateSignatureBaseString(httpMethod,requestUri,map);
+ signature = HashHelper.sig(sigKey, "SHA1withRSA", base);
+ break;
+ }
+ }
+ Authentication.Builder builder =
+ Authentication.make()
+ .scheme("OAuth");
+ if (include_additional)
+ builder.params(map);
+ else
+ builder.params(map, is_oauth_param);
+ if (signature != null)
+ builder.param("oauth_signature", signature);
+ return builder.get();
+ }
+
+ private String hmac(Key key, byte[] mat) {
+ try {
+ Mac mac = Mac.getInstance("HmacSha1");
+ mac.init(key);
+ mac.update(mat,0,mat.length);
+ byte[] sig = mac.doFinal();
+ return escaped(Base64.encodeBase64String(sig));
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+
+ private Key hmacKey(String consumer_secret, String token_secret) {
+ try {
+ return new SecretKeySpec(new StringBuilder()
+ .append(consumer_secret!=null?escaped(consumer_secret):"")
+ .append('&')
+ .append(token_secret!=null?escaped(token_secret):"")
+ .toString().getBytes("UTF-8"),"HmacSha1");
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+
+ private String escaped(String val) {
+ return UrlEncoding.encode(val, CharUtils.Profile.UNRESERVED);
+ }
+
+ private byte[] generateSignatureBaseString(
+ String method,
+ IRI request_uri,
+ ImmutableMap<String,String> map) {
+ try {
+ return new StringBuilder()
+ .append(checkNotNull(method).toUpperCase(Locale.US))
+ .append('&')
+ .append(escaped(checkNotNull(request_uri).toASCIIString()))
+ .append('&')
+ .append(generateSignatureBaseString2(map))
+ .toString().getBytes("UTF-8");
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+
+ private String generateSignatureBaseString2(
+ ImmutableMap<String,String> unsorted) {
+ TreeMap<String,String> map = Maps.newTreeMap();
+ map.putAll(unsorted);
+ StringBuilder buf = new StringBuilder();
+ boolean first = true;
+ for (Map.Entry<String,String> entry : map.entrySet()) {
+ if (!first) buf.append('&');
+ else first = false;
+ buf.append(entry.getKey());
+ buf.append('=');
+ buf.append(entry.getValue());
+ }
+ return escaped(buf.toString());
+ }
+
+ private String generatePlainTextSignature(ImmutableMap<String,String> map) {
+ StringBuilder buf = new StringBuilder();
+ buf.append(consumer_secret != null ? consumer_secret : "");
+ buf.append('&');
+ buf.append(map.containsKey("oauth_token") ? map.get("oauth_token") : "");
+ return escaped(buf.toString());
+ }
+ }
+
+ static final Joiner space_joiner =
+ Joiner.on(' ');
+
+ public static enum BearerErrorCode {
+ INVALID_REQUEST,
+ INVALID_TOKEN,
+ INSUFFICIENT_SCOPE;
+ private final String label;
+ BearerErrorCode() {
+ this.label = name().toLowerCase(Locale.US);
+ }
+ public String label() {
+ return label;
+ }
+ }
+
+ public static BearerBuilder makeBearerHeader() {
+ return new BearerBuilder();
+ }
+
+ public static final class BearerBuilder
+ implements Supplier<Authentication> {
+
+ private final Authentication.Builder builder =
+ Authentication.make().scheme("bearer")
+ .quoted("error")
+ .quoted("error-desc");
+
+ private static final ImmutableSet<String> reserved =
+ ImmutableSet.of(
+ "realm",
+ "scope",
+ "error",
+ "error-desc",
+ "error-uri");
+
+ public BearerBuilder param(String name, String val) {
+ name = checkNotNull(name).toLowerCase(Locale.US);
+ checkArgument(!reserved.contains(name));
+ builder.param(name, val);
+ return this;
+ }
+
+ public BearerBuilder params(Map<String,String> map) {
+ for (Map.Entry<String, String> entry : map.entrySet())
+ param(entry.getKey(),entry.getValue());
+ return this;
+ }
+
+ public BearerBuilder token(String token) {
+ builder.b64token(token);
+ return this;
+ }
+
+ public BearerBuilder realm(String realm) {
+ builder.param("realm", realm);
+ return this;
+ }
+
+ public BearerBuilder scope(String... scopes) {
+ builder.param("scope", space_joiner.join(scopes));
+ return this;
+ }
+
+ public BearerBuilder error(BearerErrorCode code) {
+ builder.param("error", code.label());
+ return this;
+ }
+
+ public BearerBuilder errorDescription(String description) {
+ builder.param("error_description", description);
+ return this;
+ }
+
+ public BearerBuilder errorUri(IRI uri) {
+ builder.param("error-uri", uri.toASCIIString());
+ return this;
+ }
+
+ public BearerBuilder errorUri(String uri) {
+ return errorUri(new IRI(uri));
+ }
+
+ public Authentication get() {
+ return builder.get();
+ }
+ }
+
+ public static MacBuilder makeMacHeader() {
+ return new MacBuilder();
+ }
+
+ public static enum MacAlgorithm {
+ HMAC_SHA1("hmac-sha-1","HmacSha1"),
+ HMAC_SHA256("hmac-sha-256","HmacSha256");
+ private final String label;
+ private final String alg;
+ MacAlgorithm(String label,String alg) {
+ this.label = label;
+ this.alg = alg;
+ }
+ public String alg() {
+ return alg;
+ }
+ public String label() {
+ return label;
+ }
+ public static MacAlgorithm get(String label) {
+ for (MacAlgorithm alg : MacAlgorithm.values())
+ if (alg.label().equalsIgnoreCase(label))
+ return alg;
+ return null;
+ }
+ }
+
+ public static final class MacBuilder
+ implements Supplier<Authentication> {
+
+ private String key_id;
+ private String key;
+ private MacAlgorithm algorithm = MacAlgorithm.HMAC_SHA1;
+ private DateTime issueTime = DateTimes.now();
+ private long age = -1;
+ private String httpMethod = "GET";
+ private IRI request_uri;
+ private String host;
+ private int port;
+ private String bodyhash;
+ private String ext;
+ private String nonce;
+
+ public MacBuilder age(long age) {
+ this.age = Math.max(age,-1);
+ return this;
+ }
+
+ public MacBuilder nonce() {
+ this.nonce = getNonce();
+ return this;
+ }
+
+ public MacBuilder nonce(String nonce) {
+ this.nonce = nonce;
+ return this;
+ }
+
+ public MacBuilder bodyHash(String hash) {
+ this.bodyhash = hash;
+ return this;
+ }
+
+ public MacBuilder ext(String ext) {
+ this.ext = ext;
+ return this;
+ }
+
+ public MacBuilder id(String id) {
+ this.key_id = id;
+ return this;
+ }
+
+ public MacBuilder key(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public MacBuilder algorithm(MacAlgorithm alg) {
+ this.algorithm = alg;
+ return this;
+ }
+
+ public MacBuilder issueTime(DateTime issue) {
+ this.issueTime = issue;
+ return this;
+ }
+
+ public MacBuilder httpMethod(String method) {
+ this.httpMethod = method.toUpperCase(Locale.US);
+ return this;
+ }
+
+ public MacBuilder requestUri(IRI iri) {
+ this.request_uri = iri.relative();
+ host(iri);
+ port(iri.getScheme());
+ return this;
+ }
+
+ public MacBuilder requestUri(String iri) {
+ return requestUri(new IRI(iri));
+ }
+
+ public MacBuilder host(String host) {
+ if (Strings.isNullOrEmpty(host)) return this;
+ IRI h = new IRI(String.format("http://%s",host));
+ this.host = h.getASCIIHost().toLowerCase(Locale.US);
+ return this;
+ }
+
+ public MacBuilder host(IRI iri) {
+ return host(checkNotNull(iri).getASCIIHost());
+ }
+
+ private MacBuilder port(String scheme) {
+ if (scheme == null) port(0);
+ if ("http".equalsIgnoreCase(scheme)) port(80);
+ else if ("https".equalsIgnoreCase(scheme)) port(443);
+ else port(0);
+ return this;
+ }
+
+ public MacBuilder port(int port) {
+ this.port = Math.max(0, port);
+ return this;
+ }
+
+ public Authentication getHmacSha1(String key) {
+ return key(key).algorithm(MacAlgorithm.HMAC_SHA1).get();
+ }
+
+ public Authentication getHmacSha256(String key) {
+ return key(key).algorithm(MacAlgorithm.HMAC_SHA256).get();
+ }
+
+ public Authentication get() {
+ try {
+ String nonce = buildNonce();
+ byte[] mat = getNormalizedRequestString(nonce);
+ Key hmac = getkey(algorithm,key);
+ String mac = HashHelper.hmac(hmac, algorithm.alg(), mat);
+ Authentication.Builder builder =
+ Authentication.make()
+ .quoted("nonce")
+ .quoted("mac")
+ .quoted("body-hash")
+ .quoted("ext")
+ .quoted("id")
+ .scheme("mac")
+ .param("id", key_id)
+ .param("nonce", nonce)
+ .param("mac", mac);
+ if (!Strings.isNullOrEmpty(bodyhash))
+ builder.param("body-hash", bodyhash);
+ if (!Strings.isNullOrEmpty(ext))
+ builder.param("ext", ext);
+ return builder.get();
+ } catch (NullPointerException npe) {
+ return Authentication.make().scheme("mac").get();
+ }
+ }
+
+ private Key getkey(MacAlgorithm alg, String key) {
+ try {
+ return new SecretKeySpec(key.getBytes("UTF-8"),alg.alg());
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+
+ private byte[] getNormalizedRequestString(String nonce) {
+ try {
+ StringBuilder buf = new StringBuilder();
+ buf.append(nonce).append("\n");
+ buf.append(httpMethod != null ? httpMethod : "GET").append("\n");
+ buf.append(request_uri != null ? request_uri.toASCIIString() : "").append("\n");
+ buf.append(host != null ? host : "").append("\n");
+ buf.append(port > -1 ? port : 80).append("\n");
+ buf.append(bodyhash != null ? bodyhash : "").append("\n");
+ buf.append(ext != null ? ext : "").append("\n");
+ return buf.toString().getBytes("UTF-8");
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+
+ private String buildNonce() {
+ if (age < 0) {
+ DateTime now = DateTimes.now();
+ long now_millis = now.getMillis();
+ long then_millis = issueTime.getMillis();
+ age = (then_millis - now_millis) / 1000;
+ }
+ String n = nonce != null ? nonce : getNonce();
+ return String.format("%d:%s", age, n);
+ }
+ }
+}
Propchange: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/OAuthUtil.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/iri/IRI.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/iri/IRI.java?rev=1227991&r1=1227990&r2=1227991&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/iri/IRI.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/iri/IRI.java Fri Jan 6 07:07:57 2012
@@ -499,6 +499,25 @@ public final class IRI implements Serial
return resolve(this, new IRI(iri));
}
+ /**
+ * Returns the IRI without any query or fragment
+ */
+ public IRI base() {
+ String path = getPath();
+ return resolve(path!=null&&path.length()>0?path:"/");
+ }
+
+ public IRI relative() {
+ return new IRI(
+ null,
+ null,
+ null,
+ -1,
+ path,
+ query,
+ fragment);
+ }
+
public String toString() {
StringBuilder buf = new StringBuilder();
String scheme = getScheme();
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/security/HashHelper.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/security/HashHelper.java?rev=1227991&r1=1227990&r2=1227991&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/security/HashHelper.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/security/HashHelper.java Fri Jan 6 07:07:57 2012
@@ -141,7 +141,8 @@ public final class HashHelper {
try {
Mac mac = Mac.getInstance(alg);
mac.init(key);
- byte[] sig = mac.doFinal(mat);
+ mac.update(mat,0,mat.length);
+ byte[] sig = mac.doFinal();
return Base64.encodeBase64URLSafeString(sig);
} catch (Throwable t) {
throw ExceptionHelper.propogate(t);
@@ -245,6 +246,13 @@ public final class HashHelper {
}
}
+ public static Function<byte[],String> sha1(final Key key) {
+ return new Function<byte[],String>() {
+ public String apply(byte[] input) {
+ return new SHA1(key).update(input).get();
+ }
+ };
+ }
public static Function<byte[],String> sha256(final Key key) {
return new Function<byte[],String>() {
@@ -270,6 +278,12 @@ public final class HashHelper {
};
}
+ public static class SHA1 extends SHA {
+ public SHA1(Key key) {
+ super(key, "HmacSHA1");
+ }
+ }
+
public static class SHA256 extends SHA {
public SHA256(Key key) {
super(key, "HmacSHA256");