+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.artifact;
-
-import org.opensaml.SAMLAssertion;
-import org.opensaml.artifact.Artifact;
-
-import edu.internet2.middleware.shibboleth.common.ServiceProvider;
-
-/**
- * Translates back and forth between SAML assertions and mapping strings (artifacts) needed for the SAML artifact
- * profile.
- *
- * @author Walter Hoehn
- */
-public interface ArtifactMapper {
-
- /**
- * Generates an artifact from a SAML assertion.
- *
- * @param assertion
- * the SAML assertion
- * @param serviceProvider
- * the service provider on behalf of which the artifact is being created
- * @return the artifact
- */
- public Artifact generateArtifact(SAMLAssertion assertion, ServiceProvider serviceProvider);
-
- /**
- * Recover an assertion that was previosly generated for a given artifact.
- *
- * @param artifact
- * the artifact in question
- * @return a mapping to the assertion
- */
-
- public ArtifactMapping recoverAssertion(Artifact artifact);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.artifact;
-
-import java.lang.reflect.Constructor;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
-
-/**
- * Factory for generating instances of <code>ArtifactMapper</code>. Configuration is delegated to the implementation.
- * Runtime options are passed to concrete constructors via an <ArtifactMapper/>DOM element.
- *
- * @author Walter Hoehn
- */
-public class ArtifactMapperFactory {
-
- private static Logger log = Logger.getLogger(ArtifactMapperFactory.class.getName());
-
- public static ArtifactMapper getInstance(Element config) throws ShibbolethConfigurationException {
-
- if (config.getAttribute("implementation") == null) { throw new ShibbolethConfigurationException(
- "No ArtifactMapper implementaiton specified."); }
- try {
- Class implementorClass = Class.forName(config.getAttribute("implementation"));
- Class[] params = new Class[1];
- params[0] = Class.forName("org.w3c.dom.Element");
- Constructor implementorConstructor = implementorClass.getConstructor(params);
- Object[] args = new Object[1];
- args[0] = config;
- log.debug("Initializing Artifact Mapper of type (" + implementorClass.getName() + ").");
- return (ArtifactMapper) implementorConstructor.newInstance(args);
-
- } catch (NoSuchMethodException nsme) {
- log.error("Failed to instantiate an Artifact Mapper: ArtifactMapper "
- + "implementation must contain a constructor that accepts an <ArtifactMapper/> element as "
- + "configuration data.");
- throw new ShibbolethConfigurationException("Failed to instantiate an Artifact Mapper.");
-
- } catch (Exception e) {
- log.error("Failed to instantiate an Artifact Mapper: " + e);
- throw new ShibbolethConfigurationException("Failed to instantiate an Artifact Mapper: " + e.getMessage());
-
- }
- }
-}
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.artifact;
-
-import org.opensaml.SAMLAssertion;
-import org.opensaml.artifact.Artifact;
-
-import edu.internet2.middleware.shibboleth.common.ServiceProvider;
-
-/**
- * Encapsulates internal data/functionality that is tied to a SAML artifact.
- *
- * @author Walter Hoehn
- */
-public class ArtifactMapping {
-
- private Artifact artifact;
- private long expirationTime;
- private SAMLAssertion assertion;
- private String serviceProviderId;
-
- public ArtifactMapping(Artifact artifact, SAMLAssertion assertion, ServiceProvider sp) {
-
- this.artifact = artifact;
- this.assertion = assertion;
- expirationTime = System.currentTimeMillis() + (1000 * 60 * 5); // in 5 minutes
- serviceProviderId = sp.getProviderId();
- }
-
- /**
- * Boolean indication of whether the artifact is expired.
- */
- public boolean isExpired() {
-
- if (System.currentTimeMillis() > expirationTime) { return true; }
- return false;
- }
-
- /**
- * Boolean indication of whether the artifact was created on behalf of a specified SP.
- */
- public boolean isCorrectProvider(ServiceProvider sp) {
-
- if (sp.getProviderId().equals(serviceProviderId)) { return true; }
- return false;
- }
-
- /**
- * Retrieves the SAML assertion associated with the artifact.
- */
- public SAMLAssertion getAssertion() {
-
- return assertion;
- }
-
- /**
- * Retrieves the SP on behalf of which the artifact was originally created.
- */
- public String getServiceProviderId() {
-
- return serviceProviderId;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.artifact.provider;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.log4j.Logger;
-import org.opensaml.SAMLAssertion;
-import org.opensaml.artifact.Artifact;
-import org.opensaml.artifact.SAMLArtifactType0001;
-import org.opensaml.artifact.SAMLArtifactType0002;
-import org.opensaml.artifact.Util;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.artifact.ArtifactMapper;
-import edu.internet2.middleware.shibboleth.artifact.ArtifactMapping;
-import edu.internet2.middleware.shibboleth.common.ServiceProvider;
-import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
-
-/**
- * Functionality common to most <code>ArtifactMapper</code> implementations, including creation and basic
- * encoding/decoding of arifiacts. Defers storage and lookup to subclasses.
- *
- * @author Walter Hoehn
- */
-public abstract class BaseArtifactMapper implements ArtifactMapper {
-
- private static Logger log = Logger.getLogger(BaseArtifactMapper.class.getName());
- private URI type2SourceLocation;
- private MessageDigest md;
-
- public BaseArtifactMapper() throws ShibbolethConfigurationException {
-
- try {
- md = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- log.error("No support found for SHA-1 digest algorithm: " + e);
- throw new ShibbolethConfigurationException(
- "The IdP Artifact Mapper requires JCE support for the SHA-1 digest algorithm.");
- }
- }
-
- public BaseArtifactMapper(Element config) throws ShibbolethConfigurationException {
-
- this();
-
- String attribute = config.getAttribute("sourceLocation");
- if (attribute != null && !attribute.equals("")) {
- try {
- type2SourceLocation = new URI(attribute);
- log.debug("Artifact Mapper configured to issue Type 1 artifacts & Type 2 artifacts with a "
- + "sourceLocation of (" + type2SourceLocation + ").");
- } catch (URISyntaxException e) {
- log.error("(sourceLocation) attribute for <ArtifactMapper/> is not a valid URI: " + e);
- throw new ShibbolethConfigurationException("Unable to initialize Artifact mapper");
- }
- } else {
- log.debug("No (sourceLocaton) attribute found for element <ArtifactMapper/>. The Artifact Mapper will "
- + "only be able to send Type 1 artifacts.");
- }
- }
-
- public Artifact generateArtifact(SAMLAssertion assertion, ServiceProvider serviceProvider) {
-
- // Generate the artifact
- Artifact artifact;
-
- // If the relying party prefers type 2 and we have the proper data, use it
- if (serviceProvider.getPreferredArtifactType() == 2 && type2SourceLocation != null) {
- artifact = new SAMLArtifactType0002(new org.opensaml.artifact.URI(type2SourceLocation.toString()));
- // Else, use type 1
- } else {
- if (serviceProvider.getPreferredArtifactType() == 2) {
- log.warn("The relying party prefers Type 2 artifacts, but the mapper does not "
- + "have a sourceLocation configured. Using Type 1.");
- } else if (serviceProvider.getPreferredArtifactType() != 1) {
- log.warn("The relying party prefers Type " + serviceProvider.getPreferredArtifactType()
- + " artifacts, but the mapper does not " + "support this type. Using Type 1.");
- }
-
- synchronized (md) {
- artifact = new SAMLArtifactType0001(Util.generateSourceId(md, serviceProvider.getIdentityProvider()
- .getProviderId()));
- }
- }
-
- // Delegate adding to extenders
- addAssertionImpl(artifact, new ArtifactMapping(artifact, assertion, serviceProvider));
-
- // Return the encoded artifact
- return artifact;
- }
-
- /**
- * Subclasses should implement artifact storage with this method.
- */
- protected abstract void addAssertionImpl(Artifact artifact, ArtifactMapping mapping);
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.artifact.provider;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.apache.log4j.Logger;
-import org.opensaml.artifact.Artifact;
-import org.w3c.dom.Element;
-
-import edu.internet2.middleware.shibboleth.artifact.ArtifactMapper;
-import edu.internet2.middleware.shibboleth.artifact.ArtifactMapping;
-import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
-
-/**
- * <code>ArtifactMapper</code> implementation that saves queryable artifacts in memory.
- *
- * @author Walter Hoehn
- */
-public class MemoryArtifactMapper extends BaseArtifactMapper implements ArtifactMapper {
-
- private MemoryArtifactCleaner cleaner = new MemoryArtifactCleaner();
- private static Logger log = Logger.getLogger(MemoryArtifactMapper.class.getName());
- private static Map<Artifact, ArtifactMapping> mappings = Collections
- .synchronizedMap(new HashMap<Artifact, ArtifactMapping>());
-
- public MemoryArtifactMapper() throws ShibbolethConfigurationException {
-
- super();
- }
-
- public MemoryArtifactMapper(Element config) throws ShibbolethConfigurationException {
-
- super(config);
- }
-
- public ArtifactMapping recoverAssertion(Artifact artifact) {
-
- ArtifactMapping mapping = (ArtifactMapping) mappings.get(artifact);
- mappings.remove(artifact);
- if (mapping == null || mapping.isExpired()) { return null; }
- return mapping;
- }
-
- public void addAssertionImpl(Artifact artifact, ArtifactMapping mapping) {
-
- mappings.put(artifact, mapping);
- }
-
- protected void destroy() {
-
- synchronized (cleaner) {
- if (cleaner != null) {
- cleaner.shutdown = true;
- cleaner.interrupt();
- }
- }
- }
-
- protected void finalize() throws Throwable {
-
- super.finalize();
- destroy();
- }
-
- private class MemoryArtifactCleaner extends Thread {
-
- private boolean shutdown = false;
- private Thread master;
-
- public MemoryArtifactCleaner() {
-
- super("edu.internet2.middleware.shibboleth.idp.provider.MemoryArtifactMapper..MemoryArtifactCleaner");
- this.master = Thread.currentThread();
- setDaemon(true);
- if (getPriority() > Thread.MIN_PRIORITY) {
- setPriority(getPriority() - 1);
- }
- log.debug("Starting memory-based artifact mapper cleanup thread.");
- start();
- }
-
- public void run() {
-
- try {
- sleep(60 * 1000); // one minute
- } catch (InterruptedException e) {
- log.debug("Memory-based artifact mapper cleanup interrupted.");
- }
- while (true) {
- try {
- if (!master.isAlive()) {
- shutdown = true;
- log.debug("Memory-based artifact mapper cleaner is orphaned.");
- }
- if (shutdown) {
- log.debug("Stopping Memory-based artifact mapper cleanup thread.");
- return;
- }
- log.debug("Memory-based artifact mapper cleanup thread searching for stale entries.");
- Set<Artifact> needsDeleting = new HashSet<Artifact>();
- synchronized (mappings) {
- Iterator<Entry<Artifact, ArtifactMapping>> iterator = mappings.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry entry = iterator.next();
- ArtifactMapping mapping = (ArtifactMapping) entry.getValue();
- if (mapping.isExpired()) {
- needsDeleting.add((Artifact) entry.getKey());
- }
- }
- // release the lock to be friendly
- Iterator deleteIterator = needsDeleting.iterator();
- while (deleteIterator.hasNext()) {
- synchronized (mappings) {
- log.debug("Expiring an Artifact from the memory cache.");
- mappings.remove(deleteIterator.next());
- }
- }
- }
- sleep(60 * 1000); // one minute
- } catch (InterruptedException e) {
- log.debug("Memory-based artifact mapper cleanup interrupted.");
- }
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.internet2.middleware.shibboleth.utils;
-
-import jargs.gnu.CmdLineParser;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.apache.log4j.ConsoleAppender;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.PatternLayout;
-import org.apache.xml.security.c14n.Canonicalizer;
-import org.apache.xml.security.keys.KeyInfo;
-import org.apache.xml.security.keys.content.X509Data;
-import org.apache.xml.security.signature.Reference;
-import org.apache.xml.security.signature.SignedInfo;
-import org.apache.xml.security.signature.XMLSignature;
-import org.apache.xml.security.transforms.Transforms;
-import org.opensaml.saml2.metadata.provider.MetadataProviderException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-
-import edu.internet2.middleware.shibboleth.common.XML;
-import edu.internet2.middleware.shibboleth.metadata.DOMMetadataProvider;
-
-/**
- * Signs/verifies/maintains Shibboleth metadata files
- *
- * @author Scott Cantor
- * @created June 11, 2002
- */
-public class MetadataTool {
-
- /**
- * Signs/verifies/maintains Shibboleth metadata files
- *
- * @param argv
- * The command line arguments
- * @exception Exception
- * One of about fifty different kinds of possible errors
- */
- public static void main(String args[]) throws Exception {
-
- // Process the command line.
- CmdLineParser parser = new CmdLineParser();
- CmdLineParser.Option helpOption = parser.addBooleanOption('h', "help");
- CmdLineParser.Option signOption = parser.addBooleanOption('s', "sign");
- CmdLineParser.Option noverifyOption = parser.addBooleanOption('N', "noverify");
- CmdLineParser.Option inOption = parser.addStringOption('i', "in");
- CmdLineParser.Option outOption = parser.addStringOption('o', "out");
- CmdLineParser.Option keystoreOption = parser.addStringOption('k', "keystore");
- CmdLineParser.Option aliasOption = parser.addStringOption('a', "alias");
- CmdLineParser.Option pwOption = parser.addStringOption('p', "password");
- CmdLineParser.Option nsOption = parser.addStringOption('x', "ns");
- CmdLineParser.Option nameOption = parser.addStringOption('n', "name");
- CmdLineParser.Option idOption = parser.addStringOption('I', "id");
- CmdLineParser.Option debugOption = parser.addBooleanOption('d', "debug");
-
- Boolean debugEnabled = ((Boolean) parser.getOptionValue(debugOption));
- boolean debug = false;
- if (debugEnabled != null) {
- debug = debugEnabled.booleanValue();
- }
- configureLogging(debug);
-
- try {
- parser.parse(args);
- } catch (CmdLineParser.OptionException e) {
- System.err.println(e.getMessage());
- try {
- Thread.sleep(100); // silliness to get error to print first
- } catch (InterruptedException ie) {
- // doesn't matter
- }
- printUsage(System.out);
- System.exit(-1);
- }
-
- Boolean helpEnabled = (Boolean) parser.getOptionValue(helpOption);
- if (helpEnabled != null && helpEnabled.booleanValue()) {
- printUsage(System.out);
- System.exit(0);
- }
-
- Boolean sign = (Boolean) parser.getOptionValue(signOption);
- Boolean noverify = (Boolean) parser.getOptionValue(noverifyOption);
- String keystore = (String) parser.getOptionValue(keystoreOption);
- String pw = (String) parser.getOptionValue(pwOption);
- String alias = (String) parser.getOptionValue(aliasOption);
- String infile = (String) parser.getOptionValue(inOption);
- String outfile = (String) parser.getOptionValue(outOption);
- String ns = (String) parser.getOptionValue(nsOption);
- String name = (String) parser.getOptionValue(nameOption);
- String id = (String) parser.getOptionValue(idOption);
-
- if (infile == null || infile.length() == 0) {
- printUsage(System.out);
- System.exit(-1);
- }
-
- if (keystore != null && keystore.length() > 0) {
- if (alias == null || alias.length() == 0) {
- printUsage(System.out);
- System.exit(-1);
- }
- }
-
- PrivateKey privateKey = null;
- Certificate chain[] = null;
- X509Certificate cert = null;
-
- if (sign != null && sign.booleanValue()) {
- if (keystore == null || keystore.length() == 0 || pw == null || pw.length() == 0) {
- printUsage(System.out);
- System.exit(-1);
- }
- KeyStore ks = KeyStore.getInstance("JKS");
- FileInputStream fis = new FileInputStream(keystore);
- ks.load(fis, pw.toCharArray());
- privateKey = (PrivateKey) ks.getKey(alias, pw.toCharArray());
- chain = ks.getCertificateChain(alias);
- if (privateKey == null || chain == null) {
- System.err.println("error: couldn't load key or certificate chain from keystore");
- System.exit(1);
- }
- } else if (keystore != null && keystore.length() > 0) {
- KeyStore ks = KeyStore.getInstance("JKS");
- FileInputStream fis = new FileInputStream(keystore);
- ks.load(fis, null);
- cert = (X509Certificate) ks.getCertificate(alias);
- if (cert == null) {
- System.err.println("error: couldn't load certificate from keystore");
- System.exit(1);
- }
- } else if (noverify == null || !noverify.booleanValue()) {
- printUsage(System.out);
- System.exit(-1);
- }
-
- // Parse file and verify root element.
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(false);
- factory.setNamespaceAware(true);
- Document doc = factory.newDocumentBuilder().parse(new InputSource(new FileInputStream(infile)));
-
- if (doc == null) {
- System.out.println("error: unable to read in file (" + infile + ")");
- System.exit(-1);
- }
- Element e = doc.getDocumentElement();
- if (ns != null && name != null && !org.opensaml.XML.isElementNamed(e, ns, name)) {
- System.err.println("error: root element did not match ns and name parameters");
- System.exit(1);
- } else if (org.opensaml.XML.isElementNamed(e, XML.SHIB_NS, "SiteGroup")
- || org.opensaml.XML.isElementNamed(e, XML.SAML2META_NS, "EntityDescriptor")
- || org.opensaml.XML.isElementNamed(e, XML.SAML2META_NS, "EntitiesDescriptor")) {
- try {
- // apply the same validity checks a running system would
- new DOMMetadataProvider(e);
- } catch (MetadataProviderException me) {
- System.err.println("error in metadata: " + me.getMessage());
- System.exit(1);
- }
- } else if (org.opensaml.XML.isElementNamed(e, XML.SHIB_NS, "Trust")
- || org.opensaml.XML.isElementNamed(e, XML.TRUST_NS, "Trust")) {
- /*
- * Additional validity checks for legacy trust files could be added here.
- */
- } else {
- System.err.println("error: root element must be SiteGroup, Trust, EntitiesDescriptor, or EntityDescriptor");
- System.exit(1);
- }
-
- if (id != null) {
- e = doc.getElementById(id);
- if (e == null) {
- System.err.println("error: no element with ID (" + id + ") found in document");
- System.exit(1);
- }
- }
-
- if (sign != null && sign.booleanValue()) {
- // Remove any existing signature.
- Element old = org.opensaml.XML.getFirstChildElement(e, org.opensaml.XML.XMLSIG_NS, "Signature");
- if (old != null) e.removeChild(old);
-
- // Create new signature.
- XMLSignature sig = new XMLSignature(doc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
- Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS);
- Transforms transforms = new Transforms(doc);
- transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
- transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS);
- sig.addDocument((id == null) ? ("") : ("#" + id), transforms,
- org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
-
- // Add any X.509 certificates provided.
- if (chain != null && chain.length > 0) {
- X509Data x509 = new X509Data(doc);
- for (int i = 0; i < chain.length; i++) {
- if (chain[i] instanceof X509Certificate) x509.addCertificate((X509Certificate) chain[i]);
- }
- KeyInfo keyinfo = new KeyInfo(doc);
- keyinfo.add(x509);
- sig.getElement().appendChild(keyinfo.getElement());
- }
-
- if (XML.SAML2META_NS.equals(e.getNamespaceURI())) e.insertBefore(sig.getElement(), e.getFirstChild());
- else e.appendChild(sig.getElement());
- sig.sign(privateKey);
- } else {
- // Check the root element's signature or the particular one specified.
- Element sigElement = org.opensaml.XML.getLastChildElement(e, org.opensaml.XML.XMLSIG_NS, "Signature");
- boolean v = (noverify == null || !noverify.booleanValue());
- if (v) {
- if (sigElement == null) {
- System.err.println("error: file is not signed");
- System.exit(1);
- }
- if (!verifySignature(doc, sigElement, cert)) {
- System.err.println("error: signature did not verify");
- System.exit(1);
- }
- } else if (sigElement != null) {
- System.err.println("verification of signer disabled, make sure you trust the source of this file!");
- if (!verifySignature(doc, sigElement, cert)) {
- System.err.println("error: signature did not verify");
- System.exit(1);
- }
- } else {
- System.err.println("verification disabled, and file is unsigned!");
- }
-
- // Check all the signatures.
- NodeList nlist = e.getElementsByTagNameNS(org.opensaml.XML.XMLSIG_NS, "Signature");
- for (int i = 0; i < nlist.getLength(); i++) {
- if (!verifySignature(doc, (Element) nlist.item(i), cert)) {
- System.err.println("error: signature did not verify");
- System.exit(1);
- }
- }
- }
-
- Canonicalizer c = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS);
- if (outfile != null && outfile.length() > 0) {
- OutputStream out = new FileOutputStream(outfile);
- out.write(c.canonicalizeSubtree(doc));
- out.close();
- } else {
- // For some reason, using write(byte[]) doesn't work.
- System.out.print(new String(c.canonicalizeSubtree(doc)));
- }
- }
-
- private static boolean verifySignature(Document doc, Element sigNode, X509Certificate cert) throws Exception {
-
- XMLSignature sig = new XMLSignature(sigNode, "");
-
- // Validate the signature content by checking for specific Transforms.
- boolean valid = false;
- SignedInfo si = sig.getSignedInfo();
- if (si.getLength() == 1) {
- Reference ref = si.item(0);
- if (ref.getURI() == null || ref.getURI().equals("")
- || ref.getURI().equals("#" + ((Element) sigNode.getParentNode()).getAttributeNS(null, "ID"))) {
- Transforms trans = ref.getTransforms();
- for (int i = 0; i < trans.getLength(); i++) {
- if (trans.item(i).getURI().equals(Transforms.TRANSFORM_ENVELOPED_SIGNATURE)) valid = true;
- else if (!trans.item(i).getURI().equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS)
- && !trans.item(i).getURI().equals(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)) {
- valid = false;
- break;
- }
- }
- }
- }
-
- if (!valid) {
- System.err.println("error: signature profile was invalid");
- return false;
- }
-
- if (cert != null) return sig.checkSignatureValue(cert);
- else return sig.checkSignatureValue(sig.getKeyInfo().getPublicKey());
- }
-
- private static void printUsage(PrintStream out) {
-
- out.println("usage: java edu.internet2.middleware.shibboleth.utils.MetadataTool");
- out.println();
- out.println("when signing: -i <uri> -s -k <keystore> -a <alias> -p <pass> [-o <outfile>]");
- out.println("when updating: -i <uri> [-k <keystore> -a <alias> OR -N ] [-o <outfile>]");
- out.println(" -i,--in input file or url");
- out.println(" -k,--keystore pathname of Java keystore file");
- out.println(" -a,--alias alias of signing or verification key");
- out.println(" -p,--password keystore/key password");
- out.println(" -o,--outfile write signed copy to this file instead of stdout");
- out.println(" -s,--sign sign the input file and write out a signed version");
- out.println(" -N,--noverify allows update of file without signature check");
- out.println(" -h,--help print this message");
- out.println(" -x,--ns XML namespace of root element");
- out.println(" -n,--name name of root element");
- out.println(" -I,--id ID attribute value of element to sign");
- out.println(" -d, --debug run in debug mode");
- out.println();
- System.exit(1);
- }
-
- private static void configureLogging(boolean debugEnabled) {
-
- ConsoleAppender rootAppender = new ConsoleAppender();
- rootAppender.setWriter(new PrintWriter(System.err));
- rootAppender.setName("stdout");
- Logger.getRootLogger().addAppender(rootAppender);
-
- if (debugEnabled) {
- Logger.getRootLogger().setLevel(Level.DEBUG);
- rootAppender.setLayout(new PatternLayout("%-5p %-41X{serviceId} %d{ISO8601} (%c:%L) - %m%n"));
- } else {
- Logger.getRootLogger().setLevel(Level.WARN);
- rootAppender.setLayout(new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN));
- }
- Logger.getLogger("org.apache.xml.security").setLevel(Level.OFF);
- }
-}