keycloak-uncached

fix incorrect JWS implementation

11/12/2014 12:28:35 AM

Details

diff --git a/core/src/main/java/org/keycloak/jose/jws/crypto/HMACProvider.java b/core/src/main/java/org/keycloak/jose/jws/crypto/HMACProvider.java
index f73f14e..4772280 100755
--- a/core/src/main/java/org/keycloak/jose/jws/crypto/HMACProvider.java
+++ b/core/src/main/java/org/keycloak/jose/jws/crypto/HMACProvider.java
@@ -74,7 +74,7 @@ public class HMACProvider {
 
     public static boolean verify(JWSInput input, byte[] sharedSecret) {
         try {
-            byte[] signature = sign(input.getContent(), input.getHeader().getAlgorithm(), sharedSecret);
+            byte[] signature = sign(input.getEncodedSignatureInput().getBytes("UTF-8"), input.getHeader().getAlgorithm(), sharedSecret);
             String x = Base64Url.encode(signature);
             return x.equals(input.getEncodedSignature());
         } catch (Exception e) {
diff --git a/core/src/main/java/org/keycloak/jose/jws/crypto/RSAProvider.java b/core/src/main/java/org/keycloak/jose/jws/crypto/RSAProvider.java
index 151d354..42baccf 100755
--- a/core/src/main/java/org/keycloak/jose/jws/crypto/RSAProvider.java
+++ b/core/src/main/java/org/keycloak/jose/jws/crypto/RSAProvider.java
@@ -49,7 +49,7 @@ public class RSAProvider {
         try {
             Signature verifier = getSignature(input.getHeader().getAlgorithm());
             verifier.initVerify(publicKey);
-            verifier.update(input.getContent());
+            verifier.update(input.getEncodedSignatureInput().getBytes("UTF-8"));
             return verifier.verify(input.getSignature());
         } catch (Exception e) {
             throw new RuntimeException(e);
diff --git a/core/src/main/java/org/keycloak/jose/jws/JWSBuilder.java b/core/src/main/java/org/keycloak/jose/jws/JWSBuilder.java
index 32490f7..3ef2d83 100755
--- a/core/src/main/java/org/keycloak/jose/jws/JWSBuilder.java
+++ b/core/src/main/java/org/keycloak/jose/jws/JWSBuilder.java
@@ -58,81 +58,148 @@ public class JWSBuilder {
         }
     }
 
-    protected String encode(Algorithm alg, byte[] data, byte[] signature) {
-        StringBuffer encoding = new StringBuffer();
-        encoding.append(encodeHeader(alg));
-        encoding.append('.');
-        encoding.append(Base64Url.encode(data));
+    protected String encodeAll(StringBuffer encoding, byte[] signature) {
         encoding.append('.');
-        if (alg != Algorithm.none) {
+        if (signature != null) {
             encoding.append(Base64Url.encode(signature));
         }
         return encoding.toString();
     }
 
+    protected void encode(Algorithm alg, byte[] data, StringBuffer encoding) {
+        encoding.append(encodeHeader(alg));
+        encoding.append('.');
+        encoding.append(Base64Url.encode(data));
+    }
+
     protected byte[] marshalContent() {
         return contentBytes;
     }
 
     public class EncodingBuilder {
         public String none() {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            return encode(Algorithm.none, data, null);
+            encode(Algorithm.none, data, buffer);
+            return encodeAll(buffer, null);
         }
 
         public String rsa256(PrivateKey privateKey) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = RSAProvider.sign(data, Algorithm.RS256, privateKey);
-            return encode(Algorithm.RS256, data, signature);
+            encode(Algorithm.RS256, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS256, privateKey);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String rsa384(PrivateKey privateKey) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = RSAProvider.sign(data, Algorithm.RS384, privateKey);
-            return encode(Algorithm.RS384, data, signature);
+            encode(Algorithm.RS384, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS384, privateKey);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String rsa512(PrivateKey privateKey) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = RSAProvider.sign(data, Algorithm.RS512, privateKey);
-            return encode(Algorithm.RS512, data, signature);
+            encode(Algorithm.RS512, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS512, privateKey);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
 
         public String hmac256(byte[] sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS256, sharedSecret);
-            return encode(Algorithm.HS256, data, signature);
+            encode(Algorithm.HS256, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS256, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String hmac384(byte[] sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS384, sharedSecret);
-            return encode(Algorithm.HS384, data, signature);
+            encode(Algorithm.HS384, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS384, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String hmac512(byte[] sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS512, sharedSecret);
-            return encode(Algorithm.HS512, data, signature);
+            encode(Algorithm.HS512, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS512, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String hmac256(SecretKey sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS256, sharedSecret);
-            return encode(Algorithm.HS256, data, signature);
+            encode(Algorithm.HS256, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS256, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String hmac384(SecretKey sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS384, sharedSecret);
-            return encode(Algorithm.HS384, data, signature);
+            encode(Algorithm.HS384, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS384, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
 
         public String hmac512(SecretKey sharedSecret) {
+            StringBuffer buffer = new StringBuffer();
             byte[] data = marshalContent();
-            byte[] signature = HMACProvider.sign(data, Algorithm.HS512, sharedSecret);
-            return encode(Algorithm.HS512, data, signature);
+            encode(Algorithm.HS512, data, buffer);
+            byte[] signature = null;
+            try {
+                signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS512, sharedSecret);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+            return encodeAll(buffer, signature);
         }
     }
 }
diff --git a/core/src/main/java/org/keycloak/jose/jws/JWSInput.java b/core/src/main/java/org/keycloak/jose/jws/JWSInput.java
index f86151f..6db10fa 100755
--- a/core/src/main/java/org/keycloak/jose/jws/JWSInput.java
+++ b/core/src/main/java/org/keycloak/jose/jws/JWSInput.java
@@ -15,6 +15,7 @@ public class JWSInput {
     String encodedHeader;
     String encodedContent;
     String encodedSignature;
+    String encodedSignatureInput;
     JWSHeader header;
     byte[] content;
     byte[] signature;
@@ -26,6 +27,7 @@ public class JWSInput {
         if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error");
         encodedHeader = parts[0];
         encodedContent = parts[1];
+        encodedSignatureInput = encodedHeader + '.' + encodedContent;
         try {
             content = Base64Url.decode(encodedContent);
             if (parts.length > 2) {
@@ -55,6 +57,9 @@ public class JWSInput {
     public String getEncodedSignature() {
         return encodedSignature;
     }
+    public String getEncodedSignatureInput() {
+        return encodedSignatureInput;
+    }
 
     public JWSHeader getHeader() {
         return header;