JWK.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.utils.certificate;

  21. import java.security.PrivateKey;
  22. import java.security.PublicKey;

  23. import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
  24. import org.apache.cxf.rs.security.jose.jwk.JwkReaderWriter;
  25. import org.openspcoop2.utils.UtilsException;
  26. import org.openspcoop2.utils.UtilsRuntimeException;
  27. import org.openspcoop2.utils.json.JSONUtils;

  28. import com.fasterxml.jackson.databind.JsonNode;
  29. import com.nimbusds.jose.Algorithm;
  30. import com.nimbusds.jose.jwk.KeyUse;
  31. import com.nimbusds.jose.jwk.OctetSequenceKey;
  32. import com.nimbusds.jose.jwk.RSAKey;

  33. /**
  34.  * JWK
  35.  *
  36.  * @author Poli Andrea (apoli@link.it)
  37.  * @author $Author$
  38.  * @version $Rev$, $Date$
  39.  */
  40. public class JWK {

  41.     private JwkReaderWriter engineCxf = new JwkReaderWriter();
  42.     private String jwkJson;
  43.     private String jwkJsonPretty;
  44.     private JsonWebKey jwkCxf;
  45.     private com.nimbusds.jose.jwk.JWK jwkNimbusds;
  46.     private JsonNode jwkNode;
  47.    
  48.     public JWK(String json) {
  49.         this.jwkJson = json;
  50.     }
  51.    
  52.     public JWK(JsonWebKey jwk) {
  53.         this.jwkCxf = jwk;
  54.     }
  55.    
  56.     public JWK(com.nimbusds.jose.jwk.JWK jwk) {
  57.         this.jwkNimbusds = jwk;
  58.     }
  59.    
  60.     public JWK(KeyStore keystore, String alias) throws UtilsException {
  61.         this(keystore, alias, null, null, true);
  62.     }
  63.     public JWK(KeyStore keystore, String alias, KeyUse use) throws UtilsException {
  64.         this(keystore, alias, null, use, true);
  65.     }
  66.     public JWK(KeyStore keystore, String alias, boolean kid) throws UtilsException {
  67.         this(keystore, alias, null, null, kid);
  68.     }
  69.     public JWK(KeyStore keystore, String alias, KeyUse use, boolean kid) throws UtilsException {
  70.         this(keystore, alias, null, use, kid);
  71.     }
  72.     public JWK(KeyStore keystore, String alias, String passwordPrivateKey) throws UtilsException {
  73.         this(keystore, alias, passwordPrivateKey, null, true);
  74.     }
  75.     public JWK(KeyStore keystore, String alias, String passwordPrivateKey, KeyUse use) throws UtilsException {
  76.         this(keystore, alias, passwordPrivateKey, use, true);
  77.     }
  78.     public JWK(KeyStore keystore, String alias, String passwordPrivateKey, boolean kid) throws UtilsException {
  79.         this(keystore, alias, passwordPrivateKey, null, kid);
  80.     }
  81.     public JWK(KeyStore keystore, String alias, String passwordPrivateKey, KeyUse use, boolean kid) throws UtilsException {
  82.         try {
  83.             if(!keystore.existsAlias(alias)) {
  84.                 throw new UtilsException("Alias '"+alias+"' undefined");
  85.             }
  86.             PublicKey publicKey = keystore.getPublicKey(alias);
  87.             if(publicKey instanceof java.security.interfaces.RSAPublicKey) {
  88.                 PrivateKey privateKey = null;
  89.                 if(passwordPrivateKey!=null) {
  90.                     privateKey = keystore.getPrivateKey(alias, passwordPrivateKey);
  91.                 }
  92.                 String aliasP = alias;
  93.                 if(!kid) {
  94.                     aliasP = null;
  95.                 }
  96.                 initEngine(publicKey, privateKey, aliasP, use);
  97.             }
  98.             else {
  99.                 throw new UtilsException("Unsupported type '"+publicKey.getClass().getName()+"'");
  100.             }
  101.         }catch(Exception e) {
  102.             throw new UtilsException(e.getMessage(),e);
  103.         }
  104.     }
  105.    
  106.     public JWK(PublicKey publicKey) throws UtilsException {
  107.         this(publicKey, null, null, null);
  108.     }
  109.     public JWK(PublicKey publicKey, String kid) throws UtilsException {
  110.         this(publicKey, null, kid, null);
  111.     }
  112.     public JWK(PublicKey publicKey, KeyUse use) throws UtilsException {
  113.         this(publicKey, null, null, use);
  114.     }
  115.     public JWK(PublicKey publicKey, String kid, KeyUse use) throws UtilsException {
  116.         this(publicKey, null, kid, use);
  117.     }
  118.     public JWK(PublicKey publicKey, PrivateKey privateKey) throws UtilsException {
  119.         this(publicKey, privateKey, null, null);
  120.     }
  121.     public JWK(PublicKey publicKey, PrivateKey privateKey, String kid) throws UtilsException {
  122.         this(publicKey, privateKey, kid, null);
  123.     }
  124.     public JWK(PublicKey publicKey, PrivateKey privateKey, KeyUse use) throws UtilsException {
  125.         this(publicKey, privateKey, null, use);
  126.     }
  127.     public JWK(PublicKey publicKey, PrivateKey privateKey, String kid, KeyUse use) throws UtilsException {
  128.         initEngine(publicKey, privateKey, kid, use);
  129.     }
  130.     private void initEngine(PublicKey publicKey, PrivateKey privateKey, String kid, KeyUse use) throws UtilsException {
  131.         try {
  132.             if(publicKey instanceof java.security.interfaces.RSAPublicKey) {
  133.                 java.security.interfaces.RSAPublicKey p = (java.security.interfaces.RSAPublicKey) publicKey;
  134.                 RSAKey.Builder builder = new RSAKey.Builder(p);
  135.                 if(privateKey!=null) {
  136.                     builder.privateKey(privateKey);
  137.                 }
  138.                 if(kid!=null) {
  139.                     builder.keyID(kid);
  140.                 }
  141.                 if(use!=null) {
  142.                     builder.keyUse(use);
  143.                 }
  144.                 this.jwkNimbusds = builder.build();
  145.             }
  146.             else {
  147.                 if(publicKey==null) {
  148.                     throw new UtilsException("PublicKey undefined");
  149.                 }
  150.                 else {
  151.                     throw new UtilsException("Unsupported type '"+publicKey.getClass().getName()+"'");
  152.                 }
  153.             }
  154.         }catch(Exception e) {
  155.             throw new UtilsException(e.getMessage(),e);
  156.         }
  157.     }
  158.    
  159.     public JWK(javax.crypto.SecretKey secretKey) throws UtilsException {
  160.         this(secretKey, null, null, null);
  161.     }
  162.     public JWK(javax.crypto.SecretKey secretKey, String kid) throws UtilsException {
  163.         this(secretKey, kid, null, null);
  164.     }
  165.     public JWK(javax.crypto.SecretKey secretKey, String kid, String algorithm) throws UtilsException {
  166.         this(secretKey, kid, null, algorithm);
  167.     }
  168.     public JWK(javax.crypto.SecretKey secretKey, KeyUse use) throws UtilsException {
  169.         this(secretKey, null, use, null);
  170.     }
  171.     public JWK(javax.crypto.SecretKey secretKey, KeyUse use, String algorithm) throws UtilsException {
  172.         this(secretKey, null, use, algorithm);
  173.     }
  174.     public JWK(javax.crypto.SecretKey secretKey, String kid, KeyUse use) throws UtilsException {
  175.         this(secretKey, kid, use, null);
  176.     }
  177.     public JWK(javax.crypto.SecretKey secretKey, String kid, KeyUse use, String algorithm) throws UtilsException {
  178.         try {
  179.             OctetSequenceKey.Builder builder = new OctetSequenceKey.Builder(secretKey);
  180.             if(algorithm!=null) {
  181.                 builder = builder.algorithm(Algorithm.parse(algorithm));
  182.             }
  183.             if(kid!=null) {
  184.                 builder = builder.keyID(kid);
  185.             }
  186.             if(use!=null) {
  187.                 builder = builder.keyUse(use);
  188.             }
  189.             this.jwkNimbusds = builder.build();
  190.         }catch(Exception e) {
  191.             throw new UtilsException(e.getMessage(),e);
  192.         }
  193.     }
  194.    
  195.     private synchronized void initCxf() throws UtilsException {
  196.         if(this.jwkCxf==null) {
  197.             if(this.jwkJson==null){
  198.                 throw new UtilsException("Json not defined");
  199.             }
  200.             this.jwkCxf = this.engineCxf.jsonToJwk(this.jwkJson);
  201.         }
  202.     }
  203.     public JsonWebKey getJsonWebKey() throws UtilsException {
  204.         if(this.jwkCxf==null) {
  205.             this.initCxf();
  206.         }
  207.         return this.jwkCxf;
  208.     }
  209.    
  210.     private synchronized void initNimbusds() throws UtilsException {
  211.         if(this.jwkNimbusds==null) {
  212.             if(this.jwkJson==null){
  213.                 throw new UtilsException("Json not defined");
  214.             }
  215.             try {
  216.                 this.jwkNimbusds = RSAKey.parse(this.jwkJson);
  217.             }catch(Exception e) {
  218.                 throw new UtilsException(e.getMessage(),e);
  219.             }
  220.         }
  221.     }
  222.     public com.nimbusds.jose.jwk.JWK getJWK() throws UtilsException {
  223.         if(this.jwkNimbusds==null) {
  224.             this.initNimbusds();
  225.         }
  226.         return this.jwkNimbusds;
  227.     }
  228.    
  229.     private synchronized void initJson() throws UtilsException {
  230.         if(this.jwkJson==null) {
  231.             if(this.jwkCxf==null && this.jwkNimbusds==null){
  232.                 throw new UtilsException("JWK not defined");
  233.             }
  234.             if(this.jwkCxf!=null) {
  235.                 try {
  236.                     this.jwkJson = this.engineCxf.jwkToJson(this.jwkCxf);
  237.                 }catch(Exception e) {
  238.                     throw new UtilsException(e.getMessage(),e);
  239.                 }
  240.             }
  241.             else {
  242.                 try {
  243.                     this.jwkJson = this.jwkNimbusds.toJSONString();
  244.                 }catch(Exception e) {
  245.                     throw new UtilsException(e.getMessage(),e);
  246.                 }
  247.             }
  248.         }
  249.     }
  250.     public String getJson() throws UtilsException {
  251.         if(this.jwkJson==null) {
  252.             this.initJson();
  253.         }
  254.         return this.jwkJson;
  255.     }
  256.    
  257.     private synchronized void initJsonPretty() throws UtilsException {
  258.         if(this.jwkJsonPretty==null) {
  259.             try {
  260.                 if(this.jwkNode==null) {
  261.                     initNode();
  262.                 }
  263.                 this.jwkJsonPretty = JSONUtils.getInstance(true).toString(this.jwkNode);
  264.             }catch(Exception e) {
  265.                 throw new UtilsException(e.getMessage(),e);
  266.             }
  267.         }
  268.     }
  269.     public String getJsonPretty() throws UtilsException {
  270.         if(this.jwkJsonPretty==null) {
  271.             this.initJsonPretty();
  272.         }
  273.         return this.jwkJsonPretty;
  274.     }
  275.    
  276.     private synchronized void initNode() throws UtilsException {
  277.         if(this.jwkNode==null) {
  278.             try {
  279.                 if(this.jwkJson==null) {
  280.                     initJson();
  281.                 }
  282.                 this.jwkNode = JSONUtils.getInstance().getAsNode(this.jwkJson);
  283.             }catch(Exception e) {
  284.                 throw new UtilsException(e.getMessage(),e);
  285.             }
  286.         }
  287.     }
  288.     public JsonNode getNode() throws UtilsException {
  289.         if(this.jwkNode==null) {
  290.             this.initNode();
  291.         }
  292.         return this.jwkNode;
  293.     }
  294.    
  295.     @Override
  296.     public String toString() {
  297.         try {
  298.             return this.getJsonPretty();
  299.         }catch(Exception e) {
  300.             throw new UtilsRuntimeException(e.getMessage(),e);
  301.         }
  302.     }
  303. }