You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juddi.apache.org by al...@apache.org on 2014/01/19 23:08:00 UTC
svn commit: r1559590 [2/5] - in /juddi/trunk:
juddi-client/src/main/java/org/apache/juddi/v3/annotations/
juddi-client/src/main/java/org/apache/juddi/v3/client/
juddi-client/src/main/java/org/apache/juddi/v3/client/config/
juddi-client/src/main/java/or...
Modified: juddi/trunk/juddi-client/src/main/java/org/apache/juddi/v3/client/cryptor/DigSigUtil.java
URL: http://svn.apache.org/viewvc/juddi/trunk/juddi-client/src/main/java/org/apache/juddi/v3/client/cryptor/DigSigUtil.java?rev=1559590&r1=1559589&r2=1559590&view=diff
==============================================================================
--- juddi/trunk/juddi-client/src/main/java/org/apache/juddi/v3/client/cryptor/DigSigUtil.java (original)
+++ juddi/trunk/juddi-client/src/main/java/org/apache/juddi/v3/client/cryptor/DigSigUtil.java Sun Jan 19 22:07:59 2014
@@ -89,875 +89,868 @@ import sun.security.provider.certpath.OC
*/
public class DigSigUtil {
- /**
- * Expects a properties object containing the desired configuration
- *
- * @param config
- * @throws CertificateException
- */
- public DigSigUtil(Properties config) throws CertificateException {
- cf = CertificateFactory.getInstance("X.509");
- this.map = config;
- }
-
- public DigSigUtil() throws CertificateException {
- cf = CertificateFactory.getInstance("X.509");
- }
- private Log logger = LogFactory.getLog(this.getClass());
-
- public void put(String key, String value) {
- map.put(key, value);
- }
-
- /**
- * clears the configuration for reuse
- */
- public void clear() {
- map.clear();
- }
- private Properties map = new Properties();
- /**
- * This is the location of the keystore
- *
- * If referencing a Windows certificate store, use WINDOWS-MY as a value
- * with a null password
- */
- public final static String SIGNATURE_KEYSTORE_FILE = "keyStorePath";
- /**
- * The type of file, such as JKS for most Java applications, or WINDOWS-MY
- * to use the Windows certificate store of the current user or KeychainStore
- * for MacOS
- */
- public final static String SIGNATURE_KEYSTORE_FILETYPE = "keyStoreType";
- public final static String SIGNATURE_KEYSTORE_FILE_PASSWORD = "filePassword";
- public final static String SIGNATURE_KEYSTORE_KEY_PASSWORD = "keyPassword";
- public final static String SIGNATURE_KEYSTORE_KEY_ALIAS = "keyAlias";
- public final static String TRUSTSTORE_FILE = "trustStorePath";
- public final static String TRUSTSTORE_FILETYPE = "trustStoreType";
- public final static String TRUSTSTORE_FILE_PASSWORD = "trustStorePassword";
- /**
- * default is CanonicalizationMethod.EXCLUSIVE
- * http://www.w3.org/2001/10/xml-exc-c14n#
- *
- * @see CanonicalizationMethod
- */
- public final static String CANONICALIZATIONMETHOD = "CanonicalizationMethod";
- /**
- * default is http://www.w3.org/2000/09/xmldsig#rsa-sha1
- *
- * @see SignatureMethod
- */
- public final static String SIGNATURE_METHOD = "SignatureMethod";
- /**
- * Defines whether or not a certificate is included with the signature<Br>
- * Values - Include whole X509 Public Key in the signature (recommended)
- * (default) * Example
- * <pre>
- * Map map = new HashMap();
- * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64, "true");</pre>
- * any value can be used.
- */
- public final static String SIGNATURE_OPTION_CERT_INCLUSION_BASE64 = "BASE64";
-
- /**
- * Include the signer's serial of the public key and the issuer's subject
- * name
- *
- * Clients will not be able to validate the signature unless they have a
- * copy of the signer's public key in a trust store or the full certificate
- * is included out of band
- *
- * Example
- * <pre>
- * Map map = new HashMap();
- * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL, "true");</pre>
- * any value can be used.
- *
- * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
- */
- public final static String SIGNATURE_OPTION_CERT_INCLUSION_SERIAL = "SERIAL";
- /**
- * Include the signer's Subject DN of the public key.
- *
- * Clients will not be able to validate the signature unless they have a
- * copy of the signer's public key in a trust store or the full certificate
- * is included out of band
- *
- * Example
- * <pre>
- * Map map = new HashMap();
- * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN, "true");</pre>
- * any value can be used.
- *
- * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
- */
- public final static String SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN = "SUBJECTDN";
- /*
- * Include the signer's X500 Prinicple of the public key.
- *
- * Clients will not be able to validate the signature unless they have a
- * copy of the signer's public key in a trust store or the full certificate
- * is included out of band
- *
- * Example
- * <pre>
- * Map map = new HashMap();
- * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL, "true");</pre>
- * any value can be used.
- *
- * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
- */
- //public final static String SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL = "X500";
-
- /**
- * This is the namespace of the digital signature.
- */
- public final static String XML_DIGSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
- /**
- * Default value DigestMethod.SHA1 =
- * "http://www.w3.org/2000/09/xmldsig#sha1"
- *
- * @see javax.xml.crypto.dsig.DigestMethod
- */
- public final static String SIGNATURE_OPTION_DIGEST_METHOD = "digestMethod";
- /**
- * When validating a signature, include this field will validate that the
- * signature is still valid with regards to timestamps NotBefore and
- * OnOrAfter
- *
- * Example
- * <pre>
- * Map map = new HashMap();
- * map.put(DigSigUtil.CHECK_TIMESTAMPS, true);</pre> any value can be used.
- */
- public final static String CHECK_TIMESTAMPS = "checkTimestamps";
- private CertificateFactory cf = null;
- public final static String CHECK_REVOCATION_STATUS_OCSP = "checkRevocationOCSP";
- public final static String CHECK_REVOCATION_STATUS_CRL = "checkRevocationCRL";
- public final static String CHECK_TRUST_CHAIN = "checkTrust";
-
- /**
- * Digital signs a UDDI entity, such as a business, service, tmodel or
- * binding template using the map to provide certificate key stores and
- * credentials<br><br> The UDDI entity MUST support XML Digital Signatures
- * (tModel, Business, Service, Binding Template)
- *
- * @param <T> Any UDDI entity that supports digital signatures
- * @param jaxbObj
- * @return an enveloped signed UDDI element, do not modify this object after
- * signing
- */
- public <T> T signUddiEntity(T jaxbObj) {
- DOMResult domResult = new DOMResult();
- JAXB.marshal(jaxbObj, domResult);
- Document doc = ((Document) domResult.getNode());
- Element docElement = doc.getDocumentElement();
-
- try {
- KeyStore ks = KeyStore.getInstance(map.getProperty(SIGNATURE_KEYSTORE_FILETYPE));
- URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
- if (url == null) {
+ /**
+ * Expects a properties object containing the desired configuration
+ *
+ * @param config
+ * @throws CertificateException
+ */
+ public DigSigUtil(Properties config) throws CertificateException {
+ cf = CertificateFactory.getInstance("X.509");
+ this.map = config;
+ }
+
+ public DigSigUtil() throws CertificateException {
+ cf = CertificateFactory.getInstance("X.509");
+ }
+ private Log logger = LogFactory.getLog(this.getClass());
+
+ public void put(String key, String value) {
+ map.put(key, value);
+ }
+
+ /**
+ * clears the configuration for reuse
+ */
+ public void clear() {
+ map.clear();
+ }
+ private Properties map = new Properties();
+ /**
+ * This is the location of the keystore
+ *
+ * If referencing a Windows certificate store, use WINDOWS-MY as a value
+ * with a null password
+ */
+ public final static String SIGNATURE_KEYSTORE_FILE = "keyStorePath";
+ /**
+ * The type of file, such as JKS for most Java applications, or
+ * WINDOWS-MY to use the Windows certificate store of the current user
+ * or KeychainStore for MacOS
+ */
+ public final static String SIGNATURE_KEYSTORE_FILETYPE = "keyStoreType";
+ public final static String SIGNATURE_KEYSTORE_FILE_PASSWORD = "filePassword";
+ public final static String SIGNATURE_KEYSTORE_KEY_PASSWORD = "keyPassword";
+ public final static String SIGNATURE_KEYSTORE_KEY_ALIAS = "keyAlias";
+ public final static String TRUSTSTORE_FILE = "trustStorePath";
+ public final static String TRUSTSTORE_FILETYPE = "trustStoreType";
+ public final static String TRUSTSTORE_FILE_PASSWORD = "trustStorePassword";
+ /**
+ * default is CanonicalizationMethod.EXCLUSIVE
+ * http://www.w3.org/2001/10/xml-exc-c14n#
+ *
+ * @see CanonicalizationMethod
+ */
+ public final static String CANONICALIZATIONMETHOD = "CanonicalizationMethod";
+ /**
+ * default is http://www.w3.org/2000/09/xmldsig#rsa-sha1
+ *
+ * @see SignatureMethod
+ */
+ public final static String SIGNATURE_METHOD = "SignatureMethod";
+ /**
+ * Defines whether or not a certificate is included with the
+ * signature<Br>
+ * Values - Include whole X509 Public Key in the signature (recommended)
+ * (default) * Example
+ * <pre>
+ * Map map = new HashMap();
+ * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64, "true");</pre>
+ * any value can be used.
+ */
+ public final static String SIGNATURE_OPTION_CERT_INCLUSION_BASE64 = "BASE64";
+
+ /**
+ * Include the signer's serial of the public key and the issuer's
+ * subject name
+ *
+ * Clients will not be able to validate the signature unless they have a
+ * copy of the signer's public key in a trust store or the full
+ * certificate is included out of band
+ *
+ * Example
+ * <pre>
+ * Map map = new HashMap();
+ * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL, "true");</pre>
+ * any value can be used.
+ *
+ * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
+ */
+ public final static String SIGNATURE_OPTION_CERT_INCLUSION_SERIAL = "SERIAL";
+ /**
+ * Include the signer's Subject DN of the public key.
+ *
+ * Clients will not be able to validate the signature unless they have a
+ * copy of the signer's public key in a trust store or the full
+ * certificate is included out of band
+ *
+ * Example
+ * <pre>
+ * Map map = new HashMap();
+ * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN, "true");</pre>
+ * any value can be used.
+ *
+ * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
+ */
+ public final static String SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN = "SUBJECTDN";
+ /*
+ * Include the signer's X500 Prinicple of the public key.
+ *
+ * Clients will not be able to validate the signature unless they have a
+ * copy of the signer's public key in a trust store or the full certificate
+ * is included out of band
+ *
+ * Example
+ * <pre>
+ * Map map = new HashMap();
+ * map.put(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL, "true");</pre>
+ * any value can be used.
+ *
+ * @see SIGNATURE_OPTION_CERT_INCLUSION_BASE64
+ */
+ //public final static String SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL = "X500";
+
+ /**
+ * This is the namespace of the digital signature.
+ */
+ public final static String XML_DIGSIG_NS = "http://www.w3.org/2000/09/xmldsig#";
+ /**
+ * Default value DigestMethod.SHA1 =
+ * "http://www.w3.org/2000/09/xmldsig#sha1"
+ *
+ * @see javax.xml.crypto.dsig.DigestMethod
+ */
+ public final static String SIGNATURE_OPTION_DIGEST_METHOD = "digestMethod";
+ /**
+ * When validating a signature, include this field will validate that
+ * the signature is still valid with regards to timestamps NotBefore and
+ * OnOrAfter
+ *
+ * Example
+ * <pre>
+ * Map map = new HashMap();
+ * map.put(DigSigUtil.CHECK_TIMESTAMPS, true);</pre> any value can be
+ * used.
+ */
+ public final static String CHECK_TIMESTAMPS = "checkTimestamps";
+ private CertificateFactory cf = null;
+ public final static String CHECK_REVOCATION_STATUS_OCSP = "checkRevocationOCSP";
+ public final static String CHECK_REVOCATION_STATUS_CRL = "checkRevocationCRL";
+ public final static String CHECK_TRUST_CHAIN = "checkTrust";
+
+ /**
+ * Digital signs a UDDI entity, such as a business, service, tmodel or
+ * binding template using the map to provide certificate key stores and
+ * credentials<br><br> The UDDI entity MUST support XML Digital
+ * Signatures (tModel, Business, Service, Binding Template)
+ *
+ * @param <T> Any UDDI entity that supports digital signatures
+ * @param jaxbObj
+ * @return an enveloped signed UDDI element, do not modify this object
+ * after signing
+ */
+ public <T> T signUddiEntity(T jaxbObj) {
+ DOMResult domResult = new DOMResult();
+ JAXB.marshal(jaxbObj, domResult);
+ Document doc = ((Document) domResult.getNode());
+ Element docElement = doc.getDocumentElement();
+
try {
- url = new File(map.getProperty(SIGNATURE_KEYSTORE_FILE)).toURI().toURL();
- } catch (Exception x) {
+ KeyStore ks = KeyStore.getInstance(map.getProperty(SIGNATURE_KEYSTORE_FILETYPE));
+ URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
+ if (url == null) {
+ try {
+ url = new File(map.getProperty(SIGNATURE_KEYSTORE_FILE)).toURI().toURL();
+ } catch (Exception x) {
+ }
+ }
+ if (url == null) {
+ try {
+ url = this.getClass().getClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
+ } catch (Exception x) {
+ }
+ }
+ KeyStore.PrivateKeyEntry keyEntry = null;
+ if (!map.getProperty(SIGNATURE_KEYSTORE_FILETYPE).equalsIgnoreCase("WINDOWS-MY")) {
+ ks.load(url.openStream(), (map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD)).toCharArray());
+ if (map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD) == null) {
+ keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
+ new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray()));
+ } else {
+ keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
+ new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD).toCharArray()));
+ }
+ } else {
+ //Windows only
+ ks.load(null, null);
+ keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
+ null);
+ }
+
+ PrivateKey privateKey = keyEntry.getPrivateKey();
+ Certificate origCert = keyEntry.getCertificate();
+ //PublicKey validatingKey = origCert.getPublicKey();
+ this.signDOM(docElement, privateKey, origCert);
+
+ DOMSource domSource = new DOMSource(doc);
+ T result = (T) JAXB.unmarshal(domSource, jaxbObj.getClass());
+ return result;
+ } catch (Exception e) {
+ throw new RuntimeException("Signature failure due to: " + e.getMessage(), e);
}
- }
- if (url == null) {
+ }
+
+ /**
+ * Digitally signs a UDDI entity, such as a business, service, tmodel or
+ * binding template, provided you've already done the legwork to provide
+ * the signing keys <br><br> The UDDI entity MUST support XML Digital
+ * Signatures (tModel, Business, Service, Binding Template)
+ *
+ * @param <T>
+ * @param jaxbObj
+ * @param publicKey
+ * @param privateKey
+ * @return a signed entity
+ */
+ public <T> T signUddiEntity(T jaxbObj, Certificate publicKey, PrivateKey privateKey) {
+ DOMResult domResult = new DOMResult();
+ JAXB.marshal(jaxbObj, domResult);
+ Document doc = ((Document) domResult.getNode());
+ Element docElement = doc.getDocumentElement();
try {
- url = this.getClass().getClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
- } catch (Exception x) {
- }
- }
- KeyStore.PrivateKeyEntry keyEntry = null;
- if (!map.getProperty(SIGNATURE_KEYSTORE_FILETYPE).equalsIgnoreCase("WINDOWS-MY")) {
- ks.load(url.openStream(), (map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD)).toCharArray());
- if (map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD) == null) {
- keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
- new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray()));
- } else {
- keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
- new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD).toCharArray()));
- }
- } else {
- //Windows only
- ks.load(null, null);
- keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
- null);
- }
-
-
- PrivateKey privateKey = keyEntry.getPrivateKey();
- Certificate origCert = keyEntry.getCertificate();
- //PublicKey validatingKey = origCert.getPublicKey();
- this.signDOM(docElement, privateKey, origCert);
-
- DOMSource domSource = new DOMSource(doc);
- T result = (T) JAXB.unmarshal(domSource, jaxbObj.getClass());
- return result;
- } catch (Exception e) {
- throw new RuntimeException("Signature failure due to: " + e.getMessage(), e);
- }
- }
-
- /**
- * Digitally signs a UDDI entity, such as a business, service, tmodel or
- * binding template, provided you've already done the legwork to provide the
- * signing keys <br><br> The UDDI entity MUST support XML Digital Signatures
- * (tModel, Business, Service, Binding Template)
- *
- * @param <T>
- * @param jaxbObj
- * @param publicKey
- * @param privateKey
- * @return
- */
- public <T> T signUddiEntity(T jaxbObj, Certificate publicKey, PrivateKey privateKey) {
- DOMResult domResult = new DOMResult();
- JAXB.marshal(jaxbObj, domResult);
- Document doc = ((Document) domResult.getNode());
- Element docElement = doc.getDocumentElement();
- try {
-
- //PublicKey validatingKey = origCert.getPublicKey();
- this.signDOM(docElement, privateKey, publicKey);
- DOMSource domSource = new DOMSource(doc);
- T result = (T) JAXB.unmarshal(domSource, jaxbObj.getClass());
- return result;
- } catch (Exception e) {
- throw new RuntimeException("Signature failure due to: " + e.getMessage(), e);
- }
- }
-
- /**
- * Serializes a JAXB object and prints to stdout
- *
- * @param obj
- */
- public static void JAXB_ToStdOut(Object obj) {
- StringWriter sw = new StringWriter();
- JAXB.marshal(obj, sw);
- System.out.println(sw.toString());
- }
-
- /**
- * Serializes a JAXB object and prints to stdout
- *
- * @param obj
- * @return
- */
- public static String JAXB_ToString(Object obj) {
- StringWriter sw = new StringWriter();
- JAXB.marshal(obj, sw);
- return (sw.toString());
- }
-
- /**
- *
- * returns the public key of the signing certificate used for a signed JAXB
- * object.
- *
- * @param obj
- * @return null if the item is not signed or if it references a certificate
- * that is not present in the current keystore
- * * @throws IllegalArgumentException for null input
- */
- public X509Certificate getSigningCertificatePublicKey(Object obj) throws IllegalArgumentException, CertificateException {
- DOMResult domResult = new DOMResult();
- JAXB.marshal(obj, domResult);
-
- Document doc = ((Document) domResult.getNode());
- Element docElement = doc.getDocumentElement(); //this is our signed node
- return getSigningCertificatePublicKey(docElement);
- }
-
- /**
- *
- * returns the public key of the signing certificate used for a signed JAXB
- * object.
- *
- * @param obj
- * @return null if the item is not signed or if it references a certificate
- * that is not present in the current keystore
- * * @throws IllegalArgumentException for null input
- */
- private X509Certificate getSigningCertificatePublicKey(Element docElement) throws IllegalArgumentException, CertificateException {
- if (docElement == null) {
- throw new IllegalArgumentException();
- }
-
- NodeList childNodes = docElement.getChildNodes(); //children, one of these SHOULD be our signature element
- // X509Certificate signingcert = null;
- for (int i = 0; i < childNodes.getLength(); i++) {
- //System.out.println(childNodes.item(i).getNamespaceURI() + " " + childNodes.item(i).getNodeName());
- if (childNodes.item(i).getNamespaceURI().equalsIgnoreCase(XML_DIGSIG_NS) && childNodes.item(i).getLocalName().equalsIgnoreCase("Signature")) {
- Node sig = childNodes.item(i);
- for (int k = 0; k < sig.getChildNodes().getLength(); k++) {
- // System.out.println(sig.getChildNodes().item(k).getNamespaceURI() + " " + sig.getChildNodes().item(k).getNodeName());
- if (sig.getChildNodes().item(k).getLocalName().equalsIgnoreCase("KeyInfo")) {
- //TODO figure out how to reference Subject DN, serial, thumbprint, etc
- for (int j = 0; j < sig.getChildNodes().item(k).getChildNodes().getLength(); j++) {
- if (sig.getChildNodes().item(k).getChildNodes().item(j).getLocalName().equalsIgnoreCase("X509Data")) {
- Node X509Data = sig.getChildNodes().item(k).getChildNodes().item(j);
- for (int x = 0; x < X509Data.getChildNodes().getLength(); x++) {
- if (X509Data.getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509Certificate")) {
- //yay found it!
+ //PublicKey validatingKey = origCert.getPublicKey();
+ this.signDOM(docElement, privateKey, publicKey);
+ DOMSource domSource = new DOMSource(doc);
+ T result = (T) JAXB.unmarshal(domSource, jaxbObj.getClass());
+ return result;
+ } catch (Exception e) {
+ throw new RuntimeException("Signature failure due to: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Serializes a JAXB object and prints to stdout
+ *
+ * @param obj
+ */
+ public static void JAXB_ToStdOut(Object obj) {
+ StringWriter sw = new StringWriter();
+ JAXB.marshal(obj, sw);
+ System.out.println(sw.toString());
+ }
+
+ /**
+ * Serializes a JAXB object and prints to stdout
+ *
+ * @param obj
+ * @return serialized text
+ */
+ public static String JAXB_ToString(Object obj) {
+ StringWriter sw = new StringWriter();
+ JAXB.marshal(obj, sw);
+ return (sw.toString());
+ }
+
+ /**
+ *
+ * returns the public key of the signing certificate used for a signed
+ * JAXB object.
+ *
+ * @param obj
+ * @return null if the item is not signed or if it references a
+ * certificate that is not present in the current keystore
+ * @throws IllegalArgumentException for null input
+ * @throws java.security.cert.CertificateException
+ */
+ public X509Certificate getSigningCertificatePublicKey(Object obj) throws IllegalArgumentException, CertificateException {
+ DOMResult domResult = new DOMResult();
+ JAXB.marshal(obj, domResult);
+
+ Document doc = ((Document) domResult.getNode());
+ Element docElement = doc.getDocumentElement(); //this is our signed node
+ return getSigningCertificatePublicKey(docElement);
+ }
+
+ /**
+ *
+ * returns the public key of the signing certificate used for a signed
+ * JAXB object.
+ *
+ * @param obj
+ * @return null if the item is not signed or if it references a
+ * certificate that is not present in the current keystore
+ * * @throws IllegalArgumentException for null input
+ */
+ private X509Certificate getSigningCertificatePublicKey(Element docElement) throws IllegalArgumentException, CertificateException {
+ if (docElement == null) {
+ throw new IllegalArgumentException();
+ }
+
+ NodeList childNodes = docElement.getChildNodes(); //children, one of these SHOULD be our signature element
+ // X509Certificate signingcert = null;
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ //System.out.println(childNodes.item(i).getNamespaceURI() + " " + childNodes.item(i).getNodeName());
+ if (childNodes.item(i).getNamespaceURI().equalsIgnoreCase(XML_DIGSIG_NS) && childNodes.item(i).getLocalName().equalsIgnoreCase("Signature")) {
+ Node sig = childNodes.item(i);
+ for (int k = 0; k < sig.getChildNodes().getLength(); k++) {
+ // System.out.println(sig.getChildNodes().item(k).getNamespaceURI() + " " + sig.getChildNodes().item(k).getNodeName());
+ if (sig.getChildNodes().item(k).getLocalName().equalsIgnoreCase("KeyInfo")) {
+ //TODO figure out how to reference Subject DN, serial, thumbprint, etc
+ for (int j = 0; j < sig.getChildNodes().item(k).getChildNodes().getLength(); j++) {
+ if (sig.getChildNodes().item(k).getChildNodes().item(j).getLocalName().equalsIgnoreCase("X509Data")) {
+ Node X509Data = sig.getChildNodes().item(k).getChildNodes().item(j);
+ for (int x = 0; x < X509Data.getChildNodes().getLength(); x++) {
+ if (X509Data.getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509Certificate")) {
+ //yay found it!
- String c =
- "-----BEGIN CERTIFICATE-----\n"
- + X509Data.getChildNodes().item(x).getTextContent()
- + "\n-----END CERTIFICATE-----";
- //System.out.println("X509 Public key: " + c);
- InputStream is = new ByteArrayInputStream(c.getBytes());
- X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+ String c
+ = "-----BEGIN CERTIFICATE-----\n"
+ + X509Data.getChildNodes().item(x).getTextContent()
+ + "\n-----END CERTIFICATE-----";
+ //System.out.println("X509 Public key: " + c);
+ InputStream is = new ByteArrayInputStream(c.getBytes());
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
- logger.info("embedded certificate found, X509 public key " + cert.getSubjectDN().toString());
- return cert;
+ logger.info("embedded certificate found, X509 public key " + cert.getSubjectDN().toString());
+ return cert;
- }
+ }
//if we have a
- //TODO other parsing items, lots of other potentials here
+ //TODO other parsing items, lots of other potentials here
+ }
+ X509Certificate cert = FindCert(X509Data.getChildNodes());
+ if (cert != null) {
+ logger.info("certificate loaded from local trust store, X509 public key " + cert.getSubjectDN().toString());
+ return cert;
+ }
+ }
+
+ }
+ break;
+ }
+
}
- X509Certificate cert = FindCert(X509Data.getChildNodes());
- if (cert != null) {
- logger.info("certificate loaded from local trust store, X509 public key " + cert.getSubjectDN().toString());
- return cert;
- }
- }
-
- }
- break;
- }
-
- }
-
- break;
- }
- }
- return null;
- }
-
- /**
- * Verifies the signature on an enveloped digital signature on a UDDI
- * entity, such as a business, service, tmodel or binding template. <br><Br>
- * It is expected that either the public key of the signing certificate is
- * included within the signature keyinfo section OR that sufficient
- * information is provided in the signature to reference a public key
- * located within the Trust Store provided<br><Br> Optionally, this function
- * also validate the signing certificate using the options provided to the
- * configuration map.
- *
- * @param obj an enveloped signed JAXB object
- * @param OutErrorMessage a human readable error message explaining the
- * reason for failure
- * @return true if the validation passes the signature validation test, and
- * optionally any certificate validation or trust chain validation
- * @throws IllegalArgumentException for null input
- */
- public boolean verifySignedUddiEntity(Object obj, AtomicReference<String> OutErrorMessage) throws IllegalArgumentException {
- if (OutErrorMessage == null) {
- OutErrorMessage = new AtomicReference<String>();
- OutErrorMessage.set("");
- }
- if (obj == null) {
- throw new IllegalArgumentException("obj");
- }
- try {
- DOMResult domResult = new DOMResult();
- JAXB.marshal(obj, domResult);
-
- Document doc = ((Document) domResult.getNode());
- Element docElement = doc.getDocumentElement(); //this is our signed node
-
- X509Certificate signingcert = getSigningCertificatePublicKey(docElement);
-
- if (signingcert != null) {
- logger.info("verifying signature based on X509 public key " + signingcert.getSubjectDN().toString());
- if (map.containsKey(CHECK_TIMESTAMPS) && Boolean.parseBoolean(map.getProperty(CHECK_TIMESTAMPS))) {
- signingcert.checkValidity();
- }
- if (map.containsKey(CHECK_REVOCATION_STATUS_OCSP)
- && Boolean.parseBoolean(map.getProperty(CHECK_REVOCATION_STATUS_OCSP))) {
- logger.info("verifying revocation status via OSCP for X509 public key " + signingcert.getSubjectDN().toString());
- X500Principal issuerX500Principal = signingcert.getIssuerX500Principal();
- logger.info("certificate " + signingcert.getSubjectDN().toString() + " was issued by " + issuerX500Principal.getName() + ", attempting to retrieve certificate");
- Security.setProperty("ocsp.enable", "false");
- X509Certificate issuer = FindCertByDN(issuerX500Principal);
- if (issuer == null) {
- OutErrorMessage.set("Unable to verify certificate status from OCSP because the issuer of the certificate is not in the trust store. " + OutErrorMessage.get());
- //throw new CertificateException("unable to locate the issuers certificate in the trust store");
- } else {
- RevocationStatus check = OCSP.check(signingcert, issuer);
- logger.info("certificate " + signingcert.getSubjectDN().toString() + " revocation status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString());
- if (check.getCertStatus() != RevocationStatus.CertStatus.GOOD) {
- OutErrorMessage.set("Certificate status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString() + "." + OutErrorMessage.get());
-
- //throw new CertificateException("Certificate status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString());
- }
- }
- }
- if (map.containsKey(CHECK_REVOCATION_STATUS_CRL) && Boolean.parseBoolean(map.getProperty(CHECK_REVOCATION_STATUS_CRL))) {
- logger.info("verifying revokation status via CRL for X509 public key " + signingcert.getSubjectDN().toString());
-
- Security.setProperty("ocsp.enable", "false");
- System.setProperty("com.sun.security.enableCRLDP", "true");
-
- X509CertSelector targetConstraints = new X509CertSelector();
- targetConstraints.setCertificate(signingcert);
- PKIXParameters params = new PKIXParameters(GetTrustStore());
- params.setRevocationEnabled(true);
- CertPath certPath = cf.generateCertPath(Arrays.asList(signingcert));
-
- CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
- CertPathValidatorResult result = certPathValidator.validate(certPath, params);
- try {
- PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult) result;
- logger.info("revokation status via CRL PASSED for X509 public key " + signingcert.getSubjectDN().toString());
- } catch (Exception ex) {
- OutErrorMessage.set("Certificate status is via CRL Failed: " + ex.getMessage() + "." + OutErrorMessage.get());
- }
- }
- if (map.containsKey(CHECK_TRUST_CHAIN) && Boolean.parseBoolean(map.getProperty(CHECK_TRUST_CHAIN))) {
- logger.info("verifying trust chain X509 public key " + signingcert.getSubjectDN().toString());
- try {
- PKIXParameters params = new PKIXParameters(GetTrustStore());
- params.setRevocationEnabled(false);
- CertPath certPath = cf.generateCertPath(Arrays.asList(signingcert));
-
- CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
- CertPathValidatorResult result = certPathValidator.validate(certPath, params);
-
- PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult) result;
-
- TrustAnchor ta = pkixResult.getTrustAnchor();
- X509Certificate cert = ta.getTrustedCert();
-
- logger.info("trust chain validated X509 public key " + signingcert.getSubjectDN().toString());
- } catch (Exception ex) {
- OutErrorMessage.set("Certificate status Trust validation failed: " + ex.getMessage() + "." + OutErrorMessage.get());
- }
- }
- boolean b = verifySignature(docElement, signingcert.getPublicKey(), OutErrorMessage);
- if ((OutErrorMessage.get() == null || OutErrorMessage.get().length() == 0) && b) {
- //no error message and its cryptographically valid
- return true;
- }
- return false;
- }
-
- //last chance validation
- logger.info("signature did not have an embedded X509 public key. reverting to user specified certificate");
- //cert wasn't included in the signature, revert to some other means
- KeyStore ks = KeyStore.getInstance(map.getProperty(SIGNATURE_KEYSTORE_FILETYPE));
- URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
- if (url == null) {
- try {
- url = new File(map.getProperty(SIGNATURE_KEYSTORE_FILE)).toURI().toURL();
- } catch (Exception x) {
+
+ break;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Verifies the signature on an enveloped digital signature on a UDDI
+ * entity, such as a business, service, tmodel or binding template.
+ * <br><Br>
+ * It is expected that either the public key of the signing certificate
+ * is included within the signature keyinfo section OR that sufficient
+ * information is provided in the signature to reference a public key
+ * located within the Trust Store provided<br><Br> Optionally, this
+ * function also validate the signing certificate using the options
+ * provided to the configuration map.
+ *
+ * @param obj an enveloped signed JAXB object
+ * @param OutErrorMessage a human readable error message explaining the
+ * reason for failure
+ * @return true if the validation passes the signature validation test,
+ * and optionally any certificate validation or trust chain validation
+ * @throws IllegalArgumentException for null input
+ */
+ public boolean verifySignedUddiEntity(Object obj, AtomicReference<String> OutErrorMessage) throws IllegalArgumentException {
+ if (OutErrorMessage == null) {
+ OutErrorMessage = new AtomicReference<String>();
+ OutErrorMessage.set("");
+ }
+ if (obj == null) {
+ throw new IllegalArgumentException("obj");
}
- }
- if (url == null) {
try {
- url = this.getClass().getClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
- } catch (Exception x) {
+ DOMResult domResult = new DOMResult();
+ JAXB.marshal(obj, domResult);
+
+ Document doc = ((Document) domResult.getNode());
+ Element docElement = doc.getDocumentElement(); //this is our signed node
+
+ X509Certificate signingcert = getSigningCertificatePublicKey(docElement);
+
+ if (signingcert != null) {
+ logger.info("verifying signature based on X509 public key " + signingcert.getSubjectDN().toString());
+ if (map.containsKey(CHECK_TIMESTAMPS) && Boolean.parseBoolean(map.getProperty(CHECK_TIMESTAMPS))) {
+ signingcert.checkValidity();
+ }
+ if (map.containsKey(CHECK_REVOCATION_STATUS_OCSP)
+ && Boolean.parseBoolean(map.getProperty(CHECK_REVOCATION_STATUS_OCSP))) {
+ logger.info("verifying revocation status via OSCP for X509 public key " + signingcert.getSubjectDN().toString());
+ X500Principal issuerX500Principal = signingcert.getIssuerX500Principal();
+ logger.info("certificate " + signingcert.getSubjectDN().toString() + " was issued by " + issuerX500Principal.getName() + ", attempting to retrieve certificate");
+ Security.setProperty("ocsp.enable", "false");
+ X509Certificate issuer = FindCertByDN(issuerX500Principal);
+ if (issuer == null) {
+ OutErrorMessage.set("Unable to verify certificate status from OCSP because the issuer of the certificate is not in the trust store. " + OutErrorMessage.get());
+ //throw new CertificateException("unable to locate the issuers certificate in the trust store");
+ } else {
+ RevocationStatus check = OCSP.check(signingcert, issuer);
+ logger.info("certificate " + signingcert.getSubjectDN().toString() + " revocation status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString());
+ if (check.getCertStatus() != RevocationStatus.CertStatus.GOOD) {
+ OutErrorMessage.set("Certificate status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString() + "." + OutErrorMessage.get());
+
+ //throw new CertificateException("Certificate status is " + check.getCertStatus().toString() + " reason " + check.getRevocationReason().toString());
+ }
+ }
+ }
+ if (map.containsKey(CHECK_REVOCATION_STATUS_CRL) && Boolean.parseBoolean(map.getProperty(CHECK_REVOCATION_STATUS_CRL))) {
+ logger.info("verifying revokation status via CRL for X509 public key " + signingcert.getSubjectDN().toString());
+
+ Security.setProperty("ocsp.enable", "false");
+ System.setProperty("com.sun.security.enableCRLDP", "true");
+
+ X509CertSelector targetConstraints = new X509CertSelector();
+ targetConstraints.setCertificate(signingcert);
+ PKIXParameters params = new PKIXParameters(GetTrustStore());
+ params.setRevocationEnabled(true);
+ CertPath certPath = cf.generateCertPath(Arrays.asList(signingcert));
+
+ CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
+ CertPathValidatorResult result = certPathValidator.validate(certPath, params);
+ try {
+ PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult) result;
+ logger.info("revokation status via CRL PASSED for X509 public key " + signingcert.getSubjectDN().toString());
+ } catch (Exception ex) {
+ OutErrorMessage.set("Certificate status is via CRL Failed: " + ex.getMessage() + "." + OutErrorMessage.get());
+ }
+ }
+ if (map.containsKey(CHECK_TRUST_CHAIN) && Boolean.parseBoolean(map.getProperty(CHECK_TRUST_CHAIN))) {
+ logger.info("verifying trust chain X509 public key " + signingcert.getSubjectDN().toString());
+ try {
+ PKIXParameters params = new PKIXParameters(GetTrustStore());
+ params.setRevocationEnabled(false);
+ CertPath certPath = cf.generateCertPath(Arrays.asList(signingcert));
+
+ CertPathValidator certPathValidator = CertPathValidator.getInstance(CertPathValidator.getDefaultType());
+ CertPathValidatorResult result = certPathValidator.validate(certPath, params);
+
+ PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult) result;
+
+ TrustAnchor ta = pkixResult.getTrustAnchor();
+ X509Certificate cert = ta.getTrustedCert();
+
+ logger.info("trust chain validated X509 public key " + signingcert.getSubjectDN().toString());
+ } catch (Exception ex) {
+ OutErrorMessage.set("Certificate status Trust validation failed: " + ex.getMessage() + "." + OutErrorMessage.get());
+ }
+ }
+ boolean b = verifySignature(docElement, signingcert.getPublicKey(), OutErrorMessage);
+ if ((OutErrorMessage.get() == null || OutErrorMessage.get().length() == 0) && b) {
+ //no error message and its cryptographically valid
+ return true;
+ }
+ return false;
+ }
+
+ //last chance validation
+ logger.info("signature did not have an embedded X509 public key. reverting to user specified certificate");
+ //cert wasn't included in the signature, revert to some other means
+ KeyStore ks = KeyStore.getInstance(map.getProperty(SIGNATURE_KEYSTORE_FILETYPE));
+ URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
+ if (url == null) {
+ try {
+ url = new File(map.getProperty(SIGNATURE_KEYSTORE_FILE)).toURI().toURL();
+ } catch (Exception x) {
+ }
+ }
+ if (url == null) {
+ try {
+ url = this.getClass().getClassLoader().getResource(map.getProperty(SIGNATURE_KEYSTORE_FILE));
+ } catch (Exception x) {
+ }
+ }
+ if (url == null) {
+ logger.error("");
+ OutErrorMessage.set("The signed entity is signed but does not have a certificate attached and"
+ + "you didn't specify a keystore for me to look it up in. " + OutErrorMessage.get());
+ return false;
+ }
+ KeyStore.PrivateKeyEntry keyEntry = null;
+
+ ks.load(url.openStream(), map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray());
+
+ if (map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD) == null) {
+ keyEntry
+ = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
+ new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray()));
+ } else {
+ keyEntry
+ = (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
+ new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD).toCharArray()));
+ }
+
+ Certificate origCert = keyEntry.getCertificate();
+ if (map.containsKey(CHECK_TIMESTAMPS)) {
+ if (origCert.getPublicKey() instanceof X509Certificate) {
+ X509Certificate x = (X509Certificate) origCert.getPublicKey();
+ x.checkValidity();
+ }
+ }
+ PublicKey validatingKey = origCert.getPublicKey();
+ return verifySignature(docElement, validatingKey, OutErrorMessage);
+ } catch (Exception e) {
+ //throw new RuntimeException(e);
+ logger.error("Error caught validating signature", e);
+ OutErrorMessage.set(e.getMessage());
+ return false;
}
- }
- if (url == null) {
- logger.error("");
- OutErrorMessage.set("The signed entity is signed but does not have a certificate attached and"
- + "you didn't specify a keystore for me to look it up in. " + OutErrorMessage.get());
- return false;
- }
- KeyStore.PrivateKeyEntry keyEntry = null;
-
- ks.load(url.openStream(), map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray());
-
- if (map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD) == null) {
- keyEntry =
- (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
- new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_FILE_PASSWORD).toCharArray()));
- } else {
- keyEntry =
- (KeyStore.PrivateKeyEntry) ks.getEntry(map.getProperty(SIGNATURE_KEYSTORE_KEY_ALIAS),
- new KeyStore.PasswordProtection(map.getProperty(SIGNATURE_KEYSTORE_KEY_PASSWORD).toCharArray()));
- }
-
-
- Certificate origCert = keyEntry.getCertificate();
- if (map.containsKey(CHECK_TIMESTAMPS)) {
- if (origCert.getPublicKey() instanceof X509Certificate) {
- X509Certificate x = (X509Certificate) origCert.getPublicKey();
- x.checkValidity();
- }
- }
- PublicKey validatingKey = origCert.getPublicKey();
- return verifySignature(docElement, validatingKey, OutErrorMessage);
- } catch (Exception e) {
- //throw new RuntimeException(e);
- logger.error("Error caught validating signature", e);
- OutErrorMessage.set(e.getMessage());
- return false;
- }
- }
-
- private KeyStore GetTrustStore() throws Exception {
- String type = map.getProperty(TRUSTSTORE_FILETYPE);
- if (type == null) {
- type = "JKS";
- }
- KeyStore ks = KeyStore.getInstance(type);
- boolean ksLoaded = false;
-
- //try windows trust store first
- try {
- if (map.getProperty(TRUSTSTORE_FILETYPE).equalsIgnoreCase("WINDOWS-ROOT")) {
- ks.load(null, null);
- ksLoaded = true;
- logger.info("trust store loaded from windows");
- }
- } catch (Exception ex) {
- logger.debug("unable to load truststore from windows", ex);
- }
-
- //load from thread classloader
- if (!ksLoaded) {
- try {
- URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(TRUSTSTORE_FILE));
- ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
- ksLoaded = true;
- logger.info("trust store loaded from classpath(1) " + map.getProperty(TRUSTSTORE_FILE));
- } catch (Exception x) {
- logger.debug("unable to load truststore from classpath", x);
- }
- }
-
- //load from this classloader
- if (!ksLoaded) {
- try {
- URL url = this.getClass().getClassLoader().getResource(map.getProperty(TRUSTSTORE_FILE));
- ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
- ksLoaded = true;
- logger.info("trust store loaded from classpath(2) " + map.getProperty(TRUSTSTORE_FILE));
- } catch (Exception x) {
- logger.debug("unable to load truststore from classpath", x);
- }
- }
- //load as a file
- if (!ksLoaded) {
- try {
- URL url = new File(map.getProperty(TRUSTSTORE_FILE)).toURI().toURL();
- ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
- ksLoaded = true;
- logger.info("trust store loaded from file " + map.getProperty(TRUSTSTORE_FILE));
- } catch (Exception x) {
- logger.debug("unable to load truststore from file", x);
- }
}
+ private KeyStore GetTrustStore() throws Exception {
+ String type = map.getProperty(TRUSTSTORE_FILETYPE);
+ if (type == null) {
+ type = "JKS";
+ }
+ KeyStore ks = KeyStore.getInstance(type);
+ boolean ksLoaded = false;
+
+ //try windows trust store first
+ try {
+ if (map.getProperty(TRUSTSTORE_FILETYPE).equalsIgnoreCase("WINDOWS-ROOT")) {
+ ks.load(null, null);
+ ksLoaded = true;
+ logger.info("trust store loaded from windows");
+ }
+ } catch (Exception ex) {
+ logger.debug("unable to load truststore from windows", ex);
+ }
+
+ //load from thread classloader
+ if (!ksLoaded) {
+ try {
+ URL url = Thread.currentThread().getContextClassLoader().getResource(map.getProperty(TRUSTSTORE_FILE));
+ ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
+ ksLoaded = true;
+ logger.info("trust store loaded from classpath(1) " + map.getProperty(TRUSTSTORE_FILE));
+ } catch (Exception x) {
+ logger.debug("unable to load truststore from classpath", x);
+ }
+ }
+
+ //load from this classloader
+ if (!ksLoaded) {
+ try {
+ URL url = this.getClass().getClassLoader().getResource(map.getProperty(TRUSTSTORE_FILE));
+ ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
+ ksLoaded = true;
+ logger.info("trust store loaded from classpath(2) " + map.getProperty(TRUSTSTORE_FILE));
+ } catch (Exception x) {
+ logger.debug("unable to load truststore from classpath", x);
+ }
+ }
+ //load as a file
+ if (!ksLoaded) {
+ try {
+ URL url = new File(map.getProperty(TRUSTSTORE_FILE)).toURI().toURL();
+ ks.load(url.openStream(), (map.getProperty(TRUSTSTORE_FILE_PASSWORD)).toCharArray());
+ ksLoaded = true;
+ logger.info("trust store loaded from file " + map.getProperty(TRUSTSTORE_FILE));
+ } catch (Exception x) {
+ logger.debug("unable to load truststore from file", x);
+ }
+ }
// logger.error("Unable to load user specified trust store! attempting to load the default", ex);
+ //load from system property
+ if (!ksLoaded) {
+ try {
+ String truststore = System.getProperty("javax.net.ssl.keyStore");
+ String pwd = System.getProperty("javax.net.ssl.keyStorePassword");
+ if (truststore != null && pwd != null) {
+ ks.load(new File(truststore).toURI().toURL().openStream(), pwd.toCharArray());
+ ksLoaded = true;
+ logger.info("trust store loaded from sysprop " + truststore);
+ }
+ } catch (Exception ex) {
+ logger.debug("unable to load truststore from sysprop", ex);
+ }
+ }
+
+ if (!ksLoaded) {
+ try {
+ URL cacerts = new File(System.getenv("JAVA_HOME") + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts").toURI().toURL();
+ ks.load(cacerts.openStream(), "changeit".toCharArray());
+ logger.info("trust store loaded from JRE " + cacerts.toExternalForm());
+ ksLoaded = true;
+ } catch (Exception c) {
+ logger.debug("unable to load default JDK truststore", c);
+ }
+ }
+ if (!ksLoaded) {
+ try {
+ URL cacerts = new File(System.getenv("JAVA_HOME") + File.separator + "jre" + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts").toURI().toURL();
+ ks.load(cacerts.openStream(), "changeit".toCharArray());
+ logger.info("trust store loaded from JRE " + cacerts.toExternalForm());
+ ksLoaded = true;
+ } catch (Exception c) {
+ logger.debug("unable to load default jdk/jre truststore", c);
+ }
+ }
+ if (!ksLoaded) {
+ logger.warn("unable to load trust store!");
+ }
- //load from system property
- if (!ksLoaded) {
- try {
- String truststore = System.getProperty("javax.net.ssl.keyStore");
- String pwd = System.getProperty("javax.net.ssl.keyStorePassword");
- if (truststore != null && pwd != null) {
- ks.load(new File(truststore).toURI().toURL().openStream(), pwd.toCharArray());
- ksLoaded = true;
- logger.info("trust store loaded from sysprop " + truststore);
- }
- } catch (Exception ex) {
- logger.debug("unable to load truststore from sysprop", ex);
- }
- }
-
- if (!ksLoaded) {
- try {
- URL cacerts = new File(System.getenv("JAVA_HOME") + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts").toURI().toURL();
- ks.load(cacerts.openStream(), "changeit".toCharArray());
- logger.info("trust store loaded from JRE " + cacerts.toExternalForm());
- ksLoaded = true;
- } catch (Exception c) {
- logger.debug("unable to load default JDK truststore", c);
- }
- }
- if (!ksLoaded) {
- try {
- URL cacerts = new File(System.getenv("JAVA_HOME") + File.separator + "jre" + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts").toURI().toURL();
- ks.load(cacerts.openStream(), "changeit".toCharArray());
- logger.info("trust store loaded from JRE " + cacerts.toExternalForm());
- ksLoaded = true;
- } catch (Exception c) {
- logger.debug("unable to load default jdk/jre truststore", c);
- }
- }
- if (!ksLoaded)
- {
- logger.warn("unable to load trust store!");
- }
-
-
- return ks;
- }
-
- private XMLSignatureFactory initXMLSigFactory() {
- XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
- return fac;
- }
-
- private Reference initReference(XMLSignatureFactory fac) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- List transformers = new ArrayList();
- transformers.add(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
-
- String dm = map.getProperty(SIGNATURE_OPTION_DIGEST_METHOD);
- if (dm == null) {
- dm = DigestMethod.SHA1;
- }
- Reference ref = fac.newReference("", fac.newDigestMethod(dm, null), transformers, null, null);
- return ref;
- }
-
- private SignedInfo initSignedInfo(XMLSignatureFactory fac) throws Exception {
- Reference ref = initReference(fac);
- String cm = null;
- cm = map.getProperty(CANONICALIZATIONMETHOD);
- String sigmethod = null;
- sigmethod = map.getProperty(SIGNATURE_METHOD);
- if (sigmethod == null) {
- sigmethod = SignatureMethod.RSA_SHA1;
- }
- if (cm == null) {
- cm = CanonicalizationMethod.EXCLUSIVE;
- }
- SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(
- cm,
- (C14NMethodParameterSpec) null),
- fac.newSignatureMethod(sigmethod,
- null), Collections.singletonList(ref));
- return si;
- }
-
- private boolean verifySignature(Element element, PublicKey validatingKey, AtomicReference<String> OutReadableErrorMessage) {
- if (OutReadableErrorMessage == null) {
- OutReadableErrorMessage = new AtomicReference<String>();
- }
- XMLSignatureFactory fac = initXMLSigFactory();
- NodeList nl = element.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
- if (nl.getLength() == 0) {
- throw new RuntimeException("Cannot find Signature element");
- }
- DOMValidateContext valContext = new DOMValidateContext(validatingKey, nl.item(0));
- try {
- valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
- XMLSignature signature = fac.unmarshalXMLSignature(valContext);
- boolean coreValidity = signature.validate(valContext);
- // Check core validation status.
- if (coreValidity == false) {
- logger.warn("Signature failed core validation");
- boolean sv = signature.getSignatureValue().validate(valContext);
- logger.debug("signature validation status: " + sv);
- OutReadableErrorMessage.set("signature validation failed: " + sv + "." + OutReadableErrorMessage.get());
- // Check the validation status of each Reference.
- @SuppressWarnings("unchecked")
- Iterator<Reference> i = signature.getSignedInfo().getReferences().iterator();
- //System.out.println("---------------------------------------------");
- for (int j = 0; i.hasNext(); j++) {
- Reference ref = (Reference) i.next();
- boolean refValid = ref.validate(valContext);
- logger.debug(j);
- logger.debug("ref[" + j + "] validity status: " + refValid);
- if (!refValid) {
- OutReadableErrorMessage.set("signature reference " + j + " invalid. " + OutReadableErrorMessage.get());
- }
- logger.debug("Ref type: " + ref.getType() + ", URI: " + ref.getURI());
- for (Object xform : ref.getTransforms()) {
- logger.debug("Transform: " + xform);
- }
- String calcDigValStr = digestToString(ref.getCalculatedDigestValue());
- String expectedDigValStr = digestToString(ref.getDigestValue());
- logger.warn(" Calc Digest: " + calcDigValStr);
- logger.warn("Expected Digest: " + expectedDigValStr);
- if (!calcDigValStr.equalsIgnoreCase(expectedDigValStr)) {
- OutReadableErrorMessage.set("digest mismatch for signature ref " + j + "." + OutReadableErrorMessage.get());
- }
- }
- } else {
- logger.info("Signature passed core validation");
- }
- return coreValidity;
- } catch (Exception e) {
- OutReadableErrorMessage.set("signature validation failed: " + e.getMessage() + OutReadableErrorMessage.get());
- logger.fatal(e);
- return false;
- }
- }
-
- private String digestToString(byte[] digest) {
- StringBuilder sb = new StringBuilder();
- for (byte b : digest) {
- String hex = Integer.toHexString(0xFF & b);
- if (hex.length() == 1) {
- sb.append('0');
- }
- sb.append(hex);
- }
- return sb.toString();
- }
-
- private void signDOM(Node node, PrivateKey privateKey, Certificate origCert) {
- XMLSignatureFactory fac = initXMLSigFactory();
- X509Certificate cert = (X509Certificate) origCert;
- // Create the KeyInfo containing the X509Data.
-
- KeyInfoFactory kif = fac.getKeyInfoFactory();
-
-
- List<Object> x509Content = null;//new ArrayList<Object>();
- List<X509Data> data = new ArrayList<X509Data>();
- if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN)) {
- x509Content = new ArrayList<Object>();
+ return ks;
+ }
- x509Content.add(cert.getSubjectDN().getName());
- // x509Content.add(cert);
- //x509Content.add(cert.getSubjectDN().getName());
- X509Data xd = kif.newX509Data(x509Content);
- data.add(xd);
+ private XMLSignatureFactory initXMLSigFactory() {
+ XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
+ return fac;
}
- // if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL)) {
- // }
- if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_BASE64)) {
- x509Content = new ArrayList<Object>();
- x509Content.add(cert);
- //x509Content.add(cert.getSubjectX500Principal().getName());
- X509Data xd = kif.newX509Data(x509Content);
- data.add(xd);
- }
- if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_SERIAL)) {
- x509Content = new ArrayList<Object>();
-
- X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerX500Principal().getName(), cert.getSerialNumber());
-
- x509Content.add(issuer);
- X509Data xd = kif.newX509Data(x509Content);
- data.add(xd);
+ private Reference initReference(XMLSignatureFactory fac) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ List transformers = new ArrayList();
+ transformers.add(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null));
+
+ String dm = map.getProperty(SIGNATURE_OPTION_DIGEST_METHOD);
+ if (dm == null) {
+ dm = DigestMethod.SHA1;
+ }
+ Reference ref = fac.newReference("", fac.newDigestMethod(dm, null), transformers, null, null);
+ return ref;
}
- //
- //x509Content.add(cert);
+ private SignedInfo initSignedInfo(XMLSignatureFactory fac) throws Exception {
+ Reference ref = initReference(fac);
+ String cm = null;
+ cm = map.getProperty(CANONICALIZATIONMETHOD);
+ String sigmethod = null;
+ sigmethod = map.getProperty(SIGNATURE_METHOD);
+ if (sigmethod == null) {
+ sigmethod = SignatureMethod.RSA_SHA1;
+ }
+ if (cm == null) {
+ cm = CanonicalizationMethod.EXCLUSIVE;
+ }
+ SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(
+ cm,
+ (C14NMethodParameterSpec) null),
+ fac.newSignatureMethod(sigmethod,
+ null), Collections.singletonList(ref));
+ return si;
+ }
+ private boolean verifySignature(Element element, PublicKey validatingKey, AtomicReference<String> OutReadableErrorMessage) {
+ if (OutReadableErrorMessage == null) {
+ OutReadableErrorMessage = new AtomicReference<String>();
+ }
+ XMLSignatureFactory fac = initXMLSigFactory();
+ NodeList nl = element.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
+ if (nl.getLength() == 0) {
+ throw new RuntimeException("Cannot find Signature element");
+ }
+ DOMValidateContext valContext = new DOMValidateContext(validatingKey, nl.item(0));
+ try {
+ valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
+ XMLSignature signature = fac.unmarshalXMLSignature(valContext);
+ boolean coreValidity = signature.validate(valContext);
+ // Check core validation status.
+ if (coreValidity == false) {
+ logger.warn("Signature failed core validation");
+ boolean sv = signature.getSignatureValue().validate(valContext);
+ logger.debug("signature validation status: " + sv);
+ OutReadableErrorMessage.set("signature validation failed: " + sv + "." + OutReadableErrorMessage.get());
+ // Check the validation status of each Reference.
+ @SuppressWarnings("unchecked")
+ Iterator<Reference> i = signature.getSignedInfo().getReferences().iterator();
+ //System.out.println("---------------------------------------------");
+ for (int j = 0; i.hasNext(); j++) {
+ Reference ref = (Reference) i.next();
+ boolean refValid = ref.validate(valContext);
+ logger.debug(j);
+ logger.debug("ref[" + j + "] validity status: " + refValid);
+ if (!refValid) {
+ OutReadableErrorMessage.set("signature reference " + j + " invalid. " + OutReadableErrorMessage.get());
+ }
+ logger.debug("Ref type: " + ref.getType() + ", URI: " + ref.getURI());
+ for (Object xform : ref.getTransforms()) {
+ logger.debug("Transform: " + xform);
+ }
+ String calcDigValStr = digestToString(ref.getCalculatedDigestValue());
+ String expectedDigValStr = digestToString(ref.getDigestValue());
+ logger.warn(" Calc Digest: " + calcDigValStr);
+ logger.warn("Expected Digest: " + expectedDigValStr);
+ if (!calcDigValStr.equalsIgnoreCase(expectedDigValStr)) {
+ OutReadableErrorMessage.set("digest mismatch for signature ref " + j + "." + OutReadableErrorMessage.get());
+ }
+ }
+ } else {
+ logger.info("Signature passed core validation");
+ }
+ return coreValidity;
+ } catch (Exception e) {
+ OutReadableErrorMessage.set("signature validation failed: " + e.getMessage() + OutReadableErrorMessage.get());
+ logger.fatal(e);
+ return false;
+ }
+ }
- KeyInfo ki = kif.newKeyInfo(data);
+ private String digestToString(byte[] digest) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : digest) {
+ String hex = Integer.toHexString(0xFF & b);
+ if (hex.length() == 1) {
+ sb.append('0');
+ }
+ sb.append(hex);
+ }
+ return sb.toString();
+ }
+
+ private void signDOM(Node node, PrivateKey privateKey, Certificate origCert) {
+ XMLSignatureFactory fac = initXMLSigFactory();
+ X509Certificate cert = (X509Certificate) origCert;
+ // Create the KeyInfo containing the X509Data.
+
+ KeyInfoFactory kif = fac.getKeyInfoFactory();
+
+ List<Object> x509Content = null;//new ArrayList<Object>();
+ List<X509Data> data = new ArrayList<X509Data>();
+ if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN)) {
+ x509Content = new ArrayList<Object>();
+
+ x509Content.add(cert.getSubjectDN().getName());
+ // x509Content.add(cert);
+ //x509Content.add(cert.getSubjectDN().getName());
+ X509Data xd = kif.newX509Data(x509Content);
+ data.add(xd);
+ }
+
+ // if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_X500_PRINICPAL)) {
+ // }
+ if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_BASE64)) {
+ x509Content = new ArrayList<Object>();
+ x509Content.add(cert);
+ //x509Content.add(cert.getSubjectX500Principal().getName());
+ X509Data xd = kif.newX509Data(x509Content);
+ data.add(xd);
+ }
+ if (map.containsKey(SIGNATURE_OPTION_CERT_INCLUSION_SERIAL)) {
+ x509Content = new ArrayList<Object>();
+
+ X509IssuerSerial issuer = kif.newX509IssuerSerial(cert.getIssuerX500Principal().getName(), cert.getSerialNumber());
+
+ x509Content.add(issuer);
+ X509Data xd = kif.newX509Data(x509Content);
+ data.add(xd);
+ }
+
+ //
+ //x509Content.add(cert);
+ KeyInfo ki = kif.newKeyInfo(data);
// Create a DOMSignContext and specify the RSA PrivateKey and
- // location of the resulting XMLSignature's parent element.
- DOMSignContext dsc = new DOMSignContext(privateKey, node);
- dsc.putNamespacePrefix(XML_DIGSIG_NS, "ns2");
-
- // Create the XMLSignature, but don't sign it yet.
- try {
- SignedInfo si = initSignedInfo(fac);
- XMLSignature signature = fac.newXMLSignature(si, ki);
-
- // Marshal, generate, and sign the enveloped signature.
- signature.sign(dsc);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * searches local keystores for a referenced signing certificate
- *
- * @param childNodes
- * @return null or the public key of a signing certificate
- */
- private X509Certificate FindCert(NodeList childNodes) {
- try {
- for (int x = 0; x < childNodes.getLength(); x++) {
- if (childNodes.item(x).getLocalName().equalsIgnoreCase("X509SubjectName")) {
-
- String dn = childNodes.item(x).getTextContent().trim();
- return FindCertByDN(new X500Principal(dn));
-
- }
- if (childNodes.item(x).getLocalName().equalsIgnoreCase("X509IssuerSerial")) {
- String X509IssuerName = null;
- String X509SerialNumber = null;
- for (int k = 0; k < childNodes.item(x).getChildNodes().getLength(); k++) {
- if (childNodes.item(x).getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509IssuerName")) {
- X509IssuerName = childNodes.item(x).getTextContent().trim();
- }
- if (childNodes.item(x).getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509SerialNumber")) {
- X509SerialNumber = childNodes.item(x).getTextContent().trim();
- }
-
- }
- if (X509IssuerName != null && X509SerialNumber != null) {
- return FindCertByIssuer(X509IssuerName, X509SerialNumber);
- }
-
-
- }
- }
- } catch (Exception ex) {
- logger.warn("error caught searching for a certificate", ex);
- }
- return null;
- }
-
- private X509Certificate FindCertByDN(X500Principal name) throws Exception {
- KeyStore ks = GetTrustStore();
- if (ks == null) {
- return null;
- }
- Enumeration<String> aliases = ks.aliases();
- while (aliases.hasMoreElements()) {
- String nextElement = aliases.nextElement();
- Certificate certificate = ks.getCertificate(nextElement);
- X509Certificate x = (X509Certificate) certificate;
- if (x.getSubjectX500Principal().equals(name)) {
- return x;
- }
- }
- return null;
- }
-
- /**
- * Downloads a CRL from given HTTP/HTTPS/FTP URL, e.g.
- * http://crl.infonotary.com/crl/identity-ca.crl
- */
- private X509CRL downloadCRLFromWeb(String crlURL)
- throws MalformedURLException, IOException, CertificateException,
- CRLException {
- URL url = new URL(crlURL);
- InputStream crlStream = url.openStream();
- try {
- // CertificateFactory cf = CertificateFactory.getInstance("X.509");
- X509CRL crl = (X509CRL) cf.generateCRL(crlStream);
- return crl;
- } finally {
- crlStream.close();
- }
- }
-
- private X509Certificate FindCertByIssuer(String X509IssuerName, String X509SerialNumber) throws Exception {
- KeyStore ks = GetTrustStore();
- if (ks == null) {
- return null;
- }
- Enumeration<String> aliases = ks.aliases();
- while (aliases.hasMoreElements()) {
- String nextElement = aliases.nextElement();
- Certificate certificate = ks.getCertificate(nextElement);
- X509Certificate x = (X509Certificate) certificate;
- if (x.getIssuerDN().getName().equals(X509IssuerName)
- && x.getSerialNumber().toString().equalsIgnoreCase(X509SerialNumber)) {
- return x;
- }
+ // location of the resulting XMLSignature's parent element.
+ DOMSignContext dsc = new DOMSignContext(privateKey, node);
+ dsc.putNamespacePrefix(XML_DIGSIG_NS, "ns2");
+
+ // Create the XMLSignature, but don't sign it yet.
+ try {
+ SignedInfo si = initSignedInfo(fac);
+ XMLSignature signature = fac.newXMLSignature(si, ki);
+
+ // Marshal, generate, and sign the enveloped signature.
+ signature.sign(dsc);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * searches local keystores for a referenced signing certificate
+ *
+ * @param childNodes
+ * @return null or the public key of a signing certificate
+ */
+ private X509Certificate FindCert(NodeList childNodes) {
+ try {
+ for (int x = 0; x < childNodes.getLength(); x++) {
+ if (childNodes.item(x).getLocalName().equalsIgnoreCase("X509SubjectName")) {
+
+ String dn = childNodes.item(x).getTextContent().trim();
+ return FindCertByDN(new X500Principal(dn));
+
+ }
+ if (childNodes.item(x).getLocalName().equalsIgnoreCase("X509IssuerSerial")) {
+ String X509IssuerName = null;
+ String X509SerialNumber = null;
+ for (int k = 0; k < childNodes.item(x).getChildNodes().getLength(); k++) {
+ if (childNodes.item(x).getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509IssuerName")) {
+ X509IssuerName = childNodes.item(x).getTextContent().trim();
+ }
+ if (childNodes.item(x).getChildNodes().item(x).getLocalName().equalsIgnoreCase("X509SerialNumber")) {
+ X509SerialNumber = childNodes.item(x).getTextContent().trim();
+ }
+
+ }
+ if (X509IssuerName != null && X509SerialNumber != null) {
+ return FindCertByIssuer(X509IssuerName, X509SerialNumber);
+ }
+
+ }
+ }
+ } catch (Exception ex) {
+ logger.warn("error caught searching for a certificate", ex);
+ }
+ return null;
+ }
+
+ private X509Certificate FindCertByDN(X500Principal name) throws Exception {
+ KeyStore ks = GetTrustStore();
+ if (ks == null) {
+ return null;
+ }
+ Enumeration<String> aliases = ks.aliases();
+ while (aliases.hasMoreElements()) {
+ String nextElement = aliases.nextElement();
+ Certificate certificate = ks.getCertificate(nextElement);
+ X509Certificate x = (X509Certificate) certificate;
+ if (x.getSubjectX500Principal().equals(name)) {
+ return x;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Downloads a CRL from given HTTP/HTTPS/FTP URL, e.g.
+ * http://crl.infonotary.com/crl/identity-ca.crl
+ */
+ private X509CRL downloadCRLFromWeb(String crlURL)
+ throws MalformedURLException, IOException, CertificateException,
+ CRLException {
+ URL url = new URL(crlURL);
+ InputStream crlStream = url.openStream();
+ try {
+ // CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509CRL crl = (X509CRL) cf.generateCRL(crlStream);
+ return crl;
+ } finally {
+ crlStream.close();
+ }
+ }
+
+ private X509Certificate FindCertByIssuer(String X509IssuerName, String X509SerialNumber) throws Exception {
+ KeyStore ks = GetTrustStore();
+ if (ks == null) {
+ return null;
+ }
+ Enumeration<String> aliases = ks.aliases();
[... 15 lines stripped ...]
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@juddi.apache.org
For additional commands, e-mail: commits-help@juddi.apache.org