public class HashingSigning {
- private static class Password implements PasswordFinder {
- char[] password;
-
- Password(char[] word) {
- this.password = word;
- }
-
- public char[] getPassword() {
- return password;
- }
- }
-
- /*
- * INFO: First implementation mode of SISO. ENVELOPING is used only in the present
- */
- public enum Signing_Mode {
- DETACHED, // When the data to be signed is outside of signature element
- ENVELOPING; // For signing object element that is part of the Signature
- // element
- };
-
- public static String FileName;
- private static String PKString = "PKCS12";
- private String SigTag = null;
- private static int DistributorNumber = 1;
- private static String Dist = "distributor";
- private static String Auth = "author";
- private LinkedList<String> FileList = new LinkedList<String>();
-
- public static void AuthorSignature(String appDirPath,
- String pkContentFilePath, String pkContentFilePasswd,
- String caCertPath, String rootCertPath)
- throws UnrecoverableKeyException, KeyStoreException,
- XMLSignatureException, NoSuchAlgorithmException,
- CertificateException, FileNotFoundException,
- InvalidAlgorithmParameterException, IOException,
- ParserConfigurationException, TransformerException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException, IllegalArgumentException, IllegalStateException,
- OutOfMemoryError {
- HashingSigning hashSign = new HashingSigning();
-
- hashSign.removeTmpFile(appDirPath);
-
- hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
- pkContentFilePasswd, caCertPath, rootCertPath, Auth, false);
- }
-
- public static void AuthorSignatureRDS(String appDirPath,
- String pkContentFilePath, String pkContentFilePasswd,
- String caCertPath, String rootCertPath)
- throws UnrecoverableKeyException, KeyStoreException,
- XMLSignatureException, NoSuchAlgorithmException,
- CertificateException, FileNotFoundException,
- InvalidAlgorithmParameterException, IOException,
- ParserConfigurationException, TransformerException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException, IllegalArgumentException, IllegalStateException,
- OutOfMemoryError {
- HashingSigning hashSign = new HashingSigning();
-
- hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
- pkContentFilePasswd, caCertPath, rootCertPath, Auth, true);
- }
-
- public static void DistributorSignature(String appDirPath,
- String pkContentFilePath, String pkContentFilePasswd,
- String caCertPath, String rootCertPath, int distNumber)
- throws UnrecoverableKeyException, KeyStoreException,
- NoSuchAlgorithmException, CertificateException,
- FileNotFoundException, InvalidAlgorithmParameterException,
- IOException, ParserConfigurationException, TransformerException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException {
- HashingSigning hashSign = new HashingSigning();
-
- hashSign.Set(distNumber);
- hashSign.removeTmpFile(appDirPath);
- // if (isRemoved == false) {
- // System.out.println("/manifest.tmp couldn't delete!");
- // }
- hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
- pkContentFilePasswd, caCertPath, rootCertPath, Dist, false);
- }
-
- public static void DistributorSignatureRDS(String appDirPath,
- String pkContentFilePath, String pkContentFilePasswd,
- String caCertPath, String rootCertPath, int distNumber)
- throws UnrecoverableKeyException, KeyStoreException,
- NoSuchAlgorithmException, CertificateException,
- FileNotFoundException, InvalidAlgorithmParameterException,
- IOException, ParserConfigurationException, TransformerException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException {
- HashingSigning hashSign = new HashingSigning();
-
- hashSign.Set(distNumber);
-
- hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
- pkContentFilePasswd, caCertPath, rootCertPath, Dist, true);
- }
-
- public static boolean CheckPkcs12Password(String pkcsContentFilePath,
- String pkcsPassValue) throws FileNotFoundException,
- NoSuchAlgorithmException, CertificateException, IOException,
- KeyStoreException {
-
- String alias = null;
- FileInputStream certInStream = null;
- try {
- // Load the KeyStore and get the signing key and certificate.
- KeyStore keyStore = KeyStore.getInstance(PKString);
-
- // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
- certInStream = new FileInputStream(pkcsContentFilePath);
- keyStore.load(certInStream, pkcsPassValue.toCharArray());
-
- // Find alias of privateKey from PKCS12 KeyCertificate Structure
- Enumeration<String> en = keyStore.aliases();
- for (; en.hasMoreElements();) {
- String aliasElement = (String) en.nextElement();
-
- // Check if the alias is for private key.
- if (keyStore.isKeyEntry(aliasElement) == true) {
- alias = aliasElement;
- break;
- }
- }
- if (alias.isEmpty()) {
- KeyStoreException e = new KeyStoreException(
- "Alias is not found.");
- throw e;
- }
- RSAPrivateCrtKey pKey = (RSAPrivateCrtKey) keyStore.getKey(alias,
- pkcsPassValue.toCharArray());
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- throw e;
- } catch (KeyStoreException e) {
- e.printStackTrace();
- throw e;
- } catch (IOException e) {
- System.out.println(pkcsContentFilePath
- + " is invalid certificate file or password incorrect.");
- return false;
- } catch (UnrecoverableKeyException e) {
- System.out.println(pkcsContentFilePath
- + " is invalid certificate file or password incorrect.");
- return false;
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- throw e;
- } catch (CertificateException e) {
- e.printStackTrace();
- throw e;
- } finally {
- try {
- if (certInStream != null)
- certInStream.close();
- } catch (IOException e) {
- System.out.println(pkcsContentFilePath + " cannot be closed.");
- throw e;
- }
- }
- return true;
- }
-
- private void Set(int distNumber) {
- DistributorNumber = distNumber;
- }
-
- private boolean removeTmpFile(String dirPath) {
- String tempManifestPath = dirPath.concat("/.manifest.tmp");
- File tmpManifestFile = new File(tempManifestPath);
-
- if (tmpManifestFile.exists() == true) {
- return tmpManifestFile.delete();
- }
-
- return true;
- }
-
- private void HashSignEntryFromIde(String appDirPath,
- String pkContentFilePath, String pkContentFilePasswd,
- String caCertPath, String rootCertPath, String signerType,
- boolean isRds) throws KeyStoreException, NoSuchAlgorithmException,
- CertificateException, FileNotFoundException, IOException,
- UnrecoverableKeyException, InvalidAlgorithmParameterException,
- ParserConfigurationException, TransformerException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException, IllegalArgumentException, IllegalStateException,
- OutOfMemoryError {
-
- HashingSigning hashSign = null;
-
- FileInputStream certInStream = null;
-
- try {
- FileName = "";
-
- /*
- * INFO: check arguments
- */
-
- if (appDirPath == null) {
- throw new IllegalStateException(
- "the appDir Path should not be null");
- }
-
- if (!(new File(appDirPath)).isDirectory()) {
- throw new IllegalArgumentException(
- "The directory path specified is incorrect or does not exist.");
- }
-
- if (pkContentFilePath == null) {
- throw new IllegalStateException(
- "The Author Certificate file (.p12) path should not be null.");
- }
-
- if (!(new File(pkContentFilePath)).isFile()) {
- throw new IllegalArgumentException(
- "The Author Certificate file (.p12) specified is incorrect or does not exist.");
- }
-
- // Load the KeyStore and get the signing key and certificate.
- // This will allow us to verify the input password of pk12 content
- // file is indeed correct before proceeding further
- KeyStore keyStore = KeyStore.getInstance(PKString);
- if (keyStore == null) {
- throw new KeyStoreException(
- "No provider supports a KeyStore implementation for the specified type.");
- }
-
- /*
- * INFO: check to have a key in .p12
- */
-
- // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
- certInStream = new FileInputStream(pkContentFilePath);
-
- keyStore.load(certInStream, pkContentFilePasswd.toCharArray());
-
- certInStream.close();
-
- String tempDirName = appDirPath.toString();
- tempDirName = tempDirName.replace('\\', '/');
- Signing_Mode sigMode = Signing_Mode.ENVELOPING;
-
- /*
- * INFO: unnecessary code. required refactoring
- */
- hashSign = new HashingSigning();
-
- /*
- * INFO: Unknown purpose.
- */
- Security.addProvider(new BouncyCastleProvider());
-
- hashSign.HashSignExecuteIde(appDirPath, tempDirName,
- pkContentFilePath, pkContentFilePasswd, caCertPath,
- rootCertPath, "prop", sigMode, signerType, isRds);
-
- } catch (OutOfMemoryError e) {
- throw new OutOfMemoryError("Failed to allocate memory");
- } catch (KeyStoreException e) {
- throw new KeyStoreException(
- "No provider supports a KeyStore implementation for the specified type.");
- } catch (CertificateException e) {
- throw new CertificateException(
- "Failed to load the certificates in the keystore.");
- } catch (NoSuchAlgorithmException e) {
- throw new NoSuchAlgorithmException(
- "Algorithm to check the integrity of the keystore cannot be found.");
- } catch (FileNotFoundException e) {
- throw new FileNotFoundException(
- "The file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.");
- } catch (IOException e) {
- throw new IOException(
- "Password required but not given, or the given password was incorrect.");
- } catch (UnrecoverableKeyException e) {
- throw new UnrecoverableKeyException(
- "Failed to retrieve RSA private key from pkcs12 content file.");
- } catch (InvalidAlgorithmParameterException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid Algorithm caused failure.");
- } catch (TransformerException e) {
- throw new TransformerException(
- "Error in transforming the XML source in output XML document.");
- } catch (ParserConfigurationException e) {
- throw new ParserConfigurationException(
- "Instantiating the document builder caused an error.");
- } catch (SAXException e) {
- throw new SAXException(
- "Failed to parse the XML Document since root of the XML doc may be invalid.");
- } catch (MarshalException e) {
- throw new MarshalException(
- "Failed to marshal the enveloping or detached signature.");
- } catch (javax.xml.crypto.dsig.XMLSignatureException e) {
- throw new javax.xml.crypto.dsig.XMLSignatureException(
- "Failed to sign the enveloping or detached signature.");
- } catch (IllegalArgumentException e) {
- // e.printStackTrace();
- throw e;
- } catch (IllegalStateException e) {
- // e.printStackTrace();
- // throw new IllegalStateException();
- // System.out.println("HashSignEntryFromIde(), e.getMessage() = " +
- // e.getMessage());
- throw e;
- } catch (Exception e) {
- System.out.println("Generic Exception caught");
- e.printStackTrace();
- } finally {
- try {
- if (certInStream != null) {
- certInStream.close();
- }
- } catch (IOException e) {
- throw new IOException(pkContentFilePath + " cannot be closed.");
- }
- }
- }
-
- private ObjectContainer createObjectElement(final boolean bAuthorSignature,
- final Document doc) throws XMLSecurityException,
- ParserConfigurationException {
-
- String signTypeTarget = bAuthorSignature ? SignatureConstants.authorTarget
- : SignatureConstants.distributorTarget;
- String signTypeRoleURI = bAuthorSignature ? SignatureConstants.authorRoleURI
- : SignatureConstants.distributorRoleURI;
-
- ObjectContainer container = new ObjectContainer(doc);
- container.setId("prop"); //$NON-NLS-1$
-
- Element properties = doc
- .createElement(SignatureConstants.SignatureProperties);
- properties.setAttributeNS(SignatureConstants.xmlnsURI,
- SignatureConstants.signaturePropertiesPrefix,
- SignatureConstants.signaturePropertiesURI);
-
- /* profile */
- Element profileElement = doc
- .createElement(SignatureConstants.profileProperty);
- profileElement.setAttribute(Constants._ATT_URI,
- SignatureConstants.profileURI);
- Element profileProperty = doc
- .createElement(SignatureConstants.SignatureProperty);
- profileProperty.setAttribute(SignatureConstants.id,
- SignatureConstants.profile);
- profileProperty.setAttribute(SignatureConstants.target, signTypeTarget);
- profileProperty.appendChild(profileElement);
- properties.appendChild(profileProperty);
-
- /* role */
- Element roleElement = doc
- .createElement(SignatureConstants.roleProperty);
- roleElement.setAttribute(Constants._ATT_URI, signTypeRoleURI);
- Element roleProperty = doc
- .createElement(SignatureConstants.SignatureProperty);
- roleProperty.setAttribute(SignatureConstants.id,
- SignatureConstants.role);
- roleProperty.setAttribute(SignatureConstants.target, signTypeTarget);
- roleProperty.appendChild(roleElement);
- properties.appendChild(roleProperty);
-
- /* identifier */
- Element identifierElement = doc
- .createElement(SignatureConstants.identifierProperty);
- Element identifierProperty = doc
- .createElement(SignatureConstants.SignatureProperty);
- identifierProperty.setAttribute(SignatureConstants.id,
- SignatureConstants.identifier);
- identifierProperty.setAttribute(SignatureConstants.target,
- signTypeTarget);
- identifierProperty.appendChild(identifierElement);
- properties.appendChild(identifierProperty);
-
- container.appendChild(properties);
-
- return container;
- }
-
- private void HashSignExecuteIde(String appDirPath, String dirName,
- String pkcsContentFilePath, String pkcsPassValue,
- String caCertPath, String rootCertPath, String objId,
- Signing_Mode sigMode, String signerType, boolean isRds)
-
- throws ParserConfigurationException, TransformerException, IOException,
- NoSuchAlgorithmException, InvalidAlgorithmParameterException,
- KeyStoreException, CertificateException, UnrecoverableKeyException,
- MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
- SAXException, IllegalArgumentException, IllegalStateException,
- OutOfMemoryError, XMLSignatureException {
-
- String alias = null;
- String signerFileName = null;
- File dirFolder = null;
-
- FileInputStream certInStream = null;
-
- try {
- /*
- * INFO: determine filename by sign type
- */
-
- if (signerType.matches(Auth)) {
- SigTag = "AuthorSignature";
- signerFileName = "author-signature.xml";
- }
-
- else if (signerType.matches(Dist)) {
- SigTag = "DistributorSignature";
- signerFileName = "signature"
- + String.valueOf(DistributorNumber) + ".xml";
- } else {
- throw new IllegalArgumentException(
- "The signer type cannot be recognized by the tool.");
- }
-
- /*
- * INFO: initialize XML module
- */
- org.apache.xml.security.Init.init();
-
- /*
- * INFO: make XML structures
- */
-
- // Creating signature_file.xml// String caPasswd = null;
- DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
- .newInstance();
- DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
- Document docName = docBuilder.newDocument();
-
- File baseDir = new File(dirName);
- String baseUriStr = baseDir.toURI().toString();
-
- XMLUtils.setDsPrefix(null);
-
- XMLSignature.setDefaultPrefix(SignatureConstants.dsigURI, "");
-
- XMLSignature xmlSig = new XMLSignature(docName, baseUriStr,
- XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
- CanonicalizationMethod.EXCLUSIVE);
-
- xmlSig.setId(SigTag);
-
- docName.appendChild(xmlSig.getElement());
-
- /*
- * INFO: add reference elements for calculate a digest value
- * Because depends with RDS, if failed, fully sign.
- */
-
- dirFolder = new File(appDirPath.toString());
-
- boolean isRdsAddDocSuccess = false;
-
- if (isRds == true) {
- isRdsAddDocSuccess = this.RdsAddDoc(appDirPath.toString(),
- dirName, xmlSig, signerType);
- if (isRdsAddDocSuccess != true) {
- this.DirectoryParserAndAddDoc(dirFolder, dirName, xmlSig,
- signerType);
- }
- } else {
- this.DirectoryParserAndAddDoc(dirFolder, dirName, xmlSig,
- signerType);
- }
-
- /*
- * INFO: add property elements
- */
-
- ObjectContainer objContainer = createObjectElement(
- signerType.matches(Auth), docName);
-
- xmlSig.appendObject(objContainer);
-
- Transforms transforms = new Transforms(docName);
- transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
- xmlSig.addDocument("#prop", transforms, DigestMethod.SHA256); //$NON-NLS-1$
-
- /*
- * INFO: get a key
- */
-
- // Load the KeyStore and get the signing key and certificate.
- KeyStore keyStore = KeyStore.getInstance(PKString);
-
- // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
- certInStream = new FileInputStream(pkcsContentFilePath);
- keyStore.load(certInStream, pkcsPassValue.toCharArray());
- certInStream.close();
-
- // Find alias of privateKey from PKCS12 KeyCertificate Structure
- Enumeration<String> en = keyStore.aliases();
-
- for (; en.hasMoreElements();) {
- String aliasElement = (String) en.nextElement();
-
- // Check if the alias is for private key.
- if (keyStore.isKeyEntry(aliasElement) == true) {
- alias = aliasElement;
- break;
- }
- }
-
- if (alias.isEmpty()) {
- Exception e = new KeyStoreException("Alias is not found.");
- throw e;
- }
- RSAPrivateCrtKey pKey = (RSAPrivateCrtKey) keyStore.getKey(alias,
- pkcsPassValue.toCharArray());
-
- KeyInfo keyInfo = null;
- X509Data x509Data = null;
-
- // Retrieve the Certificate from PKCS12 KeyCertificate
- Certificate[] certChainP12 = null;
-
- /*
- * INFO: get information in key
- */
- certChainP12 = keyStore.getCertificateChain(alias);
- if (certChainP12 == null) {
- throw new IllegalArgumentException(
- "P12 doesn't contain any certificate.");
- }
-
- int certCnt = certChainP12.length;
-
- if (certCnt == 0) {
- throw new IllegalArgumentException(
- "p12 file doesn't contain any certificate.");
- } else if (certCnt == 1) {
- // System.out.println("P12 contains 1 certificate.");
- X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
- xmlSig.addKeyInfo(x509CertClient);
- keyInfo = xmlSig.getKeyInfo();
-
- if (caCertPath != null) {
- X509Certificate x509CertCa = (X509Certificate) ImportCertificate(
- caCertPath, null);
-
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertCa);
- }
-
- if (rootCertPath != null) {
- X509Certificate x509CertRoot = (X509Certificate) ImportCertificate(
- rootCertPath, null);
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertRoot);
- }
-
- } else if (certCnt == 2) {
- // System.out.println("P12 contains 2 certificates.");
- X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
- xmlSig.addKeyInfo(x509CertClient);
-
- keyInfo = xmlSig.getKeyInfo();
-
- X509Certificate x509CertCa = (X509Certificate) certChainP12[1];
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertCa);
-
- if (rootCertPath != null) {
- X509Certificate x509CertRoot = (X509Certificate) ImportCertificate(
- rootCertPath, null);
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertRoot);
- }
- } else if (certCnt == 3) {
- // System.out.println("P12 contains 3 certificates.");
- X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
- xmlSig.addKeyInfo(x509CertClient);
-
- keyInfo = xmlSig.getKeyInfo();
-
- X509Certificate x509CertCa = (X509Certificate) certChainP12[1];
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertCa);
-
- X509Certificate x509CertRoot = (X509Certificate) certChainP12[2];
- x509Data = keyInfo.itemX509Data(0);
- x509Data.addCertificate(x509CertRoot);
-
- } else {
- throw new IllegalArgumentException(
- "p12 file contains too many certificate. Limit is three.");
- }
-
- /*
- * INFO: sign
- */
- if (pKey instanceof RSAPrivateCrtKey) {
- if (isRds == true && isRdsAddDocSuccess == true) {
- xmlSig.sign(pKey, dirName, true);
- } else
- xmlSig.sign(pKey, dirName, false);
- }
-
- /*
- * INFO: write XML
- */
- OutputStream outStream = new FileOutputStream(dirName + "/"
- + signerFileName);
- XMLUtils.outputDOM(docName, outStream);
- outStream.close();
-
- FileList.clear();
-
- } catch (OutOfMemoryError e) {
- throw new OutOfMemoryError("Failed to allocate memory");
- } catch (UnrecoverableKeyException e) {
- throw new UnrecoverableKeyException(
- "Failed to retrieve RSA private key from pkcs12 content file.");
- } catch (NoSuchAlgorithmException e) {
- throw new NoSuchAlgorithmException(
- "Incorrect algorithm caused failure.");
- } catch (InvalidAlgorithmParameterException e) {
- throw new InvalidAlgorithmParameterException(
- "Invalid Algorithm caused failure.");
- } catch (KeyStoreException e) {
- throw new KeyStoreException(
- "Failed to get key or certifcate from key structure which may not be in pkcs12 content file.");
- } catch (CertificateException e) {
- throw new CertificateException(
- "Failed to load the certificate because of invalid entry.");
- } catch (TransformerException e) {
- throw new TransformerException(
- "Error in transforming the XML source in output XML document.");
- } catch (ParserConfigurationException e) {
- throw new ParserConfigurationException(
- "Instantiating the document builder caused an error.");
- } catch (IOException e) {
- throw new IOException(
- "The file path given for reading or writing purpose may be invalid.");
- } catch (SAXException e) {
- throw new SAXException(
- "Failed to parse the XML Document since root of the XML doc may be invalid.");
- } catch (MarshalException e) {
- throw new MarshalException(
- "Failed to marshal the enveloping or detached signature.");
- } catch (javax.xml.crypto.dsig.XMLSignatureException e) {
- throw new javax.xml.crypto.dsig.XMLSignatureException(
- "Failed to sign the enveloping or detached signature.");
- } catch (IllegalArgumentException e) {
- throw e;
- } catch (IllegalStateException e) {
- throw e;
- } catch (NullPointerException e) {
- throw new NullPointerException();
- } catch (ClassCastException e) {
- throw new ClassCastException();
- } catch (XMLSignatureException e) {
- e.printStackTrace();
- } catch (Exception e) {
- System.out.println("Generic Exception caught.");
- e.printStackTrace();
- } finally {
- try {
- if (certInStream != null) {
- certInStream.close();
- }
- } catch (IOException e) {
- throw new IOException(pkcsContentFilePath
- + " cannot be closed.");
- }
- }
- }
-
- public static int GetCertLengthP12(String pkcsContentFilePath,
- String pkcsPassValue) throws KeyStoreException,
- NoSuchAlgorithmException, CertificateException, IOException {
- FileInputStream certInStream = null;
- String alias = null;
- int certCnt = 0;
-
- try {
- if (pkcsContentFilePath == null || pkcsPassValue == null) {
- throw new IllegalArgumentException(
- "The p12 filepath and passwd must not be null.");
- }
-
- // Load the KeyStore and get the signing key and certificate.
- KeyStore keyStore = KeyStore.getInstance(PKString);
-
- // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
- certInStream = new FileInputStream(pkcsContentFilePath);
- keyStore.load(certInStream, pkcsPassValue.toCharArray());
- certInStream.close();
-
- // Find alias of privateKey from PKCS12 KeyCertificate Structure
- Enumeration<String> en = keyStore.aliases();
-
- for (; en.hasMoreElements();) {
- String aliasElement = (String) en.nextElement();
-
- // Check if the alias is for private key.
- if (keyStore.isKeyEntry(aliasElement) == true) {
- alias = aliasElement;
- break;
- }
- }
-
- if (alias.isEmpty()) {
- Exception e = new KeyStoreException("Alias is not found.");
- try {
- throw e;
- } catch (Exception e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- // Retrieve the Certificate from PKCS12 KeyCertificate
- Certificate[] certChainP12 = null;
- certChainP12 = keyStore.getCertificateChain(alias);
- certCnt = certChainP12.length;
-
- } catch (KeyStoreException e) {
- e.printStackTrace();
- throw e;
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- throw e;
- } catch (CertificateException e) {
- throw new CertificateException(pkcsContentFilePath
- + " is invalid certificate file or password incorrect.");
- } catch (IOException e) {
- throw new IOException(pkcsContentFilePath
- + " is invalid certificate file or password incorrect.");
- } finally {
- try {
- if (certInStream != null)
- certInStream.close();
- } catch (IOException e) {
- throw new IOException(pkcsContentFilePath
- + " cannot be closed.");
- }
- }
-
- return certCnt;
- }
-
- private boolean RdsAddDoc(String dirPath, String dirName,
- XMLSignature xmlSig, String signerType)
- throws XMLSignatureException, IOException, IllegalStateException {
-
- String trimName = null;
- String tempString = null;
-
- /*
- * INFO: required files for RDS mode
- */
- File diffFp = new File(dirPath.toString().concat("/.delta.lst"));
- File rdsFp = new File(dirPath.toString().concat("/.manifest.tmp"));
-
- if (rdsFp.isFile() != true) {
- throw new IllegalStateException(
- ".manifest.tmp file doesn't exist. Incremental signing failed.");
- }
-
- if (rdsFp.length() == 0) {
- throw new IllegalStateException(
- ".manifest.tmp file exist, but size is zero. Incremental signing failed.");
- }
-
- if (diffFp.isFile() != true) {
- throw new IllegalStateException(
- ".delta.lst file doesn't exist. Incremental signing failed.");
- }
-
- if (diffFp.length() == 0) {
- throw new IllegalStateException(
- ".delta.lst file exist. but size is zero. Incremental signing failed.");
- }
-
- BufferedReader inRds = null;
- BufferedReader inDiff = null;
- FileWriter fd = null;
-
- /*
- * INFO: read the '.manifest.tmp' file
- * reference lists are file paths, and cache lists are read data.
- */
- LinkedList<String> referenceList = new LinkedList<String>();
- LinkedList<String> cacheList = new LinkedList<String>();
-
- try {
- inRds = new BufferedReader(new FileReader(rdsFp));
-
- while ((tempString = inRds.readLine()) != null) {
- if (tempString.contains(".manifest.tmp") == true)
- continue;
- if (tempString.contains(".delta.lst") == true)
- continue;
- if (tempString.contains("author-signature.xml"))
- continue;
- if (tempString.matches(".*.signature.*.xml"))
- continue;
-
- String[] stArray = tempString.split("__DEL__");
-
- if (stArray.length != 2) {
- throw new IllegalStateException(
- ".manifest.tmp file broken. Cache value must contain '__DEL__'. Error Line = "
- + tempString);
- }
- referenceList.add(stArray[0]);
- cacheList.add(tempString);
- }
- inRds.close();
-
- /*
- * INFO: check a permission denied
- */
- if (rdsFp.getParentFile().canWrite() != true) {
- throw new IllegalStateException(
- "Your account does not have sufficient permission to write. Target directory = "
- + rdsFp.getParentFile());
- }
-
- if (rdsFp.canWrite() != true) {
- rdsFp.setWritable(true);
- }
-
- /*
- * INFO: read the '.delta.lst' and update reference lists.
- * If state character is 'D', add '__DEL__DELETE' to the cache list and remove it in reference list.
- * If state character is 'C', add '__DEL_<PATH>' to the reference list.
- */
- fd = new FileWriter(rdsFp, true);
- inDiff = new BufferedReader(new FileReader(diffFp));
-
- while ((tempString = inDiff.readLine()) != null) {
- String[] stArray = tempString.split("__DEL__");
- if (stArray.length != 2) {
- throw new IllegalStateException(
- ".delta.lst file broken. Delemiter wrong. Error Line = "
- + tempString);
- }
-
- tempString = stArray[0];
- String tempKeyEncoded = org.apache.commons.httpclient.util.URIUtil
- .encodePathQuery(stArray[1]);
-
- int lastCharacter = tempString.length();
-
- if (tempString.charAt(lastCharacter - 1) == 'D') {
- tempString = tempString.substring(0, lastCharacter - 1);
-
- File deletedFile = new File(tempString);
- if (deletedFile.isFile() == true) {
- throw new IllegalStateException(
- "delta.lst's deleted file still exist in the disk. file = "
- + tempString);
- }
-
- if (referenceList.remove(tempKeyEncoded) != true) {
- throw new IllegalStateException(
- ".manifest.tmp didn't contain delta.lst's deleted list. Incremental signing cache value broken. line = "
- + tempKeyEncoded);
- }
-
- String deletedDelta = tempKeyEncoded + "__DEL__DELETED";
-
- if (cacheList.contains(deletedDelta) == false) {
- fd.write(deletedDelta + '\n');
- }
- } else if (tempString.charAt(lastCharacter - 1) == 'C') {
- tempString = tempString.substring(0, lastCharacter - 1);
- File createdFile = new File(tempString);
-
- if (createdFile.isFile() == false) {
- throw new IllegalStateException(
- "delta.lst's created file doesn't exist in the disk. file = "
- + tempKeyEncoded);
- }
-
- tempString = tempString.concat("__DEL__");
- tempString = tempString.concat(stArray[1]);
-
- if (referenceList.remove(tempKeyEncoded) == true) {
- } else {
- }
-
- String refUrl = org.apache.commons.httpclient.util.URIUtil
- .encodePathQuery(tempString);
-
- referenceList.add(refUrl);
- } else {
- throw new IllegalStateException(
- ".delta.lst file's delimeter is wrong. Last character must ended with 'C' or 'D'.");
- }
- }
-
- fd.flush();
- fd.close();
-
- inDiff.close();
-
- /*
- * INFO: If update a distributor, require to update an author-siganture.xml
- */
- if (signerType.matches(Dist)) {
- tempString = dirName
- + "/author-signature.xml__DEL__author-signature.xml";
- referenceList.add(tempString);
- }
-
- /*
- * INFO: add updated references to XML
- */
- int size = referenceList.size();
- for (int i = 0; i < size; i++) {
- trimName = referenceList.get(i);
- xmlSig.addDocument(trimName, (Transforms) null,
- DigestMethod.SHA256);
- }
- return true;
-
- } catch (URIException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (XMLSignatureException e) {
- e.printStackTrace();
- } catch (IllegalStateException e) {
- throw e;
- } finally {
- try {
- if (inDiff != null) {
- inDiff.close();
- }
- if (inRds != null) {
- inRds.close();
- }
- if (fd != null) {
- fd.close();
- }
- } catch (IOException e) {
- throw new IllegalStateException(
- ".manifest.tmp or .delta.lst cannot be closed.");
- }
- }
- return false;
- }
-
- private int CountFiles(File dirTargetPath, String signerType) {
- int totalCnt = 0;
- String trimName = null;
-
- for (File f : dirTargetPath.listFiles()) {
- if (f.isDirectory()) {
- totalCnt = totalCnt + CountFiles(f, signerType);
- } else {
- trimName = f.getPath();
- if (trimName.contains(".manifest.tmp") == true)
- continue;
- if (trimName.contains(".delta.lst") == true)
- continue;
- if (trimName.matches(".*.xml")) {
- if (trimName.matches(".*.author-signature.xml")
- && signerType.matches(Dist)) {
- // continue
- } else if (trimName.matches(".*.author-signature.xml")
- && signerType.matches(Auth)) {
- continue;
- } else if (trimName.matches(".*.signature.*.xml")) {
- continue;
- } else {
- // continue
- }
- }
- totalCnt = totalCnt + 1;
- // System.out.println("Cnt = " + totalCnt + ", trimName = "
- // + trimName);
- }
- }
- return totalCnt;
- }
-
- private void DirectoryParserAndAddDoc(File dirFolder, String dirName,
- XMLSignature xmlSig, String signerType) throws URIException,
- XMLSignatureException {
- String trimName = null;
- int strLen = 0;
-
- try {
- for (File f : dirFolder.listFiles()) {
- if (f.isDirectory()) {
- DirectoryParserAndAddDoc(f, dirName, xmlSig, signerType); // Recursive
- // Call
- } else {
- trimName = f.getPath();
- if (trimName.contains(".manifest.tmp") == true)
- continue;
- if (trimName.contains(".delta.lst") == true)
- continue;
-
- if (trimName.matches(".*.xml")) {
- if (trimName.matches(".*.author-signature.xml")
- && signerType.matches(Dist)) {
- // continue
- } else if (trimName.matches(".*.author-signature.xml")
- && signerType.matches(Auth)) {
- continue;
- } else if (trimName.matches(".*.signature.*.xml")) {
- continue;
- } else {
- // continue
- }
- }
-
- strLen = dirName.length();
- trimName = trimName.substring(strLen);
-
- trimName = trimName.replace('\\', '/');
- if (trimName.startsWith("/"))
- trimName = trimName.replaceFirst("/", "");
-
- String refUrl = org.apache.commons.httpclient.util.URIUtil
- .encodePathQuery(trimName);
-
- xmlSig.addDocument(refUrl, (Transforms) null,
- DigestMethod.SHA256);
- // System.out.println("refUrl = " + refUrl);
- }
- }
- } catch (URIException e) {
- e.printStackTrace();
- } catch (XMLSignatureException e) {
- e.printStackTrace();
- }
- }
-
- private X509Certificate ImportCertificate(String caCertPath, String password)
- throws FileNotFoundException, IOException {
-
- BufferedReader buffReader = null;
- X509Certificate caCert = null;
-
- PEMReader pemRead = null;
-
- try {
-
- PasswordFinder passFinder = null;
-
- buffReader = new BufferedReader(new FileReader(caCertPath));
- if (password != null) {
- passFinder = new Password(password.toCharArray());
- pemRead = new PEMReader(buffReader, passFinder);
- } else {
- pemRead = new PEMReader(buffReader);
- }
- Object objVal;
-
- while ((objVal = pemRead.readObject()) != null) {
- if (objVal instanceof X509Certificate) {
- caCert = (X509Certificate) objVal;
-
- } else {
- System.out.println("Failed to read CA certificate");
- }
- }
-
- pemRead.close();
- if (caCert == null)
- System.out.println("Failed to read CA certificate");
-
- if (buffReader != null)
- buffReader.close();
-
- return caCert;
-
- } catch (FileNotFoundException e) {
- throw new FileNotFoundException(
- "CA certificate file not found. Please pass valid path.");
- } catch (IOException e) {
- throw new IOException("CA certificate is not valid for reading.");
- } catch (Exception e) {
- System.out.println("Generic Exception caught.");
- e.printStackTrace();
- } finally {
- try {
- if (buffReader != null) {
- buffReader.close();
- }
- if (pemRead != null) {
- pemRead.close();
- }
- } catch (IOException e) {
- throw new IOException(caCertPath + " cannot be closed.");
- }
- }
- return null;
- }
+ private static class Password implements PasswordFinder {
+ char[] password;
+
+ Password(char[] word) {
+ this.password = word;
+ }
+
+ public char[] getPassword() {
+ return password;
+ }
+ }
+
+ /*
+ * INFO: First implementation mode of SISO. ENVELOPING is used only in the present
+ */
+ public enum Signing_Mode {
+ DETACHED, // When the data to be signed is outside of signature element
+ ENVELOPING; // For signing object element that is part of the Signature
+ // element
+ };
+
+ public static String FileName;
+ private static String PKString = "PKCS12";
+ private String SigTag = null;
+ private static int DistributorNumber = 1;
+ private static String Dist = "distributor";
+ private static String Auth = "author";
+ private LinkedList<String> FileList = new LinkedList<String>();
+
+ public static void AuthorSignature(String appDirPath,
+ String pkContentFilePath, String pkContentFilePasswd,
+ String caCertPath, String rootCertPath)
+ throws UnrecoverableKeyException, KeyStoreException,
+ XMLSignatureException, NoSuchAlgorithmException,
+ CertificateException, FileNotFoundException,
+ InvalidAlgorithmParameterException, IOException,
+ ParserConfigurationException, TransformerException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException, IllegalArgumentException, IllegalStateException,
+ OutOfMemoryError {
+ HashingSigning hashSign = new HashingSigning();
+
+ hashSign.removeTmpFile(appDirPath);
+
+ hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
+ pkContentFilePasswd, caCertPath, rootCertPath, Auth, false);
+ }
+
+ public static void AuthorSignatureRDS(String appDirPath,
+ String pkContentFilePath, String pkContentFilePasswd,
+ String caCertPath, String rootCertPath)
+ throws UnrecoverableKeyException, KeyStoreException,
+ XMLSignatureException, NoSuchAlgorithmException,
+ CertificateException, FileNotFoundException,
+ InvalidAlgorithmParameterException, IOException,
+ ParserConfigurationException, TransformerException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException, IllegalArgumentException, IllegalStateException,
+ OutOfMemoryError {
+ HashingSigning hashSign = new HashingSigning();
+
+ hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
+ pkContentFilePasswd, caCertPath, rootCertPath, Auth, true);
+ }
+
+ public static void DistributorSignature(String appDirPath,
+ String pkContentFilePath, String pkContentFilePasswd,
+ String caCertPath, String rootCertPath, int distNumber)
+ throws UnrecoverableKeyException, KeyStoreException,
+ NoSuchAlgorithmException, CertificateException,
+ FileNotFoundException, InvalidAlgorithmParameterException,
+ IOException, ParserConfigurationException, TransformerException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException {
+ HashingSigning hashSign = new HashingSigning();
+
+ hashSign.Set(distNumber);
+ hashSign.removeTmpFile(appDirPath);
+ // if (isRemoved == false) {
+ // System.out.println("/manifest.tmp couldn't delete!");
+ // }
+ hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
+ pkContentFilePasswd, caCertPath, rootCertPath, Dist, false);
+ }
+
+ public static void DistributorSignatureRDS(String appDirPath,
+ String pkContentFilePath, String pkContentFilePasswd,
+ String caCertPath, String rootCertPath, int distNumber)
+ throws UnrecoverableKeyException, KeyStoreException,
+ NoSuchAlgorithmException, CertificateException,
+ FileNotFoundException, InvalidAlgorithmParameterException,
+ IOException, ParserConfigurationException, TransformerException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException {
+ HashingSigning hashSign = new HashingSigning();
+
+ hashSign.Set(distNumber);
+
+ hashSign.HashSignEntryFromIde(appDirPath, pkContentFilePath,
+ pkContentFilePasswd, caCertPath, rootCertPath, Dist, true);
+ }
+
+ public static boolean CheckPkcs12Password(String pkcsContentFilePath,
+ String pkcsPassValue) throws FileNotFoundException,
+ NoSuchAlgorithmException, CertificateException, IOException,
+ KeyStoreException {
+
+ String alias = null;
+ FileInputStream certInStream = null;
+ try {
+ // Load the KeyStore and get the signing key and certificate.
+ KeyStore keyStore = KeyStore.getInstance(PKString);
+
+ // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
+ certInStream = new FileInputStream(pkcsContentFilePath);
+ keyStore.load(certInStream, pkcsPassValue.toCharArray());
+
+ // Find alias of privateKey from PKCS12 KeyCertificate Structure
+ Enumeration<String> en = keyStore.aliases();
+ for (; en.hasMoreElements();) {
+ String aliasElement = (String) en.nextElement();
+
+ // Check if the alias is for private key.
+ if (keyStore.isKeyEntry(aliasElement) == true) {
+ alias = aliasElement;
+ break;
+ }
+ }
+ if (alias.isEmpty()) {
+ KeyStoreException e = new KeyStoreException(
+ "Alias is not found.");
+ throw e;
+ }
+ RSAPrivateCrtKey pKey = (RSAPrivateCrtKey) keyStore.getKey(alias,
+ pkcsPassValue.toCharArray());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (IOException e) {
+ System.out.println(pkcsContentFilePath
+ + " is invalid certificate file or password incorrect.");
+ return false;
+ } catch (UnrecoverableKeyException e) {
+ System.out.println(pkcsContentFilePath
+ + " is invalid certificate file or password incorrect.");
+ return false;
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (CertificateException e) {
+ e.printStackTrace();
+ throw e;
+ } finally {
+ try {
+ if (certInStream != null)
+ certInStream.close();
+ } catch (IOException e) {
+ System.out.println(pkcsContentFilePath + " cannot be closed.");
+ throw e;
+ }
+ }
+ return true;
+ }
+
+ private void Set(int distNumber) {
+ DistributorNumber = distNumber;
+ }
+
+ private boolean removeTmpFile(String dirPath) {
+ String tempManifestPath = dirPath.concat("/.manifest.tmp");
+ File tmpManifestFile = new File(tempManifestPath);
+
+ if (tmpManifestFile.exists() == true) {
+ return tmpManifestFile.delete();
+ }
+
+ return true;
+ }
+
+ private void HashSignEntryFromIde(String appDirPath,
+ String pkContentFilePath, String pkContentFilePasswd,
+ String caCertPath, String rootCertPath, String signerType,
+ boolean isRds) throws KeyStoreException, NoSuchAlgorithmException,
+ CertificateException, FileNotFoundException, IOException,
+ UnrecoverableKeyException, InvalidAlgorithmParameterException,
+ ParserConfigurationException, TransformerException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException, IllegalArgumentException, IllegalStateException,
+ OutOfMemoryError {
+
+ HashingSigning hashSign = null;
+
+ FileInputStream certInStream = null;
+
+ try {
+ FileName = "";
+
+ /*
+ * INFO: check arguments
+ */
+
+ if (appDirPath == null) {
+ throw new IllegalStateException(
+ "the appDir Path should not be null");
+ }
+
+ if (!(new File(appDirPath)).isDirectory()) {
+ throw new IllegalArgumentException(
+ "The directory path specified is incorrect or does not exist.");
+ }
+
+ if (pkContentFilePath == null) {
+ throw new IllegalStateException(
+ "The Author Certificate file (.p12) path should not be null.");
+ }
+
+ if (!(new File(pkContentFilePath)).isFile()) {
+ throw new IllegalArgumentException(
+ "The Author Certificate file (.p12) specified is incorrect or does not exist.");
+ }
+
+ // Load the KeyStore and get the signing key and certificate.
+ // This will allow us to verify the input password of pk12 content
+ // file is indeed correct before proceeding further
+ KeyStore keyStore = KeyStore.getInstance(PKString);
+ if (keyStore == null) {
+ throw new KeyStoreException(
+ "No provider supports a KeyStore implementation for the specified type.");
+ }
+
+ /*
+ * INFO: check to have a key in .p12
+ */
+
+ // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
+ certInStream = new FileInputStream(pkContentFilePath);
+
+ keyStore.load(certInStream, pkContentFilePasswd.toCharArray());
+
+ certInStream.close();
+
+ String tempDirName = appDirPath.toString();
+ tempDirName = tempDirName.replace('\\', '/');
+ Signing_Mode sigMode = Signing_Mode.ENVELOPING;
+
+ /*
+ * INFO: unnecessary code. required refactoring
+ */
+ hashSign = new HashingSigning();
+
+ /*
+ * INFO: Unknown purpose.
+ */
+ Security.addProvider(new BouncyCastleProvider());
+
+ hashSign.HashSignExecuteIde(appDirPath, tempDirName,
+ pkContentFilePath, pkContentFilePasswd, caCertPath,
+ rootCertPath, "prop", sigMode, signerType, isRds);
+
+ } catch (OutOfMemoryError e) {
+ throw new OutOfMemoryError("Failed to allocate memory");
+ } catch (KeyStoreException e) {
+ throw new KeyStoreException(
+ "No provider supports a KeyStore implementation for the specified type.");
+ } catch (CertificateException e) {
+ throw new CertificateException(
+ "Failed to load the certificates in the keystore.");
+ } catch (NoSuchAlgorithmException e) {
+ throw new NoSuchAlgorithmException(
+ "Algorithm to check the integrity of the keystore cannot be found.");
+ } catch (FileNotFoundException e) {
+ throw new FileNotFoundException(
+ "The file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.");
+ } catch (IOException e) {
+ throw new IOException(
+ "Password required but not given, or the given password was incorrect.");
+ } catch (UnrecoverableKeyException e) {
+ throw new UnrecoverableKeyException(
+ "Failed to retrieve RSA private key from pkcs12 content file.");
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid Algorithm caused failure.");
+ } catch (TransformerException e) {
+ throw new TransformerException(
+ "Error in transforming the XML source in output XML document.");
+ } catch (ParserConfigurationException e) {
+ throw new ParserConfigurationException(
+ "Instantiating the document builder caused an error.");
+ } catch (SAXException e) {
+ throw new SAXException(
+ "Failed to parse the XML Document since root of the XML doc may be invalid.");
+ } catch (MarshalException e) {
+ throw new MarshalException(
+ "Failed to marshal the enveloping or detached signature.");
+ } catch (javax.xml.crypto.dsig.XMLSignatureException e) {
+ throw new javax.xml.crypto.dsig.XMLSignatureException(
+ "Failed to sign the enveloping or detached signature.");
+ } catch (IllegalArgumentException e) {
+ // e.printStackTrace();
+ throw e;
+ } catch (IllegalStateException e) {
+ // e.printStackTrace();
+ // throw new IllegalStateException();
+ // System.out.println("HashSignEntryFromIde(), e.getMessage() = " +
+ // e.getMessage());
+ throw e;
+ } catch (Exception e) {
+ System.out.println("Generic Exception caught");
+ e.printStackTrace();
+ } finally {
+ try {
+ if (certInStream != null) {
+ certInStream.close();
+ }
+ } catch (IOException e) {
+ throw new IOException(pkContentFilePath + " cannot be closed.");
+ }
+ }
+ }
+
+ private ObjectContainer createObjectElement(final boolean bAuthorSignature,
+ final Document doc) throws XMLSecurityException,
+ ParserConfigurationException {
+
+ String signTypeTarget = bAuthorSignature ? SignatureConstants.authorTarget
+ : SignatureConstants.distributorTarget;
+ String signTypeRoleURI = bAuthorSignature ? SignatureConstants.authorRoleURI
+ : SignatureConstants.distributorRoleURI;
+
+ ObjectContainer container = new ObjectContainer(doc);
+ container.setId("prop"); //$NON-NLS-1$
+
+ Element properties = doc
+ .createElement(SignatureConstants.SignatureProperties);
+ properties.setAttributeNS(SignatureConstants.xmlnsURI,
+ SignatureConstants.signaturePropertiesPrefix,
+ SignatureConstants.signaturePropertiesURI);
+
+ /* profile */
+ Element profileElement = doc
+ .createElement(SignatureConstants.profileProperty);
+ profileElement.setAttribute(Constants._ATT_URI,
+ SignatureConstants.profileURI);
+ Element profileProperty = doc
+ .createElement(SignatureConstants.SignatureProperty);
+ profileProperty.setAttribute(SignatureConstants.id,
+ SignatureConstants.profile);
+ profileProperty.setAttribute(SignatureConstants.target, signTypeTarget);
+ profileProperty.appendChild(profileElement);
+ properties.appendChild(profileProperty);
+
+ /* role */
+ Element roleElement = doc
+ .createElement(SignatureConstants.roleProperty);
+ roleElement.setAttribute(Constants._ATT_URI, signTypeRoleURI);
+ Element roleProperty = doc
+ .createElement(SignatureConstants.SignatureProperty);
+ roleProperty.setAttribute(SignatureConstants.id,
+ SignatureConstants.role);
+ roleProperty.setAttribute(SignatureConstants.target, signTypeTarget);
+ roleProperty.appendChild(roleElement);
+ properties.appendChild(roleProperty);
+
+ /* identifier */
+ Element identifierElement = doc
+ .createElement(SignatureConstants.identifierProperty);
+ Element identifierProperty = doc
+ .createElement(SignatureConstants.SignatureProperty);
+ identifierProperty.setAttribute(SignatureConstants.id,
+ SignatureConstants.identifier);
+ identifierProperty.setAttribute(SignatureConstants.target,
+ signTypeTarget);
+ identifierProperty.appendChild(identifierElement);
+ properties.appendChild(identifierProperty);
+
+ container.appendChild(properties);
+
+ return container;
+ }
+
+ private void HashSignExecuteIde(String appDirPath, String dirName,
+ String pkcsContentFilePath, String pkcsPassValue,
+ String caCertPath, String rootCertPath, String objId,
+ Signing_Mode sigMode, String signerType, boolean isRds)
+
+ throws ParserConfigurationException, TransformerException, IOException,
+ NoSuchAlgorithmException, InvalidAlgorithmParameterException,
+ KeyStoreException, CertificateException, UnrecoverableKeyException,
+ MarshalException, javax.xml.crypto.dsig.XMLSignatureException,
+ SAXException, IllegalArgumentException, IllegalStateException,
+ OutOfMemoryError, XMLSignatureException {
+
+ String alias = null;
+ String signerFileName = null;
+ File dirFolder = null;
+
+ FileInputStream certInStream = null;
+
+ try {
+ /*
+ * INFO: determine filename by sign type
+ */
+
+ if (signerType.matches(Auth)) {
+ SigTag = "AuthorSignature";
+ signerFileName = "author-signature.xml";
+ }
+
+ else if (signerType.matches(Dist)) {
+ SigTag = "DistributorSignature";
+ signerFileName = "signature"
+ + String.valueOf(DistributorNumber) + ".xml";
+ } else {
+ throw new IllegalArgumentException(
+ "The signer type cannot be recognized by the tool.");
+ }
+
+ /*
+ * INFO: initialize XML module
+ */
+ org.apache.xml.security.Init.init();
+
+ /*
+ * INFO: make XML structures
+ */
+
+ // Creating signature_file.xml// String caPasswd = null;
+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+ Document docName = docBuilder.newDocument();
+
+ File baseDir = new File(dirName);
+ String baseUriStr = baseDir.toURI().toString();
+
+ XMLUtils.setDsPrefix(null);
+
+ XMLSignature.setDefaultPrefix(SignatureConstants.dsigURI, "");
+
+ XMLSignature xmlSig = new XMLSignature(docName, baseUriStr,
+ XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256,
+ CanonicalizationMethod.EXCLUSIVE);
+
+ xmlSig.setId(SigTag);
+
+ docName.appendChild(xmlSig.getElement());
+
+ /*
+ * INFO: add reference elements for calculate a digest value
+ * Because depends with RDS, if failed, fully sign.
+ */
+
+ dirFolder = new File(appDirPath.toString());
+
+ boolean isRdsAddDocSuccess = false;
+
+ if (isRds == true) {
+ isRdsAddDocSuccess = this.RdsAddDoc(appDirPath.toString(),
+ dirName, xmlSig, signerType);
+ if (isRdsAddDocSuccess != true) {
+ this.DirectoryParserAndAddDoc(dirFolder, dirName, xmlSig,
+ signerType);
+ }
+ } else {
+ this.DirectoryParserAndAddDoc(dirFolder, dirName, xmlSig,
+ signerType);
+ }
+
+ /*
+ * INFO: add property elements
+ */
+
+ ObjectContainer objContainer = createObjectElement(
+ signerType.matches(Auth), docName);
+
+ xmlSig.appendObject(objContainer);
+
+ Transforms transforms = new Transforms(docName);
+ transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
+ xmlSig.addDocument("#prop", transforms, DigestMethod.SHA256); //$NON-NLS-1$
+
+ /*
+ * INFO: get a key
+ */
+
+ // Load the KeyStore and get the signing key and certificate.
+ KeyStore keyStore = KeyStore.getInstance(PKString);
+
+ // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
+ certInStream = new FileInputStream(pkcsContentFilePath);
+ keyStore.load(certInStream, pkcsPassValue.toCharArray());
+ certInStream.close();
+
+ // Find alias of privateKey from PKCS12 KeyCertificate Structure
+ Enumeration<String> en = keyStore.aliases();
+
+ for (; en.hasMoreElements();) {
+ String aliasElement = (String) en.nextElement();
+
+ // Check if the alias is for private key.
+ if (keyStore.isKeyEntry(aliasElement) == true) {
+ alias = aliasElement;
+ break;
+ }
+ }
+
+ if (alias.isEmpty()) {
+ Exception e = new KeyStoreException("Alias is not found.");
+ throw e;
+ }
+ RSAPrivateCrtKey pKey = (RSAPrivateCrtKey) keyStore.getKey(alias,
+ pkcsPassValue.toCharArray());
+
+ KeyInfo keyInfo = null;
+ X509Data x509Data = null;
+
+ // Retrieve the Certificate from PKCS12 KeyCertificate
+ Certificate[] certChainP12 = null;
+
+ /*
+ * INFO: get information in key
+ */
+ certChainP12 = keyStore.getCertificateChain(alias);
+ if (certChainP12 == null) {
+ throw new IllegalArgumentException(
+ "P12 doesn't contain any certificate.");
+ }
+
+ int certCnt = certChainP12.length;
+
+ if (certCnt == 0) {
+ throw new IllegalArgumentException(
+ "p12 file doesn't contain any certificate.");
+ } else if (certCnt == 1) {
+ // System.out.println("P12 contains 1 certificate.");
+ X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
+ xmlSig.addKeyInfo(x509CertClient);
+ keyInfo = xmlSig.getKeyInfo();
+
+ if (caCertPath != null) {
+ X509Certificate x509CertCa = (X509Certificate) ImportCertificate(
+ caCertPath, null);
+
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertCa);
+ }
+
+ if (rootCertPath != null) {
+ X509Certificate x509CertRoot = (X509Certificate) ImportCertificate(
+ rootCertPath, null);
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertRoot);
+ }
+
+ } else if (certCnt == 2) {
+ // System.out.println("P12 contains 2 certificates.");
+ X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
+ xmlSig.addKeyInfo(x509CertClient);
+
+ keyInfo = xmlSig.getKeyInfo();
+
+ X509Certificate x509CertCa = (X509Certificate) certChainP12[1];
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertCa);
+
+ if (rootCertPath != null) {
+ X509Certificate x509CertRoot = (X509Certificate) ImportCertificate(
+ rootCertPath, null);
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertRoot);
+ }
+ } else if (certCnt == 3) {
+ // System.out.println("P12 contains 3 certificates.");
+ X509Certificate x509CertClient = (X509Certificate) certChainP12[0];
+ xmlSig.addKeyInfo(x509CertClient);
+
+ keyInfo = xmlSig.getKeyInfo();
+
+ X509Certificate x509CertCa = (X509Certificate) certChainP12[1];
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertCa);
+
+ X509Certificate x509CertRoot = (X509Certificate) certChainP12[2];
+ x509Data = keyInfo.itemX509Data(0);
+ x509Data.addCertificate(x509CertRoot);
+
+ } else {
+ throw new IllegalArgumentException(
+ "p12 file contains too many certificate. Limit is three.");
+ }
+
+ /*
+ * INFO: sign
+ */
+ if (pKey instanceof RSAPrivateCrtKey) {
+ if (isRds == true && isRdsAddDocSuccess == true) {
+ xmlSig.sign(pKey, dirName, true);
+ } else
+ xmlSig.sign(pKey, dirName, false);
+ }
+
+ /*
+ * INFO: write XML
+ */
+ OutputStream outStream = new FileOutputStream(dirName + "/"
+ + signerFileName);
+ XMLUtils.outputDOM(docName, outStream);
+ outStream.close();
+
+ FileList.clear();
+
+ } catch (OutOfMemoryError e) {
+ throw new OutOfMemoryError("Failed to allocate memory");
+ } catch (UnrecoverableKeyException e) {
+ throw new UnrecoverableKeyException(
+ "Failed to retrieve RSA private key from pkcs12 content file.");
+ } catch (NoSuchAlgorithmException e) {
+ throw new NoSuchAlgorithmException(
+ "Incorrect algorithm caused failure.");
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidAlgorithmParameterException(
+ "Invalid Algorithm caused failure.");
+ } catch (KeyStoreException e) {
+ throw new KeyStoreException(
+ "Failed to get key or certifcate from key structure which may not be in pkcs12 content file.");
+ } catch (CertificateException e) {
+ throw new CertificateException(
+ "Failed to load the certificate because of invalid entry.");
+ } catch (TransformerException e) {
+ throw new TransformerException(
+ "Error in transforming the XML source in output XML document.");
+ } catch (ParserConfigurationException e) {
+ throw new ParserConfigurationException(
+ "Instantiating the document builder caused an error.");
+ } catch (IOException e) {
+ throw new IOException(
+ "The file path given for reading or writing purpose may be invalid.");
+ } catch (SAXException e) {
+ throw new SAXException(
+ "Failed to parse the XML Document since root of the XML doc may be invalid.");
+ } catch (MarshalException e) {
+ throw new MarshalException(
+ "Failed to marshal the enveloping or detached signature.");
+ } catch (javax.xml.crypto.dsig.XMLSignatureException e) {
+ throw new javax.xml.crypto.dsig.XMLSignatureException(
+ "Failed to sign the enveloping or detached signature.");
+ } catch (IllegalArgumentException e) {
+ throw e;
+ } catch (IllegalStateException e) {
+ throw e;
+ } catch (NullPointerException e) {
+ throw new NullPointerException();
+ } catch (ClassCastException e) {
+ throw new ClassCastException();
+ } catch (XMLSignatureException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ System.out.println("Generic Exception caught.");
+ e.printStackTrace();
+ } finally {
+ try {
+ if (certInStream != null) {
+ certInStream.close();
+ }
+ } catch (IOException e) {
+ throw new IOException(pkcsContentFilePath
+ + " cannot be closed.");
+ }
+ }
+ }
+
+ public static int GetCertLengthP12(String pkcsContentFilePath,
+ String pkcsPassValue) throws KeyStoreException,
+ NoSuchAlgorithmException, CertificateException, IOException {
+ FileInputStream certInStream = null;
+ String alias = null;
+ int certCnt = 0;
+
+ try {
+ if (pkcsContentFilePath == null || pkcsPassValue == null) {
+ throw new IllegalArgumentException(
+ "The p12 filepath and passwd must not be null.");
+ }
+
+ // Load the KeyStore and get the signing key and certificate.
+ KeyStore keyStore = KeyStore.getInstance(PKString);
+
+ // Retrieve the RSA PrivateKey from PKCS12 KeyCertificate Structure
+ certInStream = new FileInputStream(pkcsContentFilePath);
+ keyStore.load(certInStream, pkcsPassValue.toCharArray());
+ certInStream.close();
+
+ // Find alias of privateKey from PKCS12 KeyCertificate Structure
+ Enumeration<String> en = keyStore.aliases();
+
+ for (; en.hasMoreElements();) {
+ String aliasElement = (String) en.nextElement();
+
+ // Check if the alias is for private key.
+ if (keyStore.isKeyEntry(aliasElement) == true) {
+ alias = aliasElement;
+ break;
+ }
+ }
+
+ if (alias.isEmpty()) {
+ Exception e = new KeyStoreException("Alias is not found.");
+ try {
+ throw e;
+ } catch (Exception e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ }
+ // Retrieve the Certificate from PKCS12 KeyCertificate
+ Certificate[] certChainP12 = null;
+ certChainP12 = keyStore.getCertificateChain(alias);
+ certCnt = certChainP12.length;
+
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ throw e;
+ } catch (CertificateException e) {
+ throw new CertificateException(pkcsContentFilePath
+ + " is invalid certificate file or password incorrect.");
+ } catch (IOException e) {
+ throw new IOException(pkcsContentFilePath
+ + " is invalid certificate file or password incorrect.");
+ } finally {
+ try {
+ if (certInStream != null)
+ certInStream.close();
+ } catch (IOException e) {
+ throw new IOException(pkcsContentFilePath
+ + " cannot be closed.");
+ }
+ }
+
+ return certCnt;
+ }
+
+ private boolean RdsAddDoc(String dirPath, String dirName,
+ XMLSignature xmlSig, String signerType)
+ throws XMLSignatureException, IOException, IllegalStateException {
+
+ String trimName = null;
+ String tempString = null;
+
+ /*
+ * INFO: required files for RDS mode
+ */
+ File diffFp = new File(dirPath.toString().concat("/.delta.lst"));
+ File rdsFp = new File(dirPath.toString().concat("/.manifest.tmp"));
+
+ if (rdsFp.isFile() != true) {
+ throw new IllegalStateException(
+ ".manifest.tmp file doesn't exist. Incremental signing failed.");
+ }
+
+ if (rdsFp.length() == 0) {
+ throw new IllegalStateException(
+ ".manifest.tmp file exist, but size is zero. Incremental signing failed.");
+ }
+
+ if (diffFp.isFile() != true) {
+ throw new IllegalStateException(
+ ".delta.lst file doesn't exist. Incremental signing failed.");
+ }
+
+ if (diffFp.length() == 0) {
+ throw new IllegalStateException(
+ ".delta.lst file exist. but size is zero. Incremental signing failed.");
+ }
+
+ BufferedReader inRds = null;
+ BufferedReader inDiff = null;
+ FileWriter fd = null;
+
+ /*
+ * INFO: read the '.manifest.tmp' file
+ * reference lists are file paths, and cache lists are read data.
+ */
+ LinkedList<String> referenceList = new LinkedList<String>();
+ LinkedList<String> cacheList = new LinkedList<String>();
+
+ try {
+ inRds = new BufferedReader(new FileReader(rdsFp));
+
+ while ((tempString = inRds.readLine()) != null) {
+ if (tempString.contains(".manifest.tmp") == true)
+ continue;
+ if (tempString.contains(".delta.lst") == true)
+ continue;
+ if (tempString.contains("author-signature.xml"))
+ continue;
+ if (tempString.matches(".*.signature.*.xml"))
+ continue;
+
+ String[] stArray = tempString.split("__DEL__");
+
+ if (stArray.length != 2) {
+ throw new IllegalStateException(
+ ".manifest.tmp file broken. Cache value must contain '__DEL__'. Error Line = "
+ + tempString);
+ }
+ referenceList.add(stArray[0]);
+ cacheList.add(tempString);
+ }
+ inRds.close();
+
+ /*
+ * INFO: check a permission denied
+ */
+ if (rdsFp.getParentFile().canWrite() != true) {
+ throw new IllegalStateException(
+ "Your account does not have sufficient permission to write. Target directory = "
+ + rdsFp.getParentFile());
+ }
+
+ if (rdsFp.canWrite() != true) {
+ rdsFp.setWritable(true);
+ }
+
+ /*
+ * INFO: read the '.delta.lst' and update reference lists.
+ * If state character is 'D', add '__DEL__DELETE' to the cache list and remove it in reference list.
+ * If state character is 'C', add '__DEL_<PATH>' to the reference list.
+ */
+ fd = new FileWriter(rdsFp, true);
+ inDiff = new BufferedReader(new FileReader(diffFp));
+
+ while ((tempString = inDiff.readLine()) != null) {
+ String[] stArray = tempString.split("__DEL__");
+ if (stArray.length != 2) {
+ throw new IllegalStateException(
+ ".delta.lst file broken. Delemiter wrong. Error Line = "
+ + tempString);
+ }
+
+ tempString = stArray[0];
+ String tempKeyEncoded = org.apache.commons.httpclient.util.URIUtil
+ .encodePathQuery(stArray[1]);
+
+ int lastCharacter = tempString.length();
+
+ if (tempString.charAt(lastCharacter - 1) == 'D') {
+ tempString = tempString.substring(0, lastCharacter - 1);
+
+ File deletedFile = new File(tempString);
+ if (deletedFile.isFile() == true) {
+ throw new IllegalStateException(
+ "delta.lst's deleted file still exist in the disk. file = "
+ + tempString);
+ }
+
+ if (referenceList.remove(tempKeyEncoded) != true) {
+ throw new IllegalStateException(
+ ".manifest.tmp didn't contain delta.lst's deleted list. Incremental signing cache value broken. line = "
+ + tempKeyEncoded);
+ }
+
+ String deletedDelta = tempKeyEncoded + "__DEL__DELETED";
+
+ if (cacheList.contains(deletedDelta) == false) {
+ fd.write(deletedDelta + '\n');
+ }
+ } else if (tempString.charAt(lastCharacter - 1) == 'C') {
+ tempString = tempString.substring(0, lastCharacter - 1);
+ File createdFile = new File(tempString);
+
+ if (createdFile.isFile() == false) {
+ throw new IllegalStateException(
+ "delta.lst's created file doesn't exist in the disk. file = "
+ + tempKeyEncoded);
+ }
+
+ tempString = tempString.concat("__DEL__");
+ tempString = tempString.concat(stArray[1]);
+
+ if (referenceList.remove(tempKeyEncoded) == true) {
+ } else {
+ }
+
+ String refUrl = org.apache.commons.httpclient.util.URIUtil
+ .encodePathQuery(tempString);
+
+ referenceList.add(refUrl);
+ } else {
+ throw new IllegalStateException(
+ ".delta.lst file's delimeter is wrong. Last character must ended with 'C' or 'D'.");
+ }
+ }
+
+ fd.flush();
+ fd.close();
+
+ inDiff.close();
+
+ /*
+ * INFO: If update a distributor, require to update an author-siganture.xml
+ */
+ if (signerType.matches(Dist)) {
+ tempString = dirName
+ + "/author-signature.xml__DEL__author-signature.xml";
+ referenceList.add(tempString);
+ }
+
+ /*
+ * INFO: add updated references to XML
+ */
+ int size = referenceList.size();
+ for (int i = 0; i < size; i++) {
+ trimName = referenceList.get(i);
+ xmlSig.addDocument(trimName, (Transforms) null,
+ DigestMethod.SHA256);
+ }
+ return true;
+
+ } catch (URIException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (XMLSignatureException e) {
+ e.printStackTrace();
+ } catch (IllegalStateException e) {
+ throw e;
+ } finally {
+ try {
+ if (inDiff != null) {
+ inDiff.close();
+ }
+ if (inRds != null) {
+ inRds.close();
+ }
+ if (fd != null) {
+ fd.close();
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ ".manifest.tmp or .delta.lst cannot be closed.");
+ }
+ }
+ return false;
+ }
+
+ private int CountFiles(File dirTargetPath, String signerType) {
+ int totalCnt = 0;
+ String trimName = null;
+
+ for (File f : dirTargetPath.listFiles()) {
+ if (f.isDirectory()) {
+ totalCnt = totalCnt + CountFiles(f, signerType);
+ } else {
+ trimName = f.getPath();
+ if (trimName.contains(".manifest.tmp") == true)
+ continue;
+ if (trimName.contains(".delta.lst") == true)
+ continue;
+ if (trimName.matches(".*.xml")) {
+ if (trimName.matches(".*.author-signature.xml")
+ && signerType.matches(Dist)) {
+ // continue
+ } else if (trimName.matches(".*.author-signature.xml")
+ && signerType.matches(Auth)) {
+ continue;
+ } else if (trimName.matches(".*.signature.*.xml")) {
+ continue;
+ } else {
+ // continue
+ }
+ }
+ totalCnt = totalCnt + 1;
+ // System.out.println("Cnt = " + totalCnt + ", trimName = "
+ // + trimName);
+ }
+ }
+ return totalCnt;
+ }
+
+ private void DirectoryParserAndAddDoc(File dirFolder, String dirName,
+ XMLSignature xmlSig, String signerType) throws URIException,
+ XMLSignatureException {
+ String trimName = null;
+ int strLen = 0;
+
+ try {
+ for (File f : dirFolder.listFiles()) {
+ if (f.isDirectory()) {
+ DirectoryParserAndAddDoc(f, dirName, xmlSig, signerType); // Recursive
+ // Call
+ } else {
+ trimName = f.getPath();
+ if (trimName.contains(".manifest.tmp") == true)
+ continue;
+ if (trimName.contains(".delta.lst") == true)
+ continue;
+
+ if (trimName.matches(".*.xml")) {
+ if (trimName.matches(".*.author-signature.xml")
+ && signerType.matches(Dist)) {
+ // continue
+ } else if (trimName.matches(".*.author-signature.xml")
+ && signerType.matches(Auth)) {
+ continue;
+ } else if (trimName.matches(".*.signature.*.xml")) {
+ continue;
+ } else {
+ // continue
+ }
+ }
+
+ strLen = dirName.length();
+ trimName = trimName.substring(strLen);
+
+ trimName = trimName.replace('\\', '/');
+ if (trimName.startsWith("/"))
+ trimName = trimName.replaceFirst("/", "");
+
+ String refUrl = org.apache.commons.httpclient.util.URIUtil
+ .encodePathQuery(trimName);
+
+ xmlSig.addDocument(refUrl, (Transforms) null,
+ DigestMethod.SHA256);
+ // System.out.println("refUrl = " + refUrl);
+ }
+ }
+ } catch (URIException e) {
+ e.printStackTrace();
+ } catch (XMLSignatureException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private X509Certificate ImportCertificate(String caCertPath, String password)
+ throws FileNotFoundException, IOException {
+
+ BufferedReader buffReader = null;
+ X509Certificate caCert = null;
+
+ PEMReader pemRead = null;
+
+ try {
+
+ PasswordFinder passFinder = null;
+
+ buffReader = new BufferedReader(new FileReader(caCertPath));
+ if (password != null) {
+ passFinder = new Password(password.toCharArray());
+ pemRead = new PEMReader(buffReader, passFinder);
+ } else {
+ pemRead = new PEMReader(buffReader);
+ }
+ Object objVal;
+
+ while ((objVal = pemRead.readObject()) != null) {
+ if (objVal instanceof X509Certificate) {
+ caCert = (X509Certificate) objVal;
+
+ } else {
+ System.out.println("Failed to read CA certificate");
+ }
+ }
+
+ pemRead.close();
+ if (caCert == null)
+ System.out.println("Failed to read CA certificate");
+
+ if (buffReader != null)
+ buffReader.close();
+
+ return caCert;
+
+ } catch (FileNotFoundException e) {
+ throw new FileNotFoundException(
+ "CA certificate file not found. Please pass valid path.");
+ } catch (IOException e) {
+ throw new IOException("CA certificate is not valid for reading.");
+ } catch (Exception e) {
+ System.out.println("Generic Exception caught.");
+ e.printStackTrace();
+ } finally {
+ try {
+ if (buffReader != null) {
+ buffReader.close();
+ }
+ if (pemRead != null) {
+ pemRead.close();
+ }
+ } catch (IOException e) {
+ throw new IOException(caCertPath + " cannot be closed.");
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file