Skip to content

Commit

Permalink
Refactor package structure. Delete IdentifiedSigner as it is duplicat…
Browse files Browse the repository at this point in the history
…ed with CommonSigner
  • Loading branch information
fhanik committed Nov 17, 2016
1 parent e51b762 commit fe45dfd
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 108 deletions.

This file was deleted.

Expand Up @@ -16,7 +16,8 @@

import org.bouncycastle.asn1.ASN1Sequence;
import org.cloudfoundry.identity.uaa.impl.config.LegacyTokenKey;
import org.cloudfoundry.identity.uaa.oauth.jwt.IdentifiedSigner;
import org.cloudfoundry.identity.uaa.oauth.jwt.CommonSignatureVerifier;
import org.cloudfoundry.identity.uaa.oauth.jwt.CommonSigner;
import org.cloudfoundry.identity.uaa.oauth.jwt.Signer;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneConfiguration;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
Expand Down Expand Up @@ -52,7 +53,7 @@ public class KeyInfo {
private String keyId;
private String verifierKey = new RandomValueStringGenerator().generate();
private String signingKey = verifierKey;
private Signer signer = new IdentifiedSigner(null, new MacSigner(verifierKey));
private Signer signer = new CommonSigner(null, verifierKey);
private SignatureVerifier verifier = new MacSigner(signingKey);
private String type = "MAC";
private RSAPublicKey rsaPublicKey;
Expand Down
Expand Up @@ -14,11 +14,9 @@
*/
package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.cloudfoundry.identity.uaa.oauth.KeyInfo;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKey;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKeySet;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.jwt.crypto.sign.InvalidSignatureException;
import org.springframework.security.jwt.crypto.sign.SignatureVerifier;

import java.util.ArrayList;
Expand All @@ -29,25 +27,19 @@ public class ChainedSignatureVerifier implements SignatureVerifier {
private final List<SignatureVerifier> delegates;

public ChainedSignatureVerifier(JsonWebKeySet<? extends JsonWebKey> keys) {
if(keys == null || keys.getKeys() == null || keys.getKeys().size() == 0) {
throw new IllegalArgumentException("verificationKey cannot be null");
if(keys == null || keys.getKeys() == null) {
throw new IllegalArgumentException("keys cannot be null or empty");
}

List<SignatureVerifier> ds = new ArrayList<>(keys.getKeys().size());
for (JsonWebKey key : keys.getKeys()) {
String verificationKey = key.getValue();
if (KeyInfo.isAssymetricKey(verificationKey)) {
ds.add(new RsaVerifier(verificationKey));
} else {
ds.add(new MacSigner(verificationKey));
}
ds.add(new CommonSignatureVerifier(key.getValue()));
}
delegates = Collections.unmodifiableList(ds);
}

@Override
public void verify(byte[] content, byte[] signature) {
Exception last = null;
Exception last = new InvalidSignatureException("No matching keys found.");
for (SignatureVerifier delegate : delegates) {
try {
delegate.verify(content, signature);
Expand Down
@@ -1,17 +1,20 @@
/*******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
* <p>
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
* <p>
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
*******************************************************************************/
package org.cloudfoundry.identity.uaa.oauth;
/*
* ****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ****************************************************************************
*/
package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.cloudfoundry.identity.uaa.oauth.KeyInfo;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.jwt.crypto.sign.SignatureVerifier;
Expand Down
@@ -0,0 +1,53 @@
/*
* ****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ****************************************************************************
*/
package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.cloudfoundry.identity.uaa.oauth.KeyInfo;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.jwt.crypto.sign.RsaSigner;

public class CommonSigner implements Signer {

private final org.springframework.security.jwt.crypto.sign.Signer delegate;
private final String keyId;

public CommonSigner(String keyId, String signingKey) {
org.springframework.security.jwt.crypto.sign.Signer signer;
if (signingKey == null) {
throw new IllegalArgumentException(signingKey);
} else if(KeyInfo.isAssymetricKey(signingKey)) {
signer = new RsaSigner(signingKey);
} else {
signer = new MacSigner(signingKey);
}
delegate = signer;
this.keyId = keyId;
}

@Override
public String keyId() {
return keyId;
}

@Override
public byte[] sign(byte[] bytes) {
return delegate.sign(bytes);
}

@Override
public String algorithm() {
return delegate.algorithm();
}
}

This file was deleted.

Expand Up @@ -15,7 +15,6 @@

package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.cloudfoundry.identity.uaa.oauth.CommonSigner;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKey;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKeyHelper;
import org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKeySet;
Expand All @@ -30,8 +29,11 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.cloudfoundry.identity.uaa.oauth.jwk.JsonWebKey.KeyType.MAC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -117,6 +119,24 @@ public void test_multi_key_invalid() {
signedValidContent.verifySignature(verifier);
}

@Test
public void check_that_we_use_common_signer() {
Map<String,Object> p = new HashMap<>();
p.put("kty",MAC.name());
p.put("kid", "macid");
p.put("value", "test-mac-key");
JsonWebKey macKey = new JsonWebKey(p);
verifier = new ChainedSignatureVerifier(new JsonWebKeySet<>(Arrays.asList(validKey, invalidKey, macKey)));
List<SignatureVerifier> delegates = new ArrayList((List<SignatureVerifier>) ReflectionTestUtils.getField(verifier, verifier.getClass(), "delegates"));
assertNotNull(delegates);
assertEquals(3, delegates.size());
int pos = 0;
for (SignatureVerifier v : delegates) {
assertTrue("Checking "+(pos++), v instanceof CommonSignatureVerifier);
}
}


@Test
public void test_multi_key_both_valid() {
JsonWebKey jsonWebKey = mock(JsonWebKey.class);
Expand All @@ -126,7 +146,7 @@ public void test_multi_key_both_valid() {
List<SignatureVerifier> delegates = new ArrayList((List<SignatureVerifier>) ReflectionTestUtils.getField(verifier, verifier.getClass(), "delegates"));
assertNotNull(delegates);
assertEquals(2, delegates.size());
assertTrue(delegates.get(1) instanceof MacSigner);
assertEquals("HMACSHA256", delegates.get(1).algorithm());

//ensure the second signer never gets invoked upon success
delegates.remove(1);
Expand Down
Expand Up @@ -13,7 +13,7 @@
* ****************************************************************************
*/

package org.cloudfoundry.identity.uaa.oauth;
package org.cloudfoundry.identity.uaa.oauth.jwt;


import org.junit.Test;
Expand Down
@@ -0,0 +1,75 @@
/*
* ****************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ****************************************************************************
*/

package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class CommonSignerTest {
private String rsaSigningKey;
private String macSigningKey;

@Before
public void setup() {
rsaSigningKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIBOQIBAAJAcjAgsHEfrUxeTFwQPb17AkZ2Im4SfZdpY8Ada9pZfxXz1PZSqv9T\n" +
"PTMAzNx+EkzMk2IMYN+uNm1bfDzaxVdz+QIDAQABAkBoR39y4rw0/QsY3PKQD5xo\n" +
"hYSZCMCmJUI/sFCuECevIFY4h6q9KBP+4Set96f7Bgs9wJWVvCMx/nJ6guHAjsIB\n" +
"AiEAywVOoCGIZ2YzARXWYcMRYZ89hxoHh8kZ+QMthRSZieECIQCP/GWQYgyofAQA\n" +
"BtM8YwThXEV+S3KtuCn4IAQ89gqdGQIgULBASpZpPyc4OEM0nFBKFTGT46EtwwLj\n" +
"RrvDmLPSPiECICQi9FqIQSUH+vkGvX0qXM8ymT5ZMS7oSaA8aNPj7EYBAiEAx5V3\n" +
"2JGEulMY3bK1PVGYmtsXF1gq6zbRMoollMCRSMg=\n" +
"-----END RSA PRIVATE KEY-----";
macSigningKey = "mac-sign-key";
}

@Test
public void test_rsa_key_null_id() {
CommonSigner signer = new CommonSigner(null, rsaSigningKey);
assertEquals("SHA256withRSA", signer.algorithm());
assertNull(signer.keyId());
}

@Test
public void test_rsa_key_with_id() {
CommonSigner signer = new CommonSigner("id", rsaSigningKey);
assertEquals("SHA256withRSA", signer.algorithm());
assertEquals("id", signer.keyId());
}

@Test
public void test_mac_key_null_id() {
CommonSigner signer = new CommonSigner(null, macSigningKey);
assertEquals("HMACSHA256", signer.algorithm());
assertNull(signer.keyId());
}

@Test
public void test_mac_key_with_id() {
CommonSigner signer = new CommonSigner("id", macSigningKey);
assertEquals("HMACSHA256", signer.algorithm());
assertEquals("id", signer.keyId());
}

@Test(expected = IllegalArgumentException.class)
public void null_key_is_rejected() {
new CommonSigner("id", null);
}

}
@@ -1,15 +1,14 @@
package org.cloudfoundry.identity.uaa.oauth.jwt;

import org.junit.Test;
import org.springframework.security.jwt.crypto.sign.MacSigner;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

public class JwtHelperTest {

@Test
public void testKidInHeader() {
Signer signer = new IdentifiedSigner("testKid", new MacSigner("symmetricKey"));
Signer signer = new CommonSigner("testKid", "symmetricKey");
Jwt jwt = JwtHelper.encode("testJwtContent", signer);
assertEquals("testKid", jwt.getHeader().getKid());

Expand Down

0 comments on commit fe45dfd

Please sign in to comment.