Information

1
Story Points

Technologies

Decompiled Java File
package ee.sk.digidoc;

import ee.sk.digidoc.Base64Util;
import ee.sk.digidoc.CertID;
import ee.sk.digidoc.CertValue;
import ee.sk.digidoc.CompleteCertificateRefs;
import ee.sk.digidoc.CompleteRevocationRefs;
import ee.sk.digidoc.DataFile;
import ee.sk.digidoc.DigiDocException;
import ee.sk.digidoc.KeyInfo;
import ee.sk.digidoc.Manifest;
import ee.sk.digidoc.ManifestFileEntry;
import ee.sk.digidoc.Reference;
import ee.sk.digidoc.Signature;
import ee.sk.digidoc.SignatureProductionPlace;
import ee.sk.digidoc.SignedInfo;
import ee.sk.digidoc.UnsignedProperties;
import ee.sk.digidoc.factory.DigiDocFactory;
import ee.sk.digidoc.factory.DigiDocGenFactory;
import ee.sk.digidoc.factory.DigiDocVerifyFactory;
import ee.sk.digidoc.factory.DigiDocXmlGenFactory;
import ee.sk.utils.ConfigManager;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URL;
import java.security.MessageDigest;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.zip.CRC32;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.log4j.Logger;

public class SignedDoc implements Serializable {
   private static final long serialVersionUID = 1L;
   private String m_format;
   private String m_version;
   private ArrayList m_dataFiles;
   private ArrayList m_signatures;
   private Manifest m_manifest;
   private String m_mimeType;
   private String m_nsXmlDsig;
   private String m_nsXades;
   private String m_nsAsic;
   private String m_profile;
   private String m_comment;
   private Hashtable m_sigFormats;
   private long m_size;
   private String m_path;
   private String m_file;
   private static Logger m_logger = Logger.getLogger(SignedDoc.class);
   public static final String FORMAT_SK_XML = "SK-XML";
   public static final String FORMAT_DIGIDOC_XML = "DIGIDOC-XML";
   public static final String FORMAT_BDOC = "BDOC";
   public static final String FORMAT_BDOC_MIME = "application/vnd.bdoc";
   public static final String VERSION_1_0 = "1.0";
   public static final String VERSION_1_1 = "1.1";
   public static final String VERSION_1_2 = "1.2";
   public static final String VERSION_1_3 = "1.3";
   public static final String BDOC_VERSION_1_0 = "1.0";
   public static final String BDOC_VERSION_1_1 = "1.1";
   public static final String BDOC_VERSION_2_1 = "2.1";
   public static final String BDOC_PROFILE_BES = "BES";
   public static final String BDOC_PROFILE_T = "T";
   public static final String BDOC_PROFILE_CL = "C-L";
   public static final String BDOC_PROFILE_TM = "TM";
   public static final String BDOC_PROFILE_TS = "TS";
   public static final String BDOC_PROFILE_TMA = "TM-A";
   public static final String BDOC_PROFILE_TSA = "TS-A";
   public static final String SHA1_DIGEST_ALGORITHM = "http://www.w3.org/2000/09/xmldsig#sha1";
   public static final String SHA1_DIGEST_TYPE = "SHA-1";
   public static final String SHA1_DIGEST_TYPE_BAD = "SHA-1-00";
   public static final String SHA256_DIGEST_ALGORITHM_1 = "http://www.w3.org/2001/04/xmlenc#sha256";
   public static final String SHA256_DIGEST_ALGORITHM_2 = "http://www.w3.org/2001/04/xmldsig-more#sha256";
   public static final String SHA256_DIGEST_TYPE = "SHA-256";
   public static final String SHA224_DIGEST_TYPE = "SHA-224";
   public static final String SHA224_DIGEST_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#sha224";
   public static final String SHA384_DIGEST_TYPE = "SHA-384";
   public static final String SHA384_DIGEST_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#sha384";
   public static final String SHA512_DIGEST_TYPE = "SHA-512";
   public static final String SHA512_DIGEST_ALGORITHM = "http://www.w3.org/2001/04/xmlenc#sha512";
   public static final int SHA1_DIGEST_LENGTH = 20;
   public static final int SHA224_DIGEST_LENGTH = 28;
   public static final int SHA256_DIGEST_LENGTH = 32;
   public static final int SHA512_DIGEST_LENGTH = 64;
   public static final String CANONICALIZATION_METHOD_20010315 = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
   public static final String CANONICALIZATION_METHOD_1_1 = "http://www.w3.org/2006/12/xml-c14n11";
   public static final String TRANSFORM_20001026 = "http://www.w3.org/TR/2000/CR-xml-c14n-20001026";
   public static final String RSA_SHA1_SIGNATURE_METHOD = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
   public static final String RSA_SHA224_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha224";
   public static final String RSA_SHA256_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
   public static final String RSA_SHA384_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
   public static final String RSA_SHA512_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512";
   public static final String ECDSA_SHA1_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1";
   public static final String ECDSA_SHA224_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224";
   public static final String ECDSA_SHA256_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
   public static final String ECDSA_SHA384_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384";
   public static final String ECDSA_SHA512_SIGNATURE_METHOD = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512";
   public static final String DIGIDOC_DETATCHED_TRANSFORM = "http://www.sk.ee/2002/10/digidoc#detatched-document-signature";
   public static final String ENVELOPED_TRANSFORM = "http://www.w3.org/2000/09/xmldsig#enveloped-signature";
   public static final String SIGNEDPROPERTIES_TYPE = "http://uri.etsi.org/01903#SignedProperties";
   public static String xmlns_xmldsig = "http://www.w3.org/2000/09/xmldsig#";
   public static String xmlns_etsi = "http://uri.etsi.org/01903/v1.1.1#";
   public static String xmlns_digidoc13 = "http://www.sk.ee/DigiDoc/v1.3.0#";
   public static String xmlns_asic = "http://uri.etsi.org/02918/v1.2.1#";
   public static final String LIB_NAME = "JDigiDoc";
   public static final String LIB_VERSION = "3.9.0-726";
   public static String xmlns_xades_123 = "http://uri.etsi.org/01903/v1.3.2#";
   public static final String SIG_FILE_NAME = "META-INF/signature";
   public static final String SIG_FILE_NAME_20 = "META-INF/signatures";
   public static final String MIMET_FILE_NAME = "mimetype";
   public static final String MIMET_FILE_CONTENT_10 = "application/vnd.bdoc-1.0";
   public static final String MIMET_FILE_CONTENT_11 = "application/vnd.bdoc-1.1";
   public static final String MIMET_FILE_CONTENT_20 = "application/vnd.etsi.asic-e+zip";
   public static final String MANIF_DIR_META_INF = "META-INF";
   public static final String MANIF_FILE_NAME = "META-INF/manifest.xml";
   public static final String MIME_SIGNATURE_BDOC_ = "signature/bdoc-";
   private static final String PEM_HDR1 = "-----BEGIN CERTIFICATE-----\n";
   private static final String PEM_HDR2 = "\n-----END CERTIFICATE-----";

   public SignedDoc() {
      this.m_format = null;
      this.m_version = null;
      this.m_dataFiles = null;
      this.m_signatures = null;
      this.m_manifest = null;
      this.m_mimeType = null;
      this.m_nsXmlDsig = null;
      this.m_nsXades = null;
      this.m_nsAsic = null;
      this.m_file = null;
      this.m_path = null;
      this.m_comment = null;
   }

   public SignedDoc(String format, String version) throws DigiDocException {
      this.setFormatAndVersion(format, version);
      this.m_dataFiles = null;
      this.m_signatures = null;
      this.m_manifest = null;
      this.m_mimeType = null;
      this.m_nsXmlDsig = null;
      this.m_nsXades = null;
      this.m_comment = null;
      if(format.equals("BDOC")) {
         this.m_manifest = new Manifest();
         ManifestFileEntry fe = new ManifestFileEntry(this.getManifestEntry(version), "/");
         this.m_manifest.addFileEntry(fe);
         this.setDefaultNsPref("BDOC");
      }

   }

   public void setDefaultNsPref(String format) {
      if(format.equals("BDOC")) {
         this.m_nsXmlDsig = "ds";
         this.m_nsXades = "xades";
         this.m_nsAsic = "asic";
      }

      if(format.equals("DIGIDOC-XML") || format.equals("SK-XML")) {
         this.m_nsXmlDsig = null;
         this.m_nsXades = null;
         this.m_nsAsic = null;
      }

   }

   private String getManifestEntry(String ver) {
      return ver.equals("1.0")?"application/vnd.bdoc-1.0":(ver.equals("1.1")?"application/vnd.bdoc-1.1":"application/vnd.etsi.asic-e+zip");
   }

   public ManifestFileEntry findManifestEntryByPath(String fullPath) {
      return this.m_manifest.findFileEntryByPath(fullPath);
   }

   public String getFormat() {
      return this.m_format;
   }

   public void setFormat(String str) throws DigiDocException {
      DigiDocException ex = this.validateFormat(str);
      if(ex != null) {
         throw ex;
      } else {
         this.m_format = str;
      }
   }

   public ArrayList getDataFiles() {
      return this.m_dataFiles;
   }

   public void setDataFiles(ArrayList l) {
      this.m_dataFiles = l;
   }

   public ArrayList getSignatures() {
      return this.m_signatures;
   }

   public long getSize() {
      return this.m_size;
   }

   public void setSize(long l) {
      this.m_size = l;
   }

   public String getFile() {
      return this.m_file;
   }

   public void setFile(String fname) {
      this.m_file = fname;
   }

   public String getPath() {
      return this.m_path;
   }

   public void setPath(String p) {
      this.m_path = p;
   }

   public String getComment() {
      return this.m_comment;
   }

   public void setComment(String s) {
      this.m_comment = s;
   }

   public void addSignatureProfile(String sigId, String profile) {
      if(this.m_sigFormats == null) {
         this.m_sigFormats = new Hashtable();
      }

      if(m_logger.isDebugEnabled()) {
         m_logger.debug("Register signature: " + sigId + " profile: " + profile);
      }

      this.m_sigFormats.put(sigId, profile);
   }

   public String findSignatureProfile(String sigId) {
      return this.m_sigFormats != null?(String)this.m_sigFormats.get(sigId):null;
   }

   public String getXmlDsigNs() {
      return this.m_nsXmlDsig;
   }

   public void setXmlDsigNs(String str) {
      this.m_nsXmlDsig = str;
   }

   public String getXadesNs() {
      return this.m_nsXades;
   }

   public void setXadesNs(String str) {
      this.m_nsXades = str;
   }

   public String getAsicNs() {
      return this.m_nsAsic;
   }

   public void setAsicNs(String str) {
      this.m_nsAsic = str;
   }

   public String getProfile() {
      return this.m_profile;
   }

   public void setProfile(String s) {
      this.m_profile = s;
   }

   private DigiDocException validateFormat(String str) {
      DigiDocException ex = null;
      if(str == null) {
         ex = new DigiDocException(13, "Format attribute is mandatory!", (Throwable)null);
      } else {
         if(!str.equals("BDOC") && !str.equals("SK-XML") && !str.equals("DIGIDOC-XML")) {
            ex = new DigiDocException(13, "Currently supports only SK-XML, DIGIDOC-XML and BDOC formats", (Throwable)null);
         }

         if(str.equals("BDOC")) {
            if(this.m_manifest == null) {
               this.m_manifest = new Manifest();
            }

            if(this.m_manifest.findFileEntryByPath("/") == null) {
               ManifestFileEntry fe = new ManifestFileEntry(this.getManifestEntry(this.m_version), "/");
               this.m_manifest.addFileEntry(fe);
            }

            this.setDefaultNsPref("BDOC");
         }
      }

      return ex;
   }

   public String getVersion() {
      return this.m_version;
   }

   public void setVersion(String str) throws DigiDocException {
      DigiDocException ex = this.validateVersion(str);
      if(ex != null) {
         throw ex;
      } else {
         this.m_version = str;
      }
   }

   private DigiDocException validateVersion(String str) {
      DigiDocException ex = null;
      if(str == null) {
         ex = new DigiDocException(13, "Version attribute is mandatory!", (Throwable)null);
      } else if(this.m_format != null) {
         if(this.m_format.equals("SK-XML") && !str.equals("1.0")) {
            ex = new DigiDocException(13, "Format SK-XML supports only version 1.0", (Throwable)null);
         }

         if(this.m_format.equals("DIGIDOC-XML") && !str.equals("1.1") && !str.equals("1.2") && !str.equals("1.3")) {
            ex = new DigiDocException(13, "Format DIGIDOC-XML supports only versions 1.1, 1.2, 1.3", (Throwable)null);
         }

         if(this.m_format.equals("BDOC") && !str.equals("2.1")) {
            ex = new DigiDocException(13, "Format BDOC supports only versions 2.1", (Throwable)null);
         }
      }

      return ex;
   }

   public void setFormatAndVersion(String sFormat, String sVersion) throws DigiDocException {
      this.m_format = sFormat;
      this.m_version = sVersion;
      DigiDocException ex = this.validateFormatAndVersion();
      if(ex != null) {
         throw ex;
      }
   }

   public DigiDocException validateFormatAndVersion() {
      Object ex = null;
      if(this.m_format != null && this.m_version != null) {
         if(!this.m_format.equals("DIGIDOC-XML") && !this.m_format.equals("SK-XML")) {
            if(!this.m_format.equals("BDOC")) {
               return new DigiDocException(13, "Invalid format attribute!", (Throwable)null);
            }

            if(!this.m_version.equals("2.1")) {
               return new DigiDocException(13, "Format BDOC supports only versions 2.1", (Throwable)null);
            }
         } else if(!this.m_version.equals("1.3")) {
            return new DigiDocException(13, "Only format DIGIDOC-XML version 1.3 is supported!", (Throwable)null);
         }

         return null;
      } else {
         return new DigiDocException(13, "Format and version attributes are mandatory!", (Throwable)null);
      }
   }

   public Manifest getManifest() {
      return this.m_manifest;
   }

   public void setManifest(Manifest m) {
      this.m_manifest = m;
   }

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

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

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

   public void cleanupDfCache() {
      for(int i = 0; this.m_dataFiles != null && i < this.m_dataFiles.size(); ++i) {
         DataFile df = (DataFile)this.m_dataFiles.get(i);
         df.cleanupDfCache();
      }

   }

   public InputStream findDataFileAsStream(String dfName) {
      try {
         if(this.m_file != null) {
            StringBuffer ex = new StringBuffer();
            if(this.m_path != null) {
               ex.append(this.m_path);
               ex.append(File.separator);
            }

            ex.append(this.m_file);
            File fZip = new File(ex.toString());
            if(fZip.isFile() && fZip.canRead()) {
               ZipFile zis = new ZipFile(fZip);
               ZipArchiveEntry ze = zis.getEntry(dfName);
               if(ze != null) {
                  return zis.getInputStream(ze);
               }
            }
         }
      } catch (Exception var6) {
         m_logger.error("Error reading bdoc: " + var6);
      }

      return null;
   }

   public String getNewDataFileId() {
      int nDf = 0;
      String id = "D" + nDf;
      boolean bExists = false;

      do {
         bExists = false;

         for(int d = 0; d < this.countDataFiles(); ++d) {
            DataFile df = this.getDataFile(d);
            if(df.getId().equals(id)) {
               ++nDf;
               id = "D" + nDf;
               bExists = true;
            }
         }
      } while(bExists);

      return id;
   }

   public DataFile addDataFile(File inputFile, String mime, String contentType) throws DigiDocException {
      DigiDocException ex1 = this.validateFormatAndVersion();
      if(ex1 != null) {
         throw ex1;
      } else {
         boolean bExists = false;

         for(int df = 0; df < this.countDataFiles(); ++df) {
            DataFile df1 = this.getDataFile(df);
            if(df1.getFileName().equals(inputFile.getName())) {
               bExists = true;
            }
         }

         if(bExists) {
            m_logger.error("Duplicate DataFile name: " + inputFile.getName());
            throw new DigiDocException(28, "Duplicate DataFile filename: " + inputFile.getName(), (Throwable)null);
         } else {
            DataFile var8 = new DataFile(this.getNewDataFileId(), contentType, inputFile.getAbsolutePath(), mime, this);
            if(inputFile.canRead()) {
               var8.setSize(inputFile.length());
            }

            this.addDataFile(var8);
            if(this.m_format.equals("BDOC")) {
               var8.setId(inputFile.getName());
            }

            return var8;
         }
      }
   }

   public void writeToFile(File outputFile) throws DigiDocException {
      try {
         FileOutputStream ex = new FileOutputStream(outputFile);
         this.writeToStream(ex);
         ex.close();
      } catch (DigiDocException var3) {
         throw var3;
      } catch (Exception var4) {
         DigiDocException.handleException(var4, 11);
      }

   }

   public void writeToStream(OutputStream os) throws DigiDocException {
      DigiDocException ex1 = this.validateFormatAndVersion();
      if(ex1 != null) {
         throw ex1;
      } else {
         try {
            DigiDocXmlGenFactory ex = new DigiDocXmlGenFactory(this);
            if(this.m_format.equals("BDOC")) {
               ZipArchiveOutputStream i = new ZipArchiveOutputStream(os);
               i.setEncoding("UTF-8");
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("OS: " + (os != null?"OK":"NULL") + " zos: " + (i != null?"OK":"NULL"));
               }

               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Writing: mimetype");
               }

               ZipArchiveEntry sig = new ZipArchiveEntry("mimetype");
               if(this.m_comment == null) {
                  this.m_comment = DigiDocGenFactory.getUserInfo(this.m_format, this.m_version);
               }

               sig.setComment(this.m_comment);
               sig.setMethod(0);
               CRC32 crc = new CRC32();
               if(this.m_version.equals("1.0")) {
                  sig.setSize((long)"application/vnd.bdoc-1.0".getBytes().length);
                  crc.update("application/vnd.bdoc-1.0".getBytes());
               }

               if(this.m_version.equals("1.1")) {
                  sig.setSize((long)"application/vnd.bdoc-1.1".getBytes().length);
                  crc.update("application/vnd.bdoc-1.1".getBytes());
               }

               if(this.m_version.equals("2.1")) {
                  sig.setSize((long)"application/vnd.etsi.asic-e+zip".getBytes().length);
                  crc.update("application/vnd.etsi.asic-e+zip".getBytes());
               }

               sig.setCrc(crc.getValue());
               i.putArchiveEntry(sig);
               if(this.m_version.equals("1.0")) {
                  i.write("application/vnd.bdoc-1.0".getBytes());
               }

               if(this.m_version.equals("1.1")) {
                  i.write("application/vnd.bdoc-1.1".getBytes());
               }

               if(this.m_version.equals("2.1")) {
                  i.write("application/vnd.etsi.asic-e+zip".getBytes());
               }

               i.closeArchiveEntry();
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Writing: META-INF/manifest.xml");
               }

               new ZipArchiveEntry("META-INF");
               sig = new ZipArchiveEntry("META-INF/manifest.xml");
               sig.setComment(DigiDocGenFactory.getUserInfo(this.m_format, this.m_version));
               i.putArchiveEntry(sig);
               i.write(this.m_manifest.toXML());
               i.closeArchiveEntry();

               int i1;
               for(i1 = 0; i1 < this.countDataFiles(); ++i1) {
                  DataFile sig1 = this.getDataFile(i1);
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("Writing DF: " + sig1.getFileName() + " content: " + sig1.getContentType() + " df-cache: " + (sig1.getDfCacheFile() != null?sig1.getDfCacheFile().getAbsolutePath():"NONE"));
                  }

                  InputStream sFileName = null;
                  if(sig1.hasAccessToDataFile()) {
                     sFileName = sig1.getBodyAsStream();
                  } else {
                     sFileName = this.findDataFileAsStream(sig1.getFileName());
                  }

                  if(sFileName != null) {
                     File sSig = new File(sig1.getFileName());
                     String sdata = sSig.getName();
                     sig = new ZipArchiveEntry(sdata);
                     if(sig1.getComment() == null) {
                        sig1.setComment(DigiDocGenFactory.getUserInfo(this.m_format, this.m_version));
                     }

                     sig.setComment(sig1.getComment());
                     sig.setSize(sSig.length());
                     sig.setTime(sSig.lastModified());
                     i.putArchiveEntry(sig);
                     byte[] data = new byte[2048];
                     boolean nRead = false;
                     int nTotal = 0;
                     crc = new CRC32();

                     int var24;
                     while((var24 = sFileName.read(data)) > 0) {
                        i.write(data, 0, var24);
                        nTotal += var24;
                        crc.update(data, 0, var24);
                     }

                     sig.setSize((long)nTotal);
                     sig.setCrc(crc.getValue());
                     i.closeArchiveEntry();
                     sFileName.close();
                  }
               }

               for(i1 = 0; i1 < this.countSignatures(); ++i1) {
                  Signature var20 = this.getSignature(i1);
                  String var21 = var20.getPath();
                  if(var21 == null) {
                     if(this.m_version.equals("2.1")) {
                        var21 = "META-INF/signatures" + (i1 + 1) + ".xml";
                     } else {
                        var21 = "META-INF/signature" + (i1 + 1) + ".xml";
                     }
                  }

                  if(!var21.startsWith("META-INF")) {
                     var21 = "META-INF/" + var21;
                  }

                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("Writing SIG: " + var21 + " orig: " + (var20.getOrigContent() != null?"OK":"NULL"));
                  }

                  sig = new ZipArchiveEntry(var21);
                  if(var20.getComment() == null) {
                     var20.setComment(DigiDocGenFactory.getUserInfo(this.m_format, this.m_version));
                  }

                  sig.setComment(var20.getComment());
                  String var22 = var20.toString();
                  if(var22 == null || !var22.startsWith("<?xml")) {
                     (new StringBuilder()).append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n").append(var22).toString();
                  }

                  byte[] var23 = var20.getOrigContent();
                  if(var23 == null) {
                     var23 = ex.signatureToXML(var20);
                  }

                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("Writing SIG: " + var21 + " xml:\n---\n " + (var23 != null?new String(var23, "UTF-8"):"NULL") + "\n---\n ");
                  }

                  sig.setSize((long)var23.length);
                  crc = new CRC32();
                  crc.update(var23);
                  sig.setCrc(crc.getValue());
                  i.putArchiveEntry(sig);
                  i.write(var23);
                  i.closeArchiveEntry();
               }

               i.close();
            } else if(this.m_format.equals("DIGIDOC-XML")) {
               os.write(this.xmlHeader().getBytes());

               int var17;
               for(var17 = 0; var17 < this.countDataFiles(); ++var17) {
                  DataFile var18 = this.getDataFile(var17);
                  var18.writeToFile(os);
                  os.write("\n".getBytes());
               }

               for(var17 = 0; var17 < this.countSignatures(); ++var17) {
                  Signature var19 = this.getSignature(var17);
                  if(var19.getOrigContent() != null) {
                     os.write(var19.getOrigContent());
                  } else {
                     os.write(ex.signatureToXML(var19));
                  }

                  os.write("\n".getBytes());
               }

               os.write(this.xmlTrailer().getBytes());
            }
         } catch (DigiDocException var15) {
            throw var15;
         } catch (Exception var16) {
            DigiDocException.handleException(var16, 11);
         }

      }
   }

   public void addDataFile(DataFile df) throws DigiDocException {
      if(this.countSignatures() > 0) {
         throw new DigiDocException(14, "Cannot add DataFiles when signatures exist!", (Throwable)null);
      } else {
         boolean bExists = false;

         for(int sFile = 0; sFile < this.countDataFiles(); ++sFile) {
            DataFile fe = this.getDataFile(sFile);
            if(fe.getFileName().equals(df.getFileName())) {
               bExists = true;
            }
         }

         if(bExists) {
            m_logger.error("Duplicate DataFile name: " + df.getFileName());
            throw new DigiDocException(28, "Duplicate DataFile filename: " + df.getFileName(), (Throwable)null);
         } else {
            if(this.m_format.equals("BDOC") && this.findManifestEntryByPath(df.getFileName()) == null) {
               df.setContentType("BINARY");
               String var5 = df.getFileName();
               if(var5 != null && var5.indexOf(47) != -1 || var5.indexOf(92) != -1) {
                  File var6 = new File(var5);
                  var5 = var6.getName();
               }

               ManifestFileEntry var7 = new ManifestFileEntry(df.getMimeType(), var5);
               this.m_manifest.addFileEntry(var7);
            }

            if(this.m_dataFiles == null) {
               this.m_dataFiles = new ArrayList();
            }

            if(df.getId() == null) {
               df.setId(this.getNewDataFileId());
            }

            this.m_dataFiles.add(df);
         }
      }
   }

   public DataFile getDataFile(int idx) {
      return this.m_dataFiles != null && idx >= 0 && idx < this.m_dataFiles.size()?(DataFile)this.m_dataFiles.get(idx):null;
   }

   public DataFile getLastDataFile() {
      return this.m_dataFiles != null && this.m_dataFiles.size() > 0?(DataFile)this.m_dataFiles.get(this.m_dataFiles.size() - 1):null;
   }

   public void removeDataFile(int idx) throws DigiDocException {
      if(this.countSignatures() > 0) {
         throw new DigiDocException(14, "Cannot remove DataFiles when signatures exist!", (Throwable)null);
      } else {
         DataFile df = this.getDataFile(idx);
         if(df != null) {
            this.m_dataFiles.remove(idx);
            if(this.m_manifest != null) {
               this.m_manifest.removeFileEntryWithPath(df.getFileName());
            }

         } else {
            throw new DigiDocException(29, "Invalid DataFile index!", (Throwable)null);
         }
      }
   }

   public DataFile findDataFileById(String id) {
      for(int i = 0; this.m_dataFiles != null && i < this.m_dataFiles.size(); ++i) {
         DataFile df = (DataFile)this.m_dataFiles.get(i);
         if(df.getId() != null && id != null && df.getId().equals(id)) {
            return df;
         }
      }

      return null;
   }

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

   public String getNewSignatureId() {
      int nS = 0;
      String id = "S" + nS;
      boolean bExists = false;

      do {
         bExists = false;

         for(int i = 0; i < this.countSignatures(); ++i) {
            Signature sig = this.getSignature(i);
            if(sig.getId().equals(id)) {
               ++nS;
               id = "S" + nS;
               bExists = true;
            }
         }
      } while(bExists);

      return id;
   }

   public Signature findSignatureById(String sigId) {
      for(int i = 0; i < this.countSignatures(); ++i) {
         Signature sig = this.getSignature(i);
         if(sig.getId().equals(sigId)) {
            return sig;
         }
      }

      return null;
   }

   public Signature findSignatureByPath(String path) {
      for(int i = 0; i < this.countSignatures(); ++i) {
         Signature sig = this.getSignature(i);
         if(sig.getPath() != null && sig.getPath().equals(path)) {
            return sig;
         }
      }

      return null;
   }

   public Signature prepareSignature(X509Certificate cert, String[] claimedRoles, SignatureProductionPlace adr) throws DigiDocException {
      DigiDocException ex1 = this.validateFormatAndVersion();
      if(ex1 != null) {
         throw ex1;
      } else {
         return DigiDocGenFactory.prepareXadesBES(this, this.m_profile, cert, claimedRoles, adr, (String)null, (String)null, (String)null);
      }
   }

   public Signature prepareXadesTSignature(X509Certificate cert, String sigDatId, byte[] sigDatHash) throws DigiDocException {
      Signature sig = new Signature(this);
      sig.setId(this.getNewSignatureId());
      SignedInfo si = new SignedInfo(sig, "http://www.w3.org/2000/09/xmldsig#rsa-sha1", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
      Reference ref = new Reference(si, "#" + sigDatId, "http://www.w3.org/2000/09/xmldsig#sha1", sigDatHash, "http://www.w3.org/TR/2000/CR-xml-c14n-20001026");
      si.addReference(ref);
      sig.setSignedInfo(si);
      KeyInfo ki = new KeyInfo(cert);
      sig.setKeyInfo(ki);
      ki.setSignature(sig);
      CertValue cval = new CertValue((String)null, cert, 1, sig);
      sig.addCertValue(cval);
      CertID cid = new CertID(sig, cert, 1);
      sig.addCertID(cid);
      this.addSignature(sig);
      UnsignedProperties usp = new UnsignedProperties(sig, (CompleteCertificateRefs)null, (CompleteRevocationRefs)null);
      sig.setUnsignedProperties(usp);
      return sig;
   }

   public void addSignature(Signature sig) {
      if(this.m_signatures == null) {
         this.m_signatures = new ArrayList();
      }

      this.m_signatures.add(sig);
      if(this.m_format != null && this.m_format.equals("BDOC")) {
         Signature sig1 = null;
         if(sig.getPath() != null) {
            sig1 = this.findSignatureByPath(sig.getPath());
         }

         if(sig1 == null) {
            if(this.m_version.equals("2.1")) {
               sig.setPath("META-INF/signatures" + this.m_signatures.size() + ".xml");
            } else {
               sig.setPath("META-INF/signature" + this.m_signatures.size() + ".xml");
            }

            if(!this.m_version.equals("2.1")) {
               ManifestFileEntry fe = new ManifestFileEntry("signature/bdoc-" + this.m_version + "/" + sig.getProfile(), "META-INF/signature" + this.m_signatures.size() + ".xml");
               this.m_manifest.addFileEntry(fe);
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Register in manifest new signature: " + sig.getId());
               }
            }
         }
      }

   }

   public void readSignature(InputStream is) throws DigiDocException {
      DigiDocFactory ddfac = ConfigManager.instance().getDigiDocFactory();
      ddfac.readSignature(this, is);
   }

   public Signature getSignature(int idx) {
      return this.m_signatures != null && idx >= 0 && idx < this.m_signatures.size()?(Signature)this.m_signatures.get(idx):null;
   }

   public void removeSignature(int idx) throws DigiDocException {
      if(this.m_signatures != null && idx >= 0 && idx < this.m_signatures.size()) {
         this.m_signatures.remove(idx);
      } else {
         throw new DigiDocException(36, "Invalid signature index: " + idx, (Throwable)null);
      }
   }

   public Signature getLastSignature() {
      return this.m_signatures != null && this.m_signatures.size() > 0?(Signature)this.m_signatures.get(this.m_signatures.size() - 1):null;
   }

   public void removeLastSiganture() {
      if(this.m_signatures.size() > 0) {
         this.m_signatures.remove(this.m_signatures.size() - 1);
      }

   }

   public int removeSignaturesWithoutValue() {
      int nRemove = 0;
      boolean bOk = true;

      do {
         bOk = true;

         for(int i = 0; this.m_signatures != null && i < this.m_signatures.size() && bOk; ++i) {
            Signature sig = (Signature)this.m_signatures.get(i);
            if(sig.getSignatureValue() == null || sig.getSignatureValue().getValue() == null || sig.getSignatureValue().getValue().length == 0) {
               this.m_signatures.remove(sig);
               if(m_logger.isDebugEnabled()) {
                  m_logger.debug("Remove invalid sig: " + sig.getId());
               }

               bOk = false;
               ++nRemove;
            }
         }
      } while(!bOk);

      return nRemove;
   }

   public ArrayList validate(boolean bStrong) {
      ArrayList errs = new ArrayList();
      DigiDocException ex = this.validateFormat(this.m_format);
      if(ex != null) {
         errs.add(ex);
      }

      ex = this.validateVersion(this.m_version);
      if(ex != null) {
         errs.add(ex);
      }

      if(this.m_format != null && this.m_version != null && (this.m_format.equals("SK-XML") || this.m_format.equals("DIGIDOC-XML") && (this.m_version.equals("1.1") || this.m_version.equals("1.2")) || this.m_format.equals("BDOC") && (this.m_version.equals("1.0") || this.m_version.equals("1.1")))) {
         if(m_logger.isDebugEnabled()) {
            m_logger.debug("Old and unsupported format: " + this.m_format + " version: " + this.m_version);
         }

         ex = new DigiDocException(177, "Old and unsupported format: " + this.m_format + " version: " + this.m_version, (Throwable)null);
         errs.add(ex);
      }

      if(this.m_profile != null && (this.m_profile.equals("T") || this.m_profile.equals("TS") || this.m_profile.equals("TS-A"))) {
         if(m_logger.isDebugEnabled()) {
            m_logger.debug("T, TS and TSA profiles are currently not supported!");
         }

         ex = new DigiDocException(81, "T, TS and TSA profiles are currently not supported!", (Throwable)null);
         errs.add(ex);
      }

      try {
         if(this.getFormat() != null && this.getFormat().equals("BDOC")) {
            DigiDocVerifyFactory.verifyManifestEntries(this, errs);
         }

         int ex2;
         ArrayList j;
         for(ex2 = 0; ex2 < this.countDataFiles(); ++ex2) {
            DataFile sig1 = this.getDataFile(ex2);
            j = sig1.validate(bStrong);
            if(!j.isEmpty()) {
               errs.addAll(j);
            }
         }

         Signature var9;
         for(ex2 = 0; ex2 < this.countSignatures(); ++ex2) {
            var9 = this.getSignature(ex2);
            j = var9.validate();
            if(!j.isEmpty()) {
               errs.addAll(j);
            }
         }

         for(ex2 = 0; ex2 < this.countSignatures(); ++ex2) {
            var9 = this.getSignature(ex2);

            for(int var10 = 0; var10 < this.countSignatures(); ++var10) {
               Signature sig2 = this.getSignature(var10);
               if(this.getFormat() != null && this.getFormat().equals("BDOC") && sig2.getId() != null && var9.getId() != null && !sig2.getId().equals(var9.getId()) && sig2.getPath() != null && var9.getPath() != null && sig2.getPath().equals(var9.getPath())) {
                  if(m_logger.isDebugEnabled()) {
                     m_logger.debug("Signatures: " + var9.getId() + " and " + sig2.getId() + " are in same file: " + var9.getPath());
                  }

                  ex = new DigiDocException(75, "More than one signature in signatures.xml file is unsupported", (Throwable)null);
                  errs.add(ex);
               }
            }
         }
      } catch (DigiDocException var8) {
         errs.add(var8);
      }

      return errs;
   }

   public static boolean hasFatalErrs(ArrayList lerrs) {
      for(int i = 0; lerrs != null && i < lerrs.size(); ++i) {
         DigiDocException ex = (DigiDocException)lerrs.get(i);
         if(ex.getCode() == 75) {
            return true;
         }
      }

      return false;
   }

   public ArrayList verify(boolean checkDate, boolean demandConfirmation) {
      ArrayList errs = this.validate(true);
      if(hasFatalErrs(errs)) {
         return errs;
      } else {
         for(int i = 0; i < this.countSignatures(); ++i) {
            Signature sig = this.getSignature(i);
            ArrayList e = sig.verify(this, checkDate, demandConfirmation);
            if(!e.isEmpty()) {
               errs.addAll(e);
            }
         }

         if(this.countSignatures() == 0) {
            errs.add(new DigiDocException(98, "This document is not signed!", (Throwable)null));
         }

         return errs;
      }
   }

   private String xmlHeader() {
      StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
      if(this.m_format.equals("DIGIDOC-XML")) {
         sb.append("<SignedDoc format=\"");
         sb.append(this.m_format);
         sb.append("\" version=\"");
         sb.append(this.m_version);
         sb.append("\"");
         if(this.m_version.equals("1.3")) {
            sb.append(" xmlns=\"");
            sb.append(xmlns_digidoc13);
            sb.append("\"");
         }

         sb.append(">\n");
      }

      return sb.toString();
   }

   private String xmlTrailer() {
      return this.m_format.equals("DIGIDOC-XML")?"\n</SignedDoc>":"";
   }

   public String toXML() throws DigiDocException {
      StringBuffer sb = new StringBuffer(this.xmlHeader());

      int i;
      String str;
      for(i = 0; i < this.countDataFiles(); ++i) {
         DataFile sig = this.getDataFile(i);
         str = sig.toString();
         sb.append(str);
         sb.append("\n");
      }

      for(i = 0; i < this.countSignatures(); ++i) {
         Signature var5 = this.getSignature(i);
         str = var5.toString();
         sb.append(str);
         sb.append("\n");
      }

      sb.append(this.xmlTrailer());
      return sb.toString();
   }

   public String toString() {
      String str = null;

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

      return str;
   }

   public static byte[] digest(byte[] data) throws DigiDocException {
      return digestOfType(data, "SHA-1");
   }

   public static byte[] digestOfType(byte[] data, String digType) throws DigiDocException {
      byte[] dig = null;

      try {
         MessageDigest ex = MessageDigest.getInstance(digType, "BC");
         ex.update(data);
         dig = ex.digest();
      } catch (Exception var4) {
         DigiDocException.handleException(var4, 54);
      }

      return dig;
   }

   private static String getDnPart(String sDn, String sField, String sOid) {
      if(sDn != null && sDn.length() > 0) {
         String s = sField + "=";
         boolean bQ = false;
         int n1 = sDn.toUpperCase().indexOf(s.toUpperCase());
         if(n1 == -1 && sOid != null) {
            s = "OID." + sOid + "=";
            n1 = sDn.toUpperCase().indexOf(s.toUpperCase());
         }

         if(n1 >= 0) {
            n1 += s.length();
            if(sDn.charAt(n1) == 34) {
               bQ = true;
               ++n1;
            }

            int n2 = sDn.indexOf(bQ?"\", ":", ", n1);
            if(n2 == -1) {
               n2 = sDn.length();
            }

            if(n2 > n1 && n2 <= sDn.length()) {
               return sDn.substring(n1, n2);
            }
         }
      }

      return null;
   }

   public static String getSubjectFirstName(X509Certificate cert) {
      String dn = getDN(cert);
      String name = null;
      String cn = getDnPart(dn, "CN", (String)null);
      if(cn != null) {
         int idx1;
         for(idx1 = 0; idx1 < cn.length() && cn.charAt(idx1) != 44; ++idx1) {
            ;
         }

         if(idx1 < cn.length()) {
            ++idx1;
         }

         int idx2;
         for(idx2 = idx1; idx2 < cn.length() && cn.charAt(idx2) != 44 && cn.charAt(idx2) != 47; ++idx2) {
            ;
         }

         name = cn.substring(idx1, idx2);
      }

      return name;
   }

   public static String getSubjectLastName(X509Certificate cert) {
      String dn = getDN(cert);
      String name = null;
      String cn = getDnPart(dn, "CN", (String)null);
      if(cn != null) {
         int idx1;
         for(idx1 = 0; idx1 < cn.length() && !Character.isLetter(cn.charAt(idx1)); ++idx1) {
            ;
         }

         int idx2;
         for(idx2 = idx1; idx2 < cn.length() && cn.charAt(idx2) != 44 && dn.charAt(idx2) != 47; ++idx2) {
            ;
         }

         name = cn.substring(idx1, idx2);
      }

      return name;
   }

   public static String getSubjectPersonalCode(X509Certificate cert) {
      String dn = getDN(cert);
      String code = getDnPart(dn, "SERIALNUMBER", "2.5.4.5");
      if(code != null) {
         return code;
      } else {
         String cn = getDnPart(dn, "CN", (String)null);
         if(cn != null) {
            int idx1;
            for(idx1 = 0; idx1 < cn.length() && !Character.isDigit(cn.charAt(idx1)); ++idx1) {
               ;
            }

            int idx2;
            for(idx2 = idx1; idx2 < cn.length() && Character.isDigit(cn.charAt(idx2)); ++idx2) {
               ;
            }

            if(idx2 > idx1 + 7) {
               code = cn.substring(idx1, idx2);
            }
         }

         return code;
      }
   }

   private static String getDN(X509Certificate cert) {
      return cert.getSubjectX500Principal().getName("RFC1779");
   }

   public static String getCommonName(String dn) {
      return getDnPart(dn, "CN", (String)null);
   }

   public static X509Certificate readCertificate(byte[] data) throws DigiDocException {
      X509Certificate cert = null;

      try {
         ByteArrayInputStream ex = new ByteArrayInputStream(data);
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         cert = (X509Certificate)cf.generateCertificate(ex);
         ex.close();
         return cert;
      } catch (Exception var4) {
         m_logger.error("Error reading certificate: " + var4);
         return null;
      }
   }

   public static byte[] readFile(File inFile) throws IOException, FileNotFoundException {
      Object data = null;
      FileInputStream is = new FileInputStream(inFile);
      DataInputStream dis = new DataInputStream(is);
      byte[] data1 = new byte[dis.available()];
      dis.readFully(data1);
      dis.close();
      is.close();
      return data1;
   }

   public static X509Certificate readCertificate(File certFile) throws DigiDocException {
      X509Certificate cert = null;

      try {
         FileInputStream ex = new FileInputStream(certFile);
         CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
         cert = (X509Certificate)certificateFactory.generateCertificate(ex);
         ex.close();
      } catch (Exception var4) {
         DigiDocException.handleException(var4, 10);
      }

      return cert;
   }

   public static boolean writeCertificate(X509Certificate cert, File certFile) throws DigiDocException {
      try {
         FileOutputStream ex = new FileOutputStream(certFile);
         ex.write("-----BEGIN CERTIFICATE-----\n".getBytes());
         ex.write(Base64Util.encode(cert.getEncoded()).getBytes());
         ex.write("\n-----END CERTIFICATE-----".getBytes());
         ex.close();
      } catch (Exception var3) {
         DigiDocException.handleException(var3, 10);
      }

      return false;
   }

   public static X509Certificate readCertificate(String certLocation) throws DigiDocException {
      X509Certificate cert = null;

      try {
         Object ex = null;
         URL url = null;
         if(certLocation.startsWith("http")) {
            url = new URL(certLocation);
            ex = url.openStream();
         } else if(certLocation.startsWith("jar://")) {
            ClassLoader certificateFactory = ConfigManager.instance().getClass().getClassLoader();
            ex = certificateFactory.getResourceAsStream(certLocation.substring(6));
         } else {
            ex = new FileInputStream(certLocation);
         }

         CertificateFactory certificateFactory1 = CertificateFactory.getInstance("X.509");
         cert = (X509Certificate)certificateFactory1.generateCertificate((InputStream)ex);
         ((InputStream)ex).close();
      } catch (Exception var5) {
         DigiDocException.handleException(var5, 10);
      }

      return cert;
   }

   public static boolean compareDigests(byte[] dig1, byte[] dig2) {
      boolean ok = dig1 != null && dig2 != null && dig1.length == dig2.length;

      for(int i = 0; ok && i < dig1.length; ++i) {
         if(dig1[i] != dig2[i]) {
            ok = false;
         }
      }

      return ok;
   }

   public static byte[] hex2bin(String hexString) {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();

      try {
         for(int ex = 0; hexString != null && ex < hexString.length(); ex += 2) {
            String tmp = hexString.substring(ex, ex + 2);
            Integer x = new Integer(Integer.parseInt(tmp, 16));
            bos.write(x.byteValue());
         }
      } catch (Exception var5) {
         m_logger.error("Error converting hex string: " + var5);
      }

      return bos.toByteArray();
   }

   public static String bin2hex(byte[] arr) {
      StringBuffer sb = new StringBuffer();

      for(int i = 0; i < arr.length; ++i) {
         String str = Integer.toHexString(arr[i]);
         if(str.length() == 2) {
            sb.append(str);
         }

         if(str.length() < 2) {
            sb.append("0");
            sb.append(str);
         }

         if(str.length() > 2) {
            sb.append(str.substring(str.length() - 2));
         }
      }

      return sb.toString();
   }
}
Page generated: Oct 19, 2017 2:34:35 PM