Project: DTE
/**
 * Copyright [2009] [NIC Labs] 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License. You may obtain a copy of the  License at 
 *  
 * http://www.apache.org/licenses/LICENSE-2.0 
 *  
 * Unless required by applicable law or  
 * agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 
 * specific language governing permissions and limitations under the License. 
 *  
 **/
 
package cl.nic.dte.util; 
 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.security.AlgorithmParameters; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.Key; 
import java.security.KeyFactory; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.cert.X509Certificate; 
import java.security.interfaces.DSAPrivateKey; 
import java.security.interfaces.DSAPublicKey; 
import java.security.interfaces.RSAPrivateKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.text.DateFormat; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Locale; 
import java.util.ResourceBundle; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
 
import javax.crypto.Cipher; 
import javax.crypto.EncryptedPrivateKeyInfo; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.xml.transform.Result; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.sax.SAXResult; 
import javax.xml.transform.stream.StreamSource; 
 
import org.apache.fop.apps.FOPException; 
import org.apache.fop.apps.FOUserAgent; 
import org.apache.fop.apps.Fop; 
import org.apache.fop.apps.FopFactory; 
import org.apache.fop.apps.MimeConstants; 
 
public class Utilities { 
 
 public static DateFormat fechaFormat = null
 
 public static DateFormat fechaEstadoDte = null
 
 public static DateFormat fechaMesFormat = null
 
 public static DateFormat fechaHoraFormat = null
 
 public static ResourceBundle verificationLabels = null
 
 public static ResourceBundle netLabels = null
 
 public static ResourceBundle exceptions = null
 
 static { 
  String prop1 = System.getProperty("sii.dte.ConfigurationFile"); 
  ResourceBundle conf1 = null
 
  if (prop1 != null
   conf1 = ResourceBundle.getBundle(prop1); 
  ResourceBundle conf2 = ResourceBundle 
    .getBundle("cl.nic.dte.resources.Configuration"); 
 
  Locale language; 
  if (conf1 != null && conf1.getString("LOCALE") != null
   language = new Locale(conf1.getString("LOCALE")); 
  else 
   language = new Locale(conf2.getString("LOCALE")); 
 
  verificationLabels = ResourceBundle.getBundle( 
    "cl.nic.dte.resources.VerifyResults", language); 
 
  netLabels = ResourceBundle.getBundle("cl.nic.dte.resources.Net"
    language); 
 
  exceptions = ResourceBundle.getBundle( 
    "cl.nic.dte.resources.Exceptions", language); 
 
  if (conf1 != null && conf1.getString("FECHA_TYPE_FORMAT") != null
   fechaFormat = new SimpleDateFormat(conf1 
     .getString("FECHA_TYPE_FORMAT")); 
  else 
   fechaFormat = new SimpleDateFormat(conf2 
     .getString("FECHA_TYPE_FORMAT")); 
 
  if (conf1 != null && conf1.getString("FECHA_MES_TYPE_FORMAT") != null
   fechaMesFormat = new SimpleDateFormat(conf1 
     .getString("FECHA_MES_TYPE_FORMAT")); 
  else 
   fechaMesFormat = new SimpleDateFormat(conf2 
     .getString("FECHA_MES_TYPE_FORMAT")); 
 
  if (conf1 != null && conf1.getString("FECHA_HORA_TYPE_FORMAT") != null
   fechaHoraFormat = new SimpleDateFormat(conf1 
     .getString("FECHA_HORA_TYPE_FORMAT")); 
  else 
   fechaHoraFormat = new SimpleDateFormat(conf2 
     .getString("FECHA_HORA_TYPE_FORMAT")); 
 
  if (conf1 != null && conf1.getString("FECHA_ESTADO_DTE") != null
   fechaEstadoDte = new SimpleDateFormat(conf1 
     .getString("FECHA_ESTADO_DTE")); 
  else 
   fechaEstadoDte = new SimpleDateFormat(conf2 
     .getString("FECHA_ESTADO_DTE")); 
 
 
 public static PrivateKey readPrivateKeyFromFile(String fileName, 
   String algo, char[] password) throws IOException, 
   NoSuchAlgorithmException, NoSuchPaddingException, 
   InvalidKeySpecException, InvalidKeyException, 
   InvalidAlgorithmParameterException { 
 
  return Utilities.readPrivateKey( 
    new FileInputStream(new File(fileName)), algo, password); 
 
 
 
 public static PrivateKey readPrivateKey(InputStream in, String algo, 
   char[] password) throws IOException, NoSuchAlgorithmException, 
   NoSuchPaddingException, InvalidKeySpecException, 
   InvalidKeyException, InvalidAlgorithmParameterException { 
 
  byte[] datos = new byte[in.available()]; 
  while (in.available() > 0
   in.read(datos); 
  return Utilities.readPrivateKey(datos, algo, password); 
 
 
 public static PrivateKey readPrivateKey(byte[] datos, String algo, 
   char[] password) throws IOException, NoSuchAlgorithmException, 
   NoSuchPaddingException, InvalidKeySpecException, 
   InvalidKeyException, InvalidAlgorithmParameterException { 
 
  PKCS8EncodedKeySpec pkcs8KeySpec = null
 
  if (password != null) { 
   EncryptedPrivateKeyInfo ekey = new EncryptedPrivateKeyInfo(datos); 
   Cipher cip = Cipher.getInstance(ekey.getAlgName()); 
   PBEKeySpec pspec = new PBEKeySpec(password); 
   SecretKeyFactory skfac = SecretKeyFactory.getInstance(ekey 
     .getAlgName()); 
 
   Key pbeKey = skfac.generateSecret(pspec); 
 
   AlgorithmParameters algParams = ekey.getAlgParameters(); 
   cip.init(Cipher.DECRYPT_MODE, pbeKey, algParams); 
 
   pkcs8KeySpec = ekey.getKeySpec(cip); 
  else { 
   pkcs8KeySpec = new PKCS8EncodedKeySpec(datos); 
  
 
  KeyFactory rsaKeyFac = KeyFactory.getInstance(algo); 
  return (PrivateKey) rsaKeyFac.generatePrivate(pkcs8KeySpec); 
 
 
 public static boolean correspond(PublicKey pubKey, PrivateKey prvKey) 
   throws NoSuchAlgorithmException { 
 
  ResourceBundle labels = ResourceBundle 
    .getBundle("cl.nic.dte.resources.Exceptions"); 
 
  if (!pubKey.getAlgorithm().equals(prvKey.getAlgorithm())) 
   return false
 
  if (pubKey.getAlgorithm().equals("RSA")) { 
   if (!((RSAPrivateKey) prvKey).getModulus().equals( 
     ((RSAPublicKey) pubKey).getModulus())) 
    return false
   return true
 
  else if (pubKey.getAlgorithm().equals("DSA")) { 
   if (!(((DSAPrivateKey) prvKey).getParams().getG() 
     .equals(((DSAPublicKey) pubKey).getParams().getG()))) 
    return false
   if (!(((DSAPrivateKey) prvKey).getParams().getP() 
     .equals(((DSAPublicKey) pubKey).getParams().getP()))) 
    return false
   if (!(((DSAPrivateKey) prvKey).getParams().getQ() 
     .equals(((DSAPublicKey) pubKey).getParams().getQ()))) 
    return false
   return true
  else 
   throw new NoSuchAlgorithmException(labels 
     .getString("ALG_NOT_SUPPORTED")); 
 
 
 public static Date getDate(String date) throws ParseException { 
 
  return fechaFormat.parse(date); 
 
 
 
 public static void generatePDF(InputStream xmlFile, InputStream xslFile, 
   OutputStream pdfFile) throws FOPException, FileNotFoundException, 
   TransformerException { 
  FopFactory fopFactory = FopFactory.newInstance(); 
 
  FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
  // configure foUserAgent as desired 
 
  // Construct fop with desired output format 
  Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, 
    pdfFile); 
 
  // Setup XSLT 
  TransformerFactory factory = TransformerFactory.newInstance(); 
  Transformer transformer = factory.newTransformer(new StreamSource( 
    xslFile)); 
 
  // Set the value of a <param> in the stylesheet 
  transformer.setParameter("versionParam""2.0"); 
 
  // Setup input for XSLT transformation 
  Source src = new StreamSource(xmlFile); 
  // Resulting SAX events (the generated FO) must be piped through to FOP 
  Result res = new SAXResult(fop.getDefaultHandler()); 
 
  // res = new StreamResult(new File("data/generated/sample-fo.xml")); 
 
  // Start XSLT transformation and FOP processing 
  transformer.transform(src, res); 
 
 
 public static String getRutFormatted(String rut) { 
  rut = rut.substring(0, rut.length() - 8) + "." 
    + rut.substring(rut.length() - 8, rut.length() - 5) + "." 
    + rut.substring(rut.length() - 5, rut.length()); 
  return rut; 
 
 
 /**
  * Obtiene el RUT desde un certificado digital. Busca en la extension 
  * 2.5.29.17 
  *  
  * @param x509 
  * @return 
  */
 
 public static String getRutFromCertificate(X509Certificate x509) { 
  String rut = null
  Pattern p = Pattern.compile("[\\d]{6,8}-[\\dkK]"); 
  
  Matcher m = p.matcher(new String(x509.getExtensionValue("2.5.29.17"))); 
  if (m.find()) 
   rut = m.group(); 
   
  return rut; 
 
 
  
}