From f31fd5c3a56e4db540bc7e81a8d321f2740d386b Mon Sep 17 00:00:00 2001 From: Amanda Anganes Date: Thu, 29 Dec 2011 09:12:19 -0500 Subject: [PATCH] Added implementation of the verify method to the Rs256Signer class. Added comments for steps needed in stub of Es256Signer class. --- .../mitre/jwt/signer/impl/Es256Signer.java | 36 +++++++++++- .../mitre/jwt/signer/impl/Rs256Signer.java | 57 +++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mitre/jwt/signer/impl/Es256Signer.java b/src/main/java/org/mitre/jwt/signer/impl/Es256Signer.java index 877e4f442..5046fbb25 100644 --- a/src/main/java/org/mitre/jwt/signer/impl/Es256Signer.java +++ b/src/main/java/org/mitre/jwt/signer/impl/Es256Signer.java @@ -4,15 +4,45 @@ import org.mitre.jwt.signer.AbstractJwtSigner; public class Es256Signer extends AbstractJwtSigner { + public Es256Signer() { + this(null); + } + public Es256Signer(String algorithm) { - super(algorithm); - // TODO Auto-generated constructor stub + super("ES256"); } @Override protected String generateSignature(String signatureBase) { - // TODO Auto-generated method stub + + /* + 1) Generate a digital signature of the UTF-8 representation of the JWS Signing Input + using ECDSA P-256 SHA-256 with the desired private key. The output will be the + EC point (R, S), where R and S are unsigned integers. + 2) Turn R and S into byte arrays in big endian order. Each array will be 32 bytes long. + 3) Concatenate the two byte arrays in the order R and then S. + 4) Base64url encode the resulting 64 byte array. + */ + return null; } + + @Override + public boolean verify(String jwtString) { + + /* + 1) Take the Encoded JWS Signature and base64url decode it into a byte array. + If decoding fails, the signed content MUST be rejected. + 2) The output of the base64url decoding MUST be a 64 byte array. + 3) Split the 64 byte array into two 32 byte arrays. The first array will be R and + the second S. Remember that the byte arrays are in big endian byte order; + please check the ECDSA validator in use to see what byte order it requires. + 4) Submit the UTF-8 representation of the JWS Signing Input, R, S and the public + key (x, y) to the ECDSA P-256 SHA-256 validator. + 5) If the validation fails, the signed content MUST be rejected. + */ + + return false; + } } diff --git a/src/main/java/org/mitre/jwt/signer/impl/Rs256Signer.java b/src/main/java/org/mitre/jwt/signer/impl/Rs256Signer.java index 4e0170f22..21ee9ec83 100644 --- a/src/main/java/org/mitre/jwt/signer/impl/Rs256Signer.java +++ b/src/main/java/org/mitre/jwt/signer/impl/Rs256Signer.java @@ -4,12 +4,17 @@ import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; +import java.util.List; import org.apache.commons.codec.binary.Base64; import org.mitre.jwt.signer.AbstractJwtSigner; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + /** * JWT Signer using RSA SHA-256 algorithm * @author AANGANES @@ -19,6 +24,9 @@ public class Rs256Signer extends AbstractJwtSigner { //TODO: should this class generate a new private key or get one passed into the constructor? private PrivateKey privateKey; + //TODO: where does the publicKey come from? + private PublicKey publicKey; + private Signature signer; public Rs256Signer() { @@ -74,6 +82,55 @@ public class Rs256Signer extends AbstractJwtSigner { return sig; } + @Override + public boolean verify(String jwtString) { + + // split on the dots + List parts = Lists.newArrayList(Splitter.on(".").split(jwtString)); + + if (parts.size() != 3) { + throw new IllegalArgumentException("Invalid JWT format."); + } + + String h64 = parts.get(0); + String c64 = parts.get(1); + String s64 = parts.get(2); + + String signingInput = h64 + "." + c64 + "."; + + try { + signer.initVerify(publicKey); + } catch (InvalidKeyException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + return false; + } + + try { + signer.update(signingInput.getBytes("UTF-8")); + } catch (SignatureException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (UnsupportedEncodingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + try { + signer.verify(s64.getBytes("UTF-8")); + } catch (SignatureException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + + return true; + } + public PrivateKey getPrivateKey() { return privateKey; }