// DSigDemo.java
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

// The source code is jointly developed by W3C and some of its members
// participating in the Digital Signature Initiative.  The authors are:
//    Mark Champine, HP, <champine@apollo.hp.com>
//    Yang-hua Chu, MIT/W3C, <yhchu@w3.org>
//    Vasanthan Dasan, Sun, <vasanthan.dasan@central.sun.com>
//    Peter Lipp, University of Technology, Graz <plipp@iaik.tu-graz.ac.at>
//    Andreas Sterbenz, U. of Technology, Graz <sterbenz@iaik.tu-graz.ac.at>

package w3c.www.pics;

import java.io.*;
import java.security.*;
import java.security.interfaces.*;
import java.math.BigInteger;

import w3c.www.dsig.*;
import java.util.*;

/**
 * DSig Demo class.
 * <P>
 * This class demonstrates the use of DSig library (w3c.www.dsig package)
 * with the PICS parser library (w3c.www.pics).
 *
 * @version 1.0beta (last modified 08-February-1998)
 * @author Andreas Sterbenz
 * @author Yang-hua Chu
 */

public class DSigDemo {

  private static String labelfname = 
  "k:\\projects\\dsig\\w3c\\src\\label1.lbl";
  private static boolean DEBUG = false;

  static void println(String text)
  {
    System.out.println(text);
  }

  public static void usage()
  {
    println("Usage: java DSigDemo [LabelFile]");
    println("If LabelFile is not specified, it defaults to '" + labelfname + "'.");
    waitKey();
    System.exit(1);
  }

  private static KeyPair getDssKeyPair()
  {
    BigInteger x = new BigInteger("427680156495144453885115690373649756045959408862");
    BigInteger y = new BigInteger("177339384197349739065818268761102971597420546697560629529304621486431387773923117551613374450730394130117771062930596087436245169541121954274843478181992055685752245183950336677657126495585057247936207232282564918317794169791277754707537125797798694653557421342631893997403826497768230679355141661766921531808");
    BigInteger p = new BigInteger("178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239");
    BigInteger q = new BigInteger("864205495604807476120572616017955259175325408501");
    BigInteger g = new BigInteger("174068207532402095185811980123523436538604490794561350978495831040599953488455823147851597408940950725307797094915759492368300574252438761037084473467180148876118103083043754985190983472601550494691329488083395492313850000361646482644608492304078721818959999056496097769368017749273708962006689187956744210730");
    PublicKey pubKey = new DSAPublicKeyClass(y, p, q, g);
    PrivateKey privKey = new DSAPrivateKeyClass(x, p, q, g);
    return new KeyPair(pubKey, privKey);
  }


  public static boolean verifyDemo(String labelString) throws Throwable
  {
    println("PART II: Verifying a label");

    println("Step 1: Preparation step - Creating a SigLabel object");
    println("Trying to parse the signed label...");
    SigLabel label1 = new SigLabel(labelString);
    println("Label successfully parsed.");
    println("The label contents are:\n" + label1.prettyPrint());
    waitKey();
    
    // added
    println("\nThe excluded label looks like:");
    println(label1.toExcludedDSigString(new Hashtable())+"\n");

    Trivalue res;
    println("Quick signature verification...");
    res = label1.verify();
    println("Verification result: " + res.toString());
    waitKey();
    return true;
  }

  public static String signDemo(String filename) throws Throwable
  {
    println("PART I: Signing a label");

    println("Step 1: Preparation step - Creating a SigLabel object");
    println("Trying to load and parse label from file '" + filename + "'...");
    SigLabel label1 = new SigLabel(new FileInputStream(filename));
    println("Label successfully parsed.");
    println("The label contents are:\n" + label1.prettyPrint());
    waitKey();

    println("Step 2: Build the ResInfo - add hashes to the label");
    ResInfoExtension resinfo = label1.getResInfo();
    resinfo.addDigest(HashRegistry.MD5URL, label1, null);
    resinfo.addDigest(HashRegistry.SHA1URL, label1, null);
    println("The modified label contents are:\n" + label1.prettyPrint());
    waitKey();

    println("Step 3: Add signatures to the SigBlock");
    SignatureSuite sigdss = 
      SigSuiteRegistry.getInstance(SigSuiteRegistry.DSSURL);
    KeyPair keypair = getDssKeyPair();
    PrivateKey privkey = keypair.getPrivate();

    println("\nThe excluded label looks like:");
    println(label1.toExcludedDSigString(sigdss.getSuiteValues())+"\n");

    // yc-m    sigdss.sign(label1, privkey);
    label1.sign(sigdss, privkey);

    sigdss.setBy("ByKey", keypair.getPublic());
    label1.updateDSig();
    println("The modified label contents are:\n" + label1.prettyPrint());
    waitKey();

    return label1.toString();
  }

  public static void main(String args[])
  {
    try {
      Trivalue res;

      println("This is a simple demo application for the W3C DSig Reference Implementation.");
      println("It will demonstrate how to create and verify DSig signature labels.\n");
      switch( args.length ) {

        case 0:
          println("The label will be loaded from '" + labelfname + "',\nuse a commandline argument to specify a different file.");
          break;

        case 1:
          labelfname = args[0];
          println("The label will be loaded from '" + labelfname + "'.");
          break;

        default:
          usage();
          break;
      }

      waitKey();
      
      String signedlabel = signDemo(labelfname);
      
      verifyDemo(signedlabel);

    } catch( Throwable e ) {
      println("\nAn exception occured: " + e.getMessage());
      e.printStackTrace();
      waitKey();
    }
  }

  static void waitKey()
  {
    println("\nHit the <RETURN> key to continue.");
    try {
      do {
        System.in.read();
      } while( System.in.available() > 0 );
    } catch( java.io.IOException e ) {
      ;
    }
  }
}
