From 513145f16fd45bc33b37fe7ec3d37aa7deb3449c Mon Sep 17 00:00:00 2001 From: nemonik Date: Wed, 15 Feb 2012 17:35:18 -0500 Subject: [PATCH] refactored previously commented out unit tests, cleaned up code, service now returns only unique publickeys --- .../org/mitre/jwt/signer/impl/RsaSigner.java | 52 ++++--- ...JwtSigningAndValidationServiceDefault.java | 78 +++++----- .../jwt/signer/service/impl/KeyStore.java | 8 +- server/src/main/resources/keystore.jks | Bin 2196 -> 2195 bytes .../src/test/java/org/mitre/jwt/JwtTest.java | 136 ++++++++---------- .../jwt/signer/service/impl/KeyStoreTest.java | 23 ++- server/src/test/resources/keystore.jks | Bin 2196 -> 2195 bytes 7 files changed, 148 insertions(+), 149 deletions(-) diff --git a/server/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java b/server/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java index c697db8ab..96f4e2e88 100644 --- a/server/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java +++ b/server/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java @@ -4,6 +4,7 @@ import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; @@ -83,19 +84,14 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { private static Log logger = LogFactory.getLog(RsaSigner.class); - public static final String PROVIDER = "BC"; public static final String DEFAULT_PASSWORD = "changeit"; -// static { -// Security.addProvider(new BouncyCastleProvider()); -// } - private KeyStore keystore; private String alias; private String password; - private RSAPrivateKey privateKey; - private RSAPublicKey publicKey; + private PrivateKey privateKey; + private PublicKey publicKey; private Signature signer; /** @@ -113,7 +109,7 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { public RsaSigner(String algorithmName, KeyStore keystore, String alias) { this(algorithmName, keystore, alias, DEFAULT_PASSWORD); } - + /** * @param algorithmName * @param keystore @@ -136,14 +132,23 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { } } + /** + * Default constructor + */ + public RsaSigner(String algorithmName, RSAPublicKey publicKey, RSAPrivateKey privateKey) { + super(algorithmName); + this.publicKey = publicKey; + this.privateKey = privateKey; + } + @Override public void afterPropertiesSet() throws Exception { KeyPair keyPair = keystore.getKeyPairForAlias(alias, password); - publicKey = ((RSAPublicKey) keyPair.getPublic()); - privateKey = (RSAPrivateKey) keyPair.getPrivate(); + publicKey = keyPair.getPublic(); + privateKey = keyPair.getPrivate(); - logger.debug("RSA Signer ready for business"); + logger.debug( Algorithm.getByName(getAlgorithm()).getStandardName() + " RSA Signer ready for business"); } @@ -152,15 +157,17 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { */ @Override protected String generateSignature(String signatureBase) { - + try { signer.initSign(privateKey); signer.update(signatureBase.getBytes("UTF-8")); } catch (GeneralSecurityException e) { + System.out.println("boooom 1"); // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block + System.out.println("boooom 2"); e.printStackTrace(); } @@ -176,7 +183,7 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { // TODO Auto-generated catch block e.printStackTrace(); } - + return sig; } @@ -192,6 +199,10 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { return password; } + public PrivateKey getPrivateKey() { + return privateKey; + } + public PublicKey getPublicKey() { return publicKey; } @@ -208,6 +219,10 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { this.password = password; } + public void setPrivateKey(RSAPrivateKey privateKey) { + this.privateKey = privateKey; + } + /* * (non-Javadoc) * @@ -220,6 +235,9 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { + ", publicKey=" + publicKey + ", signer=" + signer + "]"; } + /* (non-Javadoc) + * @see org.mitre.jwt.signer.AbstractJwtSigner#verify(java.lang.String) + */ @Override public boolean verify(String jwtString) { @@ -251,12 +269,4 @@ public class RsaSigner extends AbstractJwtSigner implements InitializingBean { return true; } - - public RSAPrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(RSAPrivateKey privateKey) { - this.privateKey = privateKey; - } } diff --git a/server/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java b/server/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java index 50723a51a..9af5f71c8 100644 --- a/server/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java +++ b/server/src/main/java/org/mitre/jwt/signer/service/impl/JwtSigningAndValidationServiceDefault.java @@ -1,8 +1,11 @@ package org.mitre.jwt.signer.service.impl; import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -23,31 +26,35 @@ public class JwtSigningAndValidationServiceDefault implements /** * default constructor - */ - public JwtSigningAndValidationServiceDefault() { + */ + public JwtSigningAndValidationServiceDefault() { } /** * Create JwtSigningAndValidationServiceDefault * - * @param signer List of JwtSigners to associate with this service + * @param signer + * List of JwtSigners to associate with this service */ - public JwtSigningAndValidationServiceDefault(List signer) { + public JwtSigningAndValidationServiceDefault( + List signer) { setSigners(signer); } - - - /* (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() throws Exception { // used for debugging... if (!signers.isEmpty()) { - logger.info(this.toString()); + logger.info(this.toString()); } - - logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> JwtSigningAndValidationServiceDefault is open for business"); + + logger.info("JwtSigningAndValidationServiceDefault is open for business"); } /* @@ -59,30 +66,31 @@ public class JwtSigningAndValidationServiceDefault implements */ @Override public List getAllPublicKeys() { - // TODO Iterate through the signers, gather up, and return all the PublicKeys - - List publicKeys = new ArrayList(); - PublicKey publicKey; - - for (JwtSigner signer: signers) { - + + Map map = new HashMap(); + + PublicKey publicKey; + + for (JwtSigner signer : signers) { + if (signer instanceof RsaSigner) { - + publicKey = ((RsaSigner) signer).getPublicKey(); - + if (publicKey != null) - publicKeys.add(((RsaSigner) signer).getPublicKey()); - + map.put(((RSAPublicKey) publicKey).getModulus() + .toString(16).toUpperCase() + + ((RSAPublicKey) publicKey).getPublicExponent() + .toString(16).toUpperCase(), publicKey); + } else if (signer instanceof EcdsaSigner) { - - publicKey = ((EcdsaSigner) signer).getPublicKey(); - - if (publicKey != null) - publicKeys.add(publicKey); + + // TODO } } - - return publicKeys; + + return new ArrayList(map.values()); + } /** @@ -106,7 +114,7 @@ public class JwtSigningAndValidationServiceDefault implements // TODO Auto-generated method stub return false; } - + /** * Set the JwtSigners associated with this service * @@ -132,14 +140,14 @@ public class JwtSigningAndValidationServiceDefault implements */ @Override public boolean validateIssuedJwt(Jwt jwt) { - + // TODO Verify this is correct... - for (JwtSigner signer: signers) { + for (JwtSigner signer : signers) { if (signer.verify(jwt.toString())) return true; } - + return false; } @@ -153,11 +161,11 @@ public class JwtSigningAndValidationServiceDefault implements @Override public boolean validateSignature(String jwtString) { - for (JwtSigner signer: signers) { + for (JwtSigner signer : signers) { if (signer.verify(jwtString)) return true; } - + return false; } } diff --git a/server/src/main/java/org/mitre/jwt/signer/service/impl/KeyStore.java b/server/src/main/java/org/mitre/jwt/signer/service/impl/KeyStore.java index a9341d634..2f5ddcdaf 100644 --- a/server/src/main/java/org/mitre/jwt/signer/service/impl/KeyStore.java +++ b/server/src/main/java/org/mitre/jwt/signer/service/impl/KeyStore.java @@ -1,8 +1,5 @@ package org.mitre.jwt.signer.service.impl; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.Key; @@ -10,7 +7,6 @@ import java.security.KeyPair; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; -import java.security.interfaces.RSAPrivateKey; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -107,8 +103,8 @@ public class KeyStore implements InitializingBean { // Get public key PublicKey publicKey = cert.getPublicKey(); - - return new KeyPair(publicKey, (RSAPrivateKey) key); + + return new KeyPair(publicKey, (PrivateKey) key); } return null; diff --git a/server/src/main/resources/keystore.jks b/server/src/main/resources/keystore.jks index bb424e26437aa0e5794c7d7d4610984208822b62..b3f5de2dfa28d87b4ca988023d330580ffe69a4a 100644 GIT binary patch delta 1945 zcmV;K2WI$`5t9*+8h?W&sJj3F1pzRE1pP1$1_~<%0R#am0uccL1pows1nGNY}(R`Ml=54>mK@er%avE@c)8o`h547Jrak7W8}UL4nI!pysl+ zAJaDo5f9KTt8~&2q^2ByFltzOv2g50@Xb17#lcR|3OfQ1d%E3L;yRCRVVjKdzJisF z!gRH=F0_nT>W9WUIGjwOcKJU88b0xIAcQXEi;4w_rf)ydOft3;WObGgh-DjTsn)3lMwKj4RY)v+eUwUUZoX3oI z5V4_G2^?Y{pffMq@fjx&uqlw+W~W$2o^IHt#Yxz47jX>v(r*$E{dXMo0bW39x?&0} zkoR_ROinYLiqk|ko-hr4EPqQ@7Ef{)T6ubOa{qk{P=A0dSUB%5cBO497(Ix$2Lt9X zW$YXF8?zgb)8QxW#G;RuOFO&!5T8a8=f2oR2uTUgpC-%wyu7dLS@>6g+q6!thiS`I zI8cSGsodOZXp;jf&68+k^I8aFH5piXER}pzHmE)0$qvG7==l-FE-Dk&;iM5~lGtQe zqm9JVH-9AXldU^O>;1~uWjEqm4DBQ1ANzA$8qZZYPBWOB)UpjXll4KWEa7{-p)ulF zEp=`t8`Y6@!-RtKgMtE|QYUi;nJ(*+Q0tUd+~nr#o0zs`*OBjUb6C0K-`yd1E6v;W zdWo7RQvj>(!pD&zHUjgX21=B-DQ%A~>J&7Q3x6mbCR=c>;hJj0N#b&hAX0=JV^7hA zP;aGW;3_al>qhM~)`(_mIy4Vp zR%~|Vvuoxc*AihJnE-FIi1(|@SvaNx%D`+B*ImvM9Mx)Ka6pSx)`TVrQGC`*)4mAX zAAeCd&Ive!B%;Up1OT2i9~OW^nY&4Fr<eH;;nMp$Q|FAYm+#qxP?X0R@bFM5kfFUdysEZes^`+w48gg=+} zf^X}-FgC>uu(HZPbAFPB8weR(I3xK8!hcWpq8!NN-R0Bh`N@ZKgDp`*U%6pGCsGH3 z1nkJ(-pF{M^NB^?EIFjozaup-7ga1$&nvaUk-9}RU*b@_;gJt%uKo*$(&0P95OE%t zRiI?iAT zC)r+;RH>cF@gBIK9A_HG-ieGX~x*YT=Y$O`CjX8E((`om;KjMkO*90Y5 zZnGbnDPr~6w_5m-hCdolmqbjNoOw(TE0oE)aeu*Tz$?lQlT)V(C|8UT=sl@YeX$Hy z6i5rqRTH0+;yLtTp8x;=0RRP9E;TSY0009`FoFX~FoFUx0t8PyGK4S<1_>&LNQUQV1#FW?1|WZh^rBctCp2{Vj22jw z_#2Ji*l|)-diGGB&Y3-crDn%+npwMEQC?a5mi^=36I2=1RaOy8B#Vkso~x~Sr%hnL zA#y9{XW{qSJ~YMA#m0QWe9#zE$D#)w1&uQu8j+D(lld@(9#tX)K}Kd$7YThXQ!MiQtemVrLnUPJm{&LNQU8{JLKN*Qcbg>@V5cH6E$-~#{r&v$#2@_e2y&r%CL5RmrW zMeW*dB7c55um#ChktY}fC4BhtLd=&89-8H!YBl-t$e>csHK>mRFAz>cm!m-^Eg#Zj zQ6SL8=;o9Il fwpe^8>+v^lp5p?u7z_-~>tU1ODttWp?l8G)1Xzu8 delta 1946 zcmV;L2W9w^5tI>-8h?KNK>+{&1p+XF1pY7%1_~<%0R#am0uccL1pows1nS-Dxmd*v z3<^JA!ReTak^SQ3_96Y-~k6O1EW6~@RE+N7VNh1C;ON=X(foe z@&S}HN^e|`M(P-Q!rJk7i~&?cz6~bDyHA4$S@p`4SR=f6P$rnAR$bkW5;sp1+BnWx zjGEErTsSJF!xMv4pM@f2qMyjZwipJGJOb4$ zu10pd)hNr5q-L9F4CB<%HzK>yhAl*c2EVz}v?e4TU_xHvVMyt!mkfp#@!$8KVf)^@ z^yAn^AAh@dOT1lwbC+~``9Gm>V;*JK7F=`qoPH94Eo!AS%AWsc=xSB3LXFy$c5DOu zp+tv_ix02x80l?II~FB#xe+yD@zkLj=M`Fr>gZ55wTYix*&yBEliep zdpecs%Mn7&`3H_&ACkH zQh6z2O3I6_sq9^(GzL5vPllj(SLFAdAPoyn{Bm13;YXLS&@D$BRFE_FAo*An``!&^Do{D%B^@96_7922ojK(y@TTB1mY|i6ju2 zvU=_WACpgssHaDv=SYoqVqI~=4s434gcUpsKt*^%yCzUxYNL7qv=PeWEV%QWDKGP_ zUtx{lLu4$3Ur}K_X~w2g#K2c-U5%#5nhkri-dEHM~J!&`o?BrkPT zw~(0SJX~#fg>ePDYzLe{ky1`}1M>5R35#w#6Pc3nuWt+km0Ge4JOoLiAXGtS=6^F% zUlF!;By1NoyG#PQKcJ`I>TuUYUWkIua2_f_83ZpHcmlvazg$FD`1fKY$yelveV7dG zmeSmG>$KgUq%@l%8X9D5LD;B}Zmbp*Pz~4*2w`ni+RkwnO7F_G+-uL%rN{a4NvpWyn}diUS_)sHsXA{F@@ znWE>7IC?dPY-1uPbD+~W`EPz|t2AW|VVJni^*h+tt4)srcrwC=mzbHjdI=v^6xnqK z+5d9{u9y&=acf|kz00966SS~d%IRF3yO)!E3Nic!}F#-fnJ0eXm4F(A+hDe6@ z4FLfQlT8J87BDk0F)%q=7Y#8pFfuVTFf%bRFgaS2PX%m~Mg|~%)Gfu)Jc|M{qx&)X z(Hwm7CW;`MuMwc(k;!8g$)8#vE7)aO`Ll$nBAiBgiR;f&^L{IX7SgSb}k`%LM zof^=&7eM}Pu{iWGyjVWWM7O2NXs;28toRR?d9rg7zK8tQW*&V%Q zhF>OxLWfC92O}vRy)A&xRjiaC)IIP*_Xh;SXLZ31wJ!?9%TFXB@>|qybXt! zv}jR#yUv_{%^_dBx|P-{0rINt2XRbtaA35v_}DZ7D-5JG1JaiI%FLdB(B_BtkG_l( zkMn8E13=yySt;y~E_Dx?*p^lprBZSY*$%XdE(+Xn;p~m`i^CiX0PJ9l1heD~g}dQS zuEtnuRCldtXs}p$Z gg*%o}m_KZfEdQhBvIJde`F8@RPmu%3TLc#b7IrR*WB>pF diff --git a/server/src/test/java/org/mitre/jwt/JwtTest.java b/server/src/test/java/org/mitre/jwt/JwtTest.java index bc8a6481a..5a57c6839 100644 --- a/server/src/test/java/org/mitre/jwt/JwtTest.java +++ b/server/src/test/java/org/mitre/jwt/JwtTest.java @@ -1,6 +1,8 @@ package org.mitre.jwt; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; import java.io.UnsupportedEncodingException; @@ -15,7 +17,6 @@ import org.mitre.jwt.signer.impl.PlaintextSigner; import org.mitre.jwt.signer.impl.RsaSigner; import org.mitre.jwt.signer.service.impl.KeyStore; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -25,35 +26,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; public class JwtTest { @Autowired - @Qualifier("testKeystore") KeyStore keystore; - @Test - public void testToStringPlaintext() { - Jwt jwt = new Jwt(); - jwt.getHeader().setAlgorithm("none"); - jwt.getClaims().setExpiration(new Date(1300819380L * 1000L)); - jwt.getClaims().setIssuer("joe"); - jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE); - - // sign it with a blank signature - JwtSigner signer = new PlaintextSigner(); - signer.sign(jwt); - - /* - * Expected string based on the following structures, serialized exactly as follows and base64 encoded: - * - * header: {"alg":"none"} - * claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true} - */ - String expected = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ."; - - String actual = jwt.toString(); - - assertThat(actual, equalTo(expected)); - - } - @Test public void testGenerateHmacSignature() { Jwt jwt = new Jwt(); @@ -94,40 +68,70 @@ public class JwtTest { assertThat(jwt.getSignature(), equalTo(signature)); } - + /** * @throws Exception */ -// @Test -// public void testGenerateRsaSignature() throws Exception { -// -//// java.security.KeyStore ks = KeyStore.generateRsaKeyPair(keystore -//// .getLocation().getFile().getPath(), "OpenID Connect Server", -//// "twentyYears", KeyStore.PASSWORD, KeyStore.PASSWORD, 30, 365*20); -//// -//// keystore.setKeystore(ks); -// -// Jwt jwt = new Jwt(); -// jwt.getHeader().setType("JWT"); -// jwt.getHeader().setAlgorithm("RS256"); -// jwt.getClaims().setExpiration(new Date(1300819380L * 1000L)); -// jwt.getClaims().setIssuer("joe"); -// jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE); -// -// JwtSigner signer = new RsaSigner(RsaSigner.Algorithm.DEFAULT, keystore, "twentyYears"); -// ((RsaSigner) signer).afterPropertiesSet(); -// -// signer.sign(jwt); -// -// String signature = "TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg"; -// String expected = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.TW0nOd_vr1rnV7yIS-lIV2-00V_zJMWxzOc3Z7k3gvMO2aIjIGjZ9nByZMI0iL5komMxYXPl_RCkbd9OKiPkk4iK5CDj7Mawbzu95LgEOOqdXO1f7-IqX9dIvJhVXXInLD3RsGvavyheIqNeFEVidLrJo30tBchB_niljEW7VeX8nSZfiCOdbOTW3hu0ycnon7wFpejb-cRP_S0iqGxCgbYXJzqPT192EHmRy_wmFxxIy9Lc84uqNkAZSIn1jVIeAemm22RoWbq0xLVLTRyiZoxJTUzac_VteiSPRNFlUQuOdxqNf0Hxqh_wVfX1mfXUzv0D8vHJVy6aIqTISmn-qg"; -// -// String actual = jwt.toString(); -// -// assertThat(actual, equalTo(expected)); -// assertThat(jwt.getSignature(), equalTo(signature)); -// -// } + /** + * @throws Exception + */ + @Test + public void testGenerateRsaSignature() throws Exception { + + Jwt jwt = new Jwt(); + jwt.getHeader().setType("JWT"); + jwt.getHeader().setAlgorithm("RS256"); + jwt.getClaims().setExpiration(new Date(1300819380L * 1000L)); + jwt.getClaims().setIssuer("joe"); + jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE); + + JwtSigner signer = new RsaSigner(RsaSigner.Algorithm.RS256.toString(), keystore, "test", "changeit"); + ((RsaSigner)signer).afterPropertiesSet(); + + signer.sign(jwt); + + assertThat(jwt.getSignature(), not(nullValue())); + } + + @Test + public void testParse() { + String source = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ."; + + + Jwt jwt = Jwt.parse(source); + + assertThat(jwt.getHeader().getAlgorithm(), equalTo(PlaintextSigner.PLAINTEXT)); + assertThat(jwt.getClaims().getIssuer(), equalTo("joe")); + assertThat(jwt.getClaims().getExpiration(), equalTo(new Date(1300819380L * 1000L))); + assertThat((Boolean)jwt.getClaims().getClaim("http://example.com/is_root"), equalTo(Boolean.TRUE)); + + } + + @Test + public void testToStringPlaintext() { + Jwt jwt = new Jwt(); + jwt.getHeader().setAlgorithm("none"); + jwt.getClaims().setExpiration(new Date(1300819380L * 1000L)); + jwt.getClaims().setIssuer("joe"); + jwt.getClaims().setClaim("http://example.com/is_root", Boolean.TRUE); + + // sign it with a blank signature + JwtSigner signer = new PlaintextSigner(); + signer.sign(jwt); + + /* + * Expected string based on the following structures, serialized exactly as follows and base64 encoded: + * + * header: {"alg":"none"} + * claims: {"exp":1300819380,"iss":"joe","http://example.com/is_root":true} + */ + String expected = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ."; + + String actual = jwt.toString(); + + assertThat(actual, equalTo(expected)); + + } @Test public void testValidateHmacSignature() { @@ -158,19 +162,5 @@ public class JwtTest { assertThat(valid, equalTo(Boolean.TRUE)); } - - @Test - public void testParse() { - String source = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ."; - - - Jwt jwt = Jwt.parse(source); - - assertThat(jwt.getHeader().getAlgorithm(), equalTo(PlaintextSigner.PLAINTEXT)); - assertThat(jwt.getClaims().getIssuer(), equalTo("joe")); - assertThat(jwt.getClaims().getExpiration(), equalTo(new Date(1300819380L * 1000L))); - assertThat((Boolean)jwt.getClaims().getClaim("http://example.com/is_root"), equalTo(Boolean.TRUE)); - - } } diff --git a/server/src/test/java/org/mitre/jwt/signer/service/impl/KeyStoreTest.java b/server/src/test/java/org/mitre/jwt/signer/service/impl/KeyStoreTest.java index 8a3e39d65..1aa39a18d 100644 --- a/server/src/test/java/org/mitre/jwt/signer/service/impl/KeyStoreTest.java +++ b/server/src/test/java/org/mitre/jwt/signer/service/impl/KeyStoreTest.java @@ -25,7 +25,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -@SuppressWarnings({ "restriction", "deprecation" }) // I know... +@SuppressWarnings("deprecation") @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:test-context.xml" }) @@ -36,7 +36,7 @@ public class KeyStoreTest { KeyStore keystore; static { - // Need to create the certificate + // Needed to create the certificate Security.addProvider(new BouncyCastleProvider()); } @@ -48,7 +48,7 @@ public class KeyStoreTest { * @param daysNotValidAfter * @return */ - private X509V3CertificateGenerator createCertificate( + private static X509V3CertificateGenerator createCertificate( String commonName, int daysNotValidBefore, int daysNotValidAfter) { // BC sez X509V3CertificateGenerator is deprecated and the docs say to // use another, but it seemingly isn't included jar... @@ -81,7 +81,7 @@ public class KeyStoreTest { * @throws GeneralSecurityException * @throws IOException */ - public java.security.KeyStore generateRsaKeyPair( + public static java.security.KeyStore generateRsaKeyPair(KeyStore keystore, String domainName, String alias, String aliasPassword, int daysNotValidBefore, int daysNotValidAfter) throws GeneralSecurityException, IOException { @@ -117,13 +117,14 @@ public class KeyStoreTest { return ks; } + @Test public void storeKeyPair() throws GeneralSecurityException, IOException { java.security.KeyStore ks = null; try { - ks = generateRsaKeyPair("OpenID Connect Server", "storeKeyPair", "changeit", 30, 365); + ks = KeyStoreTest.generateRsaKeyPair(keystore, "OpenID Connect Server", "storeKeyPair", "changeit", 30, 365); } catch (GeneralSecurityException e) { // TODO Auto-generated catch block @@ -135,19 +136,13 @@ public class KeyStoreTest { assertThat(ks, not(nullValue())); } - + @Test public void readKey() throws GeneralSecurityException { - + Key key = keystore.getKeystore().getKey("storeKeyPair", KeyStore.PASSWORD.toCharArray()); - - System.out.println("-----BEGIN PRIVATE KEY-----"); - System.out - .println(new sun.misc.BASE64Encoder().encode(key.getEncoded())); - System.out.println("-----END PRIVATE KEY-----"); - + assertThat(key, not(nullValue())); - assertThat(true, not(false)); } } diff --git a/server/src/test/resources/keystore.jks b/server/src/test/resources/keystore.jks index bb424e26437aa0e5794c7d7d4610984208822b62..b3f5de2dfa28d87b4ca988023d330580ffe69a4a 100644 GIT binary patch delta 1945 zcmV;K2WI$`5t9*+8h?W&sJj3F1pzRE1pP1$1_~<%0R#am0uccL1pows1nGNY}(R`Ml=54>mK@er%avE@c)8o`h547Jrak7W8}UL4nI!pysl+ zAJaDo5f9KTt8~&2q^2ByFltzOv2g50@Xb17#lcR|3OfQ1d%E3L;yRCRVVjKdzJisF z!gRH=F0_nT>W9WUIGjwOcKJU88b0xIAcQXEi;4w_rf)ydOft3;WObGgh-DjTsn)3lMwKj4RY)v+eUwUUZoX3oI z5V4_G2^?Y{pffMq@fjx&uqlw+W~W$2o^IHt#Yxz47jX>v(r*$E{dXMo0bW39x?&0} zkoR_ROinYLiqk|ko-hr4EPqQ@7Ef{)T6ubOa{qk{P=A0dSUB%5cBO497(Ix$2Lt9X zW$YXF8?zgb)8QxW#G;RuOFO&!5T8a8=f2oR2uTUgpC-%wyu7dLS@>6g+q6!thiS`I zI8cSGsodOZXp;jf&68+k^I8aFH5piXER}pzHmE)0$qvG7==l-FE-Dk&;iM5~lGtQe zqm9JVH-9AXldU^O>;1~uWjEqm4DBQ1ANzA$8qZZYPBWOB)UpjXll4KWEa7{-p)ulF zEp=`t8`Y6@!-RtKgMtE|QYUi;nJ(*+Q0tUd+~nr#o0zs`*OBjUb6C0K-`yd1E6v;W zdWo7RQvj>(!pD&zHUjgX21=B-DQ%A~>J&7Q3x6mbCR=c>;hJj0N#b&hAX0=JV^7hA zP;aGW;3_al>qhM~)`(_mIy4Vp zR%~|Vvuoxc*AihJnE-FIi1(|@SvaNx%D`+B*ImvM9Mx)Ka6pSx)`TVrQGC`*)4mAX zAAeCd&Ive!B%;Up1OT2i9~OW^nY&4Fr<eH;;nMp$Q|FAYm+#qxP?X0R@bFM5kfFUdysEZes^`+w48gg=+} zf^X}-FgC>uu(HZPbAFPB8weR(I3xK8!hcWpq8!NN-R0Bh`N@ZKgDp`*U%6pGCsGH3 z1nkJ(-pF{M^NB^?EIFjozaup-7ga1$&nvaUk-9}RU*b@_;gJt%uKo*$(&0P95OE%t zRiI?iAT zC)r+;RH>cF@gBIK9A_HG-ieGX~x*YT=Y$O`CjX8E((`om;KjMkO*90Y5 zZnGbnDPr~6w_5m-hCdolmqbjNoOw(TE0oE)aeu*Tz$?lQlT)V(C|8UT=sl@YeX$Hy z6i5rqRTH0+;yLtTp8x;=0RRP9E;TSY0009`FoFX~FoFUx0t8PyGK4S<1_>&LNQUQV1#FW?1|WZh^rBctCp2{Vj22jw z_#2Ji*l|)-diGGB&Y3-crDn%+npwMEQC?a5mi^=36I2=1RaOy8B#Vkso~x~Sr%hnL zA#y9{XW{qSJ~YMA#m0QWe9#zE$D#)w1&uQu8j+D(lld@(9#tX)K}Kd$7YThXQ!MiQtemVrLnUPJm{&LNQU8{JLKN*Qcbg>@V5cH6E$-~#{r&v$#2@_e2y&r%CL5RmrW zMeW*dB7c55um#ChktY}fC4BhtLd=&89-8H!YBl-t$e>csHK>mRFAz>cm!m-^Eg#Zj zQ6SL8=;o9Il fwpe^8>+v^lp5p?u7z_-~>tU1ODttWp?l8G)1Xzu8 delta 1946 zcmV;L2W9w^5tI>-8h?KNK>+{&1p+XF1pY7%1_~<%0R#am0uccL1pows1nS-Dxmd*v z3<^JA!ReTak^SQ3_96Y-~k6O1EW6~@RE+N7VNh1C;ON=X(foe z@&S}HN^e|`M(P-Q!rJk7i~&?cz6~bDyHA4$S@p`4SR=f6P$rnAR$bkW5;sp1+BnWx zjGEErTsSJF!xMv4pM@f2qMyjZwipJGJOb4$ zu10pd)hNr5q-L9F4CB<%HzK>yhAl*c2EVz}v?e4TU_xHvVMyt!mkfp#@!$8KVf)^@ z^yAn^AAh@dOT1lwbC+~``9Gm>V;*JK7F=`qoPH94Eo!AS%AWsc=xSB3LXFy$c5DOu zp+tv_ix02x80l?II~FB#xe+yD@zkLj=M`Fr>gZ55wTYix*&yBEliep zdpecs%Mn7&`3H_&ACkH zQh6z2O3I6_sq9^(GzL5vPllj(SLFAdAPoyn{Bm13;YXLS&@D$BRFE_FAo*An``!&^Do{D%B^@96_7922ojK(y@TTB1mY|i6ju2 zvU=_WACpgssHaDv=SYoqVqI~=4s434gcUpsKt*^%yCzUxYNL7qv=PeWEV%QWDKGP_ zUtx{lLu4$3Ur}K_X~w2g#K2c-U5%#5nhkri-dEHM~J!&`o?BrkPT zw~(0SJX~#fg>ePDYzLe{ky1`}1M>5R35#w#6Pc3nuWt+km0Ge4JOoLiAXGtS=6^F% zUlF!;By1NoyG#PQKcJ`I>TuUYUWkIua2_f_83ZpHcmlvazg$FD`1fKY$yelveV7dG zmeSmG>$KgUq%@l%8X9D5LD;B}Zmbp*Pz~4*2w`ni+RkwnO7F_G+-uL%rN{a4NvpWyn}diUS_)sHsXA{F@@ znWE>7IC?dPY-1uPbD+~W`EPz|t2AW|VVJni^*h+tt4)srcrwC=mzbHjdI=v^6xnqK z+5d9{u9y&=acf|kz00966SS~d%IRF3yO)!E3Nic!}F#-fnJ0eXm4F(A+hDe6@ z4FLfQlT8J87BDk0F)%q=7Y#8pFfuVTFf%bRFgaS2PX%m~Mg|~%)Gfu)Jc|M{qx&)X z(Hwm7CW;`MuMwc(k;!8g$)8#vE7)aO`Ll$nBAiBgiR;f&^L{IX7SgSb}k`%LM zof^=&7eM}Pu{iWGyjVWWM7O2NXs;28toRR?d9rg7zK8tQW*&V%Q zhF>OxLWfC92O}vRy)A&xRjiaC)IIP*_Xh;SXLZ31wJ!?9%TFXB@>|qybXt! zv}jR#yUv_{%^_dBx|P-{0rINt2XRbtaA35v_}DZ7D-5JG1JaiI%FLdB(B_BtkG_l( zkMn8E13=yySt;y~E_Dx?*p^lprBZSY*$%XdE(+Xn;p~m`i^CiX0PJ9l1heD~g}dQS zuEtnuRCldtXs}p$Z gg*%o}m_KZfEdQhBvIJde`F8@RPmu%3TLc#b7IrR*WB>pF