OCA reporting engine fork for dev and update.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

333 lines
13 KiB

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.ProviderException;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.NoSuchElementException;
import java.util.ResourceBundle;
import sun.security.pkcs11.SunPKCS11;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
/*
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
*/
/**
*
* @author Jan Peter Stotz
*
*/
public class JPdfSign {
private static PrivateKey privateKey;
private static Certificate[] certificateChain;
private static ResourceBundle bundle = ResourceBundle.getBundle("strings");
private static String PRODUCTNAME = bundle.getString("productname");
private static String VERSION = bundle.getString("version");
private static String JAR_FILENAME = bundle.getString("jar-filename");
public static void main(String[] args) {
// for (int i = 0; i < args.length; i++) {
// System.out.println("arg[" + i + "] :" + args[i]);
// }
if (args.length < 2)
showUsage();
try {
String pkcs12FileName = args[0].trim();
String pdfInputFileName = args[1];
String pdfOutputFileName = args[2];
boolean usePKCS12 = !(pkcs12FileName.equals("-PKCS11"));
String passwdfile = "";
if (args.length == 4) {
passwdfile = args[3];
}
// System.out.println("");
// System.out.println("pdfInputFileName : " + pdfInputFileName);
// System.out.println("pdfOutputFileName: " + pdfOutputFileName);
if (usePKCS12)
readPrivateKeyFromPKCS12(pkcs12FileName, passwdfile);
else
readPrivateKeyFromPKCS11();
PdfReader reader = null;
try {
reader = new PdfReader(pdfInputFileName);
} catch (IOException e) {
System.err
.println("An unknown error accoured while opening the input PDF file: \""
+ pdfInputFileName + "\"");
e.printStackTrace();
System.exit(-1);
}
FileOutputStream fout = null;
try {
fout = new FileOutputStream(pdfOutputFileName);
} catch (FileNotFoundException e) {
System.err
.println("An unknown error accoured while opening the output PDF file: \""
+ pdfOutputFileName + "\"");
e.printStackTrace();
System.exit(-1);
}
PdfStamper stp = null;
try {
stp = PdfStamper.createSignature(reader, fout, '\0', null, true);
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED);
// sap.setCrypto(privateKey, certificateChain, null, null);
// sap.setReason("I'm the author");
// sap.setLocation("Lisbon");
// sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1,
// null);
sap.setCertified(true);
stp.close();
} catch (Exception e) {
System.err
.println("An unknown error accoured while signing the PDF file:");
e.printStackTrace();
System.exit(-1);
}
} catch (KeyStoreException kse) {
System.err
.println("An unknown error accoured while initializing the KeyStore instance:");
kse.printStackTrace();
System.exit(-1);
}
}
private static void readPrivateKeyFromPKCS11() throws KeyStoreException {
// Initialize PKCS#11 provider from config file
String configFileName = getConfigFilePath("pkcs11.cfg");
Provider p = null;
try {
p = new SunPKCS11(configFileName);
Security.addProvider(p);
} catch (ProviderException e) {
System.err
.println("Unable to load PKCS#11 provider with config file: "
+ configFileName);
e.printStackTrace();
System.exit(-1);
}
String pkcs11PIN = "000000";
System.out.print("Please enter the smartcard pin: ");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
pkcs11PIN = in.readLine();
// System.out.println(pkcs11PIN);
// System.out.println(pkcs11PIN.length());
} catch (Exception e) {
System.err
.println("An unknown error accoured while reading the PIN:");
e.printStackTrace();
System.exit(-1);
}
KeyStore ks = null;
try {
ks = KeyStore.getInstance("pkcs11", p);
ks.load(null, pkcs11PIN.toCharArray());
} catch (NoSuchAlgorithmException e) {
System.err
.println("An unknown error accoured while reading the PKCS#11 smartcard:");
e.printStackTrace();
System.exit(-1);
} catch (CertificateException e) {
System.err
.println("An unknown error accoured while reading the PKCS#11 smartcard:");
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
System.err
.println("An unknown error accoured while reading the PKCS#11 smartcard:");
e.printStackTrace();
System.exit(-1);
}
String alias = "";
try {
alias = (String) ks.aliases().nextElement();
privateKey = (PrivateKey) ks.getKey(alias, pkcs11PIN.toCharArray());
} catch (NoSuchElementException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
System.err
.println("The selected PKCS#12 file does not contain any private keys.");
e.printStackTrace();
System.exit(-1);
} catch (NoSuchAlgorithmException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
e.printStackTrace();
System.exit(-1);
} catch (UnrecoverableKeyException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
e.printStackTrace();
System.exit(-1);
}
certificateChain = ks.getCertificateChain(alias);
}
protected static void readPrivateKeyFromPKCS12(String pkcs12FileName, String pwdFile)
throws KeyStoreException {
String pkcs12Password = "";
KeyStore ks = null;
if (!pwdFile.equals("")) {
try {
FileInputStream pwdfis = new FileInputStream(pwdFile);
byte[] pwd = new byte[1024];
try {
do {
int r = pwdfis.read(pwd);
if (r < 0) {
break;
}
pkcs12Password += new String(pwd);
pkcs12Password = pkcs12Password.trim();
} while (pwdfis.available() > 0);
pwdfis.close();
} catch (IOException ex) {
System.err
.println("Can't read password file: " + pwdFile);
}
} catch (FileNotFoundException fnfex) {
System.err
.println("Password file not found: " + pwdFile);
}
} else {
System.out.print("Please enter the password for \"" + pkcs12FileName
+ "\": ");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
pkcs12Password = in.readLine();
} catch (Exception e) {
System.err
.println("An unknown error accoured while reading the password:");
e.printStackTrace();
System.exit(-1);
}
}
try {
ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream(pkcs12FileName), pkcs12Password
.toCharArray());
} catch (NoSuchAlgorithmException e) {
System.err
.println("An unknown error accoured while reading the PKCS#12 file:");
e.printStackTrace();
System.exit(-1);
} catch (CertificateException e) {
System.err
.println("An unknown error accoured while reading the PKCS#12 file:");
e.printStackTrace();
System.exit(-1);
} catch (FileNotFoundException e) {
System.err.println("Unable to open the PKCS#12 keystore file \""
+ pkcs12FileName + "\":");
System.err
.println("The file does not exists or missing read permission.");
System.exit(-1);
} catch (IOException e) {
System.err
.println("An unknown error accoured while reading the PKCS#12 file:");
e.printStackTrace();
System.exit(-1);
}
String alias = "";
try {
alias = (String) ks.aliases().nextElement();
privateKey = (PrivateKey) ks.getKey(alias, pkcs12Password
.toCharArray());
} catch (NoSuchElementException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
System.err
.println("The selected PKCS#12 file does not contain any private keys.");
e.printStackTrace();
System.exit(-1);
} catch (NoSuchAlgorithmException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
e.printStackTrace();
System.exit(-1);
} catch (UnrecoverableKeyException e) {
System.err
.println("An unknown error accoured while retrieving the private key:");
e.printStackTrace();
System.exit(-1);
}
certificateChain = ks.getCertificateChain(alias);
}
protected static String getConfigFilePath(String configFilename) {
CodeSource source = JPdfSign.class.getProtectionDomain()
.getCodeSource();
URL url = source.getLocation();
String jarPath = URLDecoder.decode(url.getFile());
File f = new File(jarPath);
try {
jarPath = f.getCanonicalPath();
} catch (IOException e) {
}
if (!f.isDirectory()) {
f = new File(jarPath);
jarPath = f.getParent();
}
System.out.println(jarPath);
if (jarPath.length() > 0) {
return jarPath + File.separator + configFilename;
} else
return configFilename;
}
public static void showUsage() {
System.out.println("jPdfSign v" + VERSION
+ " by Jan Peter Stotz - jpstotz@gmx.de\n");
System.out.println(PRODUCTNAME + " usage:");
System.out
.println("\nFor using a PKCS#12 (.p12) file as signature certificate and private key source:");
System.out.print("\tjava -jar " + JAR_FILENAME);
System.out
.println(" pkcs12FileName pdfInputFileName pdfOutputFileName");
System.out
.println("\nFor using a PKCS#11 smartcard as signature certificate and private key source:");
System.out.print("\tjava -jar" + JAR_FILENAME);
System.out.println(" -PKCS11 pdfInputFileName pdfOutputFileName");
System.exit(0);
}
}