From a041e8b9c6c8db5a4de6ffa8945d14bd4e7ccab1 Mon Sep 17 00:00:00 2001 From: Erandi Rajasekara Date: Mon, 25 Oct 2021 19:42:03 +0530 Subject: [PATCH 1/4] Add dpop client app --- dpop/DPoP-client-app/.gitignore | 5 + dpop/DPoP-client-app/pom.xml | 145 ++++++++++++++++++ .../wso2/dpop/client/DPOPProofGenerator.java | 98 ++++++++++++ .../dpop/client/DPOPProofGeneratorFromPP.java | 120 +++++++++++++++ .../dpop/client/GeneratePublicKeyPair.java | 62 ++++++++ pom.xml | 1 + 6 files changed, 431 insertions(+) create mode 100644 dpop/DPoP-client-app/.gitignore create mode 100644 dpop/DPoP-client-app/pom.xml create mode 100644 dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java create mode 100644 dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java create mode 100644 dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java diff --git a/dpop/DPoP-client-app/.gitignore b/dpop/DPoP-client-app/.gitignore new file mode 100644 index 000000000..26c8374f1 --- /dev/null +++ b/dpop/DPoP-client-app/.gitignore @@ -0,0 +1,5 @@ +target +*.iml +.idea +dpop.key +dpop.pub \ No newline at end of file diff --git a/dpop/DPoP-client-app/pom.xml b/dpop/DPoP-client-app/pom.xml new file mode 100644 index 000000000..2e03cbd50 --- /dev/null +++ b/dpop/DPoP-client-app/pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.wso2.dpop.client + client-app + 1.0 + + + 8 + 8 + 7.3.0.wso2v1 + 1.3 + + + + + ${project.basedir} + + lib/*.jar + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.9 + + true + false + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + lib/ + com.etl_aggregation.app.App + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.4.1 + + + + jar-with-dependencies + + + + + com.etl_aggregation.app.App + + + + + + + make-assembly + + package + + single + + + + + + + + + org.wso2.orbit.com.nimbusds + nimbus-jose-jwt + ${nimbusds.version} + + + net.minidev + json-smart + ${json-smart.version} + + + + + + wso2-nexus + WSO2 internal Repository + https://maven.wso2.org/nexus/content/groups/wso2-public/ + + true + daily + ignore + + + + wso2.releases + WSO2 internal Repository + https://maven.wso2.org/nexus/content/repositories/releases/ + + true + daily + ignore + + + + + wso2.snapshots + WSO2 Snapshot Repository + https://maven.wso2.org/nexus/content/repositories/snapshots/ + + true + daily + + + false + + + + diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java new file mode 100644 index 000000000..86603fca3 --- /dev/null +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java @@ -0,0 +1,98 @@ +package org.wso2.dpop.client; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.crypto.ECDSASigner; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.JWK; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.text.ParseException; +import java.util.Date; +import java.util.Scanner; +import java.util.UUID; + +import static com.nimbusds.jose.JWSAlgorithm.ES256; +import static com.nimbusds.jose.JWSAlgorithm.RS384; + +public class DPOPProofGenerator { + + public static void main(String args[]) throws NoSuchAlgorithmException, JOSEException, ParseException, + InvalidAlgorithmParameterException { + + Scanner scan = new Scanner(System.in); + System.out.println("Enter the public and private key pair type(EC or RSA): "); + String keyPairType = scan.nextLine(); + System.out.println("Enter the HTTP Method: "); + String httpMethod = scan.nextLine(); + System.out.println("Enter the HTTP Url: "); + String httpUrl = scan.nextLine(); + + KeyPairGenerator gen = KeyPairGenerator.getInstance(keyPairType); + KeyPair keyPair; + JWK jwk = null; + if (keyPairType.equals("EC")) { + gen.initialize(Curve.P_256.toECParameterSpec()); + keyPair = gen.generateKeyPair(); + jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()) + .build(); + } else { + gen = KeyPairGenerator.getInstance("RSA"); + gen.initialize(2048); + keyPair = gen.generateKeyPair(); + jwk = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).build(); + } + + System.out.println("jwk: " + jwk); + System.out.println("publicKey: " + keyPair.getPublic()); + System.out.println("private: " + keyPair.getPrivate()); + + JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); + jwtClaimsSetBuilder.issuer("issuer"); + jwtClaimsSetBuilder.subject("sub"); + jwtClaimsSetBuilder.issueTime(new Date(System.currentTimeMillis())); + jwtClaimsSetBuilder.jwtID(UUID.randomUUID().toString()); + jwtClaimsSetBuilder.notBeforeTime(new Date(System.currentTimeMillis())); + jwtClaimsSetBuilder.claim("htm", httpMethod); + jwtClaimsSetBuilder.claim("htu", httpUrl); + + JWSHeader.Builder headerBuilder; + if (keyPairType.equals("EC")) { + headerBuilder = new JWSHeader.Builder(ES256); + } else { + headerBuilder = new JWSHeader.Builder(RS384); + } + headerBuilder.type(new JOSEObjectType("dpop+jwt")); + headerBuilder.jwk(jwk); + SignedJWT signedJWT = new SignedJWT(headerBuilder.build(), jwtClaimsSetBuilder.build()); + + if (keyPairType.equals("EC")) { + ECDSASigner ecdsaSigner = new ECDSASigner(keyPair.getPrivate(), Curve.P_256); + signedJWT.sign(ecdsaSigner); + } else { + RSASSASigner rsassaSigner = new RSASSASigner(keyPair.getPrivate()); + signedJWT.sign(rsassaSigner); + } + + System.out.println("[Signed JWT] : " + signedJWT.serialize()); + JWK parseJwk = JWK.parse(String.valueOf(jwk)); + if (keyPairType.equals("EC")) { + ECKey ecKey = (ECKey) parseJwk; + System.out.println("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); + } else { + RSAKey rsaKey = (RSAKey) parseJwk; + System.out.println("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); + } + } +} diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java new file mode 100644 index 000000000..6b74c5e20 --- /dev/null +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java @@ -0,0 +1,120 @@ +package org.wso2.dpop.client; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.crypto.ECDSASigner; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.JWK; +import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.text.ParseException; +import java.util.Date; +import java.util.Scanner; +import java.util.UUID; + +import static com.nimbusds.jose.JWSAlgorithm.ES256; +import static com.nimbusds.jose.JWSAlgorithm.RS384; + +public class DPOPProofGeneratorFromPP { + + public static void main(String args[]) throws NoSuchAlgorithmException, JOSEException, ParseException, + IOException, InvalidKeySpecException { + + Scanner scan = new Scanner(System.in); + System.out.println("File path to private key: "); + String privateKeyPath = scan.nextLine(); + System.out.println("File path to public key: "); + String publicKeyPath = scan.nextLine(); + System.out.println("Enter the public and private key pair type(EC or RSA): "); + String keyPairType = scan.nextLine(); + System.out.println("Enter the HTTP Method: "); + String httpMethod = scan.nextLine(); + System.out.println("Enter the HTTP Url: "); + String httpUrl = scan.nextLine(); + + /* Read all bytes from the private key file */ + Path path = Paths.get(privateKeyPath); + byte[] bytes = Files.readAllBytes(path); + + /* Generate private key. */ + PKCS8EncodedKeySpec privateKs = new PKCS8EncodedKeySpec(bytes); + KeyFactory privateKf = KeyFactory.getInstance(args[3]); + PrivateKey privateKey = privateKf.generatePrivate(privateKs); + + /* Read all the public key bytes */ + Path pubPath = Paths.get(publicKeyPath); + byte[] pubBytes = Files.readAllBytes(pubPath); + + /* Generate public key. */ + X509EncodedKeySpec ks = new X509EncodedKeySpec(pubBytes); + KeyFactory kf = KeyFactory.getInstance(args[3]); + PublicKey publicCert = kf.generatePublic(ks); + + JWK jwk = null; + if (keyPairType.equals("EC")) { + jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) publicCert) + .build(); + } else { + jwk = new RSAKey.Builder((RSAPublicKey) publicCert).build(); + } + + System.out.println("jwk: " + jwk); + System.out.println("publicKey: " + publicCert); + System.out.println("private: " + privateKey); + + JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); + jwtClaimsSetBuilder.issuer("issuer"); + jwtClaimsSetBuilder.subject("sub"); + jwtClaimsSetBuilder.issueTime(new Date(System.currentTimeMillis())); + jwtClaimsSetBuilder.jwtID(UUID.randomUUID().toString()); + jwtClaimsSetBuilder.notBeforeTime(new Date(System.currentTimeMillis())); + jwtClaimsSetBuilder.claim("htm", httpMethod); + jwtClaimsSetBuilder.claim("htu", httpUrl); + + JWSHeader.Builder headerBuilder; + if (keyPairType.equals("EC")) { + headerBuilder = new JWSHeader.Builder(ES256); + } else { + headerBuilder = new JWSHeader.Builder(RS384); + } + headerBuilder.type(new JOSEObjectType("dpop+jwt")); + headerBuilder.jwk(jwk); + SignedJWT signedJWT = new SignedJWT(headerBuilder.build(), jwtClaimsSetBuilder.build()); + + if (keyPairType.equals("EC")) { + ECDSASigner ecdsaSigner = new ECDSASigner(privateKey, Curve.P_256); + signedJWT.sign(ecdsaSigner); + } else { + RSASSASigner rsassaSigner = new RSASSASigner(privateKey); + signedJWT.sign(rsassaSigner); + } + + System.out.println("[Signed JWT from File] : " + signedJWT.serialize()); + JWK parseJwk = JWK.parse(String.valueOf(jwk)); + if (keyPairType.equals("EC")) { + ECKey ecKey = (ECKey) parseJwk; + System.out.println("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); + } else { + RSAKey rsaKey = (RSAKey) parseJwk; + System.out.println("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); + } + } +} diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java new file mode 100644 index 000000000..4f9a6992a --- /dev/null +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java @@ -0,0 +1,62 @@ +package org.wso2.dpop.client; + +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.JWK; +import com.nimbusds.jose.jwk.RSAKey; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.Scanner; + +public class GeneratePublicKeyPair { + + public static void main(String args[]) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, + IOException { + + Scanner scan = new Scanner(System.in); + System.out.println("Enter the public and private key pair type(EC or RSA): "); + + String keyPairType = scan.nextLine(); + KeyPairGenerator gen = KeyPairGenerator.getInstance(keyPairType); + KeyPair keyPair; + JWK jwk; + if (keyPairType.equals("EC")) { + gen.initialize(Curve.P_256.toECParameterSpec()); + keyPair = gen.generateKeyPair(); + jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()) + .build(); + } else { + gen = KeyPairGenerator.getInstance("RSA"); + gen.initialize(2048); + keyPair = gen.generateKeyPair(); + jwk = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).build(); + } + + System.out.println("jwk: " + jwk); + System.out.println("publicKey: " + keyPair.getPublic()); + System.out.println("private: " + keyPair.getPrivate()); + + Key pub = keyPair.getPublic(); + Key pvt = keyPair.getPrivate(); + + System.out.println("Private key format: " + pvt.getFormat()); + System.out.println("Public key format: " + pub.getFormat()); + + String outFile = "dpop"; + FileOutputStream privout = new FileOutputStream(outFile + ".key"); + privout.write(pvt.getEncoded()); + privout.close(); + + FileOutputStream pubout = new FileOutputStream(outFile + ".pub"); + pubout.write(pub.getEncoded()); + pubout.close(); + } +} diff --git a/pom.xml b/pom.xml index daa8afe7a..a2aa403fc 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,7 @@ identity-mgt authenticators passive-sts + dpop/DPoP-client-app From fe9f878fa9473caa692bc02f10fd58c44527dea4 Mon Sep 17 00:00:00 2001 From: Erandi Rajasekara Date: Mon, 25 Oct 2021 22:25:45 +0530 Subject: [PATCH 2/4] Add changes to DPOPProofGeneratorFromPP class --- .../java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java index 6b74c5e20..ddd072b62 100644 --- a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java @@ -56,7 +56,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce /* Generate private key. */ PKCS8EncodedKeySpec privateKs = new PKCS8EncodedKeySpec(bytes); - KeyFactory privateKf = KeyFactory.getInstance(args[3]); + KeyFactory privateKf = KeyFactory.getInstance(keyPairType); PrivateKey privateKey = privateKf.generatePrivate(privateKs); /* Read all the public key bytes */ @@ -65,7 +65,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce /* Generate public key. */ X509EncodedKeySpec ks = new X509EncodedKeySpec(pubBytes); - KeyFactory kf = KeyFactory.getInstance(args[3]); + KeyFactory kf = KeyFactory.getInstance(keyPairType); PublicKey publicCert = kf.generatePublic(ks); JWK jwk = null; From d12829e7f9fbc866f4b627e27f7e958be3052e1e Mon Sep 17 00:00:00 2001 From: erandi Date: Mon, 25 Oct 2021 22:28:35 +0530 Subject: [PATCH 3/4] Create README.md --- dpop/DPoP-client-app/README.md | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 dpop/DPoP-client-app/README.md diff --git a/dpop/DPoP-client-app/README.md b/dpop/DPoP-client-app/README.md new file mode 100644 index 000000000..99c3d5f8d --- /dev/null +++ b/dpop/DPoP-client-app/README.md @@ -0,0 +1,73 @@ +# DPoP-client-app + This client application was originally developed by Darsa Mahendrarajah as Gradle application. This repository contains the Maven conversion of the same. + + ## How to setup : + 1. Clone /dpop/DPoP-client-app + 2. Build the project using ```mvn clean install``` + 3. Follow the below steps + +### Option 01: +1. Generate per request basis DPOPProofGenerator.java (This will generate per request +private and public keypair ) + - Navigate to /samples-is/dpop/DPoP-client-app folder. + - Run the below command. + + ```java -cp target/client-app-1.0-jar-with-dependencies.jar org.wso2.dpop.client.DPOPProofGenerator``` + - Enter the user inputs for below questions. + + ``` + Enter the public and private key pair type(EC or RSA): + EC + Enter the HTTP Method: + POST + Enter the HTTP Url: + https://localhost:9443/oauth2/token + + ``` +- Extract the dpop proof from the output. + + ``` + [Signed JWT] : eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiQ + y03b1ZVQ2Z2OUlRQmlWN0JlLVdNVVEtdF9ibmo1TzBlV0tuZkhnUUJaSSIsInkiOiJla2Rsci12dFJFMHFMdUpNYU5FUDR + vdXhKNVVHTEREdWphZUN6ejhJTkdjIn19.eyJodG0iOiJQT1NUIiwic3ViIjoic3ViIiwibmJmIjoxNjM1MTc2MDg2LCJp + c3MiOiJpc3N1ZXIiLCJodHUiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMlwvdG9rZW4iLCJpYXQiOjE2Mz + UxNzYwODYsImp0aSI6ImUzMTEzYzdmLTE0YTQtNGU2ZC1hY2VmLTZjZDQ5NWQ1ZWZjNCJ9.lgEjdP1Fv3OOAaFfM4CEREg + 46RGdbusLzb4409eCMabCwbN0dS6NdXsc6qxfR_TVhkKzIUKLSDmM4qzEIuw4LQ + ``` + + ### Option 02: + 1. Generate dpop proof by passing public key and private key file location. + - Generate public key pair and store it in a file.(GeneratePublicKeyPair.java) + 1. Navigate to /samples-is/dpop/DPoP-client-app folder and run the below command.Private key file (dpop.key) and Public key file will be generated(dpop.pub). + + ```java -cp target/client-app-1.0-jar-with-dependencies.jar org.wso2.dpop.client.GeneratePublicKeyPair``` + - Use the already created key pairs and load and generate the DPoP Proof(DPOPProofGeneratorFromPP.java) . + 1. Navigate to /samples-is/dpop/DPoP-client-app folder. + 2. Run the below command. + + ``` java -cp target/client-app-1.0-jar-with-dependencies.jar org.wso2.dpop.client.DPOPProofGeneratorFromPP``` + + 3. Enter the user inputs for the below questions. + + ``` + File path to private key: + dpop.key + File path to public key: + dpop.pub + Enter the public and private key pair type(EC or RSA): + EC + Enter the HTTP Method: + POST + Enter the HTTP Url: + https://localhost:9443/oauth2/token + ``` + 4. Extract the dpop proof from the output. + + ``` + [Signed JWT] : eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiQ + y03b1ZVQ2Z2OUlRQmlWN0JlLVdNVVEtdF9ibmo1TzBlV0tuZkhnUUJaSSIsInkiOiJla2Rsci12dFJFMHFMdUpNYU5FUDR + vdXhKNVVHTEREdWphZUN6ejhJTkdjIn19.eyJodG0iOiJQT1NUIiwic3ViIjoic3ViIiwibmJmIjoxNjM1MTc2MDg2LCJp + c3MiOiJpc3N1ZXIiLCJodHUiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMlwvdG9rZW4iLCJpYXQiOjE2Mz + UxNzYwODYsImp0aSI6ImUzMTEzYzdmLTE0YTQtNGU2ZC1hY2VmLTZjZDQ5NWQ1ZWZjNCJ9.lgEjdP1Fv3OOAaFfM4CEREg + 46RGdbusLzb4409eCMabCwbN0dS6NdXsc6qxfR_TVhkKzIUKLSDmM4qzEIuw4LQ``` + From c287b2bdd187efe4362e1dc24bc5629b9be9a1c2 Mon Sep 17 00:00:00 2001 From: Erandi Rajasekara Date: Fri, 5 Aug 2022 14:19:44 +0530 Subject: [PATCH 4/4] Add code review changes --- dpop/DPoP-client-app/.gitignore | 2 +- dpop/DPoP-client-app/pom.xml | 6 +++ .../wso2/dpop/client/DPOPProofGenerator.java | 46 +++++++++++++++---- .../dpop/client/DPOPProofGeneratorFromPP.java | 46 +++++++++++++++---- .../dpop/client/GeneratePublicKeyPair.java | 38 ++++++++++++--- 5 files changed, 111 insertions(+), 27 deletions(-) diff --git a/dpop/DPoP-client-app/.gitignore b/dpop/DPoP-client-app/.gitignore index 26c8374f1..633a3d2e2 100644 --- a/dpop/DPoP-client-app/.gitignore +++ b/dpop/DPoP-client-app/.gitignore @@ -2,4 +2,4 @@ target *.iml .idea dpop.key -dpop.pub \ No newline at end of file +dpop.pub diff --git a/dpop/DPoP-client-app/pom.xml b/dpop/DPoP-client-app/pom.xml index 2e03cbd50..73262fe37 100644 --- a/dpop/DPoP-client-app/pom.xml +++ b/dpop/DPoP-client-app/pom.xml @@ -13,6 +13,7 @@ 8 7.3.0.wso2v1 1.3 + 1.2 @@ -105,6 +106,11 @@ json-smart ${json-smart.version} + + commons-logging + commons-logging + ${commons.logging.version} + diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java index 86603fca3..e22cc1fe4 100644 --- a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGenerator.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2022, WSO2 LLC (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC 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.wso2.dpop.client; import com.nimbusds.jose.JOSEException; @@ -11,6 +30,8 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; @@ -26,8 +47,13 @@ import static com.nimbusds.jose.JWSAlgorithm.ES256; import static com.nimbusds.jose.JWSAlgorithm.RS384; +/** + * DPOPProofGenerator will generate per request private and public keypair. + */ public class DPOPProofGenerator { + private static final Log log = LogFactory.getLog(DPOPProofGenerator.class); + public static void main(String args[]) throws NoSuchAlgorithmException, JOSEException, ParseException, InvalidAlgorithmParameterException { @@ -42,7 +68,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce KeyPairGenerator gen = KeyPairGenerator.getInstance(keyPairType); KeyPair keyPair; JWK jwk = null; - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { gen.initialize(Curve.P_256.toECParameterSpec()); keyPair = gen.generateKeyPair(); jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()) @@ -54,9 +80,9 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce jwk = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).build(); } - System.out.println("jwk: " + jwk); - System.out.println("publicKey: " + keyPair.getPublic()); - System.out.println("private: " + keyPair.getPrivate()); + log.info("jwk: " + jwk); + log.info("publicKey: " + keyPair.getPublic()); + log.info("private: " + keyPair.getPrivate()); JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); jwtClaimsSetBuilder.issuer("issuer"); @@ -68,7 +94,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce jwtClaimsSetBuilder.claim("htu", httpUrl); JWSHeader.Builder headerBuilder; - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { headerBuilder = new JWSHeader.Builder(ES256); } else { headerBuilder = new JWSHeader.Builder(RS384); @@ -77,7 +103,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce headerBuilder.jwk(jwk); SignedJWT signedJWT = new SignedJWT(headerBuilder.build(), jwtClaimsSetBuilder.build()); - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { ECDSASigner ecdsaSigner = new ECDSASigner(keyPair.getPrivate(), Curve.P_256); signedJWT.sign(ecdsaSigner); } else { @@ -85,14 +111,14 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce signedJWT.sign(rsassaSigner); } - System.out.println("[Signed JWT] : " + signedJWT.serialize()); + log.info("[Signed JWT] : " + signedJWT.serialize()); JWK parseJwk = JWK.parse(String.valueOf(jwk)); - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { ECKey ecKey = (ECKey) parseJwk; - System.out.println("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); + log.info("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); } else { RSAKey rsaKey = (RSAKey) parseJwk; - System.out.println("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); + log.info("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); } } } diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java index ddd072b62..cbbfc8721 100644 --- a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/DPOPProofGeneratorFromPP.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2022, WSO2 LLC (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC 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.wso2.dpop.client; import com.nimbusds.jose.JOSEException; @@ -11,6 +30,8 @@ import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import java.io.IOException; import java.nio.file.Files; @@ -33,8 +54,13 @@ import static com.nimbusds.jose.JWSAlgorithm.ES256; import static com.nimbusds.jose.JWSAlgorithm.RS384; +/** + * DPOPProofGeneratorFromPP will use the already generated key pairs and load and generate the DPoP Proof. + */ public class DPOPProofGeneratorFromPP { + private static final Log log = LogFactory.getLog(DPOPProofGeneratorFromPP.class); + public static void main(String args[]) throws NoSuchAlgorithmException, JOSEException, ParseException, IOException, InvalidKeySpecException { @@ -69,16 +95,16 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce PublicKey publicCert = kf.generatePublic(ks); JWK jwk = null; - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) publicCert) .build(); } else { jwk = new RSAKey.Builder((RSAPublicKey) publicCert).build(); } - System.out.println("jwk: " + jwk); - System.out.println("publicKey: " + publicCert); - System.out.println("private: " + privateKey); + log.info("jwk: " + jwk); + log.info("publicKey: " + publicCert); + log.info("private: " + privateKey); JWTClaimsSet.Builder jwtClaimsSetBuilder = new JWTClaimsSet.Builder(); jwtClaimsSetBuilder.issuer("issuer"); @@ -90,7 +116,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce jwtClaimsSetBuilder.claim("htu", httpUrl); JWSHeader.Builder headerBuilder; - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { headerBuilder = new JWSHeader.Builder(ES256); } else { headerBuilder = new JWSHeader.Builder(RS384); @@ -99,7 +125,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce headerBuilder.jwk(jwk); SignedJWT signedJWT = new SignedJWT(headerBuilder.build(), jwtClaimsSetBuilder.build()); - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { ECDSASigner ecdsaSigner = new ECDSASigner(privateKey, Curve.P_256); signedJWT.sign(ecdsaSigner); } else { @@ -107,14 +133,14 @@ public static void main(String args[]) throws NoSuchAlgorithmException, JOSEExce signedJWT.sign(rsassaSigner); } - System.out.println("[Signed JWT from File] : " + signedJWT.serialize()); + log.info("[Signed JWT from File] : " + signedJWT.serialize()); JWK parseJwk = JWK.parse(String.valueOf(jwk)); - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { ECKey ecKey = (ECKey) parseJwk; - System.out.println("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); + log.info("[ThumbPrint] : " + ecKey.computeThumbprint().toString()); } else { RSAKey rsaKey = (RSAKey) parseJwk; - System.out.println("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); + log.info("[ThumbPrint] : " + rsaKey.computeThumbprint().toString()); } } } diff --git a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java index 4f9a6992a..486b48c75 100644 --- a/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java +++ b/dpop/DPoP-client-app/src/main/java/org/wso2/dpop/client/GeneratePublicKeyPair.java @@ -1,9 +1,30 @@ +/* + * Copyright (c) 2022, WSO2 LLC (http://www.wso2.org) All Rights Reserved. + * + * WSO2 LLC 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.wso2.dpop.client; import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.RSAKey; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import java.io.FileOutputStream; import java.io.IOException; @@ -16,8 +37,13 @@ import java.security.interfaces.RSAPublicKey; import java.util.Scanner; +/** + * GeneratePublicKeyPair will create a public private key pair and store it in a file. + */ public class GeneratePublicKeyPair { + private static final Log log = LogFactory.getLog(GeneratePublicKeyPair.class); + public static void main(String args[]) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException { @@ -28,7 +54,7 @@ public static void main(String args[]) throws NoSuchAlgorithmException, InvalidA KeyPairGenerator gen = KeyPairGenerator.getInstance(keyPairType); KeyPair keyPair; JWK jwk; - if (keyPairType.equals("EC")) { + if ("EC".equals(keyPairType)) { gen.initialize(Curve.P_256.toECParameterSpec()); keyPair = gen.generateKeyPair(); jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()) @@ -40,15 +66,15 @@ public static void main(String args[]) throws NoSuchAlgorithmException, InvalidA jwk = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).build(); } - System.out.println("jwk: " + jwk); - System.out.println("publicKey: " + keyPair.getPublic()); - System.out.println("private: " + keyPair.getPrivate()); + log.info("jwk: " + jwk); + log.info("publicKey: " + keyPair.getPublic()); + log.info("private: " + keyPair.getPrivate()); Key pub = keyPair.getPublic(); Key pvt = keyPair.getPrivate(); - System.out.println("Private key format: " + pvt.getFormat()); - System.out.println("Public key format: " + pub.getFormat()); + log.info("Private key format: " + pvt.getFormat()); + log.info("Public key format: " + pub.getFormat()); String outFile = "dpop"; FileOutputStream privout = new FileOutputStream(outFile + ".key");