<?php
##################
#  CyberSource Hosted Order Page library.  Inserts fields into the
#  checkout form for posting data to the CyberSource Hosted Order
#  Page.

function php_hmacsha1($data, $key) {
  $klen = strlen($key);
  $blen = 64;
  $ipad = str_pad("", $blen, chr(0x36));
  $opad = str_pad("", $blen, chr(0x5c));

  if ($klen <= $blen) {
    while (strlen($key) < $blen) {
      $key .= "\0";
    }				#zero-fill to blocksize
  } else {
    $key = cybs_sha1($key);	#if longer, pre-hash key
  }
  $key = str_pad($key, strlen($ipad) + strlen($data), "\0");
  return cybs_sha1(($key ^ $opad) . cybs_sha1($key ^ $ipad . $data));
}

# calculates SHA-1 digest of the input string
# cleaned up from John Allen's "SHA in 8 lines of perl5"
# at http://www.cypherspace.org/~adam/rsa/sha.html
#
# returns the hash in a (binary) string

function cybs_sha1($in) {
  $indx = 0;
  $chunk = "";

  $A = array(1732584193, 4023233417, 2562383102,  271733878, 3285377520);
  $K = array(1518500249, 1859775393, 2400959708, 3395469782);
  $a = $b = $c = $d = $e = 0;
  $l = $p = $r = $t = 0;

  do{
    $chunk = substr($in, $l, 64);
    $r = strlen($chunk);
    $l += $r;

    if ($r<64 && !$p++) {
      $r++;
      $chunk .= "\x80";
    }
    $chunk .= "\0\0\0\0";
    while (strlen($chunk) % 4 > 0) { 
      $chunk .= "\0";
    }
    $len = strlen($chunk) / 4;
    if ($len > 16) $len = 16;
    $fmt = "N" . $len;
    $W = array_values(unpack($fmt, $chunk));
    if ($r < 57 ) { 
      while (count($W) < 15) {
	array_push($W, "\0");
      }
      $W[15] = $l*8;
    }

    for ($i = 16; $i <= 79; $i++) {
      $v1 = d_cyber($W, $i-3);
      $v2 = d_cyber($W, $i-8);
      $v3 = d_cyber($W, $i-14);
      $v4 = d_cyber($W, $i-16);
      array_push($W, L($v1 ^ $v2 ^ $v3 ^ $v4, 1));
    }

    list($a,$b,$c,$d,$e)=$A;

    for ($i = 0; $i<=79; $i++) {
      $t0 = 0;
      switch(intval($i/20)) {
	case 1:
	case 3:
	$t0 = F1($b, $c, $d);
	break;
	case 2:
	$t0 = F2($b, $c, $d);
	break;
      default:
	$t0 = F0($b, $c, $d);
	break;
      }
      $t = M($t0 + $e  + d_cyber($W, $i) + d_cyber($K, $i/20) + L($a, 5));
      $e = $d;
      $d = $c;
      $c = L($b,30);
      $b = $a;
      $a = $t;
    }

    $A[0] = M($A[0] + $a);
    $A[1] = M($A[1] + $b);
    $A[2] = M($A[2] + $c);
    $A[3] = M($A[3] + $d);
    $A[4] = M($A[4] + $e);

  }while ($r>56);
  $v = pack("N*", $A[0], $A[1], $A[2], $A[3], $A[4]);
  return $v;
}

#### Ancillary routines used by sha1

function dd($x) {
  if (defined($x)) return $x;
  return 0;
}

function d_cyber($arr, $x) {
  if ($x < count($arr)) return $arr[$x];
  return 0;
}

function F0($b, $c, $d) {
  return $b & ($c ^ $d) ^ $d;
}

function F1($b, $c, $d) {
  return $b ^ $c ^ $d;
}

function F2($b, $c, $d) {
  return ($b | $c) & $d | $b & $c;
}

# ($num)
function M($x) {
  $m = 1+~0;
  if ($m == 0) return $x;
  return($x - $m * intval($x/$m));
}

# ($string, $count)
function L($x, $n) { 
  return ( ($x<<$n) | ((pow(2, $n) - 1) & ($x>>(32-$n))) );
}

####
#### end of HMAC SHA1 implementation #####




####
#### HOP functions
#### Copyright 2003, CyberSource Corporation.  All rights reserved.
####

function getmicrotime(){ 
  list($usec, $sec) = explode(" ",microtime());
  $usec = (int)((float)$usec * 1000);
  while (strlen($usec) < 3) { $usec = "0" . $usec; }
  return $sec . $usec;
}


function hopHash($data, $key) {
    return base64_encode(php_hmacsha1($data, $key));
}

function getMerchantID() 
	{
	GLOBAL $getMerchantID;
	return  $getMerchantID; 
	}

function getPublicKey()  
	{ 
	GLOBAL $getPublicKey;
	return $getPublicKey; 
	}
	
function getPrivateKey() 
	{
	GLOBAL $getPrivateKey;
	return $getPrivateKey; 
	}

#### HOP integration function
function InsertSignature($amount) {
  $merchantID = getMerchantID();
  $timestamp = getmicrotime();
  $data = $merchantID . $amount . $timestamp;
  $pub = getPublicKey();
  $pvt = getPrivateKey();
  $pub_digest = hopHash($data, $pub);
  $pvt_digest = hopHash($data, $pvt);

  $parse_out0=('<input type="hidden" name="amount" value="' . $amount . '">' . "\n");
  $parse_out0.=('<input type="hidden" name="orderPage_timestamp" value="' . $timestamp . '">' . "\n");
  $parse_out0.=('<input type="hidden" name="merchantID" value="' . $merchantID . '">' . "\n");
  $parse_out0.=('<input type="hidden" name="orderPage_signaturePublic" value="' . $pub_digest . '">' . "\n");
  $parse_out0.=('<input type="hidden" name="orderPage_signaturePrivate" value="' . $pvt_digest . '">' . "\n");

  return $parse_out0;
}

function VerifySignature($data, $signature) {
    $pub = getPublicKey();
    $pub_digest = hopHash($data, $pub);
    return strcmp($pub_digest, $signature) == 0;
}

# AP ADDED FUNCTIONS --------------------------------------------------------------------------------

function hop_values()
	{
	$source=file_get_contents("inc/HOP.php");
	$source=str_replace("\n", "", $source);
	$source=explode("getMerchantID", $source);
	$source=explode("}", $source[1]);

	# -----------------------------------------

	$source_0=$source[0];
	$source_0=str_replace("\"", "", $source_0);
	$source_0=str_replace(";", "", $source_0);
	$source_0=str_replace("{", "", $source_0);
	$source_0=str_replace("(", "", $source_0);
	$source_0=str_replace(")", "", $source_0);
	$source_0=explode(" ", $source_0);
	$key=array_search("return", $source_0);
	$getMerchantID=trim($source_0[$key+2]);

	# -----------------------------------------

	$source_1=$source[1];
	$source_1=explode("getPublicKey", $source_1);
	$source_1=explode("}", $source_1[1]);
	$source_1=str_replace("\"", "", $source_1[0]);
	$source_1=str_replace(";", "", $source_1);
	$source_1=str_replace("{", "", $source_1);
	$source_1=str_replace("(", "", $source_1);
	$source_1=str_replace(")", "", $source_1);
	$source_1=explode(" ", $source_1);
	$key=array_search("return", $source_1);
	$getPublicKey=trim($source_1[$key+1]);

	# -----------------------------------------

	$source_2=$source[2];
	$source_2=explode("getPrivateKey", $source_2);
	$source_2=explode("}", $source_2[1]);
	$source_2=str_replace("\"", "", $source_2[0]);
	$source_2=str_replace(";", "", $source_2);
	$source_2=str_replace("{", "", $source_2);
	$source_2=str_replace("(", "", $source_2);
	$source_2=str_replace(")", "", $source_2);
	$source_2=explode(" ", $source_2);
	# print_r($source_1);
	$key=array_search("return", $source_2);
	$getPrivateKey=trim($source_2[$key+1]);

	return array("merchant_id" => $getMerchantID, 
				"public_key" => $getPublicKey, 
				"private_key" => $getPrivateKey);
	}
?>