/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.picketlink.test.json.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.picketlink.json.JsonConstants.RSA;
import static org.picketlink.test.json.api.JWEAPITestCase.assertJwEquals;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.junit.Before;
import org.junit.Test;
import org.picketlink.json.JsonException;
import org.picketlink.json.jose.JWK;
import org.picketlink.json.jose.JWKBuilder;
import org.picketlink.json.jose.JWKSet;
import org.picketlink.json.jose.JWS;
import org.picketlink.json.jose.JWSBuilder;
/**
* The Class JWSRSAAPITestCase.
*
* @author Pedro Igor
*/
public class JWSRSAAPITestCase {
private JWKSet keySet;
private KeyPair keyPair1;
private KeyPair keyPair2;
/**
* On before.
*
* @throws Exception the exception
*/
@Before
public void onBefore() throws Exception {
this.keySet = new JWKSet();
this.keyPair1 = KeyPairGenerator.getInstance("RSA").generateKeyPair();
registerPublicKey("1", (RSAPublicKey) this.keyPair1.getPublic());
this.keyPair2 = KeyPairGenerator.getInstance("RSA").generateKeyPair();
registerPublicKey("2", (RSAPublicKey) this.keyPair2.getPublic());
}
/**
* Register public key.
*
* @param kid the kid
* @param publicKey the public key
*/
private void registerPublicKey(String kid, RSAPublicKey publicKey) {
JWK rsaJWK = new JWKBuilder()
.modulus(publicKey.getModulus())
.publicExponent(publicKey.getPublicExponent())
.keyIdentifier(kid)
.keyType(RSA)
.keyUse("sig")
.build();
this.keySet.add(rsaJWK);
}
/**
* Test RSA256 signature.
*
* @throws Exception the exception
*/
@Test
public void testRSA256Signature() throws Exception {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa256(privateKey.getEncoded())
.keys(this.keySet)
.kid("1")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWK jwkKeyPair1 = this.keySet.get("1");
JWK jwkKeyPair2 = this.keySet.get("2");
assertJwEquals(
"{\"typ\":\"JWT\",\"alg\":\"RS256\",\"keys\":[{\"n\":\""
+ jwkKeyPair2.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"2\",\"kty\":\"RSA\",\"use\":\"sig\"},{\"n\":\""
+ jwkKeyPair1.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"1\",\"kty\":\"RSA\",\"use\":\"sig\"}],\"kid\":\"1\"}.{\"jti\":\"1\",\"iss\":\"issuer\",\"sub\":\"subject\",\"aud\":\"audience\",\"exp\":123,\"iat\":456,\"nbf\":789}",
jsonString);
String jsonEncoded = token.encode();
JWS parsedToken = new JWSBuilder().build(jsonEncoded);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
assertNotNull(parsedToken);
}
/**
* Test RSA384 signature.
*/
@Test
public void testRSA384Signature() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa384(privateKey.getEncoded())
.keys(this.keySet)
.kid("1")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWK jwkKeyPair1 = this.keySet.get("1");
JWK jwkKeyPair2 = this.keySet.get("2");
assertJwEquals(
"{\"typ\":\"JWT\",\"alg\":\"RS384\",\"keys\":[{\"n\":\""
+ jwkKeyPair2.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"2\",\"kty\":\"RSA\",\"use\":\"sig\"},{\"n\":\""
+ jwkKeyPair1.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"1\",\"kty\":\"RSA\",\"use\":\"sig\"}],\"kid\":\"1\"}.{\"jti\":\"1\",\"iss\":\"issuer\",\"sub\":\"subject\",\"aud\":\"audience\",\"exp\":123,\"iat\":456,\"nbf\":789}",
jsonString);
String jsonEncoded = token.encode();
JWS parsedToken = new JWSBuilder().build(jsonEncoded);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
assertNotNull(parsedToken);
}
/**
* Test RSA512 signature.
*/
@Test
public void testRSA512Signature() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa512(privateKey.getEncoded())
.keys(this.keySet)
.kid("1")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWK jwkKeyPair1 = this.keySet.get("1");
JWK jwkKeyPair2 = this.keySet.get("2");
assertJwEquals(
"{\"typ\":\"JWT\",\"alg\":\"RS512\",\"keys\":[{\"n\":\""
+ jwkKeyPair2.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"2\",\"kty\":\"RSA\",\"use\":\"sig\"},{\"n\":\""
+ jwkKeyPair1.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"1\",\"kty\":\"RSA\",\"use\":\"sig\"}],\"kid\":\"1\"}.{\"jti\":\"1\",\"iss\":\"issuer\",\"sub\":\"subject\",\"aud\":\"audience\",\"exp\":123,\"iat\":456,\"nbf\":789}",
jsonString);
String jsonEncoded = token.encode();
JWS parsedToken = new JWSBuilder().build(jsonEncoded);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
assertNotNull(parsedToken);
}
/**
* Test RSA512 signature using public key instance.
*/
@Test
public void testRSA512SignatureUsingPublicKeyInstance() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa512(privateKey.getEncoded())
.keys(this.keySet)
.kid("1")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWS parsedToken = new JWSBuilder().build(token.encode(), this.keyPair1.getPublic().getEncoded());
assertNotNull(parsedToken);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
}
/**
* Test RSA512 signature without JWK set.
*/
@Test
public void testRSA512SignatureWithoutJWKSet() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa512(privateKey.getEncoded())
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWS parsedToken = new JWSBuilder().build(token.encode(), this.keyPair1.getPublic().getEncoded());
assertNotNull(parsedToken);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
}
/**
* Test no signature.
*/
@Test
public void testNoSignature() {
JWS token = new JWSBuilder()
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
assertJwEquals("{\"typ\":\"JWT\",\"alg\":\"none\"}.{\"jti\":\"1\",\"iss\":\"issuer\",\"sub\":\"subject\",\"aud\":\"audience\",\"exp\":123,\"iat\":456,\"nbf\":789}",
jsonString);
JWS parsedToken = new JWSBuilder().build(token.encode(), this.keyPair1.getPublic().getEncoded());
assertNotNull(parsedToken);
String parsedJsonString = parsedToken.toString();
assertEquals(jsonString, parsedJsonString);
}
/**
* Fail invalid signature.
*/
@Test(expected = JsonException.class)
public void failInvalidSignature() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa512(privateKey.getEncoded())
.keys(this.keySet)
.kid("1")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
String jsonString = token.toString();
JWK jwkKeyPair1 = this.keySet.get("1");
JWK jwkKeyPair2 = this.keySet.get("2");
assertJwEquals(
"{\"typ\":\"JWT\",\"alg\":\"RS512\",\"keys\":[{\"n\":\""
+ jwkKeyPair2.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"2\",\"kty\":\"RSA\",\"use\":\"sig\"},{\"n\":\""
+ jwkKeyPair1.getModulus()
+ "\",\"e\":\"AQAB\",\"kid\":\"1\",\"kty\":\"RSA\",\"use\":\"sig\"}],\"kid\":\"1\"}.{\"jti\":\"1\",\"iss\":\"issuer\",\"sub\":\"subject\",\"aud\":\"audience\",\"exp\":123,\"iat\":456,\"nbf\":789}",
jsonString);
// here we temper the encoded token to fail invalid signature
String tamperedToken = new StringBuilder(token.encode()).insert(3, "tampered").toString();
new JWSBuilder().build(tamperedToken);
}
/**
* Fail invalid key.
*/
@Test(expected = JsonException.class)
public void failInvalidKey() {
PrivateKey privateKey = this.keyPair1.getPrivate();
JWS token = new JWSBuilder()
.rsa512(privateKey.getEncoded())
.keys(this.keySet)
.kid("2")
.id("1")
.issuer("issuer")
.subject("subject")
.audience("audience")
.expiration(123)
.issuedAt(456)
.notBefore(789)
.build();
// token was signed with key 1 but is referencing key 2.
new JWSBuilder().build(token.encode());
}
}