cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject [07/10] Changing the oauth2-jwt source folder to oauth2-jose
Date Fri, 19 Sep 2014 14:47:52 GMT
http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java
new file mode 100644
index 0000000..fed7e1f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.HmacUtils;
+
+public class HmacJwsSignatureVerifier implements JwsSignatureVerifier {
+    private byte[] key;
+    private AlgorithmParameterSpec hmacSpec;
+    
+    public HmacJwsSignatureVerifier(byte[] key) {
+        this(key, null);
+    }
+    public HmacJwsSignatureVerifier(byte[] key, AlgorithmParameterSpec spec) {
+        this.key = key;
+        this.hmacSpec = spec;
+    }
+    public HmacJwsSignatureVerifier(String encodedKey) {
+        try {
+            this.key = Base64UrlUtility.decode(encodedKey);
+        } catch (Base64Exception ex) {
+            throw new SecurityException();
+        }
+    }
+    
+    @Override
+    public boolean verify(JwtHeaders headers, String unsignedText, byte[] signature) {
+        byte[] expected = computeMac(headers, unsignedText);
+        return Arrays.equals(expected, signature);
+    }
+    
+    private byte[] computeMac(JwtHeaders headers, String text) {
+        return HmacUtils.computeHmac(key, 
+                                     Algorithm.toJavaName(headers.getAlgorithm()),
+                                     hmacSpec,
+                                     text);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java
new file mode 100644
index 0000000..422473f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersReader;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReader;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+
+public class JwsCompactConsumer {
+    private JwtHeadersReader reader = new JwtTokenReaderWriter();
+    private String encodedSequence;
+    private String encodedSignature;
+    private String headersJson;
+    private String jwsPayload;
+    private JwsSignatureProperties props;
+    public JwsCompactConsumer(String encodedJws) {
+        this(encodedJws, null, null);
+    }
+    public JwsCompactConsumer(String encodedJws, JwsSignatureProperties props) {
+        this(encodedJws, props, null);
+    }
+    public JwsCompactConsumer(String encodedJws, JwtTokenReader r) {
+        this(encodedJws, null, r);
+    }
+    public JwsCompactConsumer(String encodedJws, JwsSignatureProperties props, JwtHeadersReader r) {
+        if (r != null) {
+            this.reader = r;
+        }
+        this.props = props;
+        String[] parts = encodedJws.split("\\.");
+        if (parts.length != 3) {
+            if (parts.length == 2 && encodedJws.endsWith(".")) {
+                encodedSignature = "";
+            } else {
+                throw new OAuthServiceException("Invalid JWS Compact sequence");
+            }
+        } else {
+            encodedSignature = parts[2];
+        }
+        headersJson = decodeToString(parts[0]);
+        jwsPayload = decodeToString(parts[1]);
+        encodedSequence = parts[0] + "." + parts[1];
+        
+    }
+    public String getUnsignedEncodedPayload() {
+        return encodedSequence;
+    }
+    public String getEncodedSignature() {
+        return encodedSignature;
+    }
+    public String getDecodedJsonHeaders() {
+        return headersJson;
+    }
+    public String getDecodedJwsPayload() {
+        return jwsPayload;
+    }
+    public byte[] getDecodedJwsPayloadBytes() {
+        try {
+            return jwsPayload.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    public byte[] getDecodedSignature() {
+        return encodedSignature.isEmpty() ? new byte[]{} : decode(encodedSignature);
+    }
+    public JwtHeaders getJwtHeaders() {
+        return getReader().fromJsonHeaders(headersJson);
+    }
+    public boolean verifySignatureWith(JwsSignatureVerifier validator) {
+        enforceJweSignatureProperties();
+        if (!validator.verify(getJwtHeaders(), getUnsignedEncodedPayload(), getDecodedSignature())) {
+            throw new SecurityException();
+        }
+        return true;
+    }
+    private void enforceJweSignatureProperties() {
+        if (props != null) {
+            //TODO:
+        }
+    }
+    private static String decodeToString(String encoded) {
+        try {
+            return new String(decode(encoded), "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new SecurityException(ex);
+        }
+        
+    }
+    protected JwtHeadersReader getReader() {
+        return reader;
+    }
+    private static byte[] decode(String encoded) {
+        try {
+            return Base64UrlUtility.decode(encoded);
+        } catch (Base64Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java
new file mode 100644
index 0000000..ef4dd52
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.rs.security.jose.jwt.JwtConstants;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+
+public class JwsCompactProducer {
+    private JwtHeadersWriter writer = new JwtTokenReaderWriter();
+    private JwtHeaders headers;
+    private String plainJwsPayload;
+    private String signature;
+    private String plainRep;
+    
+    public JwsCompactProducer(String plainJwsPayload) {
+        this(null, null, plainJwsPayload);
+    }
+    public JwsCompactProducer(JwtHeaders headers, String plainJwsPayload) {
+        this(headers, null, plainJwsPayload);
+    }
+    public JwsCompactProducer(JwtHeaders headers, JwtHeadersWriter w, String plainJwsPayload) {
+        this.headers = headers;
+        if (w != null) {
+            this.writer = w;
+        }
+        this.plainJwsPayload = plainJwsPayload;
+    }
+    public JwtHeaders getHeaders() {
+        if (headers == null) {
+            headers = new JwtHeaders();
+        }
+        return headers;
+    }
+    public String getUnsignedEncodedJws() {
+        checkAlgorithm();
+        if (plainRep == null) {
+            plainRep = Base64UrlUtility.encode(writer.headersToJson(getHeaders())) 
+                + "." 
+                + Base64UrlUtility.encode(plainJwsPayload);
+        }
+        return plainRep;
+    }
+    
+    public String getSignedEncodedJws() {
+        checkAlgorithm();
+        boolean noSignature = StringUtils.isEmpty(signature);
+        if (noSignature && !isPlainText()) {
+            throw new IllegalStateException("Signature is not available");
+        }
+        return getUnsignedEncodedJws() + "." + (noSignature ? "" : signature);
+    }
+    
+    public String signWith(JwsSignatureProvider signer) { 
+        JwsSignature worker = signer.createJwsSignature(getHeaders());
+        try {
+            byte[] bytes = getUnsignedEncodedJws().getBytes("UTF-8");
+            worker.update(bytes, 0, bytes.length);
+            signWith(worker.sign());
+            return getSignedEncodedJws();
+        } catch (Exception ex) {
+            throw new SecurityException();
+        }
+    }
+    
+    public String signWith(String signatureText) {
+        setEncodedSignature(Base64UrlUtility.encode(signatureText));
+        return getSignedEncodedJws();
+    }
+    
+    public String signWith(byte[] signatureOctets) {
+        setEncodedSignature(Base64UrlUtility.encode(signatureOctets));
+        return getSignedEncodedJws();
+    }
+    
+    private void setEncodedSignature(String sig) {
+        this.signature = sig;
+    }
+    private boolean isPlainText() {
+        return JwtConstants.PLAIN_TEXT_ALGO.equals(getAlgorithm());
+    }
+    private String getAlgorithm() {
+        return getHeaders().getAlgorithm();
+    }
+    private void checkAlgorithm() {
+        if (getAlgorithm() == null) {
+            throw new IllegalStateException("Algorithm header is not set");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactConsumer.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactConsumer.java
new file mode 100644
index 0000000..e395dc7
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactConsumer.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenJson;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReader;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+
+public class JwsJwtCompactConsumer extends JwsCompactConsumer {
+    private JwtToken token;
+    public JwsJwtCompactConsumer(String encodedJws) {
+        this(encodedJws, null, null);
+    }
+    public JwsJwtCompactConsumer(String encodedJws, JwsSignatureProperties props) {
+        this(encodedJws, props, null);
+    }
+    public JwsJwtCompactConsumer(String encodedJws, JwtTokenReader r) {
+        this(encodedJws, null, r);
+    }
+    public JwsJwtCompactConsumer(String encodedJws, JwsSignatureProperties props, JwtTokenReader r) {
+        super(encodedJws, props, r == null ? new JwtTokenReaderWriter() : r);
+    }
+    public JwtTokenJson getDecodedJsonToken() {
+        return new JwtTokenJson(getDecodedJsonHeaders(), getDecodedJwsPayload());
+    }
+    public JwtClaims getJwtClaims() {
+        return getJwtToken().getClaims();
+    }
+    public JwtToken getJwtToken() {
+        if (token == null) {
+            token = ((JwtTokenReaderWriter)getReader()).fromJson(
+                new JwtTokenJson(getDecodedJsonHeaders(), getDecodedJwsPayload()));
+        }
+        return token;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactProducer.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactProducer.java
new file mode 100644
index 0000000..cc227af
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJwtCompactProducer.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter;
+import org.apache.cxf.rs.security.jose.jwt.JwtTokenWriter;
+
+public class JwsJwtCompactProducer extends JwsCompactProducer {
+    
+    public JwsJwtCompactProducer(JwtToken token) {
+        this(token, null);
+    }
+    public JwsJwtCompactProducer(JwtClaims claims) {
+        this(new JwtToken(null, claims), null);
+    }
+    public JwsJwtCompactProducer(JwtHeaders headers, JwtClaims claims) {
+        this(headers, claims, null);
+    }
+    public JwsJwtCompactProducer(JwtHeaders headers, JwtClaims claims, JwtTokenWriter w) {
+        this(new JwtToken(headers, claims), w);
+    }
+    public JwsJwtCompactProducer(JwtToken token, JwtTokenWriter w) {
+        super(token.getHeaders(), w, serializeClaims(token.getClaims(), w));
+    }
+    
+    private static String serializeClaims(JwtClaims claims, JwtTokenWriter writer) {
+        if (writer == null) {
+            writer = new JwtTokenReaderWriter();
+        }
+        return writer.claimsToJson(claims);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsOutputStream.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsOutputStream.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsOutputStream.java
new file mode 100644
index 0000000..bfb093f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsOutputStream.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+
+public class JwsOutputStream extends FilterOutputStream {
+    private boolean flushed;
+    private JwsSignature signature;
+    public JwsOutputStream(OutputStream out, JwsSignature signature) {
+        super(out);
+        this.signature = signature;
+    }
+
+    @Override
+    public void write(int value) throws IOException {
+        byte[] bytes = ByteBuffer.allocate(Integer.SIZE / 8).putInt(value).array();
+        write(bytes, 0, bytes.length);
+    }
+    
+    @Override
+    public void write(byte b[], int off, int len) throws IOException {
+        try {
+            signature.update(b, off, len);
+        } catch (Throwable ex) {
+            throw new SecurityException();
+        }
+        out.write(b, off, len);
+    }
+    @Override
+    public void flush() throws IOException {
+        if (flushed) {
+            return;
+        }
+        try {
+            byte[] finalBytes = signature.sign();
+            out.write(new byte[]{'.'});
+            Base64UrlUtility.encodeAndStream(finalBytes, 0, finalBytes.length, out);
+        } catch (Exception ex) {
+            throw new SecurityException();
+        }
+        flushed = true;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignature.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignature.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignature.java
new file mode 100644
index 0000000..778b5cb
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignature.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+
+public interface JwsSignature {
+    void update(byte[] src, int off, int len);
+    byte[] sign();
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProperties.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProperties.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProperties.java
new file mode 100644
index 0000000..e07f559
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProperties.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+
+public class JwsSignatureProperties {
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProvider.java
new file mode 100644
index 0000000..a4d12bf
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureProvider.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+
+public interface JwsSignatureProvider {
+    String getAlgorithm();
+    JwsSignature createJwsSignature(JwtHeaders headers);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureVerifier.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureVerifier.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureVerifier.java
new file mode 100644
index 0000000..ea4a01f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsSignatureVerifier.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+
+public interface JwsSignatureVerifier {
+    boolean verify(JwtHeaders headers, String unsignedText, byte[] signature);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
new file mode 100644
index 0000000..20b2672
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
+
+public final class JwsUtils {
+    private JwsUtils() {
+        
+    }
+    public static JwsSignatureProvider getSignatureProvider(JsonWebKey jwk) {
+        return getSignatureProvider(jwk, null);
+    }
+    public static JwsSignatureProvider getSignatureProvider(JsonWebKey jwk, String defaultAlgorithm) {
+        String rsaSignatureAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        JwsSignatureProvider theSigProvider = null;
+        if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
+            theSigProvider = new PrivateKeyJwsSignatureProvider(JwkUtils.toRSAPrivateKey(jwk),
+                                                                rsaSignatureAlgo);
+        } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType()) 
+            && Algorithm.isHmacSign(rsaSignatureAlgo)) {
+            theSigProvider = 
+                new HmacJwsSignatureProvider((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE),
+                                             rsaSignatureAlgo);
+        } else if (JsonWebKey.KEY_TYPE_ELLIPTIC.equals(jwk.getKeyType())) {
+            theSigProvider = new EcDsaJwsSignatureProvider(JwkUtils.toECPrivateKey(jwk),
+                                                           rsaSignatureAlgo);
+        }
+        return theSigProvider;
+    }
+    public static JwsSignatureVerifier getSignatureVerifier(JsonWebKey jwk, String defaultAlgorithm) {
+        String rsaSignatureAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
+        JwsSignatureVerifier theVerifier = null;
+        if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
+            theVerifier = new PublicKeyJwsSignatureVerifier(JwkUtils.toRSAPublicKey(jwk));
+        } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType()) 
+            && Algorithm.isHmacSign(rsaSignatureAlgo)) {
+            theVerifier = 
+                new HmacJwsSignatureVerifier((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE));
+        } else if (JsonWebKey.KEY_TYPE_ELLIPTIC.equals(jwk.getKeyType())) {
+            theVerifier = new PublicKeyJwsSignatureVerifier(JwkUtils.toECPublicKey(jwk));
+        }
+        return theVerifier;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java
new file mode 100644
index 0000000..bbd92aa
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PrivateKeyJwsSignatureProvider.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class PrivateKeyJwsSignatureProvider extends AbstractJwsSignatureProvider {
+    private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+        Arrays.asList(Algorithm.SHA256withRSA.getJwtName(),
+                      Algorithm.SHA384withRSA.getJwtName(),
+                      Algorithm.SHA512withRSA.getJwtName())); 
+    private PrivateKey key;
+    private SecureRandom random; 
+    private AlgorithmParameterSpec signatureSpec;
+    
+    public PrivateKeyJwsSignatureProvider(PrivateKey key, String algo) {
+        this(key, null, algo);
+    }
+    public PrivateKeyJwsSignatureProvider(PrivateKey key, AlgorithmParameterSpec spec, String algo) {
+        this(key, null, spec, algo);
+    }
+    public PrivateKeyJwsSignatureProvider(PrivateKey key, SecureRandom random, 
+                                          AlgorithmParameterSpec spec, String algo) {
+        this(key, random, spec, SUPPORTED_ALGORITHMS, algo);
+    }
+    protected PrivateKeyJwsSignatureProvider(PrivateKey key, 
+                                             SecureRandom random, 
+                                             AlgorithmParameterSpec spec,
+                                             Set<String> supportedAlgorithms,
+                                             String algo) {
+        super(supportedAlgorithms, algo);
+        this.key = key;
+        this.random = random;
+        this.signatureSpec = spec;
+    }
+    protected JwsSignature doCreateJwsSignature(JwtHeaders headers) {
+        final Signature s = CryptoUtils.getSignature(key, 
+                                                     Algorithm.toJavaName(headers.getAlgorithm()),
+                                                     random,
+                                                     signatureSpec);
+        return new JwsSignature() {
+
+            @Override
+            public void update(byte[] src, int off, int len) {
+                try {
+                    s.update(src, off, len);
+                } catch (SignatureException ex) {
+                    throw new SecurityException();
+                }
+            }
+
+            @Override
+            public byte[] sign() {
+                try {
+                    return s.sign();
+                } catch (SignatureException ex) {
+                    throw new SecurityException();
+                }
+            }
+            
+        };
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java
new file mode 100644
index 0000000..c4748e0
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jws/PublicKeyJwsSignatureVerifier.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jws;
+
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils;
+
+public class PublicKeyJwsSignatureVerifier implements JwsSignatureVerifier {
+    private PublicKey key;
+    private AlgorithmParameterSpec signatureSpec;
+    public PublicKeyJwsSignatureVerifier(PublicKey key) {
+        this(key, null);
+    }
+    public PublicKeyJwsSignatureVerifier(PublicKey key, AlgorithmParameterSpec spec) {
+        this.key = key;
+        this.signatureSpec = spec;
+    }
+    @Override
+    public boolean verify(JwtHeaders headers, String unsignedText, byte[] signature) {
+        try {
+            return CryptoUtils.verifySignature(unsignedText.getBytes("UTF-8"), 
+                                               signature, 
+                                               key, 
+                                               Algorithm.toJavaName(headers.getAlgorithm()),
+                                               signatureSpec);
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObject.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObject.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObject.java
new file mode 100644
index 0000000..e8d45e5
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObject.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public abstract class AbstractJwtObject {
+    protected Map<String, Object> values = new LinkedHashMap<String, Object>();
+    
+    protected AbstractJwtObject() {
+        
+    }
+    
+    protected AbstractJwtObject(Map<String, Object> values) {
+        this.values = values;
+    }
+    
+    protected void setValue(String name, Object value) {
+        values.put(name, value);
+    }
+    
+    protected Object getValue(String name) {
+        return values.get(name);
+    }
+
+    public Map<String, Object> asMap() {
+        return new LinkedHashMap<String, Object>(values);
+    }
+    
+    protected Long getLongDate(String name) {
+        Object object = getValue(name);
+        return object instanceof Long ? (Long)object : Long.valueOf(object.toString());
+    }
+    
+    public int hashCode() { 
+        return values.hashCode();
+    }
+    
+    public boolean equals(Object obj) {
+        return obj instanceof AbstractJwtObject && ((AbstractJwtObject)obj).values.equals(this.values);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObjectReaderWriter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObjectReaderWriter.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObjectReaderWriter.java
new file mode 100644
index 0000000..a70eca7
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJwtObjectReaderWriter.java
@@ -0,0 +1,212 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+
+public class AbstractJwtObjectReaderWriter {
+    private static final Set<String> DATE_PROPERTIES = 
+        new HashSet<String>(Arrays.asList(JwtConstants.CLAIM_EXPIRY, 
+                                          JwtConstants.CLAIM_ISSUED_AT, 
+                                          JwtConstants.CLAIM_NOT_BEFORE));
+    private boolean format;
+    
+    protected String toJson(AbstractJwtObject jwt) {
+        StringBuilder sb = new StringBuilder();
+        toJsonInternal(sb, jwt.asMap());
+        return sb.toString();
+    }
+
+    protected void toJsonInternal(StringBuilder sb, Map<String, Object> map) {
+        sb.append("{");
+        for (Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator(); it.hasNext();) {
+            Map.Entry<String, Object> entry = it.next();
+            sb.append("\"").append(entry.getKey()).append("\"");
+            sb.append(":");
+            toJsonInternal(sb, entry.getValue(), it.hasNext());
+        }
+        sb.append("}");
+    }
+    
+    protected void toJsonInternal(StringBuilder sb, Object[] array) {
+        toJsonInternal(sb, Arrays.asList(array));
+    }
+    
+    protected void toJsonInternal(StringBuilder sb, Collection<?> coll) {
+        sb.append("[");
+        formatIfNeeded(sb);
+        for (Iterator<?> iter = coll.iterator(); iter.hasNext();) {
+            toJsonInternal(sb, iter.next(), iter.hasNext());
+        }
+        formatIfNeeded(sb);
+        sb.append("]");
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected void toJsonInternal(StringBuilder sb, Object value, boolean hasNext) {
+        if (AbstractJwtObject.class.isAssignableFrom(value.getClass())) {
+            sb.append(toJson((AbstractJwtObject)value));
+        } else if (value.getClass().isArray()) {
+            toJsonInternal(sb, (Object[])value);
+        } else if (Collection.class.isAssignableFrom(value.getClass())) {
+            toJsonInternal(sb, (Collection<?>)value);
+        } else if (Map.class.isAssignableFrom(value.getClass())) {
+            toJsonInternal(sb, (Map<String, Object>)value);
+        } else {
+            if (value.getClass() == String.class) {
+                sb.append("\"");
+            }
+            sb.append(value);
+            if (value.getClass() == String.class) {
+                sb.append("\"");
+            }
+        }
+        if (hasNext) {
+            sb.append(",");
+            formatIfNeeded(sb);
+        }
+        
+    }
+    
+    protected void formatIfNeeded(StringBuilder sb) {
+        if (format) {
+            sb.append("\r\n ");
+        }
+    }
+        
+    protected void fromJsonInternal(AbstractJwtObject jwt, String json) {
+        String theJson = json.trim();
+        Map<String, Object> values = readJwtObjectAsMap(theJson.substring(1, theJson.length() - 1));
+        fromJsonInternal(jwt, values);
+    }
+    
+    protected void fromJsonInternal(AbstractJwtObject jwt, Map<String, Object> values) {
+        for (Map.Entry<String, Object> entry : values.entrySet()) {
+            jwt.setValue(entry.getKey(), entry.getValue());
+        }
+    }
+    
+    protected Map<String, Object> readJwtObjectAsMap(String json) {
+        Map<String, Object> values = new LinkedHashMap<String, Object>();
+        for (int i = 0; i < json.length(); i++) {
+            if (isWhiteSpace(json.charAt(i))) {
+                continue;
+            }
+            
+            int closingQuote = json.indexOf('"', i + 1);
+            int from = json.charAt(i) == '"' ? i + 1 : i;
+            String name = json.substring(from, closingQuote);
+            int sepIndex = json.indexOf(':', closingQuote + 1);
+            
+            int j = 1;
+            while (isWhiteSpace(json.charAt(sepIndex + j))) {
+                j++;
+            }
+            if (json.charAt(sepIndex + j) == '{') {
+                int closingIndex = getClosingIndex(json, '{', '}', sepIndex + j);
+                String newJson = json.substring(sepIndex + j + 1, closingIndex);
+                values.put(name, readJwtObjectAsMap(newJson));
+                i = closingIndex + 1;
+            } else if (json.charAt(sepIndex + j) == '[') {
+                int closingIndex = getClosingIndex(json, '[', ']', sepIndex + j);
+                String newJson = json.substring(sepIndex + j + 1, closingIndex);
+                values.put(name, readJwtObjectAsList(newJson));
+                i = closingIndex + 1;
+            } else {
+                int commaIndex = getCommaIndex(json, sepIndex + j);
+                Object value = readPrimitiveValue(json, sepIndex + j, commaIndex);
+                if (DATE_PROPERTIES.contains(name)) {
+                    value = Long.valueOf(value.toString());
+                }
+                values.put(name, value);
+                i = commaIndex + 1;
+            }
+            
+        }
+        return values;
+    }
+    protected List<Object> readJwtObjectAsList(String json) {
+        List<Object> values = new LinkedList<Object>();
+        for (int i = 0; i < json.length(); i++) {
+            if (isWhiteSpace(json.charAt(i))) {
+                continue;
+            }
+            if (json.charAt(i) == '{') {
+                int closingIndex = getClosingIndex(json, '{', '}', i);
+                values.add(readJwtObjectAsMap(json.substring(i + 1, closingIndex)));
+                i = closingIndex + 1;
+            } else {
+                int commaIndex = getCommaIndex(json, i);
+                Object value = readPrimitiveValue(json, i, commaIndex);
+                values.add(value);
+                i = commaIndex + 1;
+            }
+        }
+        
+        return values;
+    }
+    protected Object readPrimitiveValue(String json, int from, int to) {
+        Object value = json.substring(from, to);
+        String valueStr = value.toString().trim(); 
+        if (valueStr.startsWith("\"")) {
+            value = valueStr.substring(1, valueStr.length() - 1);
+        } else if ("true".equals(value) || "false".equals(value)) {
+            value = Boolean.valueOf(valueStr);
+        } 
+        return value;
+    }
+    
+    protected static int getCommaIndex(String json, int from) {
+        int commaIndex = json.indexOf(",", from);
+        if (commaIndex == -1) {
+            commaIndex = json.length();
+        }
+        return commaIndex;
+    }
+    protected int getClosingIndex(String json, char openChar, char closeChar, int from) {
+        int nextOpenIndex = json.indexOf(openChar, from + 1);
+        int closingIndex = json.indexOf(closeChar, from + 1);
+        while (nextOpenIndex != -1 && nextOpenIndex < closingIndex) {
+            nextOpenIndex = json.indexOf(openChar, closingIndex + 1);
+            closingIndex = json.indexOf(closeChar, closingIndex + 1);
+        }
+        return closingIndex;
+    }
+    protected boolean isWhiteSpace(char jsonChar) {
+        return jsonChar == ' ' || jsonChar == '\r' || jsonChar == '\n' || jsonChar == '\t';
+    }
+
+    public void setFormat(boolean format) {
+        this.format = format;
+    }
+
+    
+
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtClaims.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtClaims.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtClaims.java
new file mode 100644
index 0000000..46644a8
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtClaims.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+import java.util.Map;
+
+
+
+
+public class JwtClaims extends AbstractJwtObject {
+    
+    public JwtClaims() {
+    }
+    
+    public JwtClaims(Map<String, Object> values) {
+        super(values);
+    }
+    
+    public void setIssuer(String issuer) {
+        setClaim(JwtConstants.CLAIM_ISSUER, issuer);
+    }
+    
+    public String getIssuer() {
+        return (String)getValue(JwtConstants.CLAIM_ISSUER);
+    }
+    
+    public void setSubject(String subject) {
+        setClaim(JwtConstants.CLAIM_SUBJECT, subject);
+    }
+    
+    public String getSubject() {
+        return (String)getClaim(JwtConstants.CLAIM_SUBJECT);
+    }
+    
+    public void setAudience(String audience) {
+        setClaim(JwtConstants.CLAIM_AUDIENCE, audience);
+    }
+    
+    public String getAudience() {
+        return (String)getClaim(JwtConstants.CLAIM_AUDIENCE);
+    }
+    
+    public void setExpiryTime(Long expiresIn) {
+        setClaim(JwtConstants.CLAIM_EXPIRY, expiresIn);
+    }
+    
+    public Long getExpiryTime() {
+        return getLongDate(JwtConstants.CLAIM_EXPIRY);
+    }
+    
+    public void setNotBefore(Long notBefore) {
+        setClaim(JwtConstants.CLAIM_NOT_BEFORE, notBefore);
+    }
+    
+    public Long getNotBefore() {
+        return getLongDate(JwtConstants.CLAIM_NOT_BEFORE);
+    }
+    
+    public void setIssuedAt(Long issuedAt) {
+        setClaim(JwtConstants.CLAIM_ISSUED_AT, issuedAt);
+    }
+    
+    public Long getIssuedAt() {
+        return getLongDate(JwtConstants.CLAIM_ISSUED_AT);
+    }
+    
+    public void setTokenId(String id) {
+        setValue(JwtConstants.CLAIM_JWT_ID, id);
+    }
+    
+    public String getTokenId() {
+        return (String)getClaim(JwtConstants.CLAIM_JWT_ID);
+    }
+    
+    public JwtClaims setClaim(String name, Object value) {
+        setValue(name, value);
+        return this;
+    }
+    
+    public Object getClaim(String name) {
+        return getValue(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtConstants.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtConstants.java
new file mode 100644
index 0000000..e912b31
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtConstants.java
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+public final class JwtConstants {
+    public static final String HEADER_TYPE = "typ";
+    public static final String HEADER_ALGORITHM = "alg";
+    public static final String HEADER_CONTENT_TYPE = "cty";
+    public static final String HEADER_CRITICAL = "crit";
+    
+    public static final String HEADER_KEY_ID = "kid";
+    public static final String HEADER_X509_URL = "x5u";
+    public static final String HEADER_X509_CHAIN = "x5c";
+    public static final String HEADER_X509_THUMBPRINT = "x5t";
+    public static final String HEADER_X509_THUMBPRINT_SHA256 = "x5t#S256";
+    public static final String HEADER_JSON_WEB_KEY = "jwk";
+    public static final String HEADER_JSON_WEB_KEY_SET = "jku";
+    
+    public static final String JWE_HEADER_KEY_ENC_ALGORITHM = HEADER_ALGORITHM;
+    public static final String JWE_HEADER_CONTENT_ENC_ALGORITHM = "enc";
+    public static final String JWE_HEADER_ZIP_ALGORITHM = "zip";
+    public static final String DEFLATE_ZIP_ALGORITHM = "DEF";
+    
+    public static final String TYPE_JWT = "JWT";
+    public static final String TYPE_JOSE = "JOSE";
+    public static final String TYPE_JOSE_JSON = "JOSE+JSON";
+    public static final String MEDIA_TYPE_JOSE_JSON = "application/jose+json";
+    
+    public static final String CLAIM_ISSUER = "iss";
+    public static final String CLAIM_SUBJECT = "sub";
+    public static final String CLAIM_AUDIENCE = "aud";
+    public static final String CLAIM_EXPIRY = "exp";
+    public static final String CLAIM_NOT_BEFORE = "nbf";
+    public static final String CLAIM_ISSUED_AT = "iat";
+    public static final String CLAIM_JWT_ID = "jti";
+    
+    public static final String PLAIN_TEXT_ALGO = "none";
+    public static final String HMAC_SHA_256_ALGO = "HS256";
+    public static final String HMAC_SHA_384_ALGO = "HS384";
+    public static final String HMAC_SHA_512_ALGO = "HS512";
+    public static final String RS_SHA_256_ALGO = "RS256";
+    public static final String RS_SHA_384_ALGO = "RS384";
+    public static final String RS_SHA_512_ALGO = "RS512";
+    public static final String ES_SHA_256_ALGO = "ES256";
+    public static final String ES_SHA_384_ALGO = "ES384";
+    public static final String ES_SHA_512_ALGO = "ES512";
+    
+    // Key Encryption
+    public static final String RSA_OAEP_ALGO = "RSA-OAEP";
+    public static final String RSA_OAEP_256_ALGO = "RSA-OAEP-256";
+    public static final String RSA_1_5_ALGO = "RSA1_5";
+    public static final String A128KW_ALGO = "A128KW";
+    public static final String A192KW_ALGO = "A192KW";
+    public static final String A256KW_ALGO = "A256KW";
+    public static final String A128GCMKW_ALGO = "A128GCMKW";
+    public static final String A192GCMKW_ALGO = "A192GCMKW";
+    public static final String A256GCMKW_ALGO = "A256GCMKW";
+    public static final String PBES2_HS256_A128KW_ALGO = "PBES2-HS256+A128KW";
+    public static final String PBES2_HS384_A192KW_ALGO = "PBES2-HS384+A192KW";
+    public static final String PBES2_HS512_A256KW_ALGO = "PBES2-HS512+A256KW";
+    // Content Encryption
+    public static final String A128CBC_HS256_ALGO = "A128CBC-HS256";
+    public static final String A192CBC_HS384_ALGO = "A192CBC-HS384";
+    public static final String A256CBC_HS512_ALGO = "A256CBC-HS512";
+    public static final String A128GCM_ALGO = "A128GCM";
+    public static final String A192GCM_ALGO = "A192GCM";
+    public static final String A256GCM_ALGO = "A256GCM";
+    
+    private JwtConstants() {
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeaders.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeaders.java
new file mode 100644
index 0000000..b723f7d
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeaders.java
@@ -0,0 +1,172 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.rs.security.jose.jwa.Algorithm;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+
+public class JwtHeaders extends AbstractJwtObject {
+    
+    public JwtHeaders() {
+    }
+    
+    public JwtHeaders(String algorithm) {
+        init(algorithm);
+    }
+    
+    public JwtHeaders(Algorithm algo) {
+        init(algo.getJwtName());
+    }
+    
+    public JwtHeaders(Map<String, Object> values) {
+        super(values);
+    }
+    
+    private void init(String algo) {
+        setType(JwtConstants.TYPE_JWT);
+        this.setAlgorithm(algo);
+    }
+    
+    
+    public void setType(String type) {
+        setHeader(JwtConstants.HEADER_TYPE, type);
+    }
+    
+    public String getType() {
+        return (String)getHeader(JwtConstants.HEADER_TYPE);
+    }
+    
+    public void setContentType(String type) {
+        setHeader(JwtConstants.HEADER_CONTENT_TYPE, type);
+    }
+    
+    public String getContentType() {
+        return (String)getHeader(JwtConstants.HEADER_CONTENT_TYPE);
+    }
+    
+    public void setAlgorithm(String algo) {
+        setHeader(JwtConstants.HEADER_ALGORITHM, algo);
+    }
+    
+    public String getAlgorithm() {
+        return (String)getHeader(JwtConstants.HEADER_ALGORITHM);
+    }
+    
+    public void setKeyId(String kid) {
+        setHeader(JwtConstants.HEADER_KEY_ID, kid);
+    }
+    
+    public String getKeyId() {
+        return (String)getHeader(JwtConstants.HEADER_KEY_ID);
+    }
+    
+    public void setX509Url(String x509Url) {
+        setHeader(JwtConstants.HEADER_X509_URL, x509Url);
+    }
+
+    public String getX509Url() {
+        return (String)getHeader(JwtConstants.HEADER_X509_URL);
+    }
+    
+    public void setX509Chain(String x509Chain) {
+        setHeader(JwtConstants.HEADER_X509_CHAIN, x509Chain);
+    }
+
+    public String getX509Chain() {
+        return (String)getHeader(JwtConstants.HEADER_X509_CHAIN);
+    }
+    
+    public void setX509Thumbprint(String x509Thumbprint) {
+        setHeader(JwtConstants.HEADER_X509_THUMBPRINT, x509Thumbprint);
+    }
+    
+    public String getX509Thumbprint() {
+        return (String)getHeader(JwtConstants.HEADER_X509_THUMBPRINT);
+    }
+    
+    public void setX509ThumbprintSHA256(String x509Thumbprint) {
+        super.setValue(JwtConstants.HEADER_X509_THUMBPRINT_SHA256, x509Thumbprint);
+    }
+    
+    public String getX509ThumbprintSHA256() {
+        return (String)super.getValue(JwtConstants.HEADER_X509_THUMBPRINT_SHA256);
+    }
+    
+    public void setCritical(List<String> crit) {
+        setHeader(JwtConstants.HEADER_CRITICAL, crit);
+    }
+    
+    public List<String> getCritical() {
+        return CastUtils.cast((List<?>)getHeader(JwtConstants.HEADER_CRITICAL));
+    }
+    
+    public void setJsonWebKey(JsonWebKey key) {
+        setValue(JwtConstants.HEADER_JSON_WEB_KEY, key);
+    }
+    
+    public JsonWebKey getJsonWebKey() {
+        Object jsonWebKey = getValue(JwtConstants.HEADER_JSON_WEB_KEY);
+        if (jsonWebKey == null || jsonWebKey instanceof JsonWebKey) {
+            return (JsonWebKey)jsonWebKey;
+        }  
+        Map<String, Object> map = CastUtils.cast((Map<?, ?>)jsonWebKey);
+        return new JsonWebKey(map);
+    }
+    
+    public JwtHeaders setHeader(String name, Object value) {
+        setValue(name, value);
+        return this;
+    }
+    
+    public Object getHeader(String name) {
+        return getValue(name);
+    }
+    
+    public JwtHeaders setIntegerHeader(String name, Integer value) {
+        setValue(name, value);
+        return this;
+    }
+    
+    public Integer getIntegerHeader(String name) {
+        Object value = getValue(name);
+        if (value != null) {
+            return value instanceof Integer ? (Integer)value : Integer.parseInt(value.toString());
+        } else {
+            return null;
+        }
+    }
+    public JwtHeaders setLongHeader(String name, Long value) {
+        setValue(name, value);
+        return this;
+    }
+    
+    public Long getLongHeader(String name) {
+        Object value = getValue(name);
+        if (value != null) {
+            return value instanceof Long ? (Long)value : Long.parseLong(value.toString());
+        } else {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersReader.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersReader.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersReader.java
new file mode 100644
index 0000000..8a15819
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersReader.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+public interface JwtHeadersReader {
+    JwtHeaders fromJsonHeaders(String jsonHeaders);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersWriter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersWriter.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersWriter.java
new file mode 100644
index 0000000..6c63dea
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtHeadersWriter.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+
+public interface JwtHeadersWriter {
+    
+    String headersToJson(JwtHeaders headers);
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java
new file mode 100644
index 0000000..630813c
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtToken.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+
+public class JwtToken {
+    private JwtHeaders headers;
+    private JwtClaims claims;
+    public JwtToken(JwtHeaders headers, JwtClaims claims) {
+        this.headers = headers;
+        this.claims = claims;
+    }
+    public JwtHeaders getHeaders() {
+        return headers;
+    }
+    public JwtClaims getClaims() {
+        return claims;
+    }
+    public int hashCode() { 
+        return headers.hashCode() + 37 * claims.hashCode();
+    }
+    
+    public boolean equals(Object obj) {
+        return obj instanceof JwtToken 
+            && ((JwtToken)obj).headers.equals(this.headers)
+            && ((JwtToken)obj).claims.equals(this.claims);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenJson.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenJson.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenJson.java
new file mode 100644
index 0000000..e8e79f0
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenJson.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+
+public class JwtTokenJson {
+    private String headersJson;
+    private String claimsJson;
+    public JwtTokenJson(String headersJson, String claimsJson) {
+        this.headersJson = headersJson;
+        this.claimsJson = claimsJson;
+    }
+    public String getHeadersJson() {
+        return headersJson;
+    }
+    public String getClaimsJson() {
+        return claimsJson;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReader.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReader.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReader.java
new file mode 100644
index 0000000..2be6305
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReader.java
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+public interface JwtTokenReader extends JwtHeadersReader {
+    JwtClaims fromJsonClaims(String jsonClaims);
+    JwtToken fromJson(JwtTokenJson jsonPair);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReaderWriter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReaderWriter.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReaderWriter.java
new file mode 100644
index 0000000..c207e0e
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenReaderWriter.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+
+
+public class JwtTokenReaderWriter extends AbstractJwtObjectReaderWriter
+    implements JwtTokenReader, JwtTokenWriter {
+    @Override
+    public String headersToJson(JwtHeaders headers) {
+        return toJson(headers);
+    }
+
+    @Override
+    public String claimsToJson(JwtClaims claims) {
+        return toJson(claims);
+    }
+
+    @Override
+    public JwtTokenJson tokenToJson(JwtToken token) {
+        return new JwtTokenJson(toJson(token.getHeaders()),
+                                    toJson(token.getClaims()));
+    }
+    
+    @Override
+    public JwtHeaders fromJsonHeaders(String headersJson) {
+        JwtHeaders headers = new JwtHeaders();
+        fromJsonInternal(headers, headersJson);
+        return headers;
+    }
+    
+    @Override
+    public JwtClaims fromJsonClaims(String claimsJson) {
+        JwtClaims claims = new JwtClaims();
+        fromJsonInternal(claims, claimsJson);
+        return claims;
+        
+    }
+    
+    private JwtToken fromJson(String headersJson, String claimsJson) {
+        JwtHeaders headers = fromJsonHeaders(headersJson);
+        JwtClaims claims = fromJsonClaims(claimsJson);
+        return new JwtToken(headers, claims);
+    }
+    
+    @Override
+    public JwtToken fromJson(JwtTokenJson pair) {
+        return fromJson(pair.getHeadersJson(), pair.getClaimsJson());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenWriter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenWriter.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenWriter.java
new file mode 100644
index 0000000..bdbd029
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtTokenWriter.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+
+
+public interface JwtTokenWriter extends JwtHeadersWriter {
+    
+    String claimsToJson(JwtClaims claims);
+    JwtTokenJson tokenToJson(JwtToken token);
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
new file mode 100644
index 0000000..6238e2f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/JwtUtils.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt;
+
+public final class JwtUtils {
+    private JwtUtils() {
+        
+    }
+    
+    public static String checkContentType(String contentType, String defaultType) {
+        if (contentType != null) {
+            int paramIndex = contentType.indexOf(';');
+            String typeWithoutParams = paramIndex == -1 ? contentType : contentType.substring(0, paramIndex);
+            if (typeWithoutParams.indexOf('/') == -1) {
+                contentType = "application/" + contentType;
+            }
+        } else {
+            contentType = defaultType;
+        }
+        return contentType;
+    }
+    public static String expandContentType(String contentType) {
+        int paramIndex = contentType.indexOf(';');
+        String typeWithoutParams = paramIndex == -1 ? contentType : contentType.substring(0, paramIndex);
+        if (typeWithoutParams.indexOf('/') == -1) {
+            contentType = "application/" + contentType;
+        }
+        return contentType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtBearerGrant.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtBearerGrant.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtBearerGrant.java
new file mode 100644
index 0000000..4572b30
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtBearerGrant.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt.grant;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenGrant;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public abstract class AbstractJwtBearerGrant implements AccessTokenGrant {
+    private static final long serialVersionUID = 5754722119855372511L;
+    private String assertion;
+    private String scope;
+    private boolean encoded; 
+    private String grantType;
+    protected AbstractJwtBearerGrant(String grantType, String assertion, boolean encoded, String scope) {
+        this.grantType = grantType;
+        this.assertion = assertion;
+        this.encoded = encoded;
+        this.scope = scope;
+    }
+    
+    public String getType() {
+        return grantType;
+    }
+
+    protected MultivaluedMap<String, String> initMap() {
+        MultivaluedMap<String, String> map = new MetadataMap<String, String>();
+        map.putSingle(OAuthConstants.GRANT_TYPE, grantType);
+        return map;
+    }
+
+    protected void addScope(MultivaluedMap<String, String> map) {
+        if (scope != null) {
+            map.putSingle(OAuthConstants.SCOPE, scope);
+        }
+    }
+    
+    protected String encodeAssertion() {
+        if (encoded) {
+            return assertion;
+        }
+        
+        try {
+            return Base64UrlUtility.encode(assertion);
+        } catch (Exception ex) {
+            throw new OAuthServiceException(ex.getMessage(), ex);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/4640cf1e/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtHandler.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtHandler.java b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtHandler.java
new file mode 100644
index 0000000..dbc8ffe
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2-jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/grant/AbstractJwtHandler.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.rs.security.jose.jwt.grant;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+import org.apache.cxf.rs.security.jose.jwt.JwtHeaders;
+import org.apache.cxf.rs.security.oauth2.common.Client;
+import org.apache.cxf.rs.security.oauth2.grants.AbstractGrantHandler;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+
+/**
+ * The "JWT Bearer" grant handler
+ */
+public abstract class AbstractJwtHandler extends AbstractGrantHandler {
+    private Set<String> supportedIssuers; 
+    private JwsSignatureVerifier jwsVefifier;
+        
+    protected AbstractJwtHandler(List<String> grants) {
+        super(grants);
+    }
+    
+    protected void validateSignature(JwtHeaders headers, String unsignedText, byte[] signature) {
+        if (jwsVefifier.verify(headers, unsignedText, signature)) {    
+            throw new OAuthServiceException(OAuthConstants.INVALID_GRANT);
+        }
+    }
+    
+    protected void validateClaims(Client client, JwtClaims claims) {
+        validateIssuer(claims.getIssuer());
+        validateSubject(client, claims.getSubject());
+        validateAudience(client, claims.getAudience());
+        validateExpiryTime(claims.getExpiryTime());
+        validateNotBeforeTime(claims.getNotBefore());
+        validateIssuedAtTime(claims.getIssuedAt());
+        validateTokenId(claims.getTokenId());
+    }
+
+    protected void validateIssuer(String issuer) {
+        if (issuer == null || !supportedIssuers.contains(issuer)) {
+            throw new OAuthServiceException(OAuthConstants.INVALID_GRANT);
+        }
+    }
+    
+    protected void validateSubject(Client client, String subject) {
+        //TODO
+    }
+    protected void validateAudience(Client client, String audience) {
+        //TODO
+    }
+    protected void validateExpiryTime(Long timestamp) {
+        if (timestamp != null) {
+            //TODO
+        }
+    }
+    protected void validateNotBeforeTime(Long timestamp) {
+        if (timestamp != null) {
+            //TODO    
+        }
+    }
+    protected void validateIssuedAtTime(Long timestamp) {
+        if (timestamp != null) {
+            //TODO
+        }
+    }
+    protected void validateTokenId(String tokenId) {
+        if (tokenId != null) {
+            //TODO
+        }
+    }
+    public void setSupportedIssuers(Set<String> supportedIssuers) {
+        this.supportedIssuers = supportedIssuers;
+    }
+
+    public void setJwsVefifier(JwsSignatureVerifier jwsVefifier) {
+        this.jwsVefifier = jwsVefifier;
+    }
+    
+}


Mime
View raw message