JsonDecrypt.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.security;

  21. import java.io.File;
  22. import java.security.PrivateKey;
  23. import java.security.cert.CertStore;
  24. import java.security.cert.Certificate;
  25. import java.security.cert.X509Certificate;
  26. import java.security.interfaces.RSAPublicKey;
  27. import java.util.Enumeration;
  28. import java.util.List;
  29. import java.util.Map;
  30. import java.util.Properties;

  31. import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
  32. import org.apache.cxf.rs.security.jose.jwe.JweCompactConsumer;
  33. import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput;
  34. import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
  35. import org.apache.cxf.rs.security.jose.jwe.JweException;
  36. import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
  37. import org.apache.cxf.rs.security.jose.jwe.JweJsonConsumer;
  38. import org.apache.cxf.rs.security.jose.jwe.JweUtils;
  39. import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
  40. import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
  41. import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
  42. import org.apache.cxf.rt.security.rs.RSSecurityConstants;
  43. import org.openspcoop2.utils.UtilsException;
  44. import org.openspcoop2.utils.certificate.ArchiveLoader;
  45. import org.openspcoop2.utils.certificate.CertificateInfo;
  46. import org.openspcoop2.utils.certificate.JWKSet;
  47. import org.openspcoop2.utils.certificate.KeyStore;
  48. import org.openspcoop2.utils.io.Base64Utilities;
  49. import org.openspcoop2.utils.resources.FileSystemUtilities;
  50. import org.openspcoop2.utils.transport.http.HttpResponse;
  51. import org.openspcoop2.utils.transport.http.HttpUtilities;
  52. import org.openspcoop2.utils.transport.http.IOCSPValidator;

  53. /**
  54.  * Encrypt
  55.  *
  56.  * @author Poli Andrea (apoli@link.it)
  57.  * @author $Author$
  58.  * @version $Rev$, $Date$
  59.  */
  60. public class JsonDecrypt {

  61.     private JweDecryptionProvider provider;
  62.     private JWTOptions options;
  63.     private Properties properties;
  64.     private boolean dynamicProvider;
  65.    
  66.     private String decodedPayload;
  67.     private byte[] decodedPayloadAsByte;
  68.    
  69.     private JsonWebKeys jsonWebKeys; // dove prendere la chiave privata
  70.     private KeyStore keyStore; // dove prendere la chiave privata
  71.     private Map<String, String> keystoreMapAliasPassword;
  72.     private KeyStore trustStoreVerificaCertificatiX509; // per verificare i certificati presenti nell'header
  73.     public void setTrustStoreVerificaCertificatiX509(KeyStore trustStoreVerificaCertificatiX509) {
  74.         this.trustStoreVerificaCertificatiX509 = trustStoreVerificaCertificatiX509;
  75.     }
  76.     public KeyStore getTrustStoreVerificaCertificatiX509() {
  77.         return this.trustStoreVerificaCertificatiX509;
  78.     }

  79.     private KeyStore trustStoreHttps; // per accedere ad un endpoint https dove scaricare i certificati
  80.     public KeyStore getTrustStoreHttps() {
  81.         return this.trustStoreHttps;
  82.     }
  83.     private CertStore crlHttps; // per verificare i certificati http server rispetto alle crl
  84.     public void setCrlHttps(CertStore crlHttps) {
  85.         this.crlHttps = crlHttps;
  86.     }
  87.     private IOCSPValidator ocspValidatorHttps; // per verificare i certificati http server rispetto a servizi OCSP
  88.     public void setOcspValidatorHttps(IOCSPValidator ocspValidator) {
  89.         this.ocspValidatorHttps = ocspValidator;
  90.     }
  91.        
  92.     private CertStore crlX509; // per verificare i certificati rispetto alle crl
  93.     public void setCrlX509(CertStore crlX509) {
  94.         this.crlX509 = crlX509;
  95.     }
  96.     private IOCSPValidator ocspValidatorX509; // per verificare i certificati rispetto a servizi OCSP
  97.     public void setOcspValidatorX509(IOCSPValidator ocspValidator) {
  98.         this.ocspValidatorX509 = ocspValidator;
  99.     }
  100.    
  101.     private CertificateValidityCheck validityCheck = CertificateValidityCheck.ENABLED; // validazione (date) del certificato utilizzato per firmare il token    
  102.     public void setValidityCheck(CertificateValidityCheck validityCheck) {
  103.         this.validityCheck = validityCheck;
  104.     }
  105.    
  106.     private boolean jksPasswordRequired=true;
  107.     private boolean pkcs12PasswordRequired=true;
  108.     public void setJksPasswordRequired(boolean jksPasswordRequired) {
  109.         this.jksPasswordRequired = jksPasswordRequired;
  110.     }
  111.     public void setPkcs12PasswordRequired(boolean pkcs12PasswordRequired) {
  112.         this.pkcs12PasswordRequired = pkcs12PasswordRequired;
  113.     }  
  114.    
  115.     public JsonDecrypt(Properties props, JWTOptions options) throws UtilsException{
  116.         this(props, options, true, true);
  117.     }
  118.     public JsonDecrypt(Properties props, JWTOptions options, boolean jksPasswordRequired, boolean pkcs12PasswordRequired) throws UtilsException{
  119.         try {
  120.             this.jksPasswordRequired = jksPasswordRequired;
  121.             this.pkcs12PasswordRequired = pkcs12PasswordRequired;
  122.             this.dynamicProvider = JsonUtils.isDynamicProvider(props); // rimuove l'alias
  123.             if(this.dynamicProvider) {
  124.                 this.properties = props;
  125.             }
  126.             else {
  127.                 this.provider = this.loadProviderFromProperties(props, null); // nel caso di jceks deve essere definito l'algoritmo del contenuto se non e' dinamico
  128.             }
  129.             this.options=options;      
  130.         }catch(Exception t) {
  131.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.DECRYPT,JsonUtils.RECEIVER,t);
  132.         }
  133.     }
  134.    
  135.     private JweDecryptionProvider loadProviderFromProperties(Properties props, org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgorithm) throws UtilsException {
  136.         File fTmp = null;
  137.         try {
  138.             fTmp = JsonUtils.normalizeProperties(props); // in caso di url http viene letta la risorsa remota e salvata in tmp
  139.             /**java.util.Enumeration<?> en = props.keys();
  140.             while (en.hasMoreElements()) {
  141.                 String key = (String) en.nextElement();
  142.                 System.out.println("- ["+key+"] ["+props.getProperty(key)+"]");
  143.             }*/
  144.            
  145.             JweDecryptionProvider providerBuild = buildProviderFromProperties(props, contentAlgorithm);
  146.            
  147.             try {
  148.                 Certificate cert = JsonUtils.getCertificateKey(this.jksPasswordRequired,this.pkcs12PasswordRequired,props);
  149.                 if(cert instanceof X509Certificate) {
  150.                     this.x509Certificate = (X509Certificate) cert;
  151.                 }
  152.             }catch(Exception t) {
  153.                 // ignore
  154.             }
  155.            
  156.             return providerBuild;
  157.              
  158.         }finally {
  159.             FileSystemUtilities.deleteFile(fTmp);
  160.         }
  161.     }
  162.     private JweDecryptionProvider buildProviderFromProperties(Properties props, org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgorithm) throws UtilsException {
  163.         JweDecryptionProvider providerBuild = null;
  164.         if(contentAlgorithm!=null) {
  165.             providerBuild = JsonUtils.getJweDecryptionProvider(props, contentAlgorithm);
  166.         }
  167.         else {
  168.             providerBuild = JsonUtils.getJweDecryptionProvider(props);
  169.         }
  170.         if(providerBuild==null) {
  171.             providerBuild = buildProviderFromProperties(props);
  172.         }
  173.         if(providerBuild==null) {
  174.             throw new UtilsException("JweDecryptionProvider provider not found");
  175.         }
  176.         return providerBuild;
  177.     }
  178.     private JweDecryptionProvider buildProviderFromProperties(Properties props) throws UtilsException {
  179.         JweDecryptionProvider providerBuild = null;
  180.         KeyAlgorithm keyAlgorithm = JweUtils.getKeyEncryptionAlgorithm(props, null);
  181.         if (KeyAlgorithm.DIRECT.equals(keyAlgorithm)) {
  182.             providerBuild = JsonUtils.getJweDecryptionProviderFromJWKSymmetric(props, null);
  183.         }
  184.         else {
  185.             try {
  186.                 providerBuild = JweUtils.loadDecryptionProvider(props, JsonUtils.newMessage(), null); // lasciare null come secondo parametro senno non funziona il decrypt senza keyEncoding
  187.             }catch(JweException jweExc) {
  188.                 if(jweExc.getMessage()!=null && jweExc.getMessage().contains("NO_ENCRYPTOR")) {
  189.                     // caso in cui la chiave privata PKCS11 non e' stata mappata in un PrivateKeyDecryptionProvider
  190.                     providerBuild = JsonUtils.getJweAsymmetricDecryptionProvider(props);
  191.                     if(providerBuild==null) {
  192.                         // rilancio eccezione precedente
  193.                         throw jweExc;
  194.                     }
  195.                 }
  196.             }
  197.         }
  198.         return providerBuild;
  199.     }
  200.    
  201.     public JsonDecrypt(java.security.KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  202.         this(new KeyStore(keystore), false, alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, options);
  203.     }
  204.     public JsonDecrypt(KeyStore keystore, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  205.         this(keystore, false, alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, options);
  206.     }
  207.     public JsonDecrypt(java.security.KeyStore keystore, boolean secretKey, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  208.         this(new KeyStore(keystore), secretKey, alias, passwordPrivateKey, keyAlgorithm, contentAlgorithm, options);
  209.     }
  210.     public JsonDecrypt(KeyStore keystore, boolean secretKey, String alias, String passwordPrivateKey, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  211.         try {
  212.             this.options=options;
  213.            
  214.             org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo  = org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm.getAlgorithm(keyAlgorithm);
  215.             org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgo = org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm.getAlgorithm(contentAlgorithm);
  216.             if(secretKey) {
  217.                
  218.                 if (KeyAlgorithm.DIRECT.equals(keyAlgo)) {
  219.                     this.provider = JweUtils.getDirectKeyJweDecryption(keystore.getSecretKey(alias, passwordPrivateKey), contentAlgo);
  220.                 }
  221.                 else {
  222.                     this.provider = JweUtils.createJweDecryptionProvider( keystore.getSecretKey(alias, passwordPrivateKey), keyAlgo, contentAlgo);
  223.                 }

  224.             }else {
  225.                 PrivateKey privateKey = keystore.getPrivateKey(alias, passwordPrivateKey);
  226.                 this.provider = JweUtils.createJweDecryptionProvider( privateKey, keyAlgo, contentAlgo);
  227.                 checkKeyAlgorithm();
  228.                 if(this.provider==null) {
  229.                     this.provider = JsonUtils.getJweAsymmetricDecryptionProvider(privateKey, keyAlgo, contentAlgo);
  230.                     if(this.provider==null) {
  231.                         throw new UtilsException("("+keystore.getKeystore().getType()+") JwsDecryptionProvider init failed; keyAlgorithm ("+keyAlgorithm+") contentAlgorithm("+contentAlgorithm+")");
  232.                     }
  233.                 }  
  234.             }
  235.            
  236.             setSafeCertificate(keystore, alias);
  237.            
  238.         }catch(Exception t) {
  239.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.DECRYPT,JsonUtils.RECEIVER,t);
  240.         }
  241.     }
  242.     private void setSafeCertificate(KeyStore keystore, String alias) {
  243.         try {
  244.             Certificate cert = keystore.getCertificate(alias);
  245.             if(cert instanceof X509Certificate) {
  246.                 this.x509Certificate = (X509Certificate) cert;
  247.             }
  248.         }catch(Exception t) {
  249.             // ignore
  250.         }
  251.     }
  252.     private void checkKeyAlgorithm() {
  253.         try {
  254.             this.provider.getKeyAlgorithm();
  255.         }catch(NullPointerException nullPointer) {
  256.             // caso in cui la chiave privata PKCS11 non e' stata mappata in un PrivateKeyDecryptionProvider
  257.             this.provider = null;
  258.         }
  259.     }
  260.    
  261.    
  262.     public JsonDecrypt(JsonWebKeys jsonWebKeys, boolean secretKey, String alias, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  263.         this(JsonUtils.readKey(jsonWebKeys, alias),secretKey, keyAlgorithm, contentAlgorithm, options);
  264.     }
  265.     public JsonDecrypt(JsonWebKey jsonWebKey, boolean secretKey, String keyAlgorithm, String contentAlgorithm, JWTOptions options) throws UtilsException{
  266.         try {
  267.             this.options=options;
  268.            
  269.             org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo  = org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm.getAlgorithm(keyAlgorithm);
  270.             org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgo = org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm.getAlgorithm(contentAlgorithm);
  271.            
  272.             if(secretKey) {
  273.                 if(jsonWebKey.getAlgorithm()==null) {
  274.                     jsonWebKey.setAlgorithm(contentAlgorithm);
  275.                 }
  276.                 if (KeyAlgorithm.DIRECT.equals(keyAlgo)) {
  277.                     this.provider = JweUtils.getDirectKeyJweDecryption(JwkUtils.toSecretKey(jsonWebKey), contentAlgo);
  278.                 }
  279.                 else {
  280.                     this.provider = JweUtils.createJweDecryptionProvider( JwkUtils.toSecretKey(jsonWebKey), keyAlgo, contentAlgo);
  281.                 }
  282.                 if(this.provider==null) {
  283.                     throw new UtilsException("(JsonWebKey) JwsDecryptionProvider init failed; check content algorithm ("+contentAlgorithm+")");
  284.                 }
  285.             }else {
  286.                 this.provider = JweUtils.createJweDecryptionProvider( JwkUtils.toRSAPrivateKey(jsonWebKey), keyAlgo, contentAlgo);
  287.             }

  288.         }catch(Exception t) {
  289.             throw JsonUtils.convert(options.getSerialization(), JsonUtils.DECRYPT,JsonUtils.RECEIVER,t);
  290.         }
  291.     }
  292.    
  293.    


  294.     public JsonDecrypt(Properties propsTrustStoreHttps, java.security.KeyStore trustStoreVerificaCertificato,
  295.             java.security.KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  296.             JWTOptions options) {
  297.         initDecryptHeaderJWTEngine(propsTrustStoreHttps, null,
  298.                 new KeyStore(trustStoreVerificaCertificato),
  299.                 new KeyStore(keyStore), keystoreMapAliasPassword,
  300.                 options);
  301.     }
  302.     public JsonDecrypt(KeyStore trustStoreHttps, java.security.KeyStore trustStoreVerificaCertificato,
  303.             java.security.KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  304.             JWTOptions options) {
  305.         initDecryptHeaderJWTEngine(null, trustStoreHttps,
  306.                 new KeyStore(trustStoreVerificaCertificato),
  307.                 new KeyStore(keyStore), keystoreMapAliasPassword,
  308.                 options);
  309.     }
  310.     public JsonDecrypt(Properties propsTrustStoreHttps, KeyStore trustStore,
  311.             KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  312.             JWTOptions options) {
  313.         initDecryptHeaderJWTEngine(propsTrustStoreHttps, null,
  314.                 trustStore,
  315.                 keyStore, keystoreMapAliasPassword,
  316.                 options);
  317.     }
  318.     public JsonDecrypt(KeyStore trustStoreHttps, KeyStore trustStore,
  319.             KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  320.             JWTOptions options) {
  321.         initDecryptHeaderJWTEngine(null, trustStoreHttps,
  322.                 trustStore,
  323.                 keyStore, keystoreMapAliasPassword,
  324.                 options);
  325.     }
  326.     public JsonDecrypt(java.security.KeyStore trustStoreVerificaCertificato,
  327.             java.security.KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  328.             JWTOptions options) {
  329.         initDecryptHeaderJWTEngine(null, null,
  330.                 new KeyStore(trustStoreVerificaCertificato),
  331.                 new KeyStore(keyStore), keystoreMapAliasPassword,
  332.                 options);
  333.     }
  334.     public JsonDecrypt(KeyStore trustStore,
  335.             KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  336.             JWTOptions options) {
  337.         initDecryptHeaderJWTEngine(null, null,
  338.                 trustStore,
  339.                 keyStore, keystoreMapAliasPassword,
  340.                 options);
  341.     }
  342.     private void initDecryptHeaderJWTEngine(Properties propsTrustStoreHttps, KeyStore trustStoreHttps,
  343.             KeyStore trustStoreVerificaCertificato,
  344.             KeyStore keyStore, Map<String, String> keystoreMapAliasPassword,
  345.             JWTOptions options) {
  346.         // verra usato l'header per validare ed ottenere il certificato
  347.         this.options=options;
  348.         this.properties = propsTrustStoreHttps; // le proprieta' servono per risolvere le url https
  349.         this.trustStoreHttps = trustStoreHttps;
  350.         this.trustStoreVerificaCertificatiX509 = trustStoreVerificaCertificato;
  351.         this.keyStore = keyStore;
  352.         this.keystoreMapAliasPassword = keystoreMapAliasPassword;
  353.     }
  354.    
  355.    
  356.     public JsonDecrypt(Properties propsTrustStoreHttps, JsonWebKeys jsonWebKeys,
  357.             JWTOptions options) {
  358.         initDecryptHeaderJWTEngine(propsTrustStoreHttps, null,
  359.                 jsonWebKeys,
  360.                 options);
  361.     }
  362.     public JsonDecrypt(KeyStore trustStoreHttps, JsonWebKeys jsonWebKeys,
  363.             JWTOptions options) {
  364.         initDecryptHeaderJWTEngine(null, trustStoreHttps,
  365.                 jsonWebKeys,
  366.                 options);
  367.     }
  368.     public JsonDecrypt(JsonWebKeys jsonWebKeys,
  369.             JWTOptions options) {
  370.         initDecryptHeaderJWTEngine(null, null,
  371.                 jsonWebKeys,
  372.                 options);
  373.     }
  374.     private void initDecryptHeaderJWTEngine(Properties propsTrustStoreHttps, KeyStore trustStoreHttps,
  375.             JsonWebKeys jsonWebKeys,
  376.             JWTOptions options) {
  377.         // verra usato l'header per validare ed ottenere il certificato
  378.         this.options=options;
  379.         this.properties = propsTrustStoreHttps; // le proprieta' servono per risolvere le url https
  380.         this.trustStoreHttps = trustStoreHttps;
  381.         this.jsonWebKeys = jsonWebKeys;
  382.     }
  383.    
  384.    


  385.     public void decrypt(String jsonString) throws UtilsException{
  386.         try {
  387.             switch(this.options.getSerialization()) {
  388.                 case JSON: decryptJson(jsonString); break;
  389.                 case COMPACT: decryptCompact(jsonString); break;
  390.                 default: throw new UtilsException("Unsupported serialization '"+this.options.getSerialization()+"'");
  391.             }
  392.         }
  393.         catch(Exception t) {
  394.             throw JsonUtils.convert(this.options.getSerialization(), JsonUtils.DECRYPT,JsonUtils.RECEIVER,t);
  395.         }
  396.     }
  397.    

  398.     private void decryptCompact(String jsonString) throws UtilsException {
  399.        
  400.         JweCompactConsumer consumer = new JweCompactConsumer(jsonString);
  401.         JweHeaders jweHeaders = consumer.getJweHeaders();
  402.        
  403.         JweDecryptionProvider providerBuild = getProvider(jweHeaders, null);
  404.        
  405.         JweDecryptionOutput output =  providerBuild.decrypt(jsonString);
  406.         this.decodedPayload = output.getContentText();
  407.         this.decodedPayloadAsByte = output.getContent();
  408.     }


  409.     private void decryptJson(String jsonString) throws UtilsException {
  410.        
  411.         JweJsonConsumer consumer = new JweJsonConsumer(jsonString);
  412.         JweHeaders jweHeaders = consumer.getProtectedHeader();
  413.         JweHeaders jweUnprotectedHeaders = consumer.getSharedUnprotectedHeader();
  414.        
  415.         JweDecryptionProvider providerBuild = getProvider(jweHeaders, jweUnprotectedHeaders);
  416.        
  417.         // con gestione recipients
  418. /**     org.apache.cxf.rs.security.jose.jwe.JweJsonEncryptionEntry entry = consumer.getRecipients().get(0);
  419. //      JweDecryptionOutput output = consumer.decryptWith(provider, entry);*/
  420.        
  421.         // senza gestione recipients
  422.         JweDecryptionOutput output = consumer.decryptWith(providerBuild);
  423.        
  424.         this.decodedPayload = output.getContentText();
  425.         this.decodedPayloadAsByte = output.getContent();
  426.        
  427.     }

  428.     public String getDecodedPayload() {
  429.         return this.decodedPayload;
  430.     }

  431.     public byte[] getDecodedPayloadAsByte() {
  432.         return this.decodedPayloadAsByte;
  433.     }
  434.    
  435.    
  436.     private X509Certificate x509Certificate;
  437.     private RSAPublicKey rsaPublicKey;
  438.     private String kid;
  439.     public X509Certificate getX509Certificate() {
  440.         return this.x509Certificate;
  441.     }
  442.     public RSAPublicKey getRsaPublicKey() {
  443.         return this.rsaPublicKey;
  444.     }
  445.     public String getKid() {
  446.         return this.kid;
  447.     }
  448.    
  449.     private JweDecryptionProvider getProvider(JweHeaders jweHeaders, JweHeaders jweUnprotectedHeaders) throws UtilsException {
  450.        
  451.         JweDecryptionProvider providerBuild = this.provider;
  452.         if(jweHeaders==null) {
  453.             return providerBuild;
  454.         }
  455.        
  456.         if(this.dynamicProvider) {
  457.             /**String alias = JsonUtils.readAlias(jsonString);*/
  458.             String alias = jweHeaders.getKeyId();
  459.             Properties pNew = new Properties();
  460.             pNew.putAll(this.properties);
  461.             /**System.out.println("ALIAS ["+alias+"]");*/
  462.             pNew.put(RSSecurityConstants.RSSEC_KEY_STORE_ALIAS, alias);
  463.             providerBuild = loadProviderFromProperties(pNew, jweHeaders.getContentEncryptionAlgorithm());
  464.         }
  465.        
  466.         if(providerBuild==null) {
  467.             org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo  = jweHeaders.getKeyEncryptionAlgorithm();
  468.             if(keyAlgo==null && jweUnprotectedHeaders!=null) {
  469.                 keyAlgo = jweUnprotectedHeaders.getKeyEncryptionAlgorithm();
  470.             }
  471.             if(keyAlgo==null) {
  472.                 throw new UtilsException("KeyAlgorithm not found");
  473.             }
  474.            
  475.             org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgo = jweHeaders.getContentEncryptionAlgorithm();
  476.             if(contentAlgo==null) {
  477.                 throw new UtilsException("ContentAlgorithm not found");
  478.             }
  479.            
  480.             if(jweHeaders.getX509Chain()!=null && !jweHeaders.getX509Chain().isEmpty() && this.options.isPermitUseHeaderX5C()) {
  481.                 // This parameter has the same meaning, syntax, and processing rules as
  482.                 //   the "x5c" Header Parameter defined in Section 4.1.6 of [JWS], except
  483.                 //   that the X.509 public key certificate or certificate chain [RFC5280]
  484.                 //   contains the public key to which the JWE was encrypted; this can be
  485.                 //   used to determine the private key needed to decrypt the JWE.
  486.                 try {
  487.                     byte [] cer = Base64Utilities.decode(jweHeaders.getX509Chain().get(0));
  488.                     CertificateInfo certificatoInfo = ArchiveLoader.load(cer).getCertificate();
  489.                     if(this.trustStoreVerificaCertificatiX509!=null) {
  490.                         JsonUtils.validate(certificatoInfo,
  491.                                 this.trustStoreVerificaCertificatiX509, this.crlX509, this.ocspValidatorX509, JwtHeaders.JWT_HDR_X5C, true,
  492.                                 this.validityCheck);
  493.                     }
  494.                     providerBuild = getProviderX509(certificatoInfo, keyAlgo, contentAlgo);
  495.                 }catch(Exception e) {
  496.                     throw new UtilsException("Process '"+JwtHeaders.JWT_HDR_X5C+"' error: "+e.getMessage(),e);
  497.                 }
  498.             }
  499.             else if(jweHeaders.getJsonWebKey()!=null && this.options.isPermitUseHeaderJWK()) {
  500.                 // This parameter has the same meaning, syntax, and processing rules as
  501.                 //   the "jwk" Header Parameter defined in Section 4.1.3 of [JWS], except
  502.                 //   that the key is the public key to which the JWE was encrypted; this
  503.                 //   can be used to determine the private key needed to decrypt the JWE.
  504.                 try {
  505.                     JsonWebKey webKey = jweHeaders.getJsonWebKey();
  506.                     providerBuild = getProviderJWK(webKey, keyAlgo, contentAlgo);
  507.                 }catch(Exception e) {
  508.                     throw new UtilsException("Process '"+JwtHeaders.JWT_HDR_JWK+"' error: "+e.getMessage(),e);
  509.                 }
  510.             }
  511.             else if(
  512.                     (jweHeaders.getX509Url()!=null && this.options.isPermitUseHeaderX5U())
  513.                     ||
  514.                     (jweHeaders.getJsonWebKeysUrl()!=null && this.options.isPermitUseHeaderJKU())
  515.                     ) {
  516.            
  517.                 boolean x509 = true;
  518.                 String path = jweHeaders.getX509Url();
  519.                 String hdr = JwtHeaders.JWT_HDR_X5U;
  520.                 if(path==null) {
  521.                     path=jweHeaders.getJsonWebKeysUrl();
  522.                     x509 = false;
  523.                     hdr = JwtHeaders.JWT_HDR_JKU;
  524.                 }
  525.                 try {
  526.                     byte [] cer = null;
  527.                     if(this.properties!=null) {
  528.                         this.properties.put(RSSecurityConstants.RSSEC_KEY_STORE_FILE, path);
  529.                         cer = JsonUtils.readKeystoreFromURI(this.properties);
  530.                     }
  531.                     else {
  532.                         HttpResponse httpResponse = null;
  533.                         try {
  534.                             if(this.trustStoreHttps!=null) {
  535.                                 httpResponse = HttpUtilities.getHTTPSResponse(path, this.trustStoreHttps.getKeystore(), this.crlHttps, this.ocspValidatorHttps);
  536.                             }
  537.                             else {
  538.                                 httpResponse = HttpUtilities.getHTTPResponse(path);
  539.                             }
  540.                         }catch(Exception e) {
  541.                             throw new UtilsException("Resource '"+path+"' unavailable: "+e.getMessage(),e);
  542.                         }
  543.                         if(httpResponse==null || httpResponse.getContent()==null) {
  544.                             throw new UtilsException("Resource '"+path+"' unavailable");
  545.                         }
  546.                         if(httpResponse.getResultHTTPOperation()!=200) {
  547.                             throw new UtilsException("Retrieve '"+path+"' failed (returnCode:"+httpResponse.getResultHTTPOperation()+")");
  548.                         }
  549.                         cer = httpResponse.getContent();
  550.                     }
  551.                     if(cer==null) {
  552.                         throw new UtilsException("Resource '"+path+"' unavailable");
  553.                     }
  554.                    
  555.                     if(x509) {
  556.                         CertificateInfo certificatoInfo = ArchiveLoader.load(cer).getCertificate();
  557.                         if(this.trustStoreVerificaCertificatiX509!=null) {
  558.                             JsonUtils.validate(certificatoInfo,
  559.                                     this.trustStoreVerificaCertificatiX509, this.crlX509, this.ocspValidatorX509, JwtHeaders.JWT_HDR_X5U, true,
  560.                                     this.validityCheck);
  561.                         }
  562.                         providerBuild = getProviderX509(certificatoInfo, keyAlgo, contentAlgo);
  563.                     }
  564.                     else {
  565.                         JWKSet set = new JWKSet(new String(cer));
  566.                         JsonWebKeys jsonWebKeysBuild = set.getJsonWebKeys();
  567.                         JsonWebKey jsonWebKey = null;
  568.                         if(jsonWebKeysBuild.size()==1) {
  569.                             jsonWebKey = jsonWebKeysBuild.getKeys().get(0);
  570.                         }
  571.                         else {
  572.                             if(jweHeaders.getKeyId()==null) {
  573.                                 throw new UtilsException("Kid non definito e JwkSet contiene più di un certificato");
  574.                             }
  575.                             jsonWebKey = jsonWebKeysBuild.getKey(jweHeaders.getKeyId());
  576.                         }
  577.                         if(jsonWebKey==null) {
  578.                             throw new UtilsException("JsonWebKey non trovata");
  579.                         }
  580.                         providerBuild = getProviderJWK(jsonWebKey, keyAlgo, contentAlgo);
  581.                     }
  582.                 }catch(Exception e) {
  583.                     throw new UtilsException("Process '"+hdr+"' error: "+e.getMessage(),e);
  584.                 }
  585.             }
  586.             else if(jweHeaders.getKeyId()!=null && this.options.isPermitUseHeaderKID()) {
  587.                 // This parameter has the same meaning, syntax, and processing rules as
  588.                 //   the "kid" Header Parameter defined in Section 4.1.4 of [JWS], except
  589.                 //   that the key hint references the public key to which the JWE was
  590.                 //   encrypted; this can be used to determine the private key needed to
  591.                 //   decrypt the JWE.  This parameter allows originators to explicitly
  592.                 //   signal a change of key to JWE recipients.
  593.                 try {
  594.                     this.kid = jweHeaders.getKeyId();
  595.                     if(this.jsonWebKeys!=null) {
  596.                         JsonWebKey jsonWebKey = null;
  597.                         try {
  598.                             jsonWebKey = this.jsonWebKeys.getKey(this.kid);
  599.                         }catch(Exception e) {
  600.                             // key non esistente
  601.                         }
  602.                         if(jsonWebKey!=null) {
  603.                             providerBuild = getProviderJWK(jsonWebKey, keyAlgo, contentAlgo);
  604.                         }
  605.                     }
  606.                     if(providerBuild==null &&
  607.                         this.keyStore!=null &&
  608.                         this.keyStore.existsAlias(this.kid)) {
  609.                         Certificate cer = this.keyStore.getCertificate(this.kid);
  610.                         if(cer instanceof X509Certificate) {
  611.                             X509Certificate x509CertificateBuild = (X509Certificate) cer;
  612.                            
  613.                             // La validazione serve per verificare la data e il crl
  614.                             if(this.trustStoreVerificaCertificatiX509!=null) {
  615.                                 JsonUtils.validate(new CertificateInfo(x509CertificateBuild, this.kid),
  616.                                         this.trustStoreVerificaCertificatiX509, this.crlX509, this.ocspValidatorX509, JwtHeaders.JWT_HDR_KID, false,
  617.                                         this.validityCheck);
  618.                             }
  619.                             else {
  620.                                 JsonUtils.validate(new CertificateInfo(x509CertificateBuild, this.kid),
  621.                                         this.keyStore, this.crlX509, this.ocspValidatorX509, JwtHeaders.JWT_HDR_KID, false,
  622.                                         this.validityCheck);
  623.                             }
  624.                            
  625.                             CertificateInfo certificatoInfo = new CertificateInfo(x509CertificateBuild, this.kid);
  626.                             providerBuild = getProviderX509(certificatoInfo, keyAlgo, contentAlgo);
  627.                         }
  628.                     }
  629.                 }catch(Exception e) {
  630.                     throw new UtilsException("Process '"+JwtHeaders.JWT_HDR_KID+"' error: "+e.getMessage(),e);
  631.                 }
  632.             }
  633.             else if(
  634.                     (jweHeaders.getX509ThumbprintSHA256()!=null && this.options.isPermitUseHeaderX5T_256())
  635.                     ||
  636.                     (jweHeaders.getX509Thumbprint()!=null && this.options.isPermitUseHeaderX5T())
  637.                     ) {
  638.                 String hdr = JwtHeaders.JWT_HDR_X5T;
  639.                 if (jweHeaders.getX509ThumbprintSHA256()!=null) {
  640.                     hdr = JwtHeaders.JWT_HDR_X5t_S256;
  641.                 }
  642.                 try {
  643.                     if(this.keyStore==null) {
  644.                         throw new UtilsException("KeyStore dei certificati non fornito");
  645.                     }
  646.                     Certificate cer = null;
  647.                     if(jweHeaders.getX509ThumbprintSHA256()!=null) {
  648.                         cer = this.keyStore.getCertificateByDigestSHA256UrlEncoded(jweHeaders.getX509ThumbprintSHA256());
  649.                     }
  650.                     else{
  651.                         cer = this.keyStore.getCertificateByDigestSHA1UrlEncoded(jweHeaders.getX509Thumbprint());
  652.                     }
  653.                     if(cer==null) {
  654.                         throw new UtilsException("Certificato, corrispondente al digest indicato, non trovato nel KeyStore dei certificati");
  655.                     }
  656.                     if(cer instanceof X509Certificate) {
  657.                         X509Certificate x509CertificateBuild = (X509Certificate) cer;
  658.                        
  659.                         // La validazione serve per verificare la data e il crl
  660.                         if(this.trustStoreVerificaCertificatiX509!=null) {
  661.                             JsonUtils.validate(new CertificateInfo(x509CertificateBuild, hdr),
  662.                                     this.trustStoreVerificaCertificatiX509, this.crlX509, this.ocspValidatorX509, hdr, false,
  663.                                     this.validityCheck);
  664.                         }
  665.                         else {
  666.                             JsonUtils.validate(new CertificateInfo(x509CertificateBuild, hdr),
  667.                                     this.keyStore, this.crlX509, this.ocspValidatorX509, hdr, false,
  668.                                     this.validityCheck);
  669.                         }
  670.                        
  671.                         CertificateInfo certificatoInfo = new CertificateInfo(x509CertificateBuild, "x5t");
  672.                         providerBuild = getProviderX509(certificatoInfo, keyAlgo, contentAlgo);
  673.                     }
  674.                     else {
  675.                         throw new UtilsException("Certificato indicato non è nel formato X.509");
  676.                     }
  677.                 }catch(Exception e) {
  678.                     throw new UtilsException("Process '"+hdr+"' error: "+e.getMessage(),e);
  679.                 }
  680.             }
  681.             else {
  682.                 List<String> hdrNotPermitted = this.options.headersNotPermitted(jweHeaders);
  683.                 String notPermitted = "";
  684.                 if(hdrNotPermitted!=null && !hdrNotPermitted.isEmpty()) {
  685.                     notPermitted = "; header trovati ma non abilitati all'utilizzo: "+hdrNotPermitted;
  686.                 }
  687.                 throw new UtilsException("Non è stato trovato alcun header che consentisse di recuperare il certificato per decifrare"+notPermitted);
  688.             }
  689.         }
  690.         else {
  691.             if(this.x509Certificate!=null && this.trustStoreVerificaCertificatiX509!=null) {
  692.                 try {
  693.                     CertificateInfo certificatoInfo = new CertificateInfo(this.x509Certificate, "x509");
  694.                     JsonUtils.validate(certificatoInfo,
  695.                             this.trustStoreVerificaCertificatiX509, this.crlX509, this.ocspValidatorX509, null, true,
  696.                             this.validityCheck);
  697.                 }catch(Exception e) {
  698.                     throw new UtilsException(e.getMessage(),e);
  699.                 }
  700.             }
  701.         }
  702.        
  703.         return providerBuild;
  704.     }
  705.    
  706.     private JweDecryptionProvider getProviderX509(CertificateInfo certificatoInfo,
  707.             org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo,
  708.             org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgo) throws UtilsException {
  709.         if(this.keyStore==null) {
  710.             throw new UtilsException("Keystore da utilizzare per il recupero dei certificati non definito");
  711.         }
  712.         if(this.keystoreMapAliasPassword==null) {
  713.             throw new UtilsException("Mappping alias-password non definito");
  714.         }
  715.         this.x509Certificate = certificatoInfo.getCertificate();
  716.         PrivateKey privateKey = null;
  717.         Enumeration<String> aliases = this.keyStore.aliases();
  718.         while (aliases.hasMoreElements()) {
  719.             String alias = aliases.nextElement();
  720.             Certificate certificateCheck = this.keyStore.getCertificate(alias);
  721.             if(certificateCheck instanceof X509Certificate) {
  722.                 X509Certificate x509CertificateCheck = (X509Certificate) certificateCheck;
  723.                 if(certificatoInfo.equals(x509CertificateCheck, true)) {
  724.                     try {
  725.                         String passwordPrivateKey = this.keystoreMapAliasPassword.get(alias);
  726.                         if(passwordPrivateKey==null) {
  727.                             throw new UtilsException("password non definita");
  728.                         }
  729.                         privateKey = this.keyStore.getPrivateKey(alias, passwordPrivateKey);
  730.                     }catch(Exception e) {
  731.                         throw new UtilsException("Chiave privata associato al certificato (alias: "+alias+") non recuperabile: "+e.getMessage(),e);
  732.                     }
  733.                 }
  734.             }
  735.         }
  736.         if(privateKey==null) {
  737.             throw new UtilsException("Chiave privata associato al certificato (presente in header x5c) non recuperato");
  738.         }
  739.         JweDecryptionProvider providerBuild = JweUtils.createJweDecryptionProvider( privateKey, keyAlgo, contentAlgo);
  740.         try {
  741.             providerBuild.getKeyAlgorithm();
  742.         }catch(NullPointerException nullPointer) {
  743.             // caso in cui la chiave privata PKCS11 non e' stata mappata in un PrivateKeyDecryptionProvider
  744.             providerBuild = null;
  745.         }
  746.         if(providerBuild==null) {
  747.             providerBuild = JsonUtils.getJweAsymmetricDecryptionProvider(privateKey, keyAlgo, contentAlgo);
  748.             if(providerBuild==null) {
  749.                 throw new UtilsException("JwsDecryptionProvider init failed; keyAlgorithm ("+keyAlgo+") contentAlgorithm("+contentAlgo+")");
  750.             }
  751.         }
  752.         return providerBuild;

  753.     }
  754.    
  755.     private JweDecryptionProvider getProviderJWK(JsonWebKey webKey,
  756.             org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm keyAlgo,
  757.             org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm contentAlgo) throws UtilsException {
  758.         String n = webKey.getStringProperty("n");
  759.         if(n==null) {
  760.             throw new UtilsException("JsonWebKey uncorrect? 'n' not found");
  761.         }
  762.         if(this.jsonWebKeys==null) {
  763.             throw new UtilsException("JWKSet da utilizzare per il recupero dei certificati non definito");
  764.         }
  765.         this.rsaPublicKey = JwkUtils.toRSAPublicKey(webKey);
  766.         List<JsonWebKey> keys = this.jsonWebKeys.getKeys();
  767.         if(keys==null || keys.isEmpty()) {
  768.             throw new UtilsException("JWKSet da utilizzare per il recupero dei certificati vuoto");
  769.         }
  770.         JsonWebKey privateKey = null;
  771.         for (JsonWebKey jsonWebKeyCheck : keys) {
  772.             String nCheck = jsonWebKeyCheck.getStringProperty("n");
  773.             if(nCheck!=null && nCheck.equals(n)) {
  774.                 privateKey = jsonWebKeyCheck;
  775.                 break;
  776.             }
  777.         }
  778.         return JweUtils.createJweDecryptionProvider( JwkUtils.toRSAPrivateKey(privateKey), keyAlgo, contentAlgo);
  779.     }
  780. }