package WSS4J;

import java.security.Key;
import javax.crypto.spec.SecretKeySpec;
import com.ibm.xml.dsig.util.Base64;
import java.security.SecureRandom;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Calendar;
import org.xml.sax.InputSource;

public class UserNamePasswordDigestTokenWithReference extends SignatureToken
{
    private static String userName = "";
    private static String tokenWSUId = "";

    public UserNamePasswordDigestTokenWithReference( 
                 String tokenWSUId,
                 String userName,
                 WSSMessage wssMessage 
                 ){

        super( tokenWSUId, userName, wssMessage );

        this.tokenWSUId = tokenWSUId;
        this.userName = userName;

    }

    public String getType()
    {
        return "UserNamePasswordDigestTokenWithReference";
    }

    public String getXMLString()
    {
         String nonce = "";
         String timeStamp = "";
         String passwordDigestBase64Encoded = "";

         try{
             SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
             
             byte[] bytes = new byte[1024/8];
             sr.nextBytes(bytes);
             nonce = new Base64().encode(bytes);

             long systemTime = System.currentTimeMillis();
             timeStamp = getTimeStampString ( systemTime );

             MessageDigest passwordDigestCal = 
                                         MessageDigest.getInstance("SHA-1");
             passwordDigestCal.reset();

             String password = nonce + 
                               timeStamp + 
                               new String( key.getEncoded() );

             passwordDigestCal.update(password.getBytes());

             byte[] passwordDigest = passwordDigestCal.digest();

             passwordDigestBase64Encoded = new Base64().encode(passwordDigest);

         }catch( Exception e ) {
             System.out.println( 
             "Exception in UserNameTokenWithPasswordDigest's setSecret...." );
             e.printStackTrace();
         }

        return 
        "\n<wsse:UsernameToken wsu:Id=\"" + tokenWSUId + "\" " + 
            "\nxmlns:wsu=\"http://schemas.xmlsoap.org/ws/2002/07/utility\"" +
            "\nxmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\">+ 
            "\n<wsse:Username>" + userName + "<wsse:Username>+
            "\n<wsse:Password Type=\"#PasswordDigest\">" +
                "\n" + passwordDigestBase64Encoded + 
            "\n</wsse:Password>+
            "\n<wsse:Nonce>+ nonce + "</wsse:Nonce>" +
            "\n<wsu:Created>+ timeStamp + "</wsu:Created>+
        "\n";
    }

    public void setSecret(byte[] secretBytes)
    {
         try{
             key = (Key) new SecretKeySpec(secretBytes, "DESede");
         }catch( Exception e ) {
             System.out.println( 
             "Exception in UserNameTokenWithPasswordDigest's setSecret...." );
             e.printStackTrace();
         }
    }

    private String getTimeStampString (long time) 
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis ( time );
        int hour = cal.get ( Calendar.HOUR_OF_DAY );//24 hour system
        int minute = cal.get ( Calendar.MINUTE );
        int second = cal.get ( Calendar.SECOND );

        int day = cal.get ( Calendar.DAY_OF_MONTH );
        int month = cal.get ( Calendar.MONTH );
        int year = cal.get ( Calendar.YEAR );

        String timeStampInUTC = "";
        timeStampInUTC += year;

        if ( (month + 1) < 10 )
            timeStampInUTC += "-" + "0" + ( month + 1 );
        else
            timeStampInUTC += "-" + ( month + 1 );

        if ( day < 10 )
            timeStampInUTC += "-" + "0" + day + "T";
        else
            timeStampInUTC += "-" + day + "T";

        if ( (hour-5) == -5 )
            timeStampInUTC += "20";
        else if ( (hour-5) == -4 )
            timeStampInUTC += "21";
        else if ( (hour-5) == -3 )
            timeStampInUTC += "22";
        else if ( (hour-5) == -2 )
            timeStampInUTC += "23";
        else if ( (hour-5) == -1 )
            timeStampInUTC += "24";
        else if ( (hour-5) < 10 )
            timeStampInUTC += "0" + (hour-5);
        else
            timeStampInUTC += (hour-5);

        if ( minute < 10 )
            timeStampInUTC += ":" + "0" + minute;
        else
            timeStampInUTC += ":" + minute;

        if ( second < 10 )
            timeStampInUTC += ":" + "0" + second + "Z";
        else
            timeStampInUTC += ":" + second + "Z";

        return timeStampInUTC;
    }
}