Information

0
Story Points

Technologies

Decompiled Java File
package ee.sk.xmlenc;

import ee.sk.digidoc.Base64Util;
import ee.sk.digidoc.DataFile;
import ee.sk.digidoc.DigiDocException;
import ee.sk.digidoc.SignedDoc;
import ee.sk.digidoc.factory.Pkcs12SignatureFactory;
import ee.sk.digidoc.factory.SignatureFactory;
import ee.sk.utils.ConfigManager;
import ee.sk.utils.ConvertUtils;
import ee.sk.xmlenc.EncryptedKey;
import ee.sk.xmlenc.EncryptionProperties;
import ee.sk.xmlenc.EncryptionProperty;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.log4j.Logger;

public class EncryptedData implements Serializable {
   private static final long serialVersionUID = 1L;
   private String m_id;
   private String m_type;
   private String m_mimeType;
   private String m_xmlns;
   private String m_encryptionMethod;
   private byte[] m_data;
   private int m_nDataStatus;
   private ArrayList m_arrEncryptedKeys;
   private EncryptionProperties m_encProperties;
   private static Logger m_logger = Logger.getLogger(EncryptedData.class);
   private transient SecretKey m_transportKey;
   public static final String DENC_ENCDATA_TYPE_DDOC = "http://www.sk.ee/DigiDoc/v1.3.0/digidoc.xsd";
   public static final String DENC_ENCDATA_MIME_XML = "text/xml";
   public static final String DENC_ENCDATA_MIME_ZLIB = "http://www.isi.edu/in-noes/iana/assignments/media-types/application/zip";
   public static final String DENC_ENC_METHOD_AES128 = "http://www.w3.org/2001/04/xmlenc#aes128-cbc";
   public static final String DENC_ENC_METHOD_RSA1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5";
   public static final String DENC_ENC_METHOD_RSA1_5_BUGGY = "http://www.w3.org/2001/04/xmlenc#rsa-1-5";
   public static final String DENC_XMLNS_XMLENC = "http://www.w3.org/2001/04/xmlenc#";
   public static final String DENC_XMLNS_XMLENC_ELEMENT = "http://www.w3.org/2001/04/xmlenc#Element";
   public static final String DENC_XMLNS_XMLENC_CONTENT = "http://www.w3.org/2001/04/xmlenc#Content";
   public static final String DENC_XMLNS_XMLENC_ENCPROP = "http://www.w3.org/2001/04/xmlenc#EncryptionProperties";
   public static final String DENC_XMLNS_XMLDSIG = "http://www.w3.org/2000/09/xmldsig#";
   public static final int DENC_DATA_STATUS_UNINITIALIZED = 0;
   public static final int DENC_DATA_STATUS_UNENCRYPTED_AND_NOT_COMPRESSED = 1;
   public static final int DENC_DATA_STATUS_UNENCRYPTED_AND_COMPRESSED = 2;
   public static final int DENC_DATA_STATUS_ENCRYPTED_AND_NOT_COMPRESSED = 3;
   public static final int DENC_DATA_STATUS_ENCRYPTED_AND_COMPRESSED = 4;
   /** @deprecated */
   public static final int DENC_COMPRESS_ALLWAYS = 0;
   public static final int DENC_COMPRESS_NEVER = 1;
   /** @deprecated */
   public static final int DENC_COMPRESS_BEST_EFFORT = 2;
   public static final String ENCPROP_FILENAME = "Filename";
   public static final String ENCPROP_ORIG_SIZE = "OriginalSize";
   public static final String ENCPROP_ORIG_MIME = "OriginalMimeType";
   public static final String ENCPROP_ORIG_FILE = "orig_file";
   public static final String ENCPROP_LIB_VER = "LibraryVersion";
   public static final String ENCPROP_FORMAT_VER = "DocumentFormat";
   public static final String FORMAT_ENCDOC_XML = "ENCDOC-XML";
   public static final String VERSION_1_0 = "1.0";
   public static final String DIGDOC_ENCRYPT_KEY_ALG = "AES";
   public static final String DIGIDOC_ENCRYPTION_ALOGORITHM2 = "AES/CBC/PKCS7Padding";
   public static final String DIGIDOC_ENCRYPTION_ALOGORITHM = "AES/CBC/NOPadding";
   public static final String DIGIDOC_SECRANDOM_ALGORITHM = "SHA1PRNG";
   public static final String DIGIDOC_KEY_ALOGORITHM = "RSA/NONE/PKCS1Padding";
   public static final boolean DIGDOC_ENCRYPT_USE_IV = true;
   public static final String DIGIDOC_SECURITY_PROVIDER_NAME = "BC";
   public static final String DIGIDOC_SECURITY_PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";

   public EncryptedData(String id, String type, String mimeType, String xmlns, String encryptionMethod) throws DigiDocException {
      this.setId(id);
      this.setType(type);
      this.setMimeType(mimeType);
      this.setXmlns(xmlns);
      this.setEncryptionMethod(encryptionMethod);
      this.m_data = null;
      this.m_transportKey = null;
      this.m_nDataStatus = 0;
      this.m_arrEncryptedKeys = null;
      this.m_encProperties = null;
      this.setPropLibraryNameAndVersion();
      this.setPropFormatNameAndVersion();
   }

   public EncryptedData(String xmlns) throws DigiDocException {
      this.m_id = null;
      this.m_type = null;
      this.m_mimeType = null;
      this.setXmlns(xmlns);
      this.m_encryptionMethod = null;
      this.m_data = null;
      this.m_transportKey = null;
      this.m_nDataStatus = 0;
      this.m_arrEncryptedKeys = null;
      this.m_encProperties = null;
   }

   public int getDataStatus() {
      return this.m_nDataStatus;
   }

   public void setDataStatus(int status) {
      this.m_nDataStatus = status;
   }

   public byte[] getData() {
      return this.m_data;
   }

   public void setData(byte[] data) {
      this.m_data = data;
   }

   public SecretKey getTransportKey() {
      return this.m_transportKey;
   }

   public void setTransportKey(SecretKey key) {
      this.m_transportKey = key;
   }

   public String getId() {
      return this.m_id;
   }

   public void setId(String str) {
      this.m_id = str;
   }

   public String getType() {
      return this.m_type;
   }

   public void setType(String str) {
      this.m_type = str;
   }

   public String getMimeType() {
      return this.m_mimeType;
   }

   public void setMimeType(String str) {
      this.m_mimeType = str;
   }

   public String getEncryptionMethod() {
      return this.m_encryptionMethod;
   }

   public void setEncryptionMethod(String str) throws DigiDocException {
      DigiDocException ex = this.validateEncryptionMethod(str);
      if(ex != null) {
         throw ex;
      } else {
         this.m_encryptionMethod = str;
      }
   }

   private DigiDocException validateEncryptionMethod(String str) {
      DigiDocException ex = null;
      if(str == null || !str.equals("http://www.w3.org/2001/04/xmlenc#aes128-cbc")) {
         ex = new DigiDocException(103, "EncryptionMethod atribute is required and currently the only supported value is: http://www.w3.org/2001/04/xmlenc#aes128-cbc", (Throwable)null);
      }

      return ex;
   }

   public String getXmlns() {
      return this.m_xmlns;
   }

   public void setXmlns(String str) throws DigiDocException {
      DigiDocException ex = this.validateXmlns(str);
      if(ex != null) {
         throw ex;
      } else {
         this.m_xmlns = str;
      }
   }

   private DigiDocException validateXmlns(String str) {
      DigiDocException ex = null;
      if(str == null || !str.equals("http://www.w3.org/2001/04/xmlenc#")) {
         ex = new DigiDocException(104, "xmlns atribute is required and currently the only supported value is: http://www.w3.org/2001/04/xmlenc#", (Throwable)null);
      }

      return ex;
   }

   public String getEncryptionPropertiesId() {
      return this.m_encProperties != null?this.m_encProperties.getId():null;
   }

   public void setEncryptionPropertiesId(String id) {
      if(this.m_encProperties == null) {
         this.m_encProperties = new EncryptionProperties(id);
      } else {
         this.m_encProperties.setId(id);
      }

   }

   public boolean encryptFileData(String sInFile, String sOutFile) {
      try {
         boolean ex = true;
         byte[] inData = SignedDoc.readFile(new File(sInFile));
         this.setData(inData);
         this.setDataStatus(1);
         this.addProperty("Filename", sInFile);
         if(sInFile.endsWith(".bdoc") || sInFile.endsWith(".asice")) {
            this.setMimeType("application/vnd.etsi.asic-e+zip");
         }

         this.addProperty("OriginalSize", (new Long((long)inData.length)).toString());
         this.encrypt(1);
         FileOutputStream fos = new FileOutputStream(sOutFile);
         fos.write(this.toXML());
         fos.close();
         return true;
      } catch (Exception var6) {
         m_logger.error("Error encrypting from: " + sInFile + " to: " + sOutFile + " - " + var6);
         var6.printStackTrace(System.err);
         return false;
      }
   }

   public void addProperty(EncryptionProperty prop) {
      if(this.m_encProperties == null) {
         this.m_encProperties = new EncryptionProperties((String)null);
      }

      this.m_encProperties.addProperty(prop);
   }

   public void addProperty(String name, String content) throws DigiDocException {
      if(this.m_encProperties == null) {
         this.m_encProperties = new EncryptionProperties((String)null);
      }

      this.m_encProperties.addProperty(new EncryptionProperty(name, content));
   }

   public int getNumProperties() {
      return this.m_encProperties == null?0:this.m_encProperties.getNumProperties();
   }

   public EncryptionProperty getProperty(int nIdx) {
      return nIdx < this.getNumProperties()?this.m_encProperties.getProperty(nIdx):null;
   }

   public EncryptionProperty findPropertyById(String id) {
      return this.m_encProperties != null?this.m_encProperties.findPropertyById(id):null;
   }

   public EncryptionProperty findPropertyByName(String name) {
      return this.m_encProperties != null?this.m_encProperties.findPropertyByName(name):null;
   }

   public EncryptionProperty getLastProperty() {
      return this.m_encProperties != null && this.m_encProperties.getNumProperties() > 0?this.m_encProperties.getProperty(this.m_encProperties.getNumProperties() - 1):null;
   }

   public String findPropertyContentByName(String name) {
      EncryptionProperty prop = this.findPropertyByName(name);
      return prop != null?prop.getContent():null;
   }

   public void setPropLibraryNameAndVersion() throws DigiDocException {
      EncryptionProperty prop = this.findPropertyByName("LibraryVersion");
      StringBuffer sb = new StringBuffer();
      sb.append("JDigiDoc");
      sb.append("|");
      sb.append("3.9.0-726");
      if(prop == null) {
         prop = new EncryptionProperty("LibraryVersion", sb.toString());
         this.addProperty(prop);
      } else {
         prop.setContent(sb.toString());
      }

   }

   public String getPropLibraryName() {
      StringBuffer sb = new StringBuffer();
      EncryptionProperty prop = this.findPropertyByName("LibraryVersion");
      if(prop != null) {
         String content = prop.getContent();
         boolean nIdx1 = false;
         int nIdx11;
         if(content != null && (nIdx11 = content.indexOf("|")) != -1) {
            sb.append(content.substring(0, nIdx11));
         }
      }

      return sb.toString();
   }

   public String getPropLibraryVersion() {
      StringBuffer sb = new StringBuffer();
      EncryptionProperty prop = this.findPropertyByName("LibraryVersion");
      if(prop != null) {
         String content = prop.getContent();
         boolean nIdx1 = false;
         int nIdx11;
         if(content != null && (nIdx11 = content.indexOf("|")) != -1) {
            sb.append(content.substring(nIdx11 + 1));
         }
      }

      return sb.toString();
   }

   public void setPropFormatNameAndVersion() throws DigiDocException {
      EncryptionProperty prop = this.findPropertyByName("DocumentFormat");
      StringBuffer sb = new StringBuffer();
      sb.append("ENCDOC-XML");
      sb.append("|");
      sb.append("1.0");
      if(prop == null) {
         prop = new EncryptionProperty("DocumentFormat", sb.toString());
         this.addProperty(prop);
      } else {
         prop.setContent(sb.toString());
      }

   }

   public String getPropFormatName() {
      StringBuffer sb = new StringBuffer();
      EncryptionProperty prop = this.findPropertyByName("DocumentFormat");
      if(prop != null) {
         String content = prop.getContent();
         boolean nIdx1 = false;
         int nIdx11;
         if(content != null && (nIdx11 = content.indexOf("|")) != -1) {
            sb.append(content.substring(0, nIdx11));
         }
      }

      return sb.toString();
   }

   public String getPropFormatVersion() {
      StringBuffer sb = new StringBuffer();
      EncryptionProperty prop = this.findPropertyByName("DocumentFormat");
      if(prop != null) {
         String content = prop.getContent();
         boolean nIdx1 = false;
         int nIdx11;
         if(content != null && (nIdx11 = content.indexOf("|")) != -1) {
            sb.append(content.substring(nIdx11 + 1));
         }
      }

      return sb.toString();
   }

   public void setPropRegisterDigiDoc(SignedDoc sdoc) throws DigiDocException {
      for(int i = 0; i < sdoc.countDataFiles(); ++i) {
         DataFile df = sdoc.getDataFile(i);
         StringBuffer sb = new StringBuffer();
         sb.append(df.getFileName());
         sb.append("|");
         sb.append((new Long(df.getSize())).toString());
         sb.append("|");
         sb.append(df.getMimeType());
         sb.append("|");
         sb.append(df.getId());
         this.addProperty(new EncryptionProperty("orig_file", sb.toString()));
      }

   }

   public int getPropOrigFileCount() {
      int n = 0;

      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals("orig_file")) {
            ++n;
         }
      }

      return n;
   }

   public String getPropOrigFileName(int nProp) {
      String str = null;
      int n = 0;
      boolean nIdx1 = false;

      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals("orig_file")) {
            ++n;
            if(n == nProp) {
               String content = prop.getContent();
               int var8;
               if(content != null && (var8 = content.indexOf("|")) != -1) {
                  str = content.substring(0, var8);
               }
               break;
            }
         }
      }

      return str;
   }

   public String getPropByName(String sName) {
      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals(sName)) {
            return prop.getContent();
         }
      }

      return null;
   }

   public String getPropOrigFileSize(int nProp) {
      String str = null;
      int n = 0;
      boolean nIdx1 = false;
      boolean nIdx2 = false;

      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals("orig_file")) {
            ++n;
            if(n == nProp) {
               String content = prop.getContent();
               int var9;
               int var10;
               if(content != null && (var9 = content.indexOf("|")) != -1 && (var10 = content.indexOf("|", var9 + 1)) != -1) {
                  str = content.substring(var9 + 1, var10);
               }
               break;
            }
         }
      }

      return str;
   }

   public String getPropOrigFileMime(int nProp) {
      String str = null;
      int n = 0;
      boolean nIdx1 = false;
      boolean nIdx2 = false;
      boolean nIdx3 = false;

      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals("orig_file")) {
            ++n;
            if(n == nProp) {
               String content = prop.getContent();
               int var10;
               int var11;
               int var12;
               if(content != null && (var12 = content.indexOf("|")) != -1 && (var10 = content.indexOf("|", var12 + 1)) != -1 && (var11 = content.indexOf("|", var10 + 1)) != -1) {
                  str = content.substring(var10 + 1, var11);
               }
               break;
            }
         }
      }

      return str;
   }

   public String getPropOrigFileId(int nProp) {
      String str = null;
      int n = 0;
      boolean nIdx1 = false;

      for(int i = 0; this.m_encProperties != null && i < this.m_encProperties.getNumProperties(); ++i) {
         EncryptionProperty prop = this.m_encProperties.getProperty(i);
         if(prop.getName() != null && prop.getName().equals("orig_file")) {
            ++n;
            if(n == nProp) {
               String content = prop.getContent();
               int var8;
               if(content != null && (var8 = content.lastIndexOf("|")) != -1) {
                  str = content.substring(var8 + 1);
               }
               break;
            }
         }
      }

      return str;
   }

   public void addEncryptedKey(EncryptedKey key) {
      if(this.m_arrEncryptedKeys == null) {
         this.m_arrEncryptedKeys = new ArrayList();
      }

      this.m_arrEncryptedKeys.add(key);
   }

   public int getNumKeys() {
      return this.m_arrEncryptedKeys == null?0:this.m_arrEncryptedKeys.size();
   }

   public EncryptedKey getEncryptedKey(int nIdx) {
      return nIdx < this.getNumKeys()?(EncryptedKey)this.m_arrEncryptedKeys.get(nIdx):null;
   }

   public EncryptedKey getLastEncryptedKey() {
      return this.m_arrEncryptedKeys != null && this.m_arrEncryptedKeys.size() > 0?(EncryptedKey)this.m_arrEncryptedKeys.get(this.m_arrEncryptedKeys.size() - 1):null;
   }

   public EncryptedKey findKeyById(String id) {
      for(int i = 0; this.m_arrEncryptedKeys != null && i < this.m_arrEncryptedKeys.size(); ++i) {
         EncryptedKey key = (EncryptedKey)this.m_arrEncryptedKeys.get(i);
         if(key.getId() != null && key.getId().equals(id)) {
            return key;
         }
      }

      return null;
   }

   public EncryptedKey findKeyByRecipient(String recv) {
      for(int i = 0; this.m_arrEncryptedKeys != null && i < this.m_arrEncryptedKeys.size(); ++i) {
         EncryptedKey key = (EncryptedKey)this.m_arrEncryptedKeys.get(i);
         if(key.getRecipient() != null && key.getRecipient().equals(recv)) {
            return key;
         }
      }

      return null;
   }

   private void initKey() throws DigiDocException {
      try {
         Security.addProvider((Provider)Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider").newInstance());
      } catch (Exception var4) {
         DigiDocException.handleException(var4, 116);
      }

      if(this.m_transportKey != null) {
         throw new DigiDocException(110, "Transport key allready initialized!", (Throwable)null);
      } else {
         try {
            SecureRandom ex = SecureRandom.getInstance("SHA1PRNG");
            KeyGenerator keygen = KeyGenerator.getInstance("AES", "BC");
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Keygen:" + keygen.getClass().getName() + " algorithm: " + keygen.getAlgorithm());
            }

            keygen.init(128, ex);
            this.m_transportKey = keygen.generateKey();
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("key0: " + this.m_transportKey.getEncoded().length);
            }
         } catch (Exception var3) {
            DigiDocException.handleException(var3, 107);
         }

         if(this.m_transportKey == null) {
            throw new DigiDocException(107, "Failure to initialize the transport key!", (Throwable)null);
         }
      }
   }

   public Cipher getCipher(int mode, SecretKey transportKey, byte[] iv) throws DigiDocException {
      Cipher cip = null;
      Object ivdata = null;
      if(this.m_transportKey == null && transportKey == null) {
         throw new DigiDocException(110, "Transport key has not been initialized!", (Throwable)null);
      } else {
         try {
            byte[] ivdata1;
            if(mode == 2) {
               cip = Cipher.getInstance("AES/CBC/NOPadding", "BC");
               IvParameterSpec ex = new IvParameterSpec(iv);
               cip.init(mode, transportKey == null?this.m_transportKey:transportKey, ex);
            } else {
               cip = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
               cip.init(mode, transportKey == null?this.m_transportKey:transportKey);
               ivdata1 = cip.getIV();
               System.arraycopy(ivdata1, 0, iv, 0, 16);
            }

            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Cipher: " + cip.getAlgorithm() + " provider: " + cip.getProvider().getName());
               ivdata1 = cip.getIV();
            }
         } catch (Exception var7) {
            DigiDocException.handleException(var7, 112);
         }

         return cip;
      }
   }

   public void encrypt(int nCompressOption) throws DigiDocException {
      byte[] ivdata = new byte[16];
      if(this.m_transportKey == null) {
         this.initKey();
      }

      if(this.m_data == null || this.m_nDataStatus != 2 && this.m_nDataStatus != 1) {
         throw new DigiDocException(115, "Invalid data status for encryption operation!", (Throwable)null);
      } else {
         int nTotalInput = this.m_data.length;
         boolean nTotalCompressed = false;
         boolean nTotalEncrypted = false;
         this.compress(nCompressOption);
         int var16 = this.m_data.length;
         Cipher cipher = this.getCipher(1, (SecretKey)null, ivdata);

         try {
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Encrypt - algorithm: " + cipher.getAlgorithm() + " blocksize: " + cipher.getBlockSize());
            }

            int ex = cipher.getBlockSize();
            Object cdata = null;
            int nOrigLen = this.m_data.length;
            int nLastBlockSize = this.m_data.length % ex;
            int nInput = nOrigLen - nLastBlockSize + ex;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bos.write(this.m_data, 0, this.m_data.length - nLastBlockSize);
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Encrypt - body: " + this.m_data.length + " full-data: " + (this.m_data.length - nLastBlockSize) + " left: " + nLastBlockSize);
            }

            byte[] var18 = new byte[ex];
            int i;
            if(nLastBlockSize > 0) {
               System.arraycopy(this.m_data, this.m_data.length - nLastBlockSize, var18, 0, nLastBlockSize);

               for(i = nLastBlockSize; i < ex; ++i) {
                  var18[i] = 0;
               }

               var18[ex - 1] = (new Integer(ex - nLastBlockSize)).byteValue();
            } else {
               for(i = nLastBlockSize; i < ex; ++i) {
                  var18[i] = 0;
               }

               var18[ex - 1] = 16;
            }

            bos.write(var18);
            if(m_logger.isDebugEnabled()) {
               for(i = 0; i < ex; ++i) {
                  m_logger.debug("Byte at: " + i + " = " + var18[i]);
               }
            }

            var18 = cipher.doFinal(bos.toByteArray());
            int var17 = var18.length;
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Encrypt - orig: " + nOrigLen + " input: " + nInput + " encrypted: " + var18.length);
            }

            this.m_data = new byte[var18.length + 16];
            System.arraycopy(ivdata, 0, this.m_data, 0, 16);
            System.arraycopy(var18, 0, this.m_data, 16, var18.length);
            this.m_nDataStatus = 3;

            for(i = 0; i < this.getNumKeys(); ++i) {
               EncryptedKey ekey = this.getEncryptedKey(i);
               ekey.encryptKey(this);
            }

            if(m_logger.isInfoEnabled()) {
               m_logger.info("Encrypt total - input: " + nTotalInput + " compressed: " + var16 + " encrypted: " + var17);
            }
         } catch (Exception var15) {
            DigiDocException.handleException(var15, 112);
         }

      }
   }

   public int getRecvIndex(X509Certificate cert) {
      if(cert == null) {
         return -1;
      } else {
         for(int i = 0; this.m_arrEncryptedKeys != null && i < this.m_arrEncryptedKeys.size(); ++i) {
            EncryptedKey key = (EncryptedKey)this.m_arrEncryptedKeys.get(i);
            if(key.getRecipientsCertificate() != null && key.getRecipientsCertificate().getSerialNumber().equals(cert.getSerialNumber())) {
               return i;
            }
         }

         return -1;
      }
   }

   public void decrypt(int nKey, int token, String pin) throws DigiDocException {
      EncryptedKey ekey = this.getEncryptedKey(nKey);

      try {
         SignatureFactory ex = ConfigManager.instance().getSignatureFactory();
         if(m_logger.isDebugEnabled()) {
            m_logger.debug("Decrypting key: " + nKey + " with token: " + token);
         }

         byte[] decdata = ex.decrypt(ekey.getTransportKeyData(), token, pin);
         this.decryptWithKey(decdata);
      } catch (Exception var7) {
         DigiDocException.handleException(var7, 111);
      }

   }

   public void decryptPkcs12(int nKey, String keystore, String storepass, String storetype) throws DigiDocException {
      EncryptedKey ekey = this.getEncryptedKey(nKey);

      try {
         Pkcs12SignatureFactory ex = new Pkcs12SignatureFactory();
         ex.init();
         ex.load(keystore, storetype, storepass);
         if(m_logger.isDebugEnabled()) {
            m_logger.debug("Decrypting key: " + nKey + " with token: " + nKey);
         }

         byte[] decdata = ex.decrypt(ekey.getTransportKeyData(), 0, storepass);
         this.decryptWithKey(decdata);
      } catch (Exception var8) {
         DigiDocException.handleException(var8, 111);
      }

   }

   public void decrypt(String driver, String keystoreFile, int nKey, int token, String pin) throws DigiDocException {
      EncryptedKey ekey = this.getEncryptedKey(nKey);
      boolean bOk = true;

      try {
         ConfigManager ex = ConfigManager.instance();
         SignatureFactory sigFac = ex.getSignatureFactoryOfType(driver);
         if(sigFac == null) {
            m_logger.error("No signature factory of type: " + driver);
            throw new DigiDocException(111, "No signature factory of type: " + driver, (Throwable)null);
         }

         if(sigFac.getType().equals("PKCS12")) {
            Pkcs12SignatureFactory decdata = (Pkcs12SignatureFactory)sigFac;
            bOk = decdata.load(keystoreFile, "PKCS12", pin);
         }

         if(!bOk) {
            m_logger.error("Failed to load signature token!");
            throw new DigiDocException(111, "Failed to load signature token!", (Throwable)null);
         }

         if(ekey == null) {
            m_logger.error("No recipient nr: " + nKey);
            throw new DigiDocException(111, "No recipient nr: " + nKey, (Throwable)null);
         }

         if(m_logger.isDebugEnabled()) {
            m_logger.debug("Decrypting key: " + nKey + " with token: " + token + " key-data: " + (ekey.getTransportKeyData() != null?ekey.getTransportKeyData().length:0));
         }

         byte[] decdata1 = sigFac.decrypt(ekey.getTransportKeyData(), token, pin);
         this.decryptWithKey(decdata1);
      } catch (Exception var11) {
         DigiDocException.handleException(var11, 111);
      }

   }

   public void decryptWithKey(byte[] deckey) throws DigiDocException {
      byte[] ivdata = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
      if(this.m_data != null && (this.m_nDataStatus == 4 || this.m_nDataStatus == 3)) {
         if(m_logger.isDebugEnabled()) {
            m_logger.debug("Decrypting " + this.m_data.length + " using iv " + ivdata.length + " left: " + (this.m_data.length - ivdata.length));
         }

         System.arraycopy(this.m_data, 0, ivdata, 0, ivdata.length);

         try {
            this.m_transportKey = new SecretKeySpec(deckey, "AES/CBC/NOPadding");
            Cipher ex = this.getCipher(2, this.m_transportKey, ivdata);
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Decrypting: " + this.m_data.length + " bytes");
            }

            this.m_data = ex.doFinal(this.m_data, 16, this.m_data.length - 16);
            int nPadLen;
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Decrypted data: " + this.m_data.length + " bytes");

               for(nPadLen = this.m_data.length - 16; nPadLen < this.m_data.length; ++nPadLen) {
                  m_logger.debug("byte at: " + nPadLen + " = " + this.m_data[nPadLen]);
               }
            }

            nPadLen = (new Integer(this.m_data[this.m_data.length - 1])).intValue();
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Decrypted: " + this.m_data.length + " bytes, check padding: " + nPadLen);
            }

            boolean bPadOk = this.checkPadding(this.m_data, nPadLen);
            if(bPadOk) {
               this.m_data = this.removePadding(this.m_data, nPadLen);
            }

            nPadLen = (new Integer(this.m_data[this.m_data.length - 1])).intValue();
            bPadOk = this.checkPadding(this.m_data, nPadLen);
            if(bPadOk) {
               this.m_data = this.removePadding(this.m_data, nPadLen);
            }

            if(this.m_nDataStatus == 4) {
               this.m_nDataStatus = 2;
            }

            if(this.m_nDataStatus == 3) {
               this.m_nDataStatus = 1;
            }

            if(this.m_nDataStatus == 2) {
               this.decompress();
            }
         } catch (Exception var6) {
            DigiDocException.handleException(var6, 111);
         }

      } else {
         throw new DigiDocException(115, "Invalid data status for decryption operation!", (Throwable)null);
      }
   }

   private boolean checkPadding(byte[] data, int nPadLen) {
      boolean bPadOk = true;
      if(m_logger.isDebugEnabled()) {
         m_logger.debug("Checking padding: " + nPadLen + " bytes");
      }

      if(nPadLen >= 0 && nPadLen <= 16 && data != null && data.length >= nPadLen) {
         for(int i = data.length - nPadLen; nPadLen > 0 && i < data.length - 1; ++i) {
            if(data[i] != 0 && nPadLen != 16) {
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Data at: " + i + " = " + data[i] + " cancel padding");
               }

               bPadOk = false;
               break;
            }
         }

         return bPadOk;
      } else {
         return false;
      }
   }

   private byte[] removePadding(byte[] data, int nPadLen) {
      if(m_logger.isDebugEnabled()) {
         m_logger.debug("Removing padding: " + nPadLen + " bytes");
      }

      byte[] data2 = new byte[data.length - nPadLen];
      System.arraycopy(data, 0, data2, 0, data.length - nPadLen);
      return data2;
   }

   private void compress(int nCompressOption) throws DigiDocException {
      if(nCompressOption != 1) {
         if(this.m_data != null && this.m_nDataStatus == 1) {
            try {
               int ex = this.m_data.length;
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Compressing: " + this.m_data.length + " bytes");
               }

               ByteArrayOutputStream bout = new ByteArrayOutputStream();
               DeflaterOutputStream gout = new DeflaterOutputStream(bout);
               gout.write(this.m_data);
               gout.flush();
               gout.close();
               bout.close();
               byte[] n_data = bout.toByteArray();
               int nNewSize = n_data.length;
               if(nCompressOption == 0 || nCompressOption == 2 && nNewSize < ex) {
                  this.m_nDataStatus = 2;
                  this.m_data = n_data;
                  this.addProperty("OriginalSize", (new Integer(ex)).toString());
                  if(this.m_mimeType != null) {
                     this.addProperty("OriginalMimeType", this.m_mimeType);
                  }

                  this.m_mimeType = "http://www.isi.edu/in-noes/iana/assignments/media-types/application/zip";
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("Keeping compressed: " + this.m_data.length + " bytes");
                  }
               } else if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Discarding compressed: " + this.m_data.length + " bytes");
               }
            } catch (Exception var7) {
               DigiDocException.handleException(var7, 113);
            }

         } else {
            throw new DigiDocException(115, "Invalid data status for compression operation!", (Throwable)null);
         }
      }
   }

   private void decompress() throws DigiDocException {
      if(this.m_data != null && this.m_nDataStatus == 2) {
         try {
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Decompressing: " + this.m_data.length + " bytes");
            }

            ByteArrayInputStream ex = new ByteArrayInputStream(this.m_data);
            InflaterInputStream gin = new InflaterInputStream(ex);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] data = new byte[2048];
            boolean nRead = false;

            int nRead1;
            while((nRead1 = gin.read(data)) > 0) {
               bos.write(data, 0, nRead1);
            }

            gin.close();
            ex.close();
            bos.close();
            this.m_data = bos.toByteArray();
            this.m_nDataStatus = 1;
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("Decompressed: " + this.m_data.length + " bytes");
            }
         } catch (Exception var6) {
            DigiDocException.handleException(var6, 114);
         }

      } else {
         throw new DigiDocException(115, "Invalid data status for decompression operation!", (Throwable)null);
      }
   }

   public void encryptStream(InputStream in, OutputStream out, int nCompressOption) throws DigiDocException {
      byte[] ivdata = new byte[16];
      if(this.m_transportKey == null) {
         this.initKey();
      }

      if(this.m_data == null && this.m_nDataStatus == 0) {
         Cipher cipher = this.getCipher(1, (SecretKey)null, ivdata);
         Deflater compressor = null;
         if(nCompressOption == 0) {
            compressor = new Deflater();
            if(this.m_mimeType != null) {
               this.addProperty("OriginalMimeType", this.m_mimeType);
            }

            this.m_mimeType = "http://www.isi.edu/in-noes/iana/assignments/media-types/application/zip";
         }

         int nCiphBlockSize = cipher.getBlockSize();
         short nBlockSize = 2048;
         int nTotalInput = 0;
         int nTotalCompressed = 0;
         int nTotalEncrypted = 0;
         int nTotalBase64 = 0;
         int nTotalEncInp = 0;
         int nB64left = 0;
         byte[] data1 = new byte[nBlockSize];
         byte[] data2 = new byte[nBlockSize * 10];
         byte[] b64leftover = new byte[65];

         try {
            if(m_logger.isDebugEnabled()) {
               m_logger.debug("EncryptStream - algorithm: " + cipher.getAlgorithm() + " blocksize: " + nCiphBlockSize);
            }

            for(int ex = 0; ex < this.getNumKeys(); ++ex) {
               EncryptedKey isReadFromFile = this.getEncryptedKey(ex);
               isReadFromFile.encryptKey(this);
            }

            out.write(this.xmlHeader());
            boolean var28 = false;
            boolean var29 = true;

            int nLen1;
            do {
               int nLen2;
               if(var29) {
                  nLen1 = in.read(data1);
                  if(nLen1 < 0) {
                     nLen1 = 0;
                  }

                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - input: " + nLen1);
                  }

                  nTotalInput += nLen1;
                  var28 = nLen1 < nBlockSize;
                  if(nCompressOption == 0) {
                     if(nLen1 > 0) {
                        compressor.setInput(data1, 0, nLen1);
                     }

                     if(var28) {
                        compressor.finish();
                        nLen2 = compressor.deflate(data2);
                        var29 = compressor.finished();
                     } else {
                        nLen2 = compressor.deflate(data2);
                        if(nLen2 > 0) {
                           var29 = false;
                        }
                     }

                     nTotalCompressed += nLen2;
                     if(m_logger.isDebugEnabled()) {
                        m_logger.debug("EncryptStream - input: " + nLen1 + " compressed: " + nLen2 + " needin: " + compressor.needsInput());
                     }
                  } else {
                     if(nLen1 > 0 && data2.length < nLen1) {
                        data2 = new byte[nLen1];
                     }

                     if(nLen1 > 0) {
                        System.arraycopy(data1, 0, data2, 0, nLen1);
                        nLen2 = nLen1;
                     } else {
                        nLen2 = 0;
                     }
                  }
               } else {
                  nLen1 = 0;
                  nLen2 = compressor.deflate(data2);
                  if(var28) {
                     var29 = compressor.finished();
                  } else {
                     var29 = nLen2 == 0;
                  }

                  nTotalCompressed += nLen2;
               }

               byte[] encdata = null;
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("EncryptStream - input: " + nLen1 + " enc-input: " + nLen2);
               }

               if(var29 && var28) {
                  ByteArrayOutputStream nUsed = new ByteArrayOutputStream();
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - last-data: " + nLen2);
                  }

                  encdata = cipher.update(data2, 0, nLen2);
                  if(encdata != null) {
                     nUsed.write(encdata);
                  }

                  nTotalEncInp += nLen2;
                  int nLastBlockSize = nCiphBlockSize - nTotalEncInp % nCiphBlockSize;
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - total-data: " + nTotalEncInp + " padding: " + nLastBlockSize);
                  }

                  if(nLastBlockSize == 0) {
                     nLastBlockSize = 16;
                  }

                  byte[] ldata = new byte[nLastBlockSize];

                  for(int i = 0; i < nLastBlockSize; ++i) {
                     ldata[i] = 0;
                  }

                  ldata[nLastBlockSize - 1] = (new Integer(nLastBlockSize)).byteValue();
                  encdata = cipher.doFinal(ldata);
                  nUsed.write(encdata);
                  encdata = nUsed.toByteArray();
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - encrypted: " + (encdata != null?encdata.length:0));
                  }
               } else if(nLen2 > 0) {
                  encdata = cipher.update(data2, 0, nLen2);
                  nTotalEncInp += nLen2;
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - norm input: " + nLen2 + " encrypted: " + (encdata != null?encdata.length:0));
                  }
               }

               if(encdata != null) {
                  byte[] var30;
                  if(nTotalEncrypted == 0) {
                     var30 = new byte[encdata.length + 16];
                     System.arraycopy(ivdata, 0, var30, 0, 16);
                     System.arraycopy(encdata, 0, var30, 16, encdata.length);
                     nTotalEncrypted += encdata.length;
                     encdata = var30;
                  } else {
                     nTotalEncrypted += encdata.length;
                  }

                  if(nB64left > 0) {
                     if(m_logger.isDebugEnabled()) {
                        m_logger.debug("EncryptStream - input: " + encdata.length + " left: " + nB64left);
                     }

                     var30 = new byte[encdata.length + nB64left];
                     System.arraycopy(b64leftover, 0, var30, 0, nB64left);
                     System.arraycopy(encdata, 0, var30, nB64left, encdata.length);
                     encdata = var30;
                  }

                  int var31 = Base64Util.encodeToStream(encdata, out, var28 && var29);
                  nB64left = encdata.length - var31;
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("EncryptStream - input: " + encdata.length + " used: " + var31 + " copy: " + nB64left + " pos: " + var31);
                  }

                  if(nB64left > 0) {
                     System.arraycopy(encdata, var31, b64leftover, 0, nB64left);
                     nTotalBase64 += var31 / 3 * 4;
                     if(m_logger.isDebugEnabled()) {
                        m_logger.debug("EncryptStream - input: " + encdata.length + " used: " + var31 + " base64: " + var31 / 3 * 4 + " left: " + nB64left);
                     }
                  }
               }
            } while(!var28 || nLen1 == nBlockSize || !var29);

            this.addProperty("OriginalSize", (new Integer(nTotalInput)).toString());
            out.write(this.xmlTrailer());
            out.flush();
            if(m_logger.isInfoEnabled()) {
               m_logger.info("EncryptStream total - input: " + nTotalInput + " compressed: " + nTotalCompressed + " encrypted: " + nTotalEncrypted + " base64: " + nTotalBase64);
            }
         } catch (Exception var27) {
            DigiDocException.handleException(var27, 112);
         }

      } else {
         throw new DigiDocException(115, "Invalid data status for encryption operation!", (Throwable)null);
      }
   }

   public byte[] toXML() throws DigiDocException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      try {
         bos.write(this.xmlHeader());
         byte[] ex = ConvertUtils.str2data(Base64Util.encode(this.m_data, 64));
         int nTotalBase64 = ex.length;
         bos.write(ex);
         if(m_logger.isInfoEnabled()) {
            m_logger.info("Encrypt total - base64: " + nTotalBase64);
         }

         bos.write(this.xmlTrailer());
      } catch (IOException var4) {
         DigiDocException.handleException(var4, 89);
      }

      return bos.toByteArray();
   }

   private byte[] xmlHeader() throws DigiDocException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      try {
         bos.write(ConvertUtils.str2data("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"));
         bos.write(ConvertUtils.str2data("<denc:EncryptedData xmlns:denc=\"" + this.m_xmlns + "\""));
         if(this.m_id != null) {
            bos.write(ConvertUtils.str2data(" Id=\"" + this.m_id + "\""));
         }

         if(this.m_mimeType != null) {
            bos.write(ConvertUtils.str2data(" MimeType=\"" + this.m_mimeType + "\""));
         }

         if(this.m_type != null) {
            bos.write(ConvertUtils.str2data(" Type=\"" + this.m_type + "\""));
         }

         bos.write(ConvertUtils.str2data(">"));
         bos.write(ConvertUtils.str2data("<denc:EncryptionMethod Algorithm=\""));
         bos.write(ConvertUtils.str2data(this.m_encryptionMethod));
         bos.write(ConvertUtils.str2data("\"></denc:EncryptionMethod>"));
         bos.write(ConvertUtils.str2data("<ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">"));

         for(int ex = 0; ex < this.getNumKeys(); ++ex) {
            EncryptedKey key = this.getEncryptedKey(ex);
            bos.write(key.toXML());
         }

         bos.write(ConvertUtils.str2data("</ds:KeyInfo>"));
         bos.write(ConvertUtils.str2data("<denc:CipherData><denc:CipherValue>"));
      } catch (IOException var4) {
         DigiDocException.handleException(var4, 89);
      }

      return bos.toByteArray();
   }

   private byte[] xmlTrailer() throws DigiDocException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      try {
         bos.write(ConvertUtils.str2data("</denc:CipherValue></denc:CipherData>"));
         if(this.getNumProperties() > 0) {
            bos.write(ConvertUtils.str2data("<denc:EncryptionProperties"));
            if(this.getEncryptionPropertiesId() != null) {
               bos.write(ConvertUtils.str2data(" Id=\"" + this.getEncryptionPropertiesId() + "\""));
            }

            bos.write(ConvertUtils.str2data(">"));

            for(int ex = 0; ex < this.getNumProperties(); ++ex) {
               EncryptionProperty prop = this.getProperty(ex);
               bos.write(prop.toXML());
            }

            bos.write(ConvertUtils.str2data("</denc:EncryptionProperties>"));
         }

         bos.write(ConvertUtils.str2data("</denc:EncryptedData>"));
      } catch (IOException var4) {
         DigiDocException.handleException(var4, 89);
      }

      return bos.toByteArray();
   }

   public ArrayList validate() {
      ArrayList errs = new ArrayList();
      DigiDocException ex = this.validateEncryptionMethod(this.m_encryptionMethod);
      if(ex != null) {
         errs.add(ex);
      }

      ex = this.validateXmlns(this.m_xmlns);
      if(ex != null) {
         errs.add(ex);
      }

      if(this.m_encProperties != null) {
         ArrayList i = this.m_encProperties.validate();
         if(!i.isEmpty()) {
            errs.addAll(i);
         }
      }

      for(int var6 = 0; var6 < this.getNumKeys(); ++var6) {
         EncryptedKey ekey = this.getEncryptedKey(var6);
         ArrayList e = ekey.validate();
         if(!e.isEmpty()) {
            errs.addAll(e);
         }
      }

      return errs;
   }

   public String toString() {
      String str = null;

      try {
         str = new String(this.toXML());
      } catch (Exception var3) {
         ;
      }

      return str;
   }
}
Page generated: Oct 19, 2017 2:34:25 PM