/*
 * Copyright 2006 The Apache Software Foundation.
 *
 *  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 javax.xml.crypto.dsig.samples;

import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.*;
import java.util.Arrays;
import java.util.Collections;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * This is a simple example of generating an Enveloping XML 
 * Signature using the JSR 105 API. The signature in this case references a 
 * local URI that points to an Object element. 
 * The resulting signature will look like (certificate and 
 * signature values will be different):
 *
 * <pre><code>
 * <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
 *   <SignedInfo>
 *     <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
 *     <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
 *     <Reference URI="#object">
 *       <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
 *       <DigestValue>7/XTsHaBSOnJ/jXD5v0zL6VKYsk=</DigestValue>
 *     </Reference>
 *   </SignedInfo>
 *   <SignatureValue>
 *     RpMRbtMHLa0siSS+BwUpLIEmTfh/0fsld2JYQWZzCzfa5kBTz25+XA==
 *   </SignatureValue>
 *   <KeyInfo>
 *     <KeyValue>
 *       <DSAKeyValue>
 *         <P>
 *           /KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0Imbz
 *           RMqzVDZkVG9xD7nN1kuFw==
 *         </P>
 *         <Q>
 *           li7dzDacuo67Jg7mtqEm2TRuOMU=
 *         </Q>
 *         <G>
 *           Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOH
 *           CBiNU0NogpsQW5QvnlMpA==
 *         </G>
 *         <Y>
 *           wbEUaCgHZXqK4qLvbdYrAc6+Do0XVcsziCJqxzn4cJJRxwc3E1xnEXHscVgr1Cql9
 *           i5fanOKQbFXzmb+bChqig==
 *         </Y>
 *       </DSAKeyValue>
 *     </KeyValue>
 *   </KeyInfo>
 *   <Object Id="object">some text</Object>
 * </Signature>
 *
 * </code></pre>
 */
public class GenEnveloping {

    //
    // Synopis: java GenEnveloping [output]
    //
    //   where "output" is the name of a file that will contain the
    //   generated signature. If not specified, standard ouput will be used.
    //
    public static void main(String[] args) throws Exception {

        // First, create the DOM XMLSignatureFactory that will be used to 
	// generate the XMLSignature
	String providerName = System.getProperty
            ("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
            (Provider) Class.forName(providerName).newInstance());

        // Next, create a Reference to a same-document URI that is an Object
        // element and specify the SHA1 digest algorithm
        Reference ref = fac.newReference("#object",
	    fac.newDigestMethod(DigestMethod.SHA1, null));

	// Next, create the referenced Object
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setNamespaceAware(true);
	Document doc = dbf.newDocumentBuilder().newDocument();
	Node text = doc.createTextNode("some text");
	XMLStructure content = new DOMStructure(text);
	XMLObject obj = fac.newXMLObject
	    (Collections.singletonList(content), "object", null, null);

	// Create the SignedInfo
	SignedInfo si = fac.newSignedInfo(
	    fac.newCanonicalizationMethod
		(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, 
		 (C14NMethodParameterSpec) null), 
	    fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
	    Collections.singletonList(ref));

	// Create a DSA KeyPair
	KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
	kpg.initialize(512);
	KeyPair kp = kpg.generateKeyPair();

	// Create a KeyValue containing the DSA PublicKey that was generated
	KeyInfoFactory kif = fac.getKeyInfoFactory();
	KeyValue kv = kif.newKeyValue(kp.getPublic());

	// Create a KeyInfo and add the KeyValue to it
	KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));

	// Create the XMLSignature (but don't sign it yet)
	XMLSignature signature = fac.newXMLSignature(si, ki,
	    Collections.singletonList(obj), null, null); 

        // Create a DOMSignContext and specify the DSA PrivateKey for signing
	// and the document location of the XMLSignature
        DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc);

        // Lastly, generate the enveloping signature using the PrivateKey
	signature.sign(dsc);

        // output the resulting document
	OutputStream os;
	if (args.length > 0) {
	   os = new FileOutputStream(args[0]);
	} else {
           os = System.out;
	}

        TransformerFactory tf = TransformerFactory.newInstance();
	Transformer trans = tf.newTransformer();
	trans.transform(new DOMSource(doc), new StreamResult(os));
    }
}
