diff options
Diffstat (limited to 'pdf-as-lib/src/main')
4 files changed, 2393 insertions, 2426 deletions
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java index a09a238..e501641 100644 --- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -115,7 +115,7 @@ public abstract class PdfAS * The current version of the pdf-as library. This version string is logged on every invocation
* of the api or the web application.
*/
- public static final String PDFAS_VERSION = "3.3";
+ public static final String PDFAS_VERSION = "3.5.1";
/**
* The key of the strict mode setting.
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java index b5a05ed..04e9036 100644 --- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java @@ -77,139 +77,147 @@ import at.knowcenter.wag.egov.egiz.tools.Normalizer; * All values that build or used by the signation creation process, call the
* external services, can read or set separately. All other values are defined
* in the settings file.
- *
+ *
* @author wlackner
- * @author modified by <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas Knall</a>
+ * @author modified by <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas
+ * Knall</a>
*/
-public class SignatureObject implements Serializable
-{
-
-// 03.11.2010 changed by exthex - added default for defaultValueStyle_.hAlign since we had to remove the hardcoded default in Style
-// 04.11.2010 changed by exthex - setSigValue no longer removes multiple newlines from value
-
- /**
- * SVUID.
- */
- private static final long serialVersionUID = -3535189232362254713L;
-
- /**
- * The system file separator char
- */
- private static final String FILE_SEP = System.getProperty("file.separator");
-
- /**
- * The certificate extension
- */
- private static final String CERT_FILE_EXTENSION = ".der";
-
- /**
- * certificate import dir
- */
- private static final String CERT_ADD_DIR = "tobeadded";
-
- /**
- * The default style definition for images.
- */
- private Style defaultImageStyle_ = new Style();
-
- /**
- * The default style definition for captions.
- */
- private Style defaultCaptionStyle_ = new Style();
-
- /**
- * The default style definition for values.
- */
- private Style defaultValueStyle_ = new Style();
-
- /**
- * Standard key get/set the signature meta informations
- */
- public static final String SIG_META = "SIG_META";
-
- /**
- * Standard key get/set the certification value
- */
- public static final String SIG_CER = "SIG_CER";
-
- /**
- * Standard key get/set the certification digest value
- */
- public static final String SIG_CER_DIG = "SIG_CER_DIG";
-
- private X509Cert x509Cert_ = null;
-
- private String timeStamp = null;
-
- // public static final String SIG_RES = "SIG_RES";
- // dummy value for debugging only
- private String sigResponse_ = null;
-
- /**
- * The logger definition.
- */
- private static final Logger logger_ = ConfigLogger.getLogger(SignatureObject.class);
-
- /**
- * The normalizer reference
- */
- private Normalizer normalizer_ = null;
-
- /**
- * The settings reader reference
- */
- private SettingsReader settings_ = null;
-
- // /**
- // * The reference to the settings property tree
- // */
- // private PropertyTree pTree_ = null;
- /**
- * The current signature type used reading and analysing the property tree
- */
- private String sigType_ = null;
-
- /**
- * Reference from signature key to there corresponding value
- */
- private Hashtable sigEntries_ = new Hashtable(8);
-
- /**
- * The abstract table representation
- */
- private Table sigTable_ = null;
-
- // private HashMap sigIndexMap_ = new HashMap();
-
- /**
- * Path value storing and fetching the certificates
- */
- private String certPath_ = null;
-
- /**
- * the signature definition object
- */
- private SignatureTypeDefinition signatureDefinition_ = null;
-
- /**
- * The raw xml response from the connector that was used to set the values in
- * this SignatureObject.
- *
- * <p>
- * This is set by the Connector so that signing Applications can use the
- * returned XML values.
- * </p>
- */
- protected String raw_signature_response = null;
-
- /**
- * Filters the issuer name in order to find matches.
- * @author tknall
- * @see #normalizeIssuer
- */
- private LDAPIssuerNameFilter issuerNameFilter = new LDAPIssuerNameFilter() {
+public class SignatureObject implements Serializable {
+
+ // 03.11.2010 changed by exthex - added default for
+ // defaultValueStyle_.hAlign since we had to remove the hardcoded default in
+ // Style
+ // 04.11.2010 changed by exthex - setSigValue no longer removes multiple
+ // newlines from value
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -3535189232362254713L;
+
+ /**
+ * The system file separator char
+ */
+ private static final String FILE_SEP = System.getProperty("file.separator");
+
+ /**
+ * The certificate extension
+ */
+ private static final String CERT_FILE_EXTENSION = ".der";
+
+ /**
+ * certificate import dir
+ */
+ private static final String CERT_ADD_DIR = "tobeadded";
+
+ /**
+ * The default style definition for images.
+ */
+ private Style defaultImageStyle_ = new Style();
+
+ public static Object adding_mutex = new Object();
+
+ /**
+ * The default style definition for captions.
+ */
+ private Style defaultCaptionStyle_ = new Style();
+
+ /**
+ * The default style definition for values.
+ */
+ private Style defaultValueStyle_ = new Style();
+
+ /**
+ * Standard key get/set the signature meta informations
+ */
+ public static final String SIG_META = "SIG_META";
+
+ /**
+ * Standard key get/set the certification value
+ */
+ public static final String SIG_CER = "SIG_CER";
+
+ /**
+ * Standard key get/set the certification digest value
+ */
+ public static final String SIG_CER_DIG = "SIG_CER_DIG";
+
+ private X509Cert x509Cert_ = null;
+
+ private String timeStamp = null;
+
+ // public static final String SIG_RES = "SIG_RES";
+ // dummy value for debugging only
+ private String sigResponse_ = null;
+
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger_ = ConfigLogger
+ .getLogger(SignatureObject.class);
+
+ /**
+ * The normalizer reference
+ */
+ private Normalizer normalizer_ = null;
+
+ /**
+ * The settings reader reference
+ */
+ private SettingsReader settings_ = null;
+
+ // /**
+ // * The reference to the settings property tree
+ // */
+ // private PropertyTree pTree_ = null;
+ /**
+ * The current signature type used reading and analysing the property tree
+ */
+ private String sigType_ = null;
+
+ /**
+ * Reference from signature key to there corresponding value
+ */
+ private Hashtable sigEntries_ = new Hashtable(8);
+
+ /**
+ * The abstract table representation
+ */
+ private Table sigTable_ = null;
+
+ // private HashMap sigIndexMap_ = new HashMap();
+
+ /**
+ * Path value storing and fetching the certificates
+ */
+ private String certPath_ = null;
+
+ /**
+ * the signature definition object
+ */
+ private SignatureTypeDefinition signatureDefinition_ = null;
+
+ /**
+ * The raw xml response from the connector that was used to set the values
+ * in this SignatureObject.
+ *
+ * <p>
+ * This is set by the Connector so that signing Applications can use the
+ * returned XML values.
+ * </p>
+ */
+ protected String raw_signature_response = null;
+
+ /**
+ * Filters the issuer name in order to find matches.
+ *
+ * @author tknall
+ * @see #normalizeIssuer
+ */
+ private LDAPIssuerNameFilter issuerNameFilter = new LDAPIssuerNameFilter() {
public Name applyFilter(Name name) {
- RFC2253NameParser parser = new RFC2253NameParser(normalizeIssuer(name.getName()));
+ RFC2253NameParser parser = new RFC2253NameParser(
+ normalizeIssuer(name.getName()));
try {
name = parser.parse();
} catch (RFC2253NameParserException e) {
@@ -219,591 +227,588 @@ public class SignatureObject implements Serializable }
};
- /**
- * The empty constructor. It initilize the normlizer, load the settings and
- * set the default styles.
- *
- * @throws SignatureException
- * ErrorCode:101, 400
- */
- public SignatureObject() throws SignatureException
- {
- initNormalizer();
- loadSettings();
- setDefaultStyles();
- }
-
- /**
- * This method initialize the normalizer
- *
- * @throws SignatureException
- * ErrorCode:400
- */
- private void initNormalizer() throws SignatureException
- {
- try
- {
- normalizer_ = new Normalizer();
- }
- catch (NormalizeException e)
- {
- SignatureException se = new SignatureException(400, "Normalizer can not be initialized", e);
- throw se;
- }
- }
-
- /**
- * This method load the signature definitions
- *
- * @throws SignatureException
- * ErrorCode:101
- */
- private void loadSettings() throws SignatureException
- {
- if (settings_ == null)
- {
- try
- {
- settings_ = SettingsReader.getInstance();
- }
- catch (SettingsException e)
- {
- String log_message = "Can not load pdf signature settings. Cause:\n" + e.getMessage();
- logger_.error(log_message);
- throw new SignatureException(101, log_message, e);
- }
- }
- // pTree_ = settings_.getPTree();
-
- certPath_ = SettingsReader.CERT_PATH;
- }
-
- /**
- * This method set the default styles for images, captions and values.
- */
- private void setDefaultStyles()
- {
- defaultImageStyle_.setPadding(3);
- defaultImageStyle_.setHAlign(Style.CENTER);
- defaultImageStyle_.setVAlign(Style.MIDDLE);
-
- defaultCaptionStyle_.setHAlign(Style.CENTER);
- defaultCaptionStyle_.setVAlign(Style.MIDDLE);
-
- defaultValueStyle_.setHAlign(Style.LEFT);
- defaultValueStyle_.setVAlign(Style.MIDDLE);
- }
-
- /**
- * Dummy getter Method for debugging only
- *
- * @return response string
- */
- public String getSigResponse()
- {
- return sigResponse_;
- }
-
- /**
- * Dummy setter Method for debugging only
- *
- * @param sigRespone
- * store the response string
- */
- public void setSigResponse(String sigRespone)
- {
- sigResponse_ = sigRespone;
- }
-
- /**
- * This method set the signature type.
- *
- * @param sigType
- * the signature type to be set
- * @throws SignatureTypesException
- */
- public void setSigType(String sigType) throws SignatureTypesException
- {
- SignatureTypes sig_types = SignatureTypes.getInstance();
- signatureDefinition_ = sig_types.getSignatureTypeDefinition(sigType_);
- sigType_ = sigType;
- }
-
- /**
- * Returns the default signation type
- *
- * @return the key for the default signature definition, if the key is not
- * found it returns null
- */
- private String getDefaultSigType()
- {
- return settings_.getSetting(SignatureTypes.DEFAULT_TYPE, null);
- }
-
- /**
- * This method checks if a given signature key is realy a defined signature
- * key.
- *
- * @param sigKey
- * the key to check
- * @return true if the key is correct, false if the given key is not defined
- */
- public boolean isSigKey(String sigKey)
- {
- return signatureDefinition_.contains(sigKey);
- }
-
- /**
- * This method adds an sig value to the entry cache. If a key is not in
- * the cache a new signature entry is created. Therefore the method return
- * true. <br>
- * The value that has to be set would be normalized! <br>
- * <b>If the key equals to <code>SIG_VALUE</code> all whitespaces are
- * removed! </b> <br>
- *
- * @param key
- * the key to be set
- * @param value
- * the value to be set
- * @return <code>true</code> if a new signature value is created,
- * <code>false</code> otherwise
- */
- public boolean setSigValue(String key, String value) {
- return setSigValue(key, value, false);
- }
-
- public boolean setSigValue(String key, String value, boolean placeholder)
- {
- SignatureEntry sig_entry = null;
- boolean is_new = false;
- if (sigEntries_.containsKey(key))
- {
- sig_entry = (SignatureEntry) sigEntries_.get(key);
- }
- else
- {
- sig_entry = new SignatureEntry(key);
- sigEntries_.put(key, sig_entry);
- is_new = true;
- }
- value = normalizer_.normalize(value, true);
- if (SignatureTypes.SIG_VALUE.equals(key) || SignatureTypes.SIG_ID.equals(key) || SignatureTypes.SIG_NUMBER.equals(key))
- {
- value = removeAllWhiteSpaces(value);
- }
- sig_entry.setValue(value);
- sig_entry.isPlaceholder = placeholder;
- return is_new;
- }
-
- public boolean setValueBruteForce(String key, String value)
- {
- SignatureEntry sig_entry = null;
- boolean is_new = false;
- if (sigEntries_.containsKey(key))
- {
- sig_entry = (SignatureEntry) sigEntries_.get(key);
- }
- else
- {
- sig_entry = new SignatureEntry(key);
- sigEntries_.put(key, sig_entry);
- is_new = true;
- }
- sig_entry.setValue(value);
- return is_new;
- }
-
- /**
- * Set the value and the caption to given key.
- *
- * @param key
- * the key of the signature object
- * @param value
- * the value of the given key
- * @param caption
- * the caption of the given key
- */
- public void setSigValueCaption(String key, String value, String caption)
- {
- setSigValue(key, value);
- SignatureEntry sig_entry = (SignatureEntry) sigEntries_.get(key);
- sig_entry.setCaption(caption);
- }
-
- /**
- * This method returns a value for a given signature key. If the key equals to
- * <code>SIG_NORM</code> and the value is <code>null</code> the version
- * string of the current normalizer is returned!
- *
- * @param key
- * the key to get the value for
- * @return a value for the given key
- */
- public String getSigValue(String key)
- {
-
- String value = null;
- SignatureEntry sigEntry = null;
- if (sigEntries_.containsKey(key))
- {
- sigEntry = (SignatureEntry) sigEntries_.get(key);
- value = sigEntry.getValue();
- }
- if (value == null && SignatureTypes.SIG_NORM.equals(key))
- {
- value = normalizer_.getVersion();
- }
-
- String overrideVal = OverridePropertyHolder.getProperty(key);
- if (value != null && sigEntry != null && !sigEntry.isPlaceholder && overrideVal != null) { // TODO this!! SignatureEntry.isPlaceholder
- value = overrideVal;
- if (logger_.isDebugEnabled()) {
- logger_.debug("Using override property for key '" + key + "' = " + value);
- }
- }
-
- return value;
- }
-
- /**
- * Sets the "Kennzeichnung".
- *
- * @param kz
- * The "Kennzeichnung" to be set.
- */
- public void setKZ(PdfASID kz)
- {
- setSigValue(SignatureTypes.SIG_KZ, kz.toString());
- }
-
- /**
- * Returns the "Kennzeichnung" of this signature.
- *
- * @return Returns the "Kennzeichnung" of this signature. Returns null if
- * there is no "Kennzeichnung" or it is not recognized by this
- * application.
- */
- public PdfASID getKZ() throws InvalidIDException
- {
- String kz_string = getSigValue(SignatureTypes.SIG_KZ);
- if (kz_string == null)
- {
- return null;
- }
- PdfASID kz = null;
- try
- {
- kz = new PdfASID(kz_string);
- }
- catch (InvalidIDException e)
- {
- logger_.error(e.getMessage(), e);
- }
- return kz;
- }
-
- /**
- * This method returns a caption for a given signature key. If the key exists
- * and the coresponding value is <code>null</code> the key itself is
- * returned as caption! If the key does not exist the method returns
- * <code>null</code>.
- *
- * @param key
- * the key to get the caption for
- * @return a caption for the given key
- */
- private String getSigCaption(String key)
- {
-
- String caption = null;
- if (sigEntries_.containsKey(key))
- {
- caption = ((SignatureEntry) sigEntries_.get(key)).getCaption();
- if (caption == null)
- {
- caption = key;
- }
- }
- return caption;
- }
-
- /**
- * @return Returns the SignationType.
- */
- public String getSignationType()
- {
- if (sigType_ == null)
- {
- sigType_ = getDefaultSigType();
- }
- return sigType_;
- }
-
- /**
- * @return Returns the SignationDate.
- */
- public String getSignationDate()
- {
- return getSigValue(SignatureTypes.SIG_DATE);
- }
-
- /**
- * @param sigDate
- * The SignationDate to set.
- */
- public void setSignationDate(String sigDate)
- {
- setSigValue(SignatureTypes.SIG_DATE, sigDate);
- }
-
- /**
- * @return Returns the SignationName.
- */
- public String getSignationName()
- {
- return getSigValue(SignatureTypes.SIG_NAME);
- }
-
- /**
- * @param sigName
- * The SignationName to set.
- */
- public void setSignationName(String sigName)
- {
- setSigValue(SignatureTypes.SIG_NAME, sigName);
- }
-
- /**
- * @return Returns the SignationNormVersion.
- */
- public String getSignationNormVersion()
- {
- return getSigValue(SignatureTypes.SIG_NORM);
- }
-
- /**
- * @param sigNormVersion
- * The SignationNormVersion to set.
- */
- public void setSignationNormVersion(String sigNormVersion)
- {
- setSigValue(SignatureTypes.SIG_NORM, sigNormVersion);
- }
-
- /**
- * This method removes whitespaces around RDNs. Whitespaces may be assumed by the algorithm that
- * re-merges multiple lines from a binary signature when line breaks occur after commas. Without
- * correction this will result in broken signatures.<br/>
- * e.g this
- * invalid IssuerName (note the space before the second RND CN):
- * <code>serialNumber=863532247989, CN=BMUKK - Amtssignatur Schulen,OU=Abt. IT/2,O=Bundesministerium für Unterricht, Kunst und Kultur,C=AT</code>
- * will be normalized to:
- * <code>serialNumber=863532247989,CN=BMUKK - Amtssignatur Schulen,OU=Abt. IT/2,O=Bundesministerium für Unterricht, Kunst und Kultur,C=AT</code>
- * @param The invalid RFC2253 name as string.
- * @return The normalized RFC2253 name without spaces prior to RDNs.
- */
- public static String prepareRFC2253Name(String name) {
- if (name == null) {
- return null;
- }
- StringTokenizer tokenizer = new StringTokenizer(name, ",", false);
- StringBuffer result = new StringBuffer();
- // iterate over all alleged RND=value-pairs
- while (tokenizer.hasMoreTokens()) {
- String rdnExpression = tokenizer.nextToken();
- try {
- // try to parse RDN=value
- new RFC2253NameParser(rdnExpression.trim()).parse();
- // rdnExpression is a RDN=value pair -> remove whitespaces before and after RDN=value
- rdnExpression = rdnExpression.trim();
- } catch (RFC2253NameParserException e) {
- // this is not a RDN=value pair
- // e.g. " Kunst und Kultur" from the javadoc example
- // do not trim, otherwise resulting RFC2253Name will be invalid
- }
- // re-insert delimiter
- if (result.length() > 0) {
- result.append(",");
- }
- // add token (either trimmed RND=value pair, or not trimmed text token)
- result.append(rdnExpression);
- }
- String cleanedName = result.toString();
- if (logger_.isDebugEnabled()) {
- logger_.debug("Cleaning RFC2253 name: \"" + name + "\" -> \"" + cleanedName + "\".");
- }
- return cleanedName;
- }
-
- /**
- * This method depicts a workaround for a bug with RFC2253 names with RDNs that have not been
- * resolved from ObjectID at signing time (this results from a BKU that could not resolve
- * the respective OID).<br/>
- * e.g. <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code><br/>
- * The example above shows a RDN "2.5.4.5" which should have been resolved to "serialNumber" at
- * signing time. We also recognize that the name shows spaces prior to RDNs and that the space
- * which between "Foreigner" and "CA" is missing due to text extraction/reconstruction.
- * The naive approach would be to take the complete RFC2253 name from the certificate, since that
- * name has also been used for signature. But this does not work in some cases because while
- * the bku was not able to resolve 2.5.4.5 on signing time, the entity invoking pdfas for
- * verification might be, so that taking the name from certificate on verification time, may not
- * result in the name we had at signing time.<br/>
- * e.g. at signing time: <code>2.5.4.5=#1306323030383034,CN=Foreigner CA,C=BE</code><br/>
- * after text extraction: <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code><br/>
- * from certificate: <code>serialNumber=863532247989,CN=Foreigner CA,C=BE</code><br/>
- * This method provides a workaround for that problem, by merging information from text extraction
- * with information from the certificate. The method takes all RDNs from the extracted text and
- * merges them with the values from the certificate (considering the case where the textual
- * version shows BER encoded values (e.g. <code>#1306323030383034</code>).
- * @param nameFromText The extracted RFC2253 name from the text (e.g. <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code>).
- * @param nameFromCertificate The RFC2253 name from the certificate (e.g. <code>serialNumber=863532247989,CN=Foreigner CA,C=BE</code>)
- * @return The RFC2253 name that was used for signature (e.g. <code>2.5.4.5=#1306323030383034,CN=Foreigner CA,C=BE</code>).
- */
- public static String prepareRFC2253Name(String nameFromText, String nameFromCertificate) {
-
- // do not invoke the workaround for performance reasons when both the extracted name and the
- // name from certificate are equal
- if (StringUtils.equals(nameFromText, nameFromCertificate)) {
- return nameFromText;
- }
-
- logger_.debug("Checking RFC2253 name.");
-
- // if we do not have a name from certificate just return the name from text
- if (nameFromCertificate == null) {
- logger_.debug("No certificate RFC2253 name provided. Applying less sophisticated workaround (does not cover all cases) without certificate usage.");
- return prepareRFC2253Name(nameFromText);
- }
-
- // no name from text extraction available, just return name from certificate
- if (nameFromText == null) {
- logger_.debug("No extracted/reconstructed name available. Just returning the name from certificate: \"" + nameFromCertificate + "\".");
- return nameFromCertificate;
- }
-
- // helper class
- final class RDNValuePair {
-
- private String rdn;
- private String value;
-
- public RDNValuePair(String rdn, String value) {
- this.rdn = rdn;
- this.value = value;
- }
-
- public String getRdn() {
- return this.rdn;
- }
-
- public String getValue() {
- return this.value;
- }
-
- public String toString() {
- return rdn + "=" + value;
- }
- }
-
- // retrieve RDNs from text based name
- List rdnList = new ArrayList();
- StringTokenizer tokenizer = new StringTokenizer(nameFromText, ",", false);
- while (tokenizer.hasMoreTokens()) {
- String rdnExpression = tokenizer.nextToken().trim();
- try {
- new RFC2253NameParser(rdnExpression).parse();
- // token is RDN=value pair
- // split RDN from value
- String[] split = rdnExpression.split("=", 2);
- rdnList.add(new RDNValuePair(split[0].trim(), split[1].trim()));
- } catch (RFC2253NameParserException e) {
- // no RDN in token
- }
- }
-
- // get values from certificate name
- Name nCert;
- try {
- nCert = new RFC2253NameParser(nameFromCertificate).parse();
- } catch (RFC2253NameParserException e) {
- // should never happen
- logger_.warn("Unable to parse RFC2253 name \"" + nameFromCertificate + "\". Applying less sophisticated workaround (does not cover all cases) without certificate usage.");
- return prepareRFC2253Name(nameFromText);
- }
- RDN[] values = nCert.getRDNs();
-
- // check if results are mergeable
- if (values.length != rdnList.size()) {
- // unable to merge names; returning nameFromCertificate (since this should be normal
- // behavior)
- logger_.warn("Number of parsed text based RDNs from \"" + nameFromText + "\" does not fit the number of RDN values from certificate name \"" + nameFromCertificate + "\". Returning name from certificate.");
- return nameFromCertificate;
- }
-
- // merge textual based RDNs with values from certificate
- StringBuffer result = new StringBuffer();
- for (int i = 0; i < values.length; i++) {
- if (i > 0) {
- result.append(",");
- }
- // take rdn from textual representation
- RDNValuePair rdnVP = (RDNValuePair) rdnList.get(i);
- // Note: Do not take RDN from extraction but from certificate
- // (Bug-Fix for EMAIL/EMAILADDRESS problem in ZID documents)
-
- // take value from certificate but make sure that we do not have a
- // BER encoding
- if (rdnVP.getValue().startsWith("#")) {
+ /**
+ * The empty constructor. It initilize the normlizer, load the settings and
+ * set the default styles.
+ *
+ * @throws SignatureException
+ * ErrorCode:101, 400
+ */
+ public SignatureObject() throws SignatureException {
+ initNormalizer();
+ loadSettings();
+ setDefaultStyles();
+ }
- // take rdn from textual representation
- result.append(rdnVP.getRdn()).append("=");
- // BER encoding -> take value from text representation
- result.append(rdnVP.getValue());
+ /**
+ * This method initialize the normalizer
+ *
+ * @throws SignatureException
+ * ErrorCode:400
+ */
+ private void initNormalizer() throws SignatureException {
+ try {
+ normalizer_ = new Normalizer();
+ } catch (NormalizeException e) {
+ SignatureException se = new SignatureException(400,
+ "Normalizer can not be initialized", e);
+ throw se;
+ }
+ }
+
+ /**
+ * This method load the signature definitions
+ *
+ * @throws SignatureException
+ * ErrorCode:101
+ */
+ private void loadSettings() throws SignatureException {
+ if (settings_ == null) {
+ try {
+ settings_ = SettingsReader.getInstance();
+ } catch (SettingsException e) {
+ String log_message = "Can not load pdf signature settings. Cause:\n"
+ + e.getMessage();
+ logger_.error(log_message);
+ throw new SignatureException(101, log_message, e);
+ }
+ }
+ // pTree_ = settings_.getPTree();
+
+ certPath_ = SettingsReader.CERT_PATH;
+ }
+
+ /**
+ * This method set the default styles for images, captions and values.
+ */
+ private void setDefaultStyles() {
+ defaultImageStyle_.setPadding(3);
+ defaultImageStyle_.setHAlign(Style.CENTER);
+ defaultImageStyle_.setVAlign(Style.MIDDLE);
+
+ defaultCaptionStyle_.setHAlign(Style.CENTER);
+ defaultCaptionStyle_.setVAlign(Style.MIDDLE);
+
+ defaultValueStyle_.setHAlign(Style.LEFT);
+ defaultValueStyle_.setVAlign(Style.MIDDLE);
+ }
+
+ /**
+ * Dummy getter Method for debugging only
+ *
+ * @return response string
+ */
+ public String getSigResponse() {
+ return sigResponse_;
+ }
+
+ /**
+ * Dummy setter Method for debugging only
+ *
+ * @param sigRespone
+ * store the response string
+ */
+ public void setSigResponse(String sigRespone) {
+ sigResponse_ = sigRespone;
+ }
+
+ /**
+ * This method set the signature type.
+ *
+ * @param sigType
+ * the signature type to be set
+ * @throws SignatureTypesException
+ */
+ public void setSigType(String sigType) throws SignatureTypesException {
+ SignatureTypes sig_types = SignatureTypes.getInstance();
+ signatureDefinition_ = sig_types.getSignatureTypeDefinition(sigType_);
+ sigType_ = sigType;
+ }
+
+ /**
+ * Returns the default signation type
+ *
+ * @return the key for the default signature definition, if the key is not
+ * found it returns null
+ */
+ private String getDefaultSigType() {
+ return settings_.getSetting(SignatureTypes.DEFAULT_TYPE, null);
+ }
+
+ /**
+ * This method checks if a given signature key is realy a defined signature
+ * key.
+ *
+ * @param sigKey
+ * the key to check
+ * @return true if the key is correct, false if the given key is not defined
+ */
+ public boolean isSigKey(String sigKey) {
+ return signatureDefinition_.contains(sigKey);
+ }
+
+ /**
+ * This method adds an sig value to the entry cache. If a key is not in the
+ * cache a new signature entry is created. Therefore the method return true. <br>
+ * The value that has to be set would be normalized! <br>
+ * <b>If the key equals to <code>SIG_VALUE</code> all whitespaces are
+ * removed! </b> <br>
+ *
+ * @param key
+ * the key to be set
+ * @param value
+ * the value to be set
+ * @return <code>true</code> if a new signature value is created,
+ * <code>false</code> otherwise
+ */
+ public boolean setSigValue(String key, String value) {
+ return setSigValue(key, value, false);
+ }
+
+ public boolean setSigValue(String key, String value, boolean placeholder) {
+ SignatureEntry sig_entry = null;
+ boolean is_new = false;
+ if (sigEntries_.containsKey(key)) {
+ sig_entry = (SignatureEntry) sigEntries_.get(key);
} else {
- // no BER encoding -> take value from certificate
- // also take RDN from certificate if possible
- String certValue = values[values.length - 1 - i].getAVA()
- .getValueAsString();
- String rdn = resolveRDN(nameFromCertificate, certValue, rdnVP.getRdn());
- result.append(rdn + "=").append(certValue);
+ sig_entry = new SignatureEntry(key);
+ sigEntries_.put(key, sig_entry);
+ is_new = true;
+ }
+ value = normalizer_.normalize(value, true);
+ if (SignatureTypes.SIG_VALUE.equals(key)
+ || SignatureTypes.SIG_ID.equals(key)
+ || SignatureTypes.SIG_NUMBER.equals(key)) {
+ value = removeAllWhiteSpaces(value);
+ }
+ sig_entry.setValue(value);
+ sig_entry.isPlaceholder = placeholder;
+ return is_new;
+ }
+
+ public boolean setValueBruteForce(String key, String value) {
+ SignatureEntry sig_entry = null;
+ boolean is_new = false;
+ if (sigEntries_.containsKey(key)) {
+ sig_entry = (SignatureEntry) sigEntries_.get(key);
+ } else {
+ sig_entry = new SignatureEntry(key);
+ sigEntries_.put(key, sig_entry);
+ is_new = true;
+ }
+ sig_entry.setValue(value);
+ return is_new;
+ }
+
+ /**
+ * Set the value and the caption to given key.
+ *
+ * @param key
+ * the key of the signature object
+ * @param value
+ * the value of the given key
+ * @param caption
+ * the caption of the given key
+ */
+ public void setSigValueCaption(String key, String value, String caption) {
+ setSigValue(key, value);
+ SignatureEntry sig_entry = (SignatureEntry) sigEntries_.get(key);
+ sig_entry.setCaption(caption);
+ }
+
+ /**
+ * This method returns a value for a given signature key. If the key equals
+ * to <code>SIG_NORM</code> and the value is <code>null</code> the version
+ * string of the current normalizer is returned!
+ *
+ * @param key
+ * the key to get the value for
+ * @return a value for the given key
+ */
+ public String getSigValue(String key) {
+
+ String value = null;
+ SignatureEntry sigEntry = null;
+ if (sigEntries_.containsKey(key)) {
+ sigEntry = (SignatureEntry) sigEntries_.get(key);
+ value = sigEntry.getValue();
+ }
+ if (value == null && SignatureTypes.SIG_NORM.equals(key)) {
+ value = normalizer_.getVersion();
}
- }
- String merged = result.toString();
- if (logger_.isDebugEnabled()) {
- if (merged.equals(nameFromText)) {
- logger_.debug("Taking name from text: \"" + nameFromText + "\"");
- } else if (merged.equals(nameFromCertificate)) {
- logger_.debug("Taking name from certificate: \"" + nameFromText + "\"");
- } else {
- logger_.debug("Name has been fixed.");
- logger_.debug("Name from text : \"" + nameFromText + "\"");
- logger_.debug("Name from certificate : \"" + nameFromCertificate + "\"");
- logger_.debug("Fixed name : \"" + merged + "\"");
- }
- }
- return merged;
- }
-
- /**
- * This method tries to resolve the RDN corresponding to a given value from the certificate String.
- * As values might occur multiple times for different RDNs, an unambiguous resolving cannot be assured.
- * In case of ambiguity, the RDN extracted from text is returned by default.
- *
- * This method is a bug fix for a problem that caused the verification of ZID documents to fail as the RDN
- * from the extracted text ("EMAILADDRESS") was different to the RDN in the certificate ("EMAIL")
- *
+ String overrideVal = OverridePropertyHolder.getProperty(key);
+ if (value != null && sigEntry != null && !sigEntry.isPlaceholder
+ && overrideVal != null) { // TODO this!!
+ // SignatureEntry.isPlaceholder
+ value = overrideVal;
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Using override property for key '" + key
+ + "' = " + value);
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Sets the "Kennzeichnung".
+ *
+ * @param kz
+ * The "Kennzeichnung" to be set.
+ */
+ public void setKZ(PdfASID kz) {
+ setSigValue(SignatureTypes.SIG_KZ, kz.toString());
+ }
+
+ /**
+ * Returns the "Kennzeichnung" of this signature.
+ *
+ * @return Returns the "Kennzeichnung" of this signature. Returns null if
+ * there is no "Kennzeichnung" or it is not recognized by this
+ * application.
+ */
+ public PdfASID getKZ() throws InvalidIDException {
+ String kz_string = getSigValue(SignatureTypes.SIG_KZ);
+ if (kz_string == null) {
+ return null;
+ }
+ PdfASID kz = null;
+ try {
+ kz = new PdfASID(kz_string);
+ } catch (InvalidIDException e) {
+ logger_.error(e.getMessage(), e);
+ }
+ return kz;
+ }
+
+ /**
+ * This method returns a caption for a given signature key. If the key
+ * exists and the coresponding value is <code>null</code> the key itself is
+ * returned as caption! If the key does not exist the method returns
+ * <code>null</code>.
+ *
+ * @param key
+ * the key to get the caption for
+ * @return a caption for the given key
+ */
+ private String getSigCaption(String key) {
+
+ String caption = null;
+ if (sigEntries_.containsKey(key)) {
+ caption = ((SignatureEntry) sigEntries_.get(key)).getCaption();
+ if (caption == null) {
+ caption = key;
+ }
+ }
+ return caption;
+ }
+
+ /**
+ * @return Returns the SignationType.
+ */
+ public String getSignationType() {
+ if (sigType_ == null) {
+ sigType_ = getDefaultSigType();
+ }
+ return sigType_;
+ }
+
+ /**
+ * @return Returns the SignationDate.
+ */
+ public String getSignationDate() {
+ return getSigValue(SignatureTypes.SIG_DATE);
+ }
+
+ /**
+ * @param sigDate
+ * The SignationDate to set.
+ */
+ public void setSignationDate(String sigDate) {
+ setSigValue(SignatureTypes.SIG_DATE, sigDate);
+ }
+
+ /**
+ * @return Returns the SignationName.
+ */
+ public String getSignationName() {
+ return getSigValue(SignatureTypes.SIG_NAME);
+ }
+
+ /**
+ * @param sigName
+ * The SignationName to set.
+ */
+ public void setSignationName(String sigName) {
+ setSigValue(SignatureTypes.SIG_NAME, sigName);
+ }
+
+ /**
+ * @return Returns the SignationNormVersion.
+ */
+ public String getSignationNormVersion() {
+ return getSigValue(SignatureTypes.SIG_NORM);
+ }
+
+ /**
+ * @param sigNormVersion
+ * The SignationNormVersion to set.
+ */
+ public void setSignationNormVersion(String sigNormVersion) {
+ setSigValue(SignatureTypes.SIG_NORM, sigNormVersion);
+ }
+
+ /**
+ * This method removes whitespaces around RDNs. Whitespaces may be assumed
+ * by the algorithm that re-merges multiple lines from a binary signature
+ * when line breaks occur after commas. Without correction this will result
+ * in broken signatures.<br/>
+ * e.g this invalid IssuerName (note the space before the second RND CN):
+ * <code>serialNumber=863532247989, CN=BMUKK - Amtssignatur Schulen,OU=Abt. IT/2,O=Bundesministerium für Unterricht, Kunst und Kultur,C=AT</code>
+ * will be normalized to:
+ * <code>serialNumber=863532247989,CN=BMUKK - Amtssignatur Schulen,OU=Abt. IT/2,O=Bundesministerium für Unterricht, Kunst und Kultur,C=AT</code>
+ *
+ * @param The
+ * invalid RFC2253 name as string.
+ * @return The normalized RFC2253 name without spaces prior to RDNs.
+ */
+ public static String prepareRFC2253Name(String name) {
+ if (name == null) {
+ return null;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(name, ",", false);
+ StringBuffer result = new StringBuffer();
+ // iterate over all alleged RND=value-pairs
+ while (tokenizer.hasMoreTokens()) {
+ String rdnExpression = tokenizer.nextToken();
+ try {
+ // try to parse RDN=value
+ new RFC2253NameParser(rdnExpression.trim()).parse();
+ // rdnExpression is a RDN=value pair -> remove whitespaces
+ // before and after RDN=value
+ rdnExpression = rdnExpression.trim();
+ } catch (RFC2253NameParserException e) {
+ // this is not a RDN=value pair
+ // e.g. " Kunst und Kultur" from the javadoc example
+ // do not trim, otherwise resulting RFC2253Name will be invalid
+ }
+ // re-insert delimiter
+ if (result.length() > 0) {
+ result.append(",");
+ }
+ // add token (either trimmed RND=value pair, or not trimmed text
+ // token)
+ result.append(rdnExpression);
+ }
+ String cleanedName = result.toString();
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Cleaning RFC2253 name: \"" + name + "\" -> \""
+ + cleanedName + "\".");
+ }
+ return cleanedName;
+ }
+
+ /**
+ * This method depicts a workaround for a bug with RFC2253 names with RDNs
+ * that have not been resolved from ObjectID at signing time (this results
+ * from a BKU that could not resolve the respective OID).<br/>
+ * e.g. <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code><br/>
+ * The example above shows a RDN "2.5.4.5" which should have been resolved
+ * to "serialNumber" at signing time. We also recognize that the name shows
+ * spaces prior to RDNs and that the space which between "Foreigner" and
+ * "CA" is missing due to text extraction/reconstruction. The naive approach
+ * would be to take the complete RFC2253 name from the certificate, since
+ * that name has also been used for signature. But this does not work in
+ * some cases because while the bku was not able to resolve 2.5.4.5 on
+ * signing time, the entity invoking pdfas for verification might be, so
+ * that taking the name from certificate on verification time, may not
+ * result in the name we had at signing time.<br/>
+ * e.g. at signing time:
+ * <code>2.5.4.5=#1306323030383034,CN=Foreigner CA,C=BE</code><br/>
+ * after text extraction:
+ * <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code><br/>
+ * from certificate:
+ * <code>serialNumber=863532247989,CN=Foreigner CA,C=BE</code><br/>
+ * This method provides a workaround for that problem, by merging
+ * information from text extraction with information from the certificate.
+ * The method takes all RDNs from the extracted text and merges them with
+ * the values from the certificate (considering the case where the textual
+ * version shows BER encoded values (e.g. <code>#1306323030383034</code>).
+ *
+ * @param nameFromText
+ * The extracted RFC2253 name from the text (e.g.
+ * <code>2.5.4.5=#1306323030383034, CN=ForeignerCA,C=BE</code>).
+ * @param nameFromCertificate
+ * The RFC2253 name from the certificate (e.g.
+ * <code>serialNumber=863532247989,CN=Foreigner CA,C=BE</code>)
+ * @return The RFC2253 name that was used for signature (e.g.
+ * <code>2.5.4.5=#1306323030383034,CN=Foreigner CA,C=BE</code>).
+ */
+ public static String prepareRFC2253Name(String nameFromText,
+ String nameFromCertificate) {
+
+ // do not invoke the workaround for performance reasons when both the
+ // extracted name and the
+ // name from certificate are equal
+ if (StringUtils.equals(nameFromText, nameFromCertificate)) {
+ return nameFromText;
+ }
+
+ logger_.debug("Checking RFC2253 name.");
+
+ // if we do not have a name from certificate just return the name from
+ // text
+ if (nameFromCertificate == null) {
+ logger_.debug("No certificate RFC2253 name provided. Applying less sophisticated workaround (does not cover all cases) without certificate usage.");
+ return prepareRFC2253Name(nameFromText);
+ }
+
+ // no name from text extraction available, just return name from
+ // certificate
+ if (nameFromText == null) {
+ logger_.debug("No extracted/reconstructed name available. Just returning the name from certificate: \""
+ + nameFromCertificate + "\".");
+ return nameFromCertificate;
+ }
+
+ // helper class
+ final class RDNValuePair {
+
+ private String rdn;
+ private String value;
+
+ public RDNValuePair(String rdn, String value) {
+ this.rdn = rdn;
+ this.value = value;
+ }
+
+ public String getRdn() {
+ return this.rdn;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public String toString() {
+ return rdn + "=" + value;
+ }
+ }
+
+ // retrieve RDNs from text based name
+ List rdnList = new ArrayList();
+ StringTokenizer tokenizer = new StringTokenizer(nameFromText, ",",
+ false);
+ while (tokenizer.hasMoreTokens()) {
+ String rdnExpression = tokenizer.nextToken().trim();
+ try {
+ new RFC2253NameParser(rdnExpression).parse();
+ // token is RDN=value pair
+ // split RDN from value
+ String[] split = rdnExpression.split("=", 2);
+ rdnList.add(new RDNValuePair(split[0].trim(), split[1].trim()));
+ } catch (RFC2253NameParserException e) {
+ // no RDN in token
+ }
+ }
+
+ // get values from certificate name
+ Name nCert;
+ try {
+ nCert = new RFC2253NameParser(nameFromCertificate).parse();
+ } catch (RFC2253NameParserException e) {
+ // should never happen
+ logger_.warn("Unable to parse RFC2253 name \""
+ + nameFromCertificate
+ + "\". Applying less sophisticated workaround (does not cover all cases) without certificate usage.");
+ return prepareRFC2253Name(nameFromText);
+ }
+ RDN[] values = nCert.getRDNs();
+
+ // check if results are mergeable
+ if (values.length != rdnList.size()) {
+ // unable to merge names; returning nameFromCertificate (since this
+ // should be normal
+ // behavior)
+ logger_.warn("Number of parsed text based RDNs from \""
+ + nameFromText
+ + "\" does not fit the number of RDN values from certificate name \""
+ + nameFromCertificate
+ + "\". Returning name from certificate.");
+ return nameFromCertificate;
+ }
+
+ // merge textual based RDNs with values from certificate
+ StringBuffer result = new StringBuffer();
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ result.append(",");
+ }
+ // take rdn from textual representation
+ RDNValuePair rdnVP = (RDNValuePair) rdnList.get(i);
+ // Note: Do not take RDN from extraction but from certificate
+ // (Bug-Fix for EMAIL/EMAILADDRESS problem in ZID documents)
+
+ // take value from certificate but make sure that we do not have a
+ // BER encoding
+ if (rdnVP.getValue().startsWith("#")) {
+
+ // take rdn from textual representation
+ result.append(rdnVP.getRdn()).append("=");
+ // BER encoding -> take value from text representation
+ result.append(rdnVP.getValue());
+ } else {
+ // no BER encoding -> take value from certificate
+ // also take RDN from certificate if possible
+ String certValue = values[values.length - 1 - i].getAVA()
+ .getValueAsString();
+ String rdn = resolveRDN(nameFromCertificate, certValue,
+ rdnVP.getRdn());
+ result.append(rdn + "=").append(certValue);
+ }
+
+ }
+ String merged = result.toString();
+ if (logger_.isDebugEnabled()) {
+ if (merged.equals(nameFromText)) {
+ logger_.debug("Taking name from text: \"" + nameFromText + "\"");
+ } else if (merged.equals(nameFromCertificate)) {
+ logger_.debug("Taking name from certificate: \"" + nameFromText
+ + "\"");
+ } else {
+ logger_.debug("Name has been fixed.");
+ logger_.debug("Name from text : \"" + nameFromText
+ + "\"");
+ logger_.debug("Name from certificate : \""
+ + nameFromCertificate + "\"");
+ logger_.debug("Fixed name : \"" + merged + "\"");
+ }
+ }
+ return merged;
+ }
+
+ /**
+ * This method tries to resolve the RDN corresponding to a given value from
+ * the certificate String. As values might occur multiple times for
+ * different RDNs, an unambiguous resolving cannot be assured. In case of
+ * ambiguity, the RDN extracted from text is returned by default.
+ *
+ * This method is a bug fix for a problem that caused the verification of
+ * ZID documents to fail as the RDN from the extracted text ("EMAILADDRESS")
+ * was different to the RDN in the certificate ("EMAIL")
+ *
* @param certString
- * The String obtained from the certificate
+ * The String obtained from the certificate
* @param value
- * The RDN's value
+ * The RDN's value
* @param extractedRDN
- * The RDN extracted from the given text
- * @return
- * The resolved RDN from the certificate, or the RDN from text extraction
+ * The RDN extracted from the given text
+ * @return The resolved RDN from the certificate, or the RDN from text
+ * extraction
*/
- private static String resolveRDN(String certString, String value, String extractedRDN) {
+ private static String resolveRDN(String certString, String value,
+ String extractedRDN) {
if (!certString.contains(value)) {
@@ -813,7 +818,8 @@ public class SignatureObject implements Serializable if (certString.indexOf(value) != certString.lastIndexOf(value)) {
- // given value is ambiguous - cannot resolve RDN from certificate string
+ // given value is ambiguous - cannot resolve RDN from certificate
+ // string
return extractedRDN;
}
@@ -840,1268 +846,1223 @@ public class SignatureObject implements Serializable return extractedRDN;
}
- /**
- * @return Returns the SignationIssuer.
- */
- public String getSignationIssuer()
- {
- String issuer = getSigValue(SignatureTypes.SIG_ISSUER);
- X509Cert cert = loadCertificate(getSigValue(SignatureTypes.SIG_NUMBER), issuer);
- if (cert != null)
- {
- // merge RDNs from file with values from certificate
- if (getSigValue(SignatureTypes.SIG_ISSUER) != null) {
- this.setSignationIssuer(prepareRFC2253Name(getSigValue(SignatureTypes.SIG_ISSUER), cert.getIssuerName()));
- } else {
- this.setSignationIssuer(cert.getIssuerName());
- }
- /*
- if (getSigValue(SignatureTypes.SIG_ISSUER) == null) {
- this.setSignationIssuer(cert.getIssuerName());
- }
- */
- setSigValue(SIG_CER, cert.getCertString());
- // setSigValue(SIG_CER_DIG, cert.getCertDigest());
- x509Cert_ = cert;
- }
- issuer = getSigValue(SignatureTypes.SIG_ISSUER);
- return issuer;
- }
-
- /**
- * @param sigIssuer
- * The SignationIssuer to set.
- */
- public void setSignationIssuer(String sigIssuer)
- {
- setSigValue(SignatureTypes.SIG_ISSUER, sigIssuer);
- }
-
- /**
- * @return Returns the SignationValue.
- */
- public String getSignationValue()
- {
- return getSigValue(SignatureTypes.SIG_VALUE);
- }
-
- /**
- * @param sigValue
- * The SignationValue to set.
- */
- public void setSignationValue(String sigValue)
- {
- setSigValue(SignatureTypes.SIG_VALUE, sigValue);
- }
-
- /**
- * @return the reference to the signature label
- */
- public String getOfficialSeal()
- {
- return getSigValue(SignatureTypes.SIG_LABEL);
- }
-
- /**
- * @param serialNumber
- * The serial number of the signature to set
- */
- public void setSignationSerialNumber(String serialNumber)
- {
- setSigValue(SignatureTypes.SIG_NUMBER, serialNumber);
- }
-
- /**
- * @return sigNumber the serial number of the signature
- */
- public String getSignationSerialNumber()
- {
- return getSigValue(SignatureTypes.SIG_NUMBER);
- }
-
- // dferbas baik
-
- /**
- * signature algorithm if embedded
- * @param sigAlg
- */
- public void setSigAlg(String sigAlg)
- {
- setSigValue(SignatureTypes.SIG_ALG, sigAlg);
- }
-
- /**
- * signature algorithm if embedded
- * @return
- */
- public String getSigAlg()
- {
- return getSigValue(SignatureTypes.SIG_ALG);
- }
-
- /**
- * @param certDigest
- * set the digest value for the X509Certificate
- */
- public void setX509CertificateDigest(String certDigest)
- {
- setSigValue(SIG_CER_DIG, certDigest);
- }
-
- /**
- * This method load the current certificate getting the current SerialNumber
- * and the current SignationIssuer. <br>
- * It stores back the SignationIssuer, X509Certificate and
- * X509CertificateDigest
- */
- private void loadCurrentCert()
- {
- X509Cert cert = loadCertificate(getSignationSerialNumber(), getSignationIssuer());
- if (cert != null)
- {
- // merge RDNs from file with values from certificate
- if (getSigValue(SignatureTypes.SIG_ISSUER) != null) {
- this.setSignationIssuer(prepareRFC2253Name(getSigValue(SignatureTypes.SIG_ISSUER), cert.getIssuerName()));
- } else {
- this.setSignationIssuer(cert.getIssuerName());
- }
- /*
- if (getSigValue(SignatureTypes.SIG_ISSUER) == null) {
- this.setSignationIssuer(cert.getIssuerName());
- }
- */
- setSigValue(SIG_CER, cert.getCertString());
- // setSigValue(SIG_CER_DIG, cert.getCertDigest());
- x509Cert_ = cert;
- }
- }
-
- /**
- * @return the current X509CertificateDigest value (as SHA1 digest).
- */
- public String getX509CertificateDigest()
- {
- String dig = getSigValue(SIG_CER_DIG);
- if (dig == null)
- {
- loadCurrentCert();
- byte[] cert_b64 = CodingHelper.decodeBase64(x509Cert_.getCertString());
- byte[] cert_hash = CodingHelper.buildDigest(cert_b64, "SHA");
- dig = new String(CodingHelper.encodeBase64(cert_hash));
- setSigValue(SIG_CER_DIG, dig);
- }
- return dig;
- }
-
- /**
- * @return the current X509v3 certificate string
- */
- public String getX509CertificateString()
- {
- String cert = getSigValue(SIG_CER);
- if (cert == null)
- {
- loadCurrentCert();
- cert = getSigValue(SIG_CER);
- }
- return cert;
- }
-
- /**
- * @param x509Certificate
- * The X509v3 certificate of the signature to set
- */
- public void setX509Certificate(String x509Certificate)
- {
- setSigValue(SIG_CER, x509Certificate);
- storeCertificate(getSignationSerialNumber(), getSignationIssuer(), x509Certificate);
- }
-
- public void setX509Certificate(X509Certificate cert)
- {
- try
- {
-// byte [] der = cert.getEncoded();
-// String certStr = CodingHelper.encodeBase64(der);
-// setX509Certificate(certStr);
- X509Cert knowcenterCert = X509Cert.initByX509Certificate(cert);
- setSigValue(SIG_CER, knowcenterCert.getCertString());
- storeCertificate(cert.getSerialNumber().toString(), knowcenterCert.getIssuerName(), knowcenterCert.getCertString());
- }
- catch (CertificateEncodingException e)
- {
- logger_.error(e.getMessage(), e);
- }
- }
-
- /**
- * return the 509v3 certificate of the given serialNumber and the given issuer
- * string
- *
- * @param serialNumber
- * the serialNumber which the certificates should load
- * @param issuer
- * the issuer which the certificates should load
- * @return the X509v3 certificate string
- */
- public String getX509CertificateString(String serialNumber, String issuer)
- {
- X509Cert cert = loadCertificate(serialNumber, issuer);
- if (cert != null)
- {
- return cert.getCertString();
- }
- return null;
- }
-
- public X509Cert getX509Cert(String serialNumber, String issuer)
- {
- return loadCertificate(serialNumber, issuer);
- }
-
- public X509Cert getX509Cert()
- {
- if (x509Cert_ == null)
- {
- loadCurrentCert();
- }
- return x509Cert_;
- }
-
- /**
- * Set the signation id's build by a BKU signated SignatureObject.
- *
- * @param sigIds
- * the string to store.
- */
- public void setSignationIDs(String sigIds)
- {
- if (sigIds != null)
- {
- setSigValue(SignatureTypes.SIG_ID, sigIds);
- }
- }
-
- // /**
- // * Set the signation id's build by a BKU signated SignatureObject.
- // *
- // * @param sigIds
- // * The sination id's are defined into five parts, that have the same
- // * base as prefix. Therefore the ids's are reduced by the base prefix
- // * and stored in the SignatureObject.
- // */
- // public void setSignationIDs(String[] sigIds)
- // {
- // String join = "";
- // String base = null;
- // for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
- // {
- // String id = sigIds[arr_idx];
- // if (logger_.isDebugEnabled())
- // {
- // logger_.debug("Set BKU id:" + id);
- // }
- // int id_idx = id.lastIndexOf("-");
- // if (arr_idx == 0)
- // {
- // base = id.substring(0, id_idx);
- // }
- // String cur_id = id.substring(id_idx + 1);
- // join += "-" + cur_id;
- // }
- // setSignationIDs(base + "@" + join.substring(1));
- // }
-
- // TODO hotfix
- public static String formatSigIds(Properties response_properties,
- String[] sigIds) throws SignatureException
- {
- // ids algorithm:
- String join = "";
- String base = null;
- for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
- {
- String id = sigIds[arr_idx];
- if (logger_.isDebugEnabled())
- {
- logger_.debug("Set BKU id:" + id);
- }
- int id_idx = id.lastIndexOf("-");
- if (arr_idx == 0)
- {
- base = id.substring(0, id_idx);
- }
- String cur_id = id.substring(id_idx + 1);
- join += "-" + cur_id;
- }
- // setSignationIDs(base + "@" + join.substring(1));
- String ids = base + "@" + join.substring(1);
- // :ids algorithm
-
- String productName = response_properties.getProperty("productName");
- logger_.debug("productName = " + productName);
-// if (!productName.equals("trustDeskbasic"))
- // modified by tknall
- if (!productName.startsWith("trustDeskbasic"))
- {
- final String msg = "The BKU environment " + productName + " is not trustDeskbasic and therefore the productVersion cannot be decided.";
- logger_.error(msg);
- // uncomment the following line in order to check new bkus
- throw new SignatureException(0, msg);
- }
-
- String productVersion = response_properties.getProperty("productVersion");
- logger_.debug("productVersion = " + productVersion);
- boolean new_etsi = decideNewEtsiByBKUVersion(productVersion);
- logger_.debug("verwende neue etsi properties = " + new_etsi);
-
- String etsi_prefix = "";
- if (new_etsi)
- {
- // TODO hotfix
- etsi_prefix = "etsi-bka-1.0@";
- }
-
- String final_ids = etsi_prefix + ids;
- logger_.debug("final_ids = " + final_ids);
-
- return final_ids;
- }
-
- // TODO hotfix
- public static boolean decideNewEtsiByBKUVersion(String productVersion)
- {
- boolean new_etsi = true;
- // TODO hotfix
- if (productVersion.startsWith("2.5") || productVersion.startsWith("2.4") || productVersion.startsWith("2.3") || productVersion.startsWith("2.2") || productVersion.startsWith("2.1") || productVersion.startsWith("1") || productVersion.startsWith("0"))
- {
- new_etsi = false;
- }
- return new_etsi;
- }
-
- /**
- * Checks if the current SignatureObject is siganted by MOA. It checks if the
- * current SignatureObject has a signation id value.
- *
- * @return true if no signation id value is found, false otherwise
- */
- public boolean isMOASigned()
- {
- try
- {
- PdfASID sig_kz = getKZ();
- String sig_id = getSignationIds();
- return SigKZIDHelper.isMOASigned(sig_kz, sig_id);
- //return getSignationIds() == null;
- }
- catch (InvalidIDException e)
- {
- logger_.error(e.getMessage(), e);
- return false;
- }
- }
-
- /**
- * Tells if this SignatureObject is textual.
- *
- * @return Returns true, if it is textual.
- */
- public boolean isTextual()
- {
- PdfASID kz = null;
- try
- {
- kz = getKZ();
- }
- catch (InvalidIDException e)
- {
- logger_.error(e.getMessage(), e);
- }
- return SigKZIDHelper.isTextual(kz);
- }
-
- /**
- * Tells, if this SignatureObject is binary.
- *
- * @return Returns true, if it is binary.
- */
- public boolean isBinary()
- {
- PdfASID kz = null;
- try
- {
- kz = getKZ();
- }
- catch (InvalidIDException e)
- {
- logger_.error(e.getMessage(), e);
- }
-
- return SigKZIDHelper.isBinary(kz);
- }
-
- /**
- * Takes the signation id value of the current SignatureObject and split them
- * into the corresponding id array added with the id-base.
- *
- * @return the id array
- */
- // TODO hotifx
- public String getSignationIds()
- {
- String sig_ids = getSigValue(SignatureTypes.SIG_ID);
- return sig_ids;
-
- // if (sig_ids == null || sig_ids.length() == 0)
- // {
- // return null;
- // }
- //
- // // int index = sig_ids.indexOf(PdfAS.IDS);
- // // if (index < 0)
- // // {
- // // return null;
- // // }
- // // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
- // //
- // // if (sig_ids == null || sig_ids.length() == 0)
- // // {
- // // return null;
- // // }
- //
- // String[] ids_str = sig_ids.split("@");
- // String base = ids_str[0];
- // String[] ids = ids_str[1].split("-");
- // String[] real_ids = new String[5];
- // real_ids[0] = base + "-" + ids[0];
- // real_ids[1] = "0-" + base + "-" + ids[1];
- // real_ids[2] = "0-" + base + "-" + ids[2];
- // real_ids[3] = "0-" + base + "-" + ids[3];
- // real_ids[4] = "0-" + base + "-" + ids[4];
- // if (logger_.isDebugEnabled())
- // {
- // for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
- // {
- // logger_.debug("Set BKU id:" + real_ids[id_idx]);
- // }
- // }
- // return real_ids;
- }
-
- // TODO hotfix
- public static String[] parseSigIds(String sig_ids)
- {
- if (sig_ids == null || sig_ids.length() == 0)
- {
- return null;
- }
-
- // int index = sig_ids.indexOf(PdfAS.IDS);
- // if (index < 0)
- // {
- // return null;
- // }
- // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
- //
- // if (sig_ids == null || sig_ids.length() == 0)
- // {
- // return null;
- // }
-
- String[] ids_str = sig_ids.split("@");
-
- String etsi_string = null;
- if (ids_str.length == 3)
- {
- etsi_string = ids_str[0];
- String[] rest_ids = new String[] { ids_str[1], ids_str[2] };
- ids_str = rest_ids;
- }
-
- String base = ids_str[0];
- String[] ids = ids_str[1].split("-");
- String[] real_ids = new String[6]; // the last one contains the etsi string
- real_ids[0] = base + "-" + ids[0];
- real_ids[1] = "0-" + base + "-" + ids[1];
- real_ids[2] = "0-" + base + "-" + ids[2];
- real_ids[3] = "0-" + base + "-" + ids[3];
- real_ids[4] = "0-" + base + "-" + ids[4];
- real_ids[5] = etsi_string;
-
- if (logger_.isDebugEnabled())
- {
- for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
- {
- logger_.debug("real_ids[" + id_idx + "] = " + real_ids[id_idx]);
- }
- }
-
- return real_ids;
- }
-
- /**
- * This method normalizes the issuer string to support unique issuer string
- * for equition. Used to store and find corresponting certificates.
- * Normalzing: normalizing the string using the normalizer, remove all white
- * spaces, encode as base64 and replace all "/" chars with "_".
- *
- * @param issuer
- * the issuer string to normalize
- * @return the normalized issuer string
- * @author modified by tknall
- */
- private String getIssuerFileHash(String issuer)
- {
- try
- {
- if (issuer != null)
- {
- // use explicit method for normalization
- issuer = normalizeIssuer(issuer);
- /* this block may be used to enhance normalization (tknall)
- try {
- Name issuerName = new RFC2253NameParser(issuer).parse();
- issuer = issuerName.getRFC2253String();
- } catch (RFC2253NameParserException e) {
- logger_.error(e);
- }
- */
- // added the ("UTF-8")
- issuer = CodingHelper.encodeBase64(CodingHelper.buildDigest(issuer.getBytes("UTF-8"), "sha1"));
- issuer = issuer.replaceAll("/", "_");
- }
- return issuer;
- }
- catch (UnsupportedEncodingException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Prepares issuer for further processing (e.g. calculation of certificate store location or
- * comparison with registered ldap mappings.)
- * @param issuer The issuer.
- * @return normalized issuer
- * @see #issuerNameFilter
- * @author tknall
- */
- private String normalizeIssuer(String issuer) {
- issuer = normalizer_.normalize(issuer, false);
- issuer = removeAllWhiteSpaces(issuer);
- return issuer;
- }
-
- /**
- * This method imports new certificates into the certstore path.
- */
- private void addNewCertificates()
- {
- String cert_add_path = certPath_ + CERT_ADD_DIR;
- File cert_add_dir = new File(cert_add_path);
- if (cert_add_dir.isDirectory())
- {
- File[] cert_files = cert_add_dir.listFiles();
- for (int cert_file_idx = 0; cert_file_idx < cert_files.length; cert_file_idx++)
- {
- File cert_file = cert_files[cert_file_idx];
- if (cert_file.isFile() && cert_file.canRead())
- {
- X509Cert cert = X509Cert.initByFile(cert_file);
- // System.err.println("isCert:" + cert.isX509Cert() + ":" +
- // cert_file.getAbsolutePath());
- if (cert.isX509Cert())
- {
- String issuer = cert.getIssuerName();
- String serial_number = cert.getSerialNumber();
- String iss_hash = getIssuerFileHash(issuer);
- String cert_store_path = certPath_ + iss_hash;
-
- File cert_store_dir = new File(cert_store_path);
- if (!cert_store_dir.exists())
- {
- cert_store_dir.mkdir();
- }
- if (cert_store_dir.isDirectory())
- {
- String cert_file_name = cert_store_path + FILE_SEP + serial_number + CERT_FILE_EXTENSION;
- logger_.debug("Adding cert (issuer=\"" + cert.getIssuerName() + "\", sn=\"" + cert.getSerialNumber() + "\") to certstore: \"" + cert_file_name + "\".");
- // boolean store =
- FileHelper.writeToFile(cert_file_name, cert.getCertString());
- // System.err.println("store:" + store + ":" +
- // cert_file.getAbsolutePath());
- }
- }
- boolean deleted = cert_file.delete();
- if (deleted == false)
- {
- logger_.error("couldn't delete:" + cert_file.getAbsolutePath());
- }
- }
- }
- }
- }
-
- private X509Cert loadCertificateFromCertstore(String serialNumber, String issuer) {
- String iss_hash = getIssuerFileHash(issuer);
- String cert_store_path = certPath_ + iss_hash;
- String cert_file_name = cert_store_path + FILE_SEP + serialNumber + CERT_FILE_EXTENSION;
- if (logger_.isDebugEnabled()) {
- logger_.debug("Trying to load cert (issuer=\"" + (issuer != null ? normalizeIssuer(issuer) : issuer) + "\", sn=\"" + serialNumber + "\") from certstore: \"" + cert_file_name + "\".");
- }
- return X509Cert.initByFilePath(cert_file_name);
- }
-
- /**
- * This method load a X509v3 certificate from the filesystem. The reference to
- * the stored certificate is build by the serialNumber and the issuer string.
- * The issuer string is normalized because if getting this value from a pdf
- * extraction it can be splited into more sections or necessary spaces are
- * removed. The real issuer value is stored in the certificates meta file. The
- * certficate is devided into two files: certificate.der (the binary value)
- * and the meta information used in SignatureObjects as well in
- * SignatureImages of a signed pdf-document. The storing path of the
- * certificate is build by:
- * <ol>
- * <li>normalize the issuer string</li>
- * <li>reduce all white spaces in the normalized issuer string</li>
- * <li>build a hash value of this reduced string</li>
- * <li>code this hash value as base64 value</li>
- * <li>add the base64 normalized issuer hash value to the certificate base
- * store path</li>
- * <li>add the serialNumber to the cert path</li>
- * <li>add the <code>.der</code> extension to get the certificate binary</li>
- * <li>add the <code>.txt</code> extension to get the meta information of
- * the certificate</li>
- * </ol>
- *
- * The certificate meta file is build by the base64 coded issuer string and
- * the cert digest value devided by the <code>@</code> char.
- *
- * @param serialNumber
- * the file name of the certificate .der|.txt
- * @param issuer
- * the file path value of the certificate
- * @return String array: [0]--> issuer string; [1]-->certificate binary;
- * [2]--> cert digest value
- */
- private X509Cert loadCertificate(String serialNumber, String issuer)
- {
- addNewCertificates();
- X509Cert cert = null;
- if (issuer != null && serialNumber != null)
- {
- cert = loadCertificateFromCertstore(serialNumber, issuer);
- if (cert == null) {
- logger_.debug("Certificate not found. Trying alternative normalization method.");
- try {
- Name issuerName = new RFC2253NameParser(issuer).parse();
- cert = loadCertificateFromCertstore(serialNumber, issuerName.getRFC2253String(false));
- } catch (RFC2253NameParserException e) {
- logger_.error(e.getMessage(), e);
- }
- }
-
- if (cert == null)
- {
- logger_.info("The certificate '" + issuer + "', '" + serialNumber + "' wasn't found in the local certificate store - connecting to LDAP.");
-
- // the certificate wasn't found in the local store
- // - load it from the LDAP server.
-
- byte[] cert_data = loadCertificateFromLDAP(serialNumber, issuer);
- if (cert_data == null)
- {
- logger_.info("The certificate '" + issuer + "', '" + serialNumber + "' wasn't found on the LDAP server either.");
-
- return null;
- }
-
- storeNewCertificateInLocalStore(cert_data);
-
- cert = X509Cert.initByByteArray(cert_data);
- if (cert == null)
- {
- logger_.debug("The certificate should be loaded here, but is null - something's wrong.");
- }
- }
- } else {
- logger_.warn("loadCertificate(\"" + serialNumber + "\", \"" + issuer + "\")");
- }
- return cert;
- }
-
- /**
- * This is an internal counter for added certificates.
- */
- protected static int new_cert_num = 0;
-
- /**
- * Writes the certificate data to a file and stores the file in the local
- * certificate store.
- *
- * @param cert_data
- * The binary certificate data.
- */
- public void storeNewCertificateInLocalStore(byte[] cert_data)
- {
- // write the loaded certificate to the add directory
- String cert_add_path = certPath_ + CERT_ADD_DIR;
- File cert_add_dir = new File(cert_add_path);
- if (!cert_add_dir.exists())
- {
- cert_add_dir.mkdirs();
- }
- File save_file = new File(cert_add_dir, "newcert_" + new_cert_num + ".der");
- new_cert_num++;
- try
- {
- FileOutputStream fos = new FileOutputStream(save_file);
- fos.write(cert_data);
- fos.close();
- // fixed by tknall: if serialnumber or issuername is omitted (binary signature) the
- // certificate could not be found in the certstore. The fix sets the issuername and
- // serialnumber as long the are known.
- X509Cert cert = X509Cert.initByByteArray(cert_data);
- if (cert.isX509Cert()) {
- this.setSignationSerialNumber(cert.getSerialNumber());
- this.setSignationIssuer(cert.getIssuerName());
- }
- } catch (IOException e) {
- logger_.error(e.getMessage(), e);
- return;
- }
-
- // add the new certificate to the local store
- addNewCertificates();
- }
-
- /**
- * Connects to the LDAP server to look for the certificate.
- *
- * @param serialNumber
- * The serial number String of the certificate being sought. E.g.
- * "123455676744123432".
- * @param issuer
- * The issuer String of the certificate being sought.
- *
- * @return Returns the DER certificate file as can be stored in the local
- * repository. Returns null, if the document wasn't found on the
- * server.
- * @throws ClassNotFoundException
- */
- protected byte[] loadCertificateFromLDAP(String serialNumber, String issuer) {
- // START modification by TK
- String implClassURI = System.getProperty(LDAPAPI.SYS_PROP_IMPLEMENTATION);
- LDAPAPI ldapAPIImpl;
- try {
- // note: in case of implClassURI==null the default implementation
- // at.knowcenter.wag.egov.egiz.ldap.api.LDAPAPIImpl is used
- ldapAPIImpl = LDAPAPIFactory.getInstance(issuerNameFilter).createLDAPAPI(implClassURI);
- } catch (LDAPAPIException e) {
- throw new RuntimeException(e);
- }
- return ldapAPIImpl.loadBase64CertificateFromLDAP(serialNumber, issuer);
- // STOP modification by TK
- }
-
- /**
- * This method stores a X509v3 certificate to the filesystem. The reference to
- * the stored certificate is build by the serialNumber and the issuer string.
- * The issuer string is normalized because if getting this value from a pdf
- * extraction it can be splited into more sections or necessary spaces are
- * removed. The real issuer value is stored in the certificates meta file. The
- * certficate is devided into two files: certificate.der (the binary value)
- * and the meta information used in SignatureObjects as well in
- * SignatureImages of a signed pdf-document. The storing path of the
- * certificate is build by:
- * <ol>
- * <li>normalize the issuer string</li>
- * <li>reduce all white spaces in the normalized issuer string</li>
- * <li>build a hash value of this reduced string</li>
- * <li>code this hash value as base64 value</li>
- * <li>add the base64 normalized issuer hash value to the certificate base
- * store path</li>
- * <li>add the serialNumber to the cert path</li>
- * <li>add the <code>.der</code> extension to get the certificate binary</li>
- * <li>add the <code>.txt</code> extension to get the meta information of
- * the certificate</li>
- * </ol>
- *
- * The certificate meta file is build by the base64 coded issuer string and
- * the cert digest value devided by the <code>@</code> char.
- *
- * @param serialNumber
- * the file name of the certificate .der|.txt
- * @param issuer
- * the issuer string for the file path value of the certificate and
- * for metainformation
- * @param x509Certificate
- * the x509v3 binary string
- * @param x509Digest
- * the digest value of the given x509Certificate
- * @return true the certificate is stored completely, false otherwise
- * @deprecated Use {@link #storeCertificate(String, String, String)} instead.
- */
- private boolean storeCertificate(String serialNumber, String issuer,
- String x509Certificate, String x509Digest)
- {
- return storeCertificate(serialNumber, issuer, x509Certificate);
- }
-
- /**
- * This method stores a X509v3 certificate to the filesystem. The reference to
- * the stored certificate is build by the serialNumber and the issuer string.
- * The issuer string is normalized because if getting this value from a pdf
- * extraction it can be splited into more sections or necessary spaces are
- * removed. The real issuer value is stored in the certificates meta file. The
- * certficate is devided into two files: certificate.der (the binary value)
- * and the meta information used in SignatureObjects as well in
- * SignatureImages of a signed pdf-document. The storing path of the
- * certificate is build by:
- * <ol>
- * <li>normalize the issuer string</li>
- * <li>reduce all white spaces in the normalized issuer string</li>
- * <li>build a hash value of this reduced string</li>
- * <li>code this hash value as base64 value</li>
- * <li>add the base64 normalized issuer hash value to the certificate base
- * store path</li>
- * <li>add the serialNumber to the cert path</li>
- * <li>add the <code>.der</code> extension to get the certificate binary</li>
- * <li>add the <code>.txt</code> extension to get the meta information of
- * the certificate</li>
- * </ol>
- *
- * The certificate meta file is build by the base64 coded issuer string and
- * the cert digest value devided by the <code>@</code> char.
- *
- * @param serialNumber
- * the file name of the certificate .der|.txt
- * @param issuer
- * the issuer string for the file path value of the certificate and
- * for metainformation
- * @param x509Certificate
- * the x509v3 binary string
- * @return true the certificate is stored completely, false otherwise
- */
- private boolean storeCertificate(String serialNumber, String issuer,
- String x509Certificate)
- {
- boolean store_complete = false;
- if (issuer != null && serialNumber != null)
- {
- logger_.debug("Storing certificate.");
- // String issuer_b64 = CodingHelper.encodeBase64(issuer.getBytes());
- String iss_hash = getIssuerFileHash(issuer);
- File cert_path_dir = new File(certPath_);
- if (!cert_path_dir.exists())
- {
- logger_.debug("Certstore path \"" + cert_path_dir + "\" does not exist. Creating.");
- cert_path_dir.mkdir();
- }
- String cert_store_path = certPath_ + iss_hash;
- File cert_store_dir = new File(cert_store_path);
- if (!cert_store_dir.exists())
- {
- logger_.debug("Certstore dir \"" + cert_store_dir + "\" does not exist. Creating.");
- cert_store_dir.mkdir();
- }
- if (cert_store_dir.isDirectory())
- {
- String cert_file_name = cert_store_path + FILE_SEP + serialNumber + CERT_FILE_EXTENSION;
- if (logger_.isInfoEnabled())
- {
- logger_.debug("store certificate:" + cert_file_name);
- }
- boolean store_cert_file = FileHelper.writeToFile(cert_file_name, x509Certificate);
- store_complete = store_cert_file;// && store_cert_meta;
- } else {
- logger_.warn("Certstore dir \"" + cert_store_dir + "\" is not a directory. Skipping storage.");
- }
- }
- return store_complete;
- }
-
- /**
- * @return Returns the AbstractTable.
- * @see at.knowcenter.wag.egov.egiz.table.Table
- */
- public Table getAbstractTable()
- {
- if (sigTable_ == null)
- {
- sigTable_ = createSigTable(SignatureTypes.MAIN_TABLE);
- }
- return sigTable_;
- }
-
- /**
- * This method read the style definitions from the settings file.
- *
- * @param styleKey
- * the key to read the style definitions
- * @return the defined style informations
- * @see at.knowcenter.wag.egov.egiz.table.Style
- */
- private Style readStyle(String styleKey)
- {
- ArrayList styles = settings_.getKeys(styleKey);
- Style style = new Style();
- for (int style_idx = 0; style_idx < styles.size(); style_idx++)
- {
- String style_id = (String) styles.get(style_idx);
- String style_val = settings_.getSetting(styleKey + "." + style_id, null);
- style.setStyle(style_id, style_val);
- }
- return style;
- }
-
- /**
- * This method creates an abstract signature table object. It takes all keys
- * and values set by the signature object to create the corresponding abstract
- * table object. The table definition is read from the settings file.
- *
- * @param tableKey
- * is the name of the table definition in the settings file
- * @return a new abstract signature table
- * @see at.knowcenter.wag.egov.egiz.table.Style
- * @see at.knowcenter.wag.egov.egiz.table.Table
- * @see at.knowcenter.wag.egov.egiz.table.Entry
- */
- private Table createSigTable(String tableKey)
- {
- String table_key_prefix = SignatureTypes.SIG_OBJ + getSignationType() + "." + SignatureTypes.TABLE;
- String table_key = table_key_prefix + tableKey;
- // String caption_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
- // ".key.";
- // String value_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
- // ".value.";
- // ArrayList table_def_keys = settings_.getKeys(table_key);
- Vector table_def_keys = settings_.getSettingKeys(table_key);
- if (table_def_keys == null)
- {
- return null;
- }
- Table sig_table = new Table(tableKey);
- boolean found_style = false;
- for (int table_key_idx = table_def_keys.size() - 1; table_key_idx >= 0; table_key_idx--)
- {
- String table_def = (String) table_def_keys.get(table_key_idx);
- int dot_idx = (table_def.indexOf(".") > 0 ? table_def.indexOf(".") : table_def.length());
- table_def = table_def.substring(0, dot_idx);
- String table_def_keys_prefix = table_key + "." + table_def;
- String table_def_string = settings_.getSetting(table_def_keys_prefix, null);
- if (table_def.matches("\\D*"))
- {
- // if the table key is not a number (row number index)
- if (SignatureTypes.COLS_WITH.equals(table_def))
- {
- String[] cols_s = table_def_string.split(" ");
- float[] cols_f = new float[cols_s.length];
- for (int i = 0; i < cols_s.length; i++)
- {
- cols_f[i] = Float.parseFloat(cols_s[i]);
- }
- sig_table.setColsRelativeWith(cols_f);
- }
- if (SignatureTypes.STYLE.equals(table_def) && !found_style)
- {
- Style style = readStyle(table_def_keys_prefix);
- sig_table.setStyle(style);
- found_style = true;
- }
- continue;
- }
- if (table_def_string != null)
- {
- // analyse the row definition
- String[] elems = table_def_string.split("\\|");
- ArrayList row = new ArrayList();
- for (int elem_idx = 0; elem_idx < elems.length; elem_idx++)
- {
- String elem = elems[elem_idx];
- String[] key_type = elem.split("-");
- if (key_type.length < 2)
- {
- return null;
- }
- String key = key_type[0];
- String type = key_type[1];
- if (SignatureTypes.TYPE_TABLE.equals(key))
- {
- // add a table entry
- Table table = createSigTable(type);
- if (table != null)
- {
- Entry entry = new Entry(Entry.TYPE_TABLE, table, key);
- row.add(entry);
- }
- }
- if (SignatureTypes.TYPE_IMAGE.equals(type))
- {
- // add an image entry
- String value = getSigValue(key);
- if (value != null)
- {
- Entry entry = new Entry(Entry.TYPE_IMAGE, value, key);
- entry.setStyle(defaultImageStyle_);
- row.add(entry);
- }
- }
- if (SignatureTypes.TYPE_VALUE.equals(type))
- {
- // add a single value entry
- String value = getSigValue(key);
- Entry entry = new Entry(Entry.TYPE_VALUE, value, key);
- if (entry != null)
- {
- entry.setColSpan(2);
- entry.setStyle(defaultValueStyle_);
- row.add(entry);
- }
- }
- if ((SignatureTypes.TYPE_VALUE + SignatureTypes.TYPE_CAPTION).equals(type) || (SignatureTypes.TYPE_CAPTION + SignatureTypes.TYPE_VALUE).equals(type))
- {
- // add a caption value pair
- String caption = getSigCaption(key);
- String value = getSigValue(key);
- if (value != null)
- {
- Entry c_entry = new Entry(Entry.TYPE_CAPTION, caption, key);
- c_entry.setNoWrap(true); // dferbas fix bug #331
- c_entry.setStyle(defaultCaptionStyle_);
-
- Entry v_entry = new Entry(Entry.TYPE_VALUE, value, key);
- v_entry.setStyle(defaultValueStyle_);
- if (c_entry != null && v_entry != null)
- {
- row.add(c_entry);
- row.add(v_entry);
- }
- }
- }
- }
- sig_table.addRow(table_def, row);
- }
- }
-
- return sig_table;
- }
-
- /**
- * This method inits the signature object by the given type. It loads the
- * configured values and captions from the config.properties file.
- */
- public void initByType() throws SignatureTypesException
- {
- if (sigType_ == null)
- {
- sigType_ = getDefaultSigType();
- }
- SignatureTypes sig_types = SignatureTypes.getInstance();
- signatureDefinition_ = sig_types.getSignatureTypeDefinition(sigType_);
- if (signatureDefinition_ == null)
- {
- final String msg = "The SignatureObject's sigType '" + sigType_ + "' wasn't found in the configuration file's specified signature profiles. This usually happens if the sig_obj.type.default object has been turned off or is misspelled.";
- logger_.error(msg);
- throw new SignatureTypesException(msg);
- }
- Map key_cap_map = signatureDefinition_.getKeyCaptionMap();
- if (key_cap_map != null)
- {
- Iterator key_cap = key_cap_map.entrySet().iterator();
- while (key_cap.hasNext())
- {
- Map.Entry entry = (Map.Entry) key_cap.next();
- String key = (String) entry.getKey();
- String caption = (String) entry.getValue();
- SignatureEntry sig_entry = null;
- if (sigEntries_.containsKey(key))
- {
- sig_entry = (SignatureEntry) sigEntries_.get(key);
- }
- else
- {
- sig_entry = new SignatureEntry(key);
- sigEntries_.put(key, sig_entry);
- }
- sig_entry.setCaption(caption);
- }
- }
-
- Map key_val_map = signatureDefinition_.getKeyValueMap();
- if (key_val_map != null)
- {
- Set key_val_set = key_val_map.entrySet();
- Iterator key_val = key_val_set.iterator();
- while (key_val.hasNext())
- {
- Map.Entry entry = (Map.Entry) key_val.next();
- String key = (String) entry.getKey();
- String value = (String) entry.getValue();
- if (SignatureTypes.SIG_NORM.equals(key))
- {
- try
- {
- normalizer_.setVersion(value);
- }
- catch (NormalizeException e)
- {
- throw new SignatureTypesException(e);
- }
- }
- // value = new String(CodingHelper.encodeUTF8(value));
- // if (logger_.isDebugEnabled())
- // {
- // logger_.debug("key:" + key + " value:" + value);
- // }
- setSigValue(key, value);
- }
- }
- }
-
- /**
- * This method returns a signature entry object.
- *
- * @param key
- * the corresponding key
- * @return the signature entry object of the given key, null if the key does
- * not exist
- */
- public SignatureEntry getSigEntry(String key)
- {
- return (SignatureEntry) sigEntries_.get(key);
- }
-
- /**
- * This method is a helper function to remove all white spaces from a text.
- *
- * @param text
- * the white spaces should remove from
- * @return a text without white spaces
- */
- private static String removeAllWhiteSpaces(String text)
- {
- return text.replaceAll("\\s", "");
- }
-
- public SignatureTypeDefinition getSignatureTypeDefinition()
- {
- return this.signatureDefinition_;
- }
-
- /**
- *
- * @param placeholder
- * @return Returns the list of SignatureFieldDefinitions that's values in the
- * SignatureObject have been filled out with placeholders.
- */
- public List fillValues(final char placeholder, boolean has_SIG_ID, boolean baikEnabled)
- {
- List variable_fields = new ArrayList();
-
- List field_definitions = this.signatureDefinition_.getFieldDefinitions();
- Iterator it = field_definitions.iterator();
- while (it.hasNext())
- {
- SignatureFieldDefinition sfd = (SignatureFieldDefinition) it.next();
- String value_string = null;
- if (sfd.placeholder_length > 0)
- {
- if (sfd.field_name.equals(SignatureTypes.SIG_ID) && has_SIG_ID == false)
- {
- setValueBruteForce(SignatureTypes.SIG_ID, null);
- continue;
- }
-
- if (sfd.field_name.equals(SignatureTypes.SIG_ALG) && !baikEnabled) {
- setValueBruteForce(SignatureTypes.SIG_ID, null);
- continue;
- }
-
- char[] placeholder_chars = new char[sfd.placeholder_length];
- for (int i = 0; i < placeholder_chars.length; i++)
- {
- placeholder_chars[i] = placeholder;
- }
- value_string = new String(placeholder_chars);
-
- variable_fields.add(sfd);
-
- setSigValue(sfd.field_name, value_string, true);
- }
- }
-
- return variable_fields;
- }
-
- /**
- * Returns the raw signature response XML string as set by the signing
- * Connector.
- *
- * @return Returns the XML response String.
- */
- public String getRawSignatureResponse()
- {
- return this.raw_signature_response;
- }
-
- /**
- * Sets the raw signature response XML string.
- *
- * <p>
- * This should be used by the Connector to pass the response String to the
- * signer.
- * </p>
- *
- * @param raw_response_string
- * The new raw signature response string.
- */
- public void setRawSignatureResponse(String raw_response_string)
- {
- this.raw_signature_response = raw_response_string;
- }
-
-
-
- /**
- * get timestamp if available
- * @return
- */
- public String getTimeStamp() {
- return this.timeStamp;
- }
-
- /**
- * set timestamp
- * @param timeStamp
- */
- public void setTimeStamp(String timeStamp) {
- this.timeStamp = timeStamp;
- }
+ /**
+ * @return Returns the SignationIssuer.
+ */
+ public String getSignationIssuer() {
+ String issuer = getSigValue(SignatureTypes.SIG_ISSUER);
+ X509Cert cert = loadCertificate(getSigValue(SignatureTypes.SIG_NUMBER),
+ issuer);
+ if (cert != null) {
+ // merge RDNs from file with values from certificate
+ if (getSigValue(SignatureTypes.SIG_ISSUER) != null) {
+ this.setSignationIssuer(prepareRFC2253Name(
+ getSigValue(SignatureTypes.SIG_ISSUER),
+ cert.getIssuerName()));
+ } else {
+ this.setSignationIssuer(cert.getIssuerName());
+ }
+ /*
+ * if (getSigValue(SignatureTypes.SIG_ISSUER) == null) {
+ * this.setSignationIssuer(cert.getIssuerName()); }
+ */
+ setSigValue(SIG_CER, cert.getCertString());
+ // setSigValue(SIG_CER_DIG, cert.getCertDigest());
+ x509Cert_ = cert;
+ }
+ issuer = getSigValue(SignatureTypes.SIG_ISSUER);
+ return issuer;
+ }
-/**
- * The toString method, used for tests or debugging.
- */
- public String toString()
- {
- String strg = "";
- Iterator it = sigEntries_.values().iterator();
- while (it.hasNext())
- {
- SignatureEntry sig_entry = (SignatureEntry) it.next();
- String key = sig_entry.getKey();
- String caption = sig_entry.getCaption();
- String value = sig_entry.getValue();
- strg += key + "=" + caption + ":" + value + "\n";
- }
- strg += "Signation Type:" + getSignationType() + "\n";
- return strg;
- }
-
- public Map getSigEntries() {
- return sigEntries_;
- }
+ /**
+ * @param sigIssuer
+ * The SignationIssuer to set.
+ */
+ public void setSignationIssuer(String sigIssuer) {
+ setSigValue(SignatureTypes.SIG_ISSUER, sigIssuer);
+ }
+
+ /**
+ * @return Returns the SignationValue.
+ */
+ public String getSignationValue() {
+ return getSigValue(SignatureTypes.SIG_VALUE);
+ }
+
+ /**
+ * @param sigValue
+ * The SignationValue to set.
+ */
+ public void setSignationValue(String sigValue) {
+ setSigValue(SignatureTypes.SIG_VALUE, sigValue);
+ }
+
+ /**
+ * @return the reference to the signature label
+ */
+ public String getOfficialSeal() {
+ return getSigValue(SignatureTypes.SIG_LABEL);
+ }
+
+ /**
+ * @param serialNumber
+ * The serial number of the signature to set
+ */
+ public void setSignationSerialNumber(String serialNumber) {
+ setSigValue(SignatureTypes.SIG_NUMBER, serialNumber);
+ }
+
+ /**
+ * @return sigNumber the serial number of the signature
+ */
+ public String getSignationSerialNumber() {
+ return getSigValue(SignatureTypes.SIG_NUMBER);
+ }
+
+ // dferbas baik
+
+ /**
+ * signature algorithm if embedded
+ *
+ * @param sigAlg
+ */
+ public void setSigAlg(String sigAlg) {
+ setSigValue(SignatureTypes.SIG_ALG, sigAlg);
+ }
+
+ /**
+ * signature algorithm if embedded
+ *
+ * @return
+ */
+ public String getSigAlg() {
+ return getSigValue(SignatureTypes.SIG_ALG);
+ }
+
+ /**
+ * @param certDigest
+ * set the digest value for the X509Certificate
+ */
+ public void setX509CertificateDigest(String certDigest) {
+ setSigValue(SIG_CER_DIG, certDigest);
+ }
+
+ /**
+ * This method load the current certificate getting the current SerialNumber
+ * and the current SignationIssuer. <br>
+ * It stores back the SignationIssuer, X509Certificate and
+ * X509CertificateDigest
+ */
+ private void loadCurrentCert() {
+ X509Cert cert = loadCertificate(getSignationSerialNumber(),
+ getSignationIssuer());
+ if (cert != null) {
+ // merge RDNs from file with values from certificate
+ if (getSigValue(SignatureTypes.SIG_ISSUER) != null) {
+ this.setSignationIssuer(prepareRFC2253Name(
+ getSigValue(SignatureTypes.SIG_ISSUER),
+ cert.getIssuerName()));
+ } else {
+ this.setSignationIssuer(cert.getIssuerName());
+ }
+ /*
+ * if (getSigValue(SignatureTypes.SIG_ISSUER) == null) {
+ * this.setSignationIssuer(cert.getIssuerName()); }
+ */
+ setSigValue(SIG_CER, cert.getCertString());
+ // setSigValue(SIG_CER_DIG, cert.getCertDigest());
+ x509Cert_ = cert;
+ }
+ }
+
+ /**
+ * @return the current X509CertificateDigest value (as SHA1 digest).
+ */
+ public String getX509CertificateDigest() {
+ String dig = getSigValue(SIG_CER_DIG);
+ if (dig == null) {
+ loadCurrentCert();
+ byte[] cert_b64 = CodingHelper.decodeBase64(x509Cert_
+ .getCertString());
+ byte[] cert_hash = CodingHelper.buildDigest(cert_b64, "SHA");
+ dig = new String(CodingHelper.encodeBase64(cert_hash));
+ setSigValue(SIG_CER_DIG, dig);
+ }
+ return dig;
+ }
+
+ /**
+ * @return the current X509v3 certificate string
+ */
+ public String getX509CertificateString() {
+ String cert = getSigValue(SIG_CER);
+ if (cert == null) {
+ loadCurrentCert();
+ cert = getSigValue(SIG_CER);
+ }
+ return cert;
+ }
+
+ /**
+ * @param x509Certificate
+ * The X509v3 certificate of the signature to set
+ */
+ public void setX509Certificate(String x509Certificate) {
+ setSigValue(SIG_CER, x509Certificate);
+ storeCertificate(getSignationSerialNumber(), getSignationIssuer(),
+ x509Certificate);
+ }
+
+ public void setX509Certificate(X509Certificate cert) {
+ try {
+ // byte [] der = cert.getEncoded();
+ // String certStr = CodingHelper.encodeBase64(der);
+ // setX509Certificate(certStr);
+ X509Cert knowcenterCert = X509Cert.initByX509Certificate(cert);
+ setSigValue(SIG_CER, knowcenterCert.getCertString());
+ storeCertificate(cert.getSerialNumber().toString(),
+ knowcenterCert.getIssuerName(),
+ knowcenterCert.getCertString());
+ } catch (CertificateEncodingException e) {
+ logger_.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * return the 509v3 certificate of the given serialNumber and the given
+ * issuer string
+ *
+ * @param serialNumber
+ * the serialNumber which the certificates should load
+ * @param issuer
+ * the issuer which the certificates should load
+ * @return the X509v3 certificate string
+ */
+ public String getX509CertificateString(String serialNumber, String issuer) {
+ X509Cert cert = loadCertificate(serialNumber, issuer);
+ if (cert != null) {
+ return cert.getCertString();
+ }
+ return null;
+ }
+
+ public X509Cert getX509Cert(String serialNumber, String issuer) {
+ return loadCertificate(serialNumber, issuer);
+ }
+
+ public X509Cert getX509Cert() {
+ if (x509Cert_ == null) {
+ loadCurrentCert();
+ }
+ return x509Cert_;
+ }
+
+ /**
+ * Set the signation id's build by a BKU signated SignatureObject.
+ *
+ * @param sigIds
+ * the string to store.
+ */
+ public void setSignationIDs(String sigIds) {
+ if (sigIds != null) {
+ setSigValue(SignatureTypes.SIG_ID, sigIds);
+ }
+ }
+
+ // /**
+ // * Set the signation id's build by a BKU signated SignatureObject.
+ // *
+ // * @param sigIds
+ // * The sination id's are defined into five parts, that have the same
+ // * base as prefix. Therefore the ids's are reduced by the base prefix
+ // * and stored in the SignatureObject.
+ // */
+ // public void setSignationIDs(String[] sigIds)
+ // {
+ // String join = "";
+ // String base = null;
+ // for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
+ // {
+ // String id = sigIds[arr_idx];
+ // if (logger_.isDebugEnabled())
+ // {
+ // logger_.debug("Set BKU id:" + id);
+ // }
+ // int id_idx = id.lastIndexOf("-");
+ // if (arr_idx == 0)
+ // {
+ // base = id.substring(0, id_idx);
+ // }
+ // String cur_id = id.substring(id_idx + 1);
+ // join += "-" + cur_id;
+ // }
+ // setSignationIDs(base + "@" + join.substring(1));
+ // }
+
+ // TODO hotfix
+ public static String formatSigIds(Properties response_properties,
+ String[] sigIds) throws SignatureException {
+ // ids algorithm:
+ String join = "";
+ String base = null;
+ for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++) {
+ String id = sigIds[arr_idx];
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Set BKU id:" + id);
+ }
+ int id_idx = id.lastIndexOf("-");
+ if (arr_idx == 0) {
+ base = id.substring(0, id_idx);
+ }
+ String cur_id = id.substring(id_idx + 1);
+ join += "-" + cur_id;
+ }
+ // setSignationIDs(base + "@" + join.substring(1));
+ String ids = base + "@" + join.substring(1);
+ // :ids algorithm
+
+ String productName = response_properties.getProperty("productName");
+ logger_.debug("productName = " + productName);
+ // if (!productName.equals("trustDeskbasic"))
+ // modified by tknall
+ if (!productName.startsWith("trustDeskbasic")) {
+ final String msg = "The BKU environment "
+ + productName
+ + " is not trustDeskbasic and therefore the productVersion cannot be decided.";
+ logger_.error(msg);
+ // uncomment the following line in order to check new bkus
+ throw new SignatureException(0, msg);
+ }
+
+ String productVersion = response_properties
+ .getProperty("productVersion");
+ logger_.debug("productVersion = " + productVersion);
+ boolean new_etsi = decideNewEtsiByBKUVersion(productVersion);
+ logger_.debug("verwende neue etsi properties = " + new_etsi);
+
+ String etsi_prefix = "";
+ if (new_etsi) {
+ // TODO hotfix
+ etsi_prefix = "etsi-bka-1.0@";
+ }
+
+ String final_ids = etsi_prefix + ids;
+ logger_.debug("final_ids = " + final_ids);
+
+ return final_ids;
+ }
+
+ // TODO hotfix
+ public static boolean decideNewEtsiByBKUVersion(String productVersion) {
+ boolean new_etsi = true;
+ // TODO hotfix
+ if (productVersion.startsWith("2.5")
+ || productVersion.startsWith("2.4")
+ || productVersion.startsWith("2.3")
+ || productVersion.startsWith("2.2")
+ || productVersion.startsWith("2.1")
+ || productVersion.startsWith("1")
+ || productVersion.startsWith("0")) {
+ new_etsi = false;
+ }
+ return new_etsi;
+ }
+
+ /**
+ * Checks if the current SignatureObject is siganted by MOA. It checks if
+ * the current SignatureObject has a signation id value.
+ *
+ * @return true if no signation id value is found, false otherwise
+ */
+ public boolean isMOASigned() {
+ try {
+ PdfASID sig_kz = getKZ();
+ String sig_id = getSignationIds();
+ return SigKZIDHelper.isMOASigned(sig_kz, sig_id);
+ // return getSignationIds() == null;
+ } catch (InvalidIDException e) {
+ logger_.error(e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * Tells if this SignatureObject is textual.
+ *
+ * @return Returns true, if it is textual.
+ */
+ public boolean isTextual() {
+ PdfASID kz = null;
+ try {
+ kz = getKZ();
+ } catch (InvalidIDException e) {
+ logger_.error(e.getMessage(), e);
+ }
+ return SigKZIDHelper.isTextual(kz);
+ }
+
+ /**
+ * Tells, if this SignatureObject is binary.
+ *
+ * @return Returns true, if it is binary.
+ */
+ public boolean isBinary() {
+ PdfASID kz = null;
+ try {
+ kz = getKZ();
+ } catch (InvalidIDException e) {
+ logger_.error(e.getMessage(), e);
+ }
+
+ return SigKZIDHelper.isBinary(kz);
+ }
+
+ /**
+ * Takes the signation id value of the current SignatureObject and split
+ * them into the corresponding id array added with the id-base.
+ *
+ * @return the id array
+ */
+ // TODO hotifx
+ public String getSignationIds() {
+ String sig_ids = getSigValue(SignatureTypes.SIG_ID);
+ return sig_ids;
+
+ // if (sig_ids == null || sig_ids.length() == 0)
+ // {
+ // return null;
+ // }
+ //
+ // // int index = sig_ids.indexOf(PdfAS.IDS);
+ // // if (index < 0)
+ // // {
+ // // return null;
+ // // }
+ // // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
+ // //
+ // // if (sig_ids == null || sig_ids.length() == 0)
+ // // {
+ // // return null;
+ // // }
+ //
+ // String[] ids_str = sig_ids.split("@");
+ // String base = ids_str[0];
+ // String[] ids = ids_str[1].split("-");
+ // String[] real_ids = new String[5];
+ // real_ids[0] = base + "-" + ids[0];
+ // real_ids[1] = "0-" + base + "-" + ids[1];
+ // real_ids[2] = "0-" + base + "-" + ids[2];
+ // real_ids[3] = "0-" + base + "-" + ids[3];
+ // real_ids[4] = "0-" + base + "-" + ids[4];
+ // if (logger_.isDebugEnabled())
+ // {
+ // for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
+ // {
+ // logger_.debug("Set BKU id:" + real_ids[id_idx]);
+ // }
+ // }
+ // return real_ids;
+ }
+
+ // TODO hotfix
+ public static String[] parseSigIds(String sig_ids) {
+ if (sig_ids == null || sig_ids.length() == 0) {
+ return null;
+ }
+
+ // int index = sig_ids.indexOf(PdfAS.IDS);
+ // if (index < 0)
+ // {
+ // return null;
+ // }
+ // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
+ //
+ // if (sig_ids == null || sig_ids.length() == 0)
+ // {
+ // return null;
+ // }
+
+ String[] ids_str = sig_ids.split("@");
+
+ String etsi_string = null;
+ if (ids_str.length == 3) {
+ etsi_string = ids_str[0];
+ String[] rest_ids = new String[] { ids_str[1], ids_str[2] };
+ ids_str = rest_ids;
+ }
+
+ String base = ids_str[0];
+ String[] ids = ids_str[1].split("-");
+ String[] real_ids = new String[6]; // the last one contains the etsi
+ // string
+ real_ids[0] = base + "-" + ids[0];
+ real_ids[1] = "0-" + base + "-" + ids[1];
+ real_ids[2] = "0-" + base + "-" + ids[2];
+ real_ids[3] = "0-" + base + "-" + ids[3];
+ real_ids[4] = "0-" + base + "-" + ids[4];
+ real_ids[5] = etsi_string;
+
+ if (logger_.isDebugEnabled()) {
+ for (int id_idx = 0; id_idx < real_ids.length; id_idx++) {
+ logger_.debug("real_ids[" + id_idx + "] = " + real_ids[id_idx]);
+ }
+ }
+
+ return real_ids;
+ }
+
+ /**
+ * This method normalizes the issuer string to support unique issuer string
+ * for equition. Used to store and find corresponting certificates.
+ * Normalzing: normalizing the string using the normalizer, remove all white
+ * spaces, encode as base64 and replace all "/" chars with "_".
+ *
+ * @param issuer
+ * the issuer string to normalize
+ * @return the normalized issuer string
+ * @author modified by tknall
+ */
+ private String getIssuerFileHash(String issuer) {
+ try {
+ if (issuer != null) {
+ // use explicit method for normalization
+ issuer = normalizeIssuer(issuer);
+ /*
+ * this block may be used to enhance normalization (tknall) try
+ * { Name issuerName = new RFC2253NameParser(issuer).parse();
+ * issuer = issuerName.getRFC2253String(); } catch
+ * (RFC2253NameParserException e) { logger_.error(e); }
+ */
+ // added the ("UTF-8")
+ issuer = CodingHelper.encodeBase64(CodingHelper.buildDigest(
+ issuer.getBytes("UTF-8"), "sha1"));
+ issuer = issuer.replaceAll("/", "_");
+ }
+ return issuer;
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Prepares issuer for further processing (e.g. calculation of certificate
+ * store location or comparison with registered ldap mappings.)
+ *
+ * @param issuer
+ * The issuer.
+ * @return normalized issuer
+ * @see #issuerNameFilter
+ * @author tknall
+ */
+ private String normalizeIssuer(String issuer) {
+ issuer = normalizer_.normalize(issuer, false);
+ issuer = removeAllWhiteSpaces(issuer);
+ return issuer;
+ }
+
+ /**
+ * This method imports new certificates into the certstore path.
+ */
+ private void addNewCertificates() {
+ synchronized (adding_mutex) {
+ String cert_add_path = certPath_ + CERT_ADD_DIR;
+ File cert_add_dir = new File(cert_add_path);
+ if (cert_add_dir.isDirectory()) {
+ File[] cert_files = cert_add_dir.listFiles();
+ for (int cert_file_idx = 0; cert_file_idx < cert_files.length; cert_file_idx++) {
+ File cert_file = cert_files[cert_file_idx];
+ if (cert_file.isFile() && cert_file.canRead()) {
+ X509Cert cert = X509Cert.initByFile(cert_file);
+ // System.err.println("isCert:" + cert.isX509Cert() +
+ // ":" +
+ // cert_file.getAbsolutePath());
+ if (cert.isX509Cert()) {
+ String issuer = cert.getIssuerName();
+ String serial_number = cert.getSerialNumber();
+ String iss_hash = getIssuerFileHash(issuer);
+ String cert_store_path = certPath_ + iss_hash;
+
+ File cert_store_dir = new File(cert_store_path);
+ if (!cert_store_dir.exists()) {
+ cert_store_dir.mkdir();
+ }
+ if (cert_store_dir.isDirectory()) {
+ String cert_file_name = cert_store_path
+ + FILE_SEP + serial_number
+ + CERT_FILE_EXTENSION;
+ File cert_file_name_file = new File(
+ cert_file_name);
+
+ logger_.debug("Adding cert (issuer=\""
+ + cert.getIssuerName() + "\", sn=\""
+ + cert.getSerialNumber()
+ + "\") to certstore: \""
+ + cert_file_name + "\".");
+
+ // boolean store =
+ FileHelper.writeToFile(cert_file_name,
+ cert.getCertString());
+ // System.err.println("store:" + store + ":" +
+ // cert_file.getAbsolutePath());
+ }
+ }
+ boolean deleted = cert_file.delete();
+ if (deleted == false) {
+ logger_.error("couldn't delete:"
+ + cert_file.getAbsolutePath());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private X509Cert loadCertificateFromCertstore(String serialNumber,
+ String issuer) {
+ synchronized (adding_mutex) {
+ String iss_hash = getIssuerFileHash(issuer);
+ String cert_store_path = certPath_ + iss_hash;
+ String cert_file_name = cert_store_path + FILE_SEP + serialNumber
+ + CERT_FILE_EXTENSION;
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Trying to load cert (issuer=\""
+ + (issuer != null ? normalizeIssuer(issuer) : issuer)
+ + "\", sn=\"" + serialNumber + "\") from certstore: \""
+ + cert_file_name + "\".");
+ }
+ return X509Cert.initByFilePath(cert_file_name);
+ }
+ }
+
+ /**
+ * This method load a X509v3 certificate from the filesystem. The reference
+ * to the stored certificate is build by the serialNumber and the issuer
+ * string. The issuer string is normalized because if getting this value
+ * from a pdf extraction it can be splited into more sections or necessary
+ * spaces are removed. The real issuer value is stored in the certificates
+ * meta file. The certficate is devided into two files: certificate.der (the
+ * binary value) and the meta information used in SignatureObjects as well
+ * in SignatureImages of a signed pdf-document. The storing path of the
+ * certificate is build by:
+ * <ol>
+ * <li>normalize the issuer string</li>
+ * <li>reduce all white spaces in the normalized issuer string</li>
+ * <li>build a hash value of this reduced string</li>
+ * <li>code this hash value as base64 value</li>
+ * <li>add the base64 normalized issuer hash value to the certificate base
+ * store path</li>
+ * <li>add the serialNumber to the cert path</li>
+ * <li>add the <code>.der</code> extension to get the certificate binary</li>
+ * <li>add the <code>.txt</code> extension to get the meta information of
+ * the certificate</li>
+ * </ol>
+ *
+ * The certificate meta file is build by the base64 coded issuer string and
+ * the cert digest value devided by the <code>@</code> char.
+ *
+ * @param serialNumber
+ * the file name of the certificate .der|.txt
+ * @param issuer
+ * the file path value of the certificate
+ * @return String array: [0]--> issuer string; [1]-->certificate binary;
+ * [2]--> cert digest value
+ */
+ private X509Cert loadCertificate(String serialNumber, String issuer) {
+ synchronized (adding_mutex) {
+ addNewCertificates();
+ X509Cert cert = null;
+ if (issuer != null && serialNumber != null) {
+ cert = loadCertificateFromCertstore(serialNumber, issuer);
+ if (cert == null) {
+ logger_.debug("Certificate not found. Trying alternative normalization method.");
+ try {
+ Name issuerName = new RFC2253NameParser(issuer).parse();
+ cert = loadCertificateFromCertstore(serialNumber,
+ issuerName.getRFC2253String(false));
+ } catch (RFC2253NameParserException e) {
+ logger_.error(e.getMessage(), e);
+ }
+ }
+
+ if (cert == null) {
+ logger_.info("The certificate '"
+ + issuer
+ + "', '"
+ + serialNumber
+ + "' wasn't found in the local certificate store - connecting to LDAP.");
+
+ // the certificate wasn't found in the local store
+ // - load it from the LDAP server.
+
+ byte[] cert_data = loadCertificateFromLDAP(serialNumber,
+ issuer);
+ if (cert_data == null) {
+ logger_.info("The certificate '" + issuer + "', '"
+ + serialNumber
+ + "' wasn't found on the LDAP server either.");
+
+ return null;
+ }
+
+ storeNewCertificateInLocalStore(cert_data);
+
+ cert = X509Cert.initByByteArray(cert_data);
+ if (cert == null) {
+ logger_.debug("The certificate should be loaded here, but is null - something's wrong.");
+ }
+ }
+ } else {
+ logger_.warn("loadCertificate(\"" + serialNumber + "\", \""
+ + issuer + "\")");
+ }
+ return cert;
+ }
+ }
+
+ /**
+ * This is an internal counter for added certificates.
+ */
+ protected static int new_cert_num = 0;
+
+ /**
+ * Writes the certificate data to a file and stores the file in the local
+ * certificate store.
+ *
+ * @param cert_data
+ * The binary certificate data.
+ */
+ public void storeNewCertificateInLocalStore(byte[] cert_data) {
+ synchronized (adding_mutex) {
+ // write the loaded certificate to the add directory
+ String cert_add_path = certPath_ + CERT_ADD_DIR;
+ File cert_add_dir = new File(cert_add_path);
+ if (!cert_add_dir.exists()) {
+ cert_add_dir.mkdirs();
+ }
+ File save_file = new File(cert_add_dir, "newcert_" + new_cert_num
+ + ".der");
+ new_cert_num++;
+ try {
+ FileOutputStream fos = new FileOutputStream(save_file);
+ fos.write(cert_data);
+ fos.close();
+ // fixed by tknall: if serialnumber or issuername is omitted
+ // (binary
+ // signature) the
+ // certificate could not be found in the certstore. The fix sets
+ // the
+ // issuername and
+ // serialnumber as long the are known.
+ X509Cert cert = X509Cert.initByByteArray(cert_data);
+ if (cert.isX509Cert()) {
+ this.setSignationSerialNumber(cert.getSerialNumber());
+ this.setSignationIssuer(cert.getIssuerName());
+ }
+ } catch (IOException e) {
+ logger_.error(e.getMessage(), e);
+ return;
+ }
+
+ // add the new certificate to the local store
+ addNewCertificates();
+ }
+ }
+
+ /**
+ * Connects to the LDAP server to look for the certificate.
+ *
+ * @param serialNumber
+ * The serial number String of the certificate being sought. E.g.
+ * "123455676744123432".
+ * @param issuer
+ * The issuer String of the certificate being sought.
+ *
+ * @return Returns the DER certificate file as can be stored in the local
+ * repository. Returns null, if the document wasn't found on the
+ * server.
+ * @throws ClassNotFoundException
+ */
+ protected byte[] loadCertificateFromLDAP(String serialNumber, String issuer) {
+ // START modification by TK
+ String implClassURI = System
+ .getProperty(LDAPAPI.SYS_PROP_IMPLEMENTATION);
+ LDAPAPI ldapAPIImpl;
+ try {
+ // note: in case of implClassURI==null the default implementation
+ // at.knowcenter.wag.egov.egiz.ldap.api.LDAPAPIImpl is used
+ ldapAPIImpl = LDAPAPIFactory.getInstance(issuerNameFilter)
+ .createLDAPAPI(implClassURI);
+ } catch (LDAPAPIException e) {
+ throw new RuntimeException(e);
+ }
+ return ldapAPIImpl.loadBase64CertificateFromLDAP(serialNumber, issuer);
+ // STOP modification by TK
+ }
+
+ /**
+ * This method stores a X509v3 certificate to the filesystem. The reference
+ * to the stored certificate is build by the serialNumber and the issuer
+ * string. The issuer string is normalized because if getting this value
+ * from a pdf extraction it can be splited into more sections or necessary
+ * spaces are removed. The real issuer value is stored in the certificates
+ * meta file. The certficate is devided into two files: certificate.der (the
+ * binary value) and the meta information used in SignatureObjects as well
+ * in SignatureImages of a signed pdf-document. The storing path of the
+ * certificate is build by:
+ * <ol>
+ * <li>normalize the issuer string</li>
+ * <li>reduce all white spaces in the normalized issuer string</li>
+ * <li>build a hash value of this reduced string</li>
+ * <li>code this hash value as base64 value</li>
+ * <li>add the base64 normalized issuer hash value to the certificate base
+ * store path</li>
+ * <li>add the serialNumber to the cert path</li>
+ * <li>add the <code>.der</code> extension to get the certificate binary</li>
+ * <li>add the <code>.txt</code> extension to get the meta information of
+ * the certificate</li>
+ * </ol>
+ *
+ * The certificate meta file is build by the base64 coded issuer string and
+ * the cert digest value devided by the <code>@</code> char.
+ *
+ * @param serialNumber
+ * the file name of the certificate .der|.txt
+ * @param issuer
+ * the issuer string for the file path value of the certificate
+ * and for metainformation
+ * @param x509Certificate
+ * the x509v3 binary string
+ * @param x509Digest
+ * the digest value of the given x509Certificate
+ * @return true the certificate is stored completely, false otherwise
+ * @deprecated Use {@link #storeCertificate(String, String, String)}
+ * instead.
+ */
+ private boolean storeCertificate(String serialNumber, String issuer,
+ String x509Certificate, String x509Digest) {
+ return storeCertificate(serialNumber, issuer, x509Certificate);
+ }
+
+ /**
+ * This method stores a X509v3 certificate to the filesystem. The reference
+ * to the stored certificate is build by the serialNumber and the issuer
+ * string. The issuer string is normalized because if getting this value
+ * from a pdf extraction it can be splited into more sections or necessary
+ * spaces are removed. The real issuer value is stored in the certificates
+ * meta file. The certficate is devided into two files: certificate.der (the
+ * binary value) and the meta information used in SignatureObjects as well
+ * in SignatureImages of a signed pdf-document. The storing path of the
+ * certificate is build by:
+ * <ol>
+ * <li>normalize the issuer string</li>
+ * <li>reduce all white spaces in the normalized issuer string</li>
+ * <li>build a hash value of this reduced string</li>
+ * <li>code this hash value as base64 value</li>
+ * <li>add the base64 normalized issuer hash value to the certificate base
+ * store path</li>
+ * <li>add the serialNumber to the cert path</li>
+ * <li>add the <code>.der</code> extension to get the certificate binary</li>
+ * <li>add the <code>.txt</code> extension to get the meta information of
+ * the certificate</li>
+ * </ol>
+ *
+ * The certificate meta file is build by the base64 coded issuer string and
+ * the cert digest value devided by the <code>@</code> char.
+ *
+ * @param serialNumber
+ * the file name of the certificate .der|.txt
+ * @param issuer
+ * the issuer string for the file path value of the certificate
+ * and for metainformation
+ * @param x509Certificate
+ * the x509v3 binary string
+ * @return true the certificate is stored completely, false otherwise
+ */
+ private boolean storeCertificate(String serialNumber, String issuer,
+ String x509Certificate) {
+ boolean store_complete = false;
+ if (issuer != null && serialNumber != null) {
+ logger_.debug("Storing certificate.");
+ // String issuer_b64 = CodingHelper.encodeBase64(issuer.getBytes());
+ String iss_hash = getIssuerFileHash(issuer);
+ File cert_path_dir = new File(certPath_);
+ if (!cert_path_dir.exists()) {
+ logger_.debug("Certstore path \"" + cert_path_dir
+ + "\" does not exist. Creating.");
+ cert_path_dir.mkdir();
+ }
+ String cert_store_path = certPath_ + iss_hash;
+ File cert_store_dir = new File(cert_store_path);
+ if (!cert_store_dir.exists()) {
+ logger_.debug("Certstore dir \"" + cert_store_dir
+ + "\" does not exist. Creating.");
+ cert_store_dir.mkdir();
+ }
+ if (cert_store_dir.isDirectory()) {
+ String cert_file_name = cert_store_path + FILE_SEP
+ + serialNumber + CERT_FILE_EXTENSION;
+ if (logger_.isInfoEnabled()) {
+ logger_.debug("store certificate:" + cert_file_name);
+ }
+ boolean store_cert_file = FileHelper.writeToFile(
+ cert_file_name, x509Certificate);
+ store_complete = store_cert_file;// && store_cert_meta;
+ } else {
+ logger_.warn("Certstore dir \"" + cert_store_dir
+ + "\" is not a directory. Skipping storage.");
+ }
+ }
+ return store_complete;
+ }
+
+ /**
+ * @return Returns the AbstractTable.
+ * @see at.knowcenter.wag.egov.egiz.table.Table
+ */
+ public Table getAbstractTable() {
+ if (sigTable_ == null) {
+ sigTable_ = createSigTable(SignatureTypes.MAIN_TABLE);
+ }
+ return sigTable_;
+ }
+
+ /**
+ * This method read the style definitions from the settings file.
+ *
+ * @param styleKey
+ * the key to read the style definitions
+ * @return the defined style informations
+ * @see at.knowcenter.wag.egov.egiz.table.Style
+ */
+ private Style readStyle(String styleKey) {
+ ArrayList styles = settings_.getKeys(styleKey);
+ Style style = new Style();
+ for (int style_idx = 0; style_idx < styles.size(); style_idx++) {
+ String style_id = (String) styles.get(style_idx);
+ String style_val = settings_.getSetting(styleKey + "." + style_id,
+ null);
+ style.setStyle(style_id, style_val);
+ }
+ return style;
+ }
+
+ /**
+ * This method creates an abstract signature table object. It takes all keys
+ * and values set by the signature object to create the corresponding
+ * abstract table object. The table definition is read from the settings
+ * file.
+ *
+ * @param tableKey
+ * is the name of the table definition in the settings file
+ * @return a new abstract signature table
+ * @see at.knowcenter.wag.egov.egiz.table.Style
+ * @see at.knowcenter.wag.egov.egiz.table.Table
+ * @see at.knowcenter.wag.egov.egiz.table.Entry
+ */
+ private Table createSigTable(String tableKey) {
+ String table_key_prefix = SignatureTypes.SIG_OBJ + getSignationType()
+ + "." + SignatureTypes.TABLE;
+ String table_key = table_key_prefix + tableKey;
+ // String caption_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
+ // ".key.";
+ // String value_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
+ // ".value.";
+ // ArrayList table_def_keys = settings_.getKeys(table_key);
+ Vector table_def_keys = settings_.getSettingKeys(table_key);
+ if (table_def_keys == null) {
+ return null;
+ }
+ Table sig_table = new Table(tableKey);
+ boolean found_style = false;
+ for (int table_key_idx = table_def_keys.size() - 1; table_key_idx >= 0; table_key_idx--) {
+ String table_def = (String) table_def_keys.get(table_key_idx);
+ int dot_idx = (table_def.indexOf(".") > 0 ? table_def.indexOf(".")
+ : table_def.length());
+ table_def = table_def.substring(0, dot_idx);
+ String table_def_keys_prefix = table_key + "." + table_def;
+ String table_def_string = settings_.getSetting(
+ table_def_keys_prefix, null);
+ if (table_def.matches("\\D*")) {
+ // if the table key is not a number (row number index)
+ if (SignatureTypes.COLS_WITH.equals(table_def)) {
+ String[] cols_s = table_def_string.split(" ");
+ float[] cols_f = new float[cols_s.length];
+ for (int i = 0; i < cols_s.length; i++) {
+ cols_f[i] = Float.parseFloat(cols_s[i]);
+ }
+ sig_table.setColsRelativeWith(cols_f);
+ }
+ if (SignatureTypes.STYLE.equals(table_def) && !found_style) {
+ Style style = readStyle(table_def_keys_prefix);
+ sig_table.setStyle(style);
+ found_style = true;
+ }
+ continue;
+ }
+ if (table_def_string != null) {
+ // analyse the row definition
+ String[] elems = table_def_string.split("\\|");
+ ArrayList row = new ArrayList();
+ for (int elem_idx = 0; elem_idx < elems.length; elem_idx++) {
+ String elem = elems[elem_idx];
+ String[] key_type = elem.split("-");
+ if (key_type.length < 2) {
+ return null;
+ }
+ String key = key_type[0];
+ String type = key_type[1];
+ if (SignatureTypes.TYPE_TABLE.equals(key)) {
+ // add a table entry
+ Table table = createSigTable(type);
+ if (table != null) {
+ Entry entry = new Entry(Entry.TYPE_TABLE, table,
+ key);
+ row.add(entry);
+ }
+ }
+ if (SignatureTypes.TYPE_IMAGE.equals(type)) {
+ // add an image entry
+ String value = getSigValue(key);
+ if (value != null) {
+ Entry entry = new Entry(Entry.TYPE_IMAGE, value,
+ key);
+ entry.setStyle(defaultImageStyle_);
+ row.add(entry);
+ }
+ }
+ if (SignatureTypes.TYPE_VALUE.equals(type)) {
+ // add a single value entry
+ String value = getSigValue(key);
+ Entry entry = new Entry(Entry.TYPE_VALUE, value, key);
+ if (entry != null) {
+ entry.setColSpan(2);
+ entry.setStyle(defaultValueStyle_);
+ row.add(entry);
+ }
+ }
+ if ((SignatureTypes.TYPE_VALUE + SignatureTypes.TYPE_CAPTION)
+ .equals(type)
+ || (SignatureTypes.TYPE_CAPTION + SignatureTypes.TYPE_VALUE)
+ .equals(type)) {
+ // add a caption value pair
+ String caption = getSigCaption(key);
+ String value = getSigValue(key);
+ if (value != null) {
+ Entry c_entry = new Entry(Entry.TYPE_CAPTION,
+ caption, key);
+ c_entry.setNoWrap(true); // dferbas fix bug #331
+ c_entry.setStyle(defaultCaptionStyle_);
+
+ Entry v_entry = new Entry(Entry.TYPE_VALUE, value,
+ key);
+ v_entry.setStyle(defaultValueStyle_);
+ if (c_entry != null && v_entry != null) {
+ row.add(c_entry);
+ row.add(v_entry);
+ }
+ }
+ }
+ }
+ sig_table.addRow(table_def, row);
+ }
+ }
+
+ return sig_table;
+ }
+
+ /**
+ * This method inits the signature object by the given type. It loads the
+ * configured values and captions from the config.properties file.
+ */
+ public void initByType() throws SignatureTypesException {
+ if (sigType_ == null) {
+ sigType_ = getDefaultSigType();
+ }
+ SignatureTypes sig_types = SignatureTypes.getInstance();
+ signatureDefinition_ = sig_types.getSignatureTypeDefinition(sigType_);
+ if (signatureDefinition_ == null) {
+ final String msg = "The SignatureObject's sigType '"
+ + sigType_
+ + "' wasn't found in the configuration file's specified signature profiles. This usually happens if the sig_obj.type.default object has been turned off or is misspelled.";
+ logger_.error(msg);
+ throw new SignatureTypesException(msg);
+ }
+ Map key_cap_map = signatureDefinition_.getKeyCaptionMap();
+ if (key_cap_map != null) {
+ Iterator key_cap = key_cap_map.entrySet().iterator();
+ while (key_cap.hasNext()) {
+ Map.Entry entry = (Map.Entry) key_cap.next();
+ String key = (String) entry.getKey();
+ String caption = (String) entry.getValue();
+ SignatureEntry sig_entry = null;
+ if (sigEntries_.containsKey(key)) {
+ sig_entry = (SignatureEntry) sigEntries_.get(key);
+ } else {
+ sig_entry = new SignatureEntry(key);
+ sigEntries_.put(key, sig_entry);
+ }
+ sig_entry.setCaption(caption);
+ }
+ }
+
+ Map key_val_map = signatureDefinition_.getKeyValueMap();
+ if (key_val_map != null) {
+ Set key_val_set = key_val_map.entrySet();
+ Iterator key_val = key_val_set.iterator();
+ while (key_val.hasNext()) {
+ Map.Entry entry = (Map.Entry) key_val.next();
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+ if (SignatureTypes.SIG_NORM.equals(key)) {
+ try {
+ normalizer_.setVersion(value);
+ } catch (NormalizeException e) {
+ throw new SignatureTypesException(e);
+ }
+ }
+ // value = new String(CodingHelper.encodeUTF8(value));
+ // if (logger_.isDebugEnabled())
+ // {
+ // logger_.debug("key:" + key + " value:" + value);
+ // }
+ setSigValue(key, value);
+ }
+ }
+ }
+
+ /**
+ * This method returns a signature entry object.
+ *
+ * @param key
+ * the corresponding key
+ * @return the signature entry object of the given key, null if the key does
+ * not exist
+ */
+ public SignatureEntry getSigEntry(String key) {
+ return (SignatureEntry) sigEntries_.get(key);
+ }
+
+ /**
+ * This method is a helper function to remove all white spaces from a text.
+ *
+ * @param text
+ * the white spaces should remove from
+ * @return a text without white spaces
+ */
+ private static String removeAllWhiteSpaces(String text) {
+ return text.replaceAll("\\s", "");
+ }
+
+ public SignatureTypeDefinition getSignatureTypeDefinition() {
+ return this.signatureDefinition_;
+ }
+
+ /**
+ *
+ * @param placeholder
+ * @return Returns the list of SignatureFieldDefinitions that's values in
+ * the SignatureObject have been filled out with placeholders.
+ */
+ public List fillValues(final char placeholder, boolean has_SIG_ID,
+ boolean baikEnabled) {
+ List variable_fields = new ArrayList();
+
+ List field_definitions = this.signatureDefinition_
+ .getFieldDefinitions();
+ Iterator it = field_definitions.iterator();
+ while (it.hasNext()) {
+ SignatureFieldDefinition sfd = (SignatureFieldDefinition) it.next();
+ String value_string = null;
+ if (sfd.placeholder_length > 0) {
+ if (sfd.field_name.equals(SignatureTypes.SIG_ID)
+ && has_SIG_ID == false) {
+ setValueBruteForce(SignatureTypes.SIG_ID, null);
+ continue;
+ }
+
+ if (sfd.field_name.equals(SignatureTypes.SIG_ALG)
+ && !baikEnabled) {
+ setValueBruteForce(SignatureTypes.SIG_ID, null);
+ continue;
+ }
+
+ char[] placeholder_chars = new char[sfd.placeholder_length];
+ for (int i = 0; i < placeholder_chars.length; i++) {
+ placeholder_chars[i] = placeholder;
+ }
+ value_string = new String(placeholder_chars);
+
+ variable_fields.add(sfd);
+
+ setSigValue(sfd.field_name, value_string, true);
+ }
+ }
+
+ return variable_fields;
+ }
+
+ /**
+ * Returns the raw signature response XML string as set by the signing
+ * Connector.
+ *
+ * @return Returns the XML response String.
+ */
+ public String getRawSignatureResponse() {
+ return this.raw_signature_response;
+ }
+
+ /**
+ * Sets the raw signature response XML string.
+ *
+ * <p>
+ * This should be used by the Connector to pass the response String to the
+ * signer.
+ * </p>
+ *
+ * @param raw_response_string
+ * The new raw signature response string.
+ */
+ public void setRawSignatureResponse(String raw_response_string) {
+ this.raw_signature_response = raw_response_string;
+ }
+
+ /**
+ * get timestamp if available
+ *
+ * @return
+ */
+ public String getTimeStamp() {
+ return this.timeStamp;
+ }
+
+ /**
+ * set timestamp
+ *
+ * @param timeStamp
+ */
+ public void setTimeStamp(String timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ /**
+ * The toString method, used for tests or debugging.
+ */
+ public String toString() {
+ String strg = "";
+ Iterator it = sigEntries_.values().iterator();
+ while (it.hasNext()) {
+ SignatureEntry sig_entry = (SignatureEntry) it.next();
+ String key = sig_entry.getKey();
+ String caption = sig_entry.getCaption();
+ String value = sig_entry.getValue();
+ strg += key + "=" + caption + ":" + value + "\n";
+ }
+ strg += "Signation Type:" + getSignationType() + "\n";
+ return strg;
+ }
+
+ public Map getSigEntries() {
+ return sigEntries_;
+ }
}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java index e11a38c..4e849b7 100644 --- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java @@ -25,6 +25,7 @@ */
package at.knowcenter.wag.egov.egiz.sig;
+import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -38,461 +39,455 @@ import java.security.cert.X509Certificate; import java.util.List;
import org.apache.log4j.Logger;
+import org.omg.CORBA.portable.ApplicationException;
import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
import at.knowcenter.wag.egov.egiz.tools.CodingHelper;
import at.knowcenter.wag.egov.egiz.tools.FileHelper;
-public class X509Cert implements Serializable
-{
-
- /**
- * SVUID.
- */
- private static final long serialVersionUID = 6945327015386694557L;
-
- /**
- * The x509 certificate binary string Base64 coded
- */
- private String certString_ = null;
-
- /**
- * The name value of the issuer
- */
- private String issuerName_ = null;
-
- /**
- * The serial number of the certificate
- */
- private String serialNumber_ = null;
-
- /**
- * The digest value of the certificate
- */
- private String certDigest_ = null;
-
- /**
- * The name value of the subject
- */
- private String subjectName_ = null;
-
- /**
- * The X509Certificate object
- */
- private X509Certificate x509Cert_ = null;
-
- /**
- * The logger definition.
- */
- private static final Logger logger_ = ConfigLogger.getLogger(X509Cert.class);
-
- /**
- * The empty constructor not acessible from outside --> use the static init
- * methods instead
- */
- private X509Cert()
- {
- }
-
- /**
- * Normalize the base64 coded .cer or .der string. Remove the begin and end
- * statement and remove all whitespaces in the string. The result string
- * (base64) is used by reconstructing the certiface sign by the verification
- * process.
- *
- * @param certString
- * the string to normalize
- * @return the normalized cert string
- */
- private static String normalizeCertString(String certString)
- {
- certString = certString.replaceAll("-----BEGIN CERTIFICATE-----", "");
- certString = certString.replaceAll("-----END CERTIFICATE-----", "");
- certString = certString.replaceAll("\\s", "");
- return certString;
- }
-
- /**
- * This method initialzes a X509Certificate by a string value. It must be
- * coded Base64 or as plain binary stream.
- *
- * @param certString
- * the certificate string to analyse
- * @return the X509Cert object
- * @see CertificateFactory
- * @see X509Certificate
- */
- public static X509Cert initByString(String certString)
- {
- if (certString == null)
- {
- return null;
- }
- certString = normalizeCertString(certString);
- X509Cert x509_cert = new X509Cert();
- x509_cert.setCertString(certString);
- try
- {
- byte[] b64_dec = certString.getBytes("US-ASCII");
- if (CodingHelper.isB64(b64_dec))
- {
- b64_dec = CodingHelper.decodeBase64(b64_dec);
- }
- else
- {
- b64_dec = CodingHelper.encodeBase64(b64_dec).getBytes("US-ASCII");
- }
- ByteArrayInputStream bais = new ByteArrayInputStream(b64_dec);
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) cf.generateCertificate(bais);
- bais.close();
- x509_cert.setX509Cert(cert);
-
- String serial_num = cert.getSerialNumber().toString();
- String issuer = cert.getIssuerDN().getName();
- // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
-// issuer = issuer.replaceAll(", ", ",");
- issuer = issuer.replaceAll("[^\\\\], ", ",");
- String subject_name = cert.getSubjectDN().toString();
- x509_cert.setSerialNumber(serial_num);
- x509_cert.setIssuerName(issuer);
- x509_cert.setSubjectName(subject_name);
- if (logger_.isDebugEnabled())
- {
- logger_.debug("Serial number from certificate:" + serial_num);
- logger_.debug("Issuer name from certificate :" + issuer);
- logger_.debug("Subject name from certificate :" + subject_name);
- }
- }
- catch (java.security.cert.CertificateException ce)
- {
- // nothing to do, cause certString is not X509 conformc
- logger_.error(ce.getMessage(), ce);
- }
- catch (IOException ioe)
- {
- // nothing to do, cause certString is not X509 conform
- logger_.error(ioe.getMessage(), ioe);
- }
- return x509_cert;
- }
-
- public static X509Cert initByX509Certificate(X509Certificate cert) throws CertificateEncodingException {
- X509Cert x509_cert = new X509Cert();
- x509_cert.setX509Cert(cert);
- x509_cert.setCertString(CodingHelper.encodeBase64(cert.getEncoded()));
-
- String serial_num = cert.getSerialNumber().toString();
- String issuer = cert.getIssuerDN().getName();
- // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
-// issuer = issuer.replaceAll(", ", ",");
- issuer = issuer.replaceAll("[^\\\\], ", ",");
- String subject_name = cert.getSubjectDN().toString();
- x509_cert.setSerialNumber(serial_num);
- x509_cert.setIssuerName(issuer);
- x509_cert.setSubjectName(subject_name);
- if (logger_.isDebugEnabled())
- {
- logger_.debug("Serial number from certificate:" + serial_num);
- logger_.debug("Issuer name from certificate :" + issuer);
- logger_.debug("Subject name from certificate :" + subject_name);
- }
- return x509_cert;
- }
-
- public static X509Cert initByByteArray(byte[] data)
- {
- X509Cert x509_cert = new X509Cert();
- try
- {
- ByteArrayInputStream bais = new ByteArrayInputStream(data);
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509Certificate cert = (X509Certificate) cf.generateCertificate(bais);
- bais.close();
-
- x509_cert.setX509Cert(cert);
-
- String serial_num = cert.getSerialNumber().toString();
- String issuer = cert.getIssuerDN().getName();
- // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
-// issuer = issuer.replaceAll(", ", ",");
- issuer = issuer.replaceAll("[^\\\\], ", ",");
- String subject_name = cert.getSubjectDN().toString();
- x509_cert.setSerialNumber(serial_num);
- x509_cert.setIssuerName(issuer);
- x509_cert.setSubjectName(subject_name);
- if (logger_.isDebugEnabled())
- {
- logger_.debug("Serial number from certificate:" + serial_num);
- logger_.debug("Issuer name from certificate :" + issuer);
- logger_.debug("Subject name from certificate :" + subject_name);
- }
- }
- catch (java.security.cert.CertificateException ce)
- {
- // nothing to do, cause certString is not X509 conformc
- logger_.error(ce.getMessage(), ce);
-
- }
- catch (IOException ioe)
- {
- // nothing to do, cause certString is not X509 conform
- logger_.error(ioe.getMessage(), ioe);
- }
-
- return x509_cert;
- }
-
- /**
- * This method initialzes a X509Certificate by a file path value. The file
- * must be a plain binary file like .cer format.
- *
- * @param filePath
- * the certificate file to analyse
- * @return the X509Cert object
- * @see CertificateFactory
- * @see X509Certificate
- */
- public static X509Cert initByFilePath(String filePath)
- {
- if (filePath == null)
- {
- return null;
- }
- X509Cert x509_cert = new X509Cert();
- try
- {
- FileInputStream fis = new FileInputStream(filePath);
- X509Certificate cert = null;
- try
- {
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- cert = (X509Certificate) cf.generateCertificate(fis);
- }
- catch (java.security.cert.CertificateException ce)
- {
- fis.close();
- String cert_string = FileHelper.readFromFile(filePath);
- return initByString(cert_string);
- }
- fis.close();
- x509_cert.setX509Cert(cert);
- String cert_string = FileHelper.readFromFile(filePath);
- x509_cert.setCertString(normalizeCertString(cert_string));
-
- String serial_num = cert.getSerialNumber().toString();
- String issuer = cert.getIssuerDN().getName();
- // fixed by dti: commas within issuer rdns are escapted by "\,". These escapted commas must not be replaced.
-// issuer = issuer.replaceAll(", ", ",");
- issuer = issuer.replaceAll("[^\\\\], ", ",");
- String subject_name = cert.getSubjectDN().toString();
- x509_cert.setSerialNumber(serial_num);
- x509_cert.setIssuerName(issuer);
- x509_cert.setSubjectName(subject_name);
- if (logger_.isDebugEnabled())
- {
- logger_.debug("Serial number from certificate:" + serial_num);
- logger_.debug("Issuer name from certificate :" + issuer);
- logger_.debug("Subject name from certificate :" + subject_name);
- }
- }
- catch (IOException ioe)
- {
- String cert_string = FileHelper.readFromFile(filePath);
- return initByString(cert_string);
- }
- return x509_cert;
-
- }
-
- /**
- * This method initialzes a X509Certificate by a file value. The file must be
- * a plain binary file like .cer format.
- *
- * @param certFile
- * the certificate file to analyse
- * @return the X509Cert object
- * @see CertificateFactory
- * @see X509Certificate
- */
- public static X509Cert initByFile(File certFile)
- {
- return initByFilePath(certFile.getAbsolutePath());
- }
-
- /**
- * This method checks if a certificate file is X509 conform.
- *
- * @return true if a certificate file is X509 conform, false otherwise
- */
- public boolean isX509Cert()
- {
- return x509Cert_ != null;
- }
-
- /**
- * @return Returns the certificate digest value.
- * @deprecated Should not be used any more.
- */
- public String getCertDigest()
- {
- if (certDigest_ == null)
- {
- if (certString_ != null)
- {
- byte[] cert_b64 = CodingHelper.decodeBase64(certString_);
- String sigAlgName = this.x509Cert_.getSigAlgName();
- String digestAlg = sigAlgName.split("/")[0];
- if (sigAlgName.toLowerCase().indexOf("with") != -1 ) {
- digestAlg = sigAlgName.substring(0,sigAlgName.toLowerCase().indexOf("with"));
- }
- byte[] cert_hash = CodingHelper.buildDigest(cert_b64, digestAlg);
- certDigest_ = new String(CodingHelper.encodeBase64(cert_hash));
- }
- }
- return certDigest_;
- }
-
- /**
- * @return Returns the certificate Base64 binary string.
- */
- public String getCertString()
- {
- return certString_;
- }
-
- /**
- * @return Returns the issuer string.
- */
- public String getIssuerName()
- {
- return issuerName_;
- }
-
- /**
- * @return Returns the serial number.
- */
- public String getSerialNumber()
- {
- return serialNumber_;
- }
-
- /**
- * @return Returns the real X509Certifcate object.
- * @see X509Certificate
- */
- public X509Certificate getX509Certificate()
- {
- return x509Cert_;
- }
-
- /**
- * @return Returns the subject name.
- */
- public String getSubjectName()
- {
- return subjectName_;
- }
-
- // /**
- // * @param certDigest
- // * The certDigest to set.
- // */
- // private void setCertDigest(String certDigest)
- // {
- // certDigest_ = certDigest;
- // }
-
- /**
- * @param certString
- * The certString to set.
- */
- private void setCertString(String certString)
- {
- certString_ = certString;
- }
-
- /**
- * @param issuerString
- * The issuerString to set.
- */
- private void setIssuerName(String issuerString)
- {
- issuerName_ = issuerString;
- }
-
- /**
- * @param serialNumber
- * The serialNumber to set.
- */
- private void setSerialNumber(String serialNumber)
- {
- serialNumber_ = serialNumber;
- }
-
- /**
- * @param cert
- * The x509Cert to set.
- */
- private void setX509Cert(X509Certificate cert)
- {
- x509Cert_ = cert;
- }
-
- /**
- * @param subjectName
- * The subjectName to set.
- */
- private void setSubjectName(String subjectName)
- {
- subjectName_ = subjectName;
- }
-
- public byte[] getTBSCertificate() throws CertificateEncodingException
- {
- return x509Cert_.getTBSCertificate();
- }
-
- public String getSigAlgName()
- {
- return x509Cert_.getSigAlgName();
- }
-
- public String getSigAlgOID()
- {
- return x509Cert_.getSigAlgOID();
- }
-
- public List getExtendedKeyUsage()
- {
- List list = null;
- try
- {
- list = x509Cert_.getExtendedKeyUsage();
- }
- catch (CertificateParsingException e)
- {
- logger_.error(e.getMessage(), e);
- }
- return null;
- }
-
- /**
- * @return the public key of the X509Certificate
- */
- public PublicKey getPublicKey()
- {
- return x509Cert_.getPublicKey();
- }
-
- /**
- * This method checks, if a X509Certificate has a public key with the rsa
- * algorithm.
- *
- * @return true if the public key is produced with rsa, false otherwise
- */
- public boolean isRSA()
- {
- return (x509Cert_.getPublicKey().getAlgorithm()).indexOf("RSA") >= 0;
- }
+public class X509Cert implements Serializable {
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = 6945327015386694557L;
+
+ /**
+ * The x509 certificate binary string Base64 coded
+ */
+ private String certString_ = null;
+
+ /**
+ * The name value of the issuer
+ */
+ private String issuerName_ = null;
+
+ /**
+ * The serial number of the certificate
+ */
+ private String serialNumber_ = null;
+
+ /**
+ * The digest value of the certificate
+ */
+ private String certDigest_ = null;
+
+ /**
+ * The name value of the subject
+ */
+ private String subjectName_ = null;
+
+ /**
+ * The X509Certificate object
+ */
+ private X509Certificate x509Cert_ = null;
+
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger_ = ConfigLogger
+ .getLogger(X509Cert.class);
+
+ /**
+ * The empty constructor not acessible from outside --> use the static init
+ * methods instead
+ */
+ private X509Cert() {
+ }
+
+ /**
+ * Normalize the base64 coded .cer or .der string. Remove the begin and end
+ * statement and remove all whitespaces in the string. The result string
+ * (base64) is used by reconstructing the certiface sign by the verification
+ * process.
+ *
+ * @param certString
+ * the string to normalize
+ * @return the normalized cert string
+ */
+ private static String normalizeCertString(String certString) {
+ certString = certString.replaceAll("-----BEGIN CERTIFICATE-----", "");
+ certString = certString.replaceAll("-----END CERTIFICATE-----", "");
+ certString = certString.replaceAll("\\s", "");
+ return certString;
+ }
+
+ /**
+ * This method initialzes a X509Certificate by a string value. It must be
+ * coded Base64 or as plain binary stream.
+ *
+ * @param certString
+ * the certificate string to analyse
+ * @return the X509Cert object
+ * @see CertificateFactory
+ * @see X509Certificate
+ */
+ public static X509Cert initByString(String certString) {
+ synchronized (SignatureObject.adding_mutex) {
+
+ if (certString == null) {
+ return null;
+ }
+ certString = normalizeCertString(certString);
+ X509Cert x509_cert = new X509Cert();
+ x509_cert.setCertString(certString);
+ try {
+ byte[] b64_dec = certString.getBytes("US-ASCII");
+ if (CodingHelper.isB64(b64_dec)) {
+ b64_dec = CodingHelper.decodeBase64(b64_dec);
+ } else {
+ b64_dec = CodingHelper.encodeBase64(b64_dec).getBytes(
+ "US-ASCII");
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(b64_dec);
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf
+ .generateCertificate(bais);
+ bais.close();
+ x509_cert.setX509Cert(cert);
+
+ String serial_num = cert.getSerialNumber().toString();
+ String issuer = cert.getIssuerDN().getName();
+ // fixed by dti: commas within issuer rdns are escapted by "\,".
+ // These escapted commas must not be replaced.
+ // issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
+ String subject_name = cert.getSubjectDN().toString();
+ x509_cert.setSerialNumber(serial_num);
+ x509_cert.setIssuerName(issuer);
+ x509_cert.setSubjectName(subject_name);
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Serial number from certificate:"
+ + serial_num);
+ logger_.debug("Issuer name from certificate :" + issuer);
+ logger_.debug("Subject name from certificate :"
+ + subject_name);
+ }
+ } catch (java.security.cert.CertificateException ce) {
+ // nothing to do, cause certString is not X509 conformc
+ logger_.error(ce.getMessage(), ce);
+ } catch (IOException ioe) {
+ // nothing to do, cause certString is not X509 conform
+ logger_.error(ioe.getMessage(), ioe);
+ }
+ return x509_cert;
+
+ }
+ }
+
+ public static X509Cert initByX509Certificate(X509Certificate cert)
+ throws CertificateEncodingException {
+ synchronized (SignatureObject.adding_mutex) {
+ X509Cert x509_cert = new X509Cert();
+ x509_cert.setX509Cert(cert);
+ x509_cert
+ .setCertString(CodingHelper.encodeBase64(cert.getEncoded()));
+
+ String serial_num = cert.getSerialNumber().toString();
+ String issuer = cert.getIssuerDN().getName();
+ // fixed by dti: commas within issuer rdns are escapted by "\,".
+ // These
+ // escapted commas must not be replaced.
+ // issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
+ String subject_name = cert.getSubjectDN().toString();
+ x509_cert.setSerialNumber(serial_num);
+ x509_cert.setIssuerName(issuer);
+ x509_cert.setSubjectName(subject_name);
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Serial number from certificate:" + serial_num);
+ logger_.debug("Issuer name from certificate :" + issuer);
+ logger_.debug("Subject name from certificate :" + subject_name);
+ }
+ return x509_cert;
+ }
+ }
+
+ public static X509Cert initByByteArray(byte[] data) {
+ synchronized (SignatureObject.adding_mutex) {
+ X509Cert x509_cert = new X509Cert();
+ try {
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf
+ .generateCertificate(bais);
+ bais.close();
+
+ x509_cert.setX509Cert(cert);
+
+ String serial_num = cert.getSerialNumber().toString();
+ String issuer = cert.getIssuerDN().getName();
+ // fixed by dti: commas within issuer rdns are escapted by "\,".
+ // These escapted commas must not be replaced.
+ // issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
+ String subject_name = cert.getSubjectDN().toString();
+ x509_cert.setSerialNumber(serial_num);
+ x509_cert.setIssuerName(issuer);
+ x509_cert.setSubjectName(subject_name);
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Serial number from certificate:"
+ + serial_num);
+ logger_.debug("Issuer name from certificate :" + issuer);
+ logger_.debug("Subject name from certificate :"
+ + subject_name);
+ }
+ } catch (java.security.cert.CertificateException ce) {
+ // nothing to do, cause certString is not X509 conformc
+ logger_.error(ce.getMessage(), ce);
+
+ } catch (IOException ioe) {
+ // nothing to do, cause certString is not X509 conform
+ logger_.error(ioe.getMessage(), ioe);
+ }
+
+ return x509_cert;
+ }
+ }
+
+ /**
+ * This method initialzes a X509Certificate by a file path value. The file
+ * must be a plain binary file like .cer format.
+ *
+ * @param filePath
+ * the certificate file to analyse
+ * @return the X509Cert object
+ * @see CertificateFactory
+ * @see X509Certificate
+ */
+ public static X509Cert initByFilePath(String filePath) {
+ synchronized (SignatureObject.adding_mutex) {
+ if (filePath == null) {
+ return null;
+ }
+ X509Cert x509_cert = new X509Cert();
+ try {
+ FileInputStream fis = new FileInputStream(filePath);
+
+ X509Certificate cert = null;
+ try {
+ CertificateFactory cf = CertificateFactory
+ .getInstance("X.509");
+ //logger_.error("Decoding Info reading : [ " + filePath + " ]");
+ cert = (X509Certificate) cf.generateCertificate(fis);
+ } catch (java.security.cert.CertificateException ce) {
+ File f = new File(filePath);
+ //logger_.error("Decoding Error: [ " + filePath + " ] " + f.exists() + " ", ce);
+ fis.close();
+ String cert_string = FileHelper.readFromFile(filePath);
+ //logger_.error(cert_string);
+ int max_count = 5;
+ int count = 0;
+ while(cert_string.equals("") && count < max_count) {
+ // Invalid File contents reread ....
+ cert_string = FileHelper.readFromFile(filePath);
+ count++;
+ Thread.yield();
+ }
+ if(count == 5) {
+ logger_.error("Cannot read from file " + filePath);
+ }
+ return initByString(cert_string);
+ }
+ fis.close();
+ x509_cert.setX509Cert(cert);
+ String cert_string = FileHelper.readFromFile(filePath);
+ x509_cert.setCertString(normalizeCertString(cert_string));
+
+ String serial_num = cert.getSerialNumber().toString();
+ String issuer = cert.getIssuerDN().getName();
+ // fixed by dti: commas within issuer rdns are escapted by "\,".
+ // These escapted commas must not be replaced.
+ // issuer = issuer.replaceAll(", ", ",");
+ issuer = issuer.replaceAll("[^\\\\], ", ",");
+ String subject_name = cert.getSubjectDN().toString();
+ x509_cert.setSerialNumber(serial_num);
+ x509_cert.setIssuerName(issuer);
+ x509_cert.setSubjectName(subject_name);
+ if (logger_.isDebugEnabled()) {
+ logger_.debug("Serial number from certificate:"
+ + serial_num);
+ logger_.debug("Issuer name from certificate :" + issuer);
+ logger_.debug("Subject name from certificate :"
+ + subject_name);
+ }
+ } catch (IOException ioe) {
+ String cert_string = FileHelper.readFromFile(filePath);
+ return initByString(cert_string);
+ }
+ return x509_cert;
+ }
+ }
+
+ /**
+ * This method initialzes a X509Certificate by a file value. The file must
+ * be a plain binary file like .cer format.
+ *
+ * @param certFile
+ * the certificate file to analyse
+ * @return the X509Cert object
+ * @see CertificateFactory
+ * @see X509Certificate
+ */
+ public static X509Cert initByFile(File certFile) {
+ synchronized (SignatureObject.adding_mutex) {
+ return initByFilePath(certFile.getAbsolutePath());
+ }
+ }
+
+ /**
+ * This method checks if a certificate file is X509 conform.
+ *
+ * @return true if a certificate file is X509 conform, false otherwise
+ */
+ public boolean isX509Cert() {
+ return x509Cert_ != null;
+ }
+
+ /**
+ * @return Returns the certificate digest value.
+ * @deprecated Should not be used any more.
+ */
+ public String getCertDigest() {
+ if (certDigest_ == null) {
+ if (certString_ != null) {
+ byte[] cert_b64 = CodingHelper.decodeBase64(certString_);
+ String sigAlgName = this.x509Cert_.getSigAlgName();
+ String digestAlg = sigAlgName.split("/")[0];
+ if (sigAlgName.toLowerCase().indexOf("with") != -1) {
+ digestAlg = sigAlgName.substring(0, sigAlgName
+ .toLowerCase().indexOf("with"));
+ }
+ byte[] cert_hash = CodingHelper
+ .buildDigest(cert_b64, digestAlg);
+ certDigest_ = new String(CodingHelper.encodeBase64(cert_hash));
+ }
+ }
+ return certDigest_;
+ }
+
+ /**
+ * @return Returns the certificate Base64 binary string.
+ */
+ public String getCertString() {
+ return certString_;
+ }
+
+ /**
+ * @return Returns the issuer string.
+ */
+ public String getIssuerName() {
+ return issuerName_;
+ }
+
+ /**
+ * @return Returns the serial number.
+ */
+ public String getSerialNumber() {
+ return serialNumber_;
+ }
+
+ /**
+ * @return Returns the real X509Certifcate object.
+ * @see X509Certificate
+ */
+ public X509Certificate getX509Certificate() {
+ return x509Cert_;
+ }
+
+ /**
+ * @return Returns the subject name.
+ */
+ public String getSubjectName() {
+ return subjectName_;
+ }
+
+ // /**
+ // * @param certDigest
+ // * The certDigest to set.
+ // */
+ // private void setCertDigest(String certDigest)
+ // {
+ // certDigest_ = certDigest;
+ // }
+
+ /**
+ * @param certString
+ * The certString to set.
+ */
+ private void setCertString(String certString) {
+ certString_ = certString;
+ }
+
+ /**
+ * @param issuerString
+ * The issuerString to set.
+ */
+ private void setIssuerName(String issuerString) {
+ issuerName_ = issuerString;
+ }
+
+ /**
+ * @param serialNumber
+ * The serialNumber to set.
+ */
+ private void setSerialNumber(String serialNumber) {
+ serialNumber_ = serialNumber;
+ }
+
+ /**
+ * @param cert
+ * The x509Cert to set.
+ */
+ private void setX509Cert(X509Certificate cert) {
+ x509Cert_ = cert;
+ }
+
+ /**
+ * @param subjectName
+ * The subjectName to set.
+ */
+ private void setSubjectName(String subjectName) {
+ subjectName_ = subjectName;
+ }
+
+ public byte[] getTBSCertificate() throws CertificateEncodingException {
+ return x509Cert_.getTBSCertificate();
+ }
+
+ public String getSigAlgName() {
+ return x509Cert_.getSigAlgName();
+ }
+
+ public String getSigAlgOID() {
+ return x509Cert_.getSigAlgOID();
+ }
+
+ public List getExtendedKeyUsage() {
+ List list = null;
+ try {
+ list = x509Cert_.getExtendedKeyUsage();
+ } catch (CertificateParsingException e) {
+ logger_.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * @return the public key of the X509Certificate
+ */
+ public PublicKey getPublicKey() {
+ return x509Cert_.getPublicKey();
+ }
+
+ /**
+ * This method checks, if a X509Certificate has a public key with the rsa
+ * algorithm.
+ *
+ * @return true if the public key is produced with rsa, false otherwise
+ */
+ public boolean isRSA() {
+ return (x509Cert_.getPublicKey().getAlgorithm()).indexOf("RSA") >= 0;
+ }
}
\ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/FileHelper.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/FileHelper.java index 17b98d7..e7bef08 100644 --- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/FileHelper.java +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/tools/FileHelper.java @@ -29,11 +29,13 @@ import java.io.BufferedReader; import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import org.apache.log4j.Logger;
@@ -60,7 +62,10 @@ public class FileHelper { String file_string = null;
logger_.trace("Looking for file: " + fileName);
try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
+ FileInputStream fis = new FileInputStream(fileName);
+ fis.getFD().sync();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
+ //InputStreamReader reader = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
logger_.trace("Reading file: " + fileName);
String line = null;
file_string = "";
@@ -112,10 +117,16 @@ public class FileHelper { public static boolean writeToFile(String fileName, String fileString) {
BufferedWriter writer;
try {
- FileWriter fwriter = new FileWriter(fileName);
- writer = new BufferedWriter(fwriter);
+ FileOutputStream out = new FileOutputStream(fileName);
+ OutputStreamWriter osw = new OutputStreamWriter(out);
+ writer = new BufferedWriter(osw);
writer.write(fileString);
+ writer.flush();
writer.close();
+ writer.flush();
+ osw.flush();
+ out.flush();
+ out.getFD().sync();
} catch (IOException e) {
logger_.info("File:" + fileName + " can not be written. Cause:" + e.getMessage());
return false;
|