/////const //////////////////////////
var CERT_SRC_BASE64	=					1;		//证书来自Base64字符串
var CERT_SRC_UNIQUEID =					2;		//证书来自唯一表示
var CERT_SRC_FILE =						3;		//证书来自der文件
var CERT_SRC_CONTAINER_UCA = 			4;		//证书来自UCA类型证书容器
var CERT_SRC_CONTAINER_SIGN	=			5;		//证书来自容器下签名证书
var CERT_SRC_CONTAINER_ENC =			6;		//证书来自容器下加密证书
var CERT_SRC_CONTAINER_BOTH	=			7;		//证书来自容器下签名加密证书
var CERT_SRC_PKCS12	=					8;		//证书来自PKCS12文件

var CERT_DST_BASE64	=					1;		//导出证书为Base64字符串
var CERT_DST_DERFILE =					2;		//导出证书为der文件
var CERT_DST_P12 =						3;		//到出证书为PKCS12文件

var CERT_XML_SUBJECT =					1;		//从XML配置文件取用户名
var CERT_XML_UNIQUEID =					2;		//从XML配置文件取用户唯一表识
var CERT_XML_DEPT =						3;		//从XML配置文件取用户所有者部门
var CERT_XML_ISSUE =					4;		//从XML配置文件取用户证书颁发者
var CERT_XML_STATE =					5;		//从XML配置文件取用户证书使用状态
var CERT_XML_TRADETYPE =				6;		//从XML配置文件取用户证书应用类型
var CERT_XML_PASSWORD =					7;		//从XML配置文件取用户证书私钥保护口令
var CERT_XML_DEVICETYPE =				8;		//从XML配置文件取用户证书介质类型
var CERT_XML_CATYPE	 =					9;		//从XML配置文件取用户证书CA类型
var CERT_XML_KEYTYPE =					10;		//从XML配置文件取用户证书密钥类型
var CERT_XML_SIGNSN	=					11;		//从XML配置文件取用户签名证书序列号
var CERT_XML_EXCHSN	=					12;		//从XML配置文件取用户加密证书序列号
var CERT_XML_DEVICENAME =				13;		//从XML配置文件取用户证书介质名称
var CERT_XML_DEVICEPROVIDER =			14;		//从XML配置文件取用户证书介质提供者
var CERT_XML_DEVICEAFFIX =				15;		//从XML配置文件取用户证书介质附加库
var CERT_XML_SIGNPATH =					16;		//从XML配置文件取用户签名证书路径
var CERT_XML_EXCHPATH =					17;		//从XML配置文件取用户加密证书路径
var CERT_XML_SIGNPFXPATH =				18;		//从XML配置文件取用户签名P12证书路径
var CERT_XML_EXCHPFXPATH =				19;		//从XML配置文件取用户加密P12证书路径
var CERT_XML_CHAINPATH =				20;		//从XML配置文件取用户证书链路径
var CERT_XML_CRLPATH =					21;		//从XML配置文件取用户证书作废列表路径
var CERT_XML_UNIQUEIDOID =				22;		//从XML配置文件取用户证书UniqueID的OID
var CERT_XML_VERIFYTYPE	=				23;		//从XML配置文件取用户证书验证类型
var CERT_XML_CACOUNTS =					24;		//从XML配置文件取用户证书根证书个数
var CERT_XML_CANUMTYPE =				25;		//从XML配置文件取用户证书跟证书类型

var CRYPT_CFGTYPE_UNSET =				0;		//用户应用类型未定义
var CRYPT_CFGTYPE_CSP =					1;		//用户应用类型CSP
var CRYPT_CFGTYPE_P11 =					2;		//用户应用类型P11
var CRYPT_CFGTYPE_P12 =					3;		//用户应用类型软算法

var ENVELOP_ENC =						1;		//加密P7数字信封
var ENVELOP_DEC =						0;		//解密P7数字信封
var CRYPT_ALG_HASH =					1;		//Hash标志位
 

var g_xmluserlist;

 

/////define object  /////////////////////////////////
try{
	
var oCert = new ActiveXObject("BJCASecCOM.Certificate");
var oCrypto = new ActiveXObject("BJCASecCOM.Crypto");
var oDevice = new ActiveXObject("BJCASecCOM.DeviceMgr");
var oUtil = new ActiveXObject("BJCASecCOM.Util");


document.writeln("<OBJECT classid=\"clsid:0CF5259B-A812-4B6E-9746-ACF7279FEF74\" height=1 id=USBKEY  style=\"HEIGHT: 1px; LEFT: 10px; TOP: 28px; WIDTH: 1px\" width=1 VIEWASTEXT>");
document.writeln("</OBJECT>");
USBKEY.getUserList();
}
catch(e)
{
	//alert("没有正确安装证书应用环境或者证书应用环境已经损坏！");
}

/////组件接口转换为脚本接口////////////////////////

/////Certificate
function importCert(sCertSrc, SrcType, sPwd) {

	if (sPwd != null)
		return oCert.importCert(sCertSrc, SrcType, sPwd);
	else
		return oCert.importCert(sCertSrc, SrcType);
}

function exportCert(DstType, sCertPath){

	if (sCertPath != null)
		return oCert.exportCert(DstType, sCertPath);
	else
		return oCert.exportCert(DstType);
}

function getBasicCertInfoByOID(OID) {

	return oCert.getBasicCertInfoByOID(OID);
}

function getExtCertInfoByOID(sOID) {

	return oCert.getExtCertInfoByOID(sOID);
}

function checkValidaty(sDate) {

 
	if (sDate != null)
		return oCert.checkValidaty(sDate);
	else
		return oCert.checkValidaty();
}

 

function modifyPFXPwd(sPFXPath, sOldPwd, sNewPwd) {

	return oCert.modifyPFXPwd(sPFXPath, sOldPwd, sNewPwd);
}

/////Crypto

function setUserCfg(CfgFlag, sCfgValue, sExt1CfgValue, sExt2CfgValue) {

	return oCrypto.setUserCfg(CfgFlag, sCfgValue, sExt1CfgValue, sExt2CfgValue);
}

 

function signedData(sInData, sContainerName) {

	if (sContainerName != null)
		return oCrypto.signedData(sInData, sContainerName);
	else
		return oCrypto.signedData(sInData);
}

function verifySignedData(sSignValue, sCert, sOriData) {

	return oCrypto.verifySignedData(sSignValue, sCert, sOriData);
}

 

function generateRandom(RandomLen) {

	return oCrypto.generateRandom(RandomLen);
}


function getCertBasicInfo(sCert, OID) {

	oCert.importCert(sCert, CERT_SRC_BASE64);
	
	return oCert.getBasicCertInfoByOID(OID);
	
}

/////Device
function changeUserPin(sCSPName, sExtLib, sOldPin, sNewPin) {

	return oDevice.changeUserPin(sCSPName, sExtLib, sOldPin, sNewPin);
}

function userLogin(sCSPName, sUserPin) {

	return oDevice.userLogin(sCSPName, sUserPin);
}

 

function getKeyRetrys(sExtLib) {
	
	 
	return oDevice.getKeyRetrys(sExtLib);
}
/////Util
function EnumUsbKey()
{
	 
	try
	{
		USBKEY.EnumUsbKey();
	}
	catch(e)
	{
		  
	}
   
}
function getUserList_pnp() {
	
	var list;
	try
	{
		list = USBKEY.getUserList();
		return list;
	}
	catch(e)
	{
		 
		return "";
	}
	
}
function getUserList() {

 try
{
	g_xmluserlist = oUtil.getUserList();
}
catch(e)
{
	g_xmluserlist="";
	
}
	return g_xmluserlist;
}

function getUserInfoByContainer_pnp(sContainerName, TypeID) {
	
 	return USBKEY.getUserInfoByContainer(sContainerName, TypeID);
}
 
function getUserInfoByContainer(sContainerName, TypeID) {
	
	return oUtil.getUserInfoByContainer(sContainerName, TypeID);
}

function getUserCert(strContainerName)
{  
   var UserCert = getExchCert(strContainerName);
   return UserCert;
}

function getExchCert(strContainerName)
{  
	var strDeviceType = getUserInfoByContainer(strContainerName, CERT_XML_DEVICETYPE);
	var KeyType = getUserInfoByContainer(strContainerName, CERT_XML_KEYTYPE);
	if (strDeviceType == "BJSOFT") {
		//P12软算法
	   var Cert = getUserInfoByContainer(strContainerName,CERT_XML_EXCHPATH);
	   importCert(Cert,CERT_SRC_FILE);
	}
	 
	else {
		//智能卡
	 
		var strCSPName = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEPROVIDER);
		importCert(strContainerName, CERT_SRC_CONTAINER_ENC, strCSPName);
	}
    var UserCert = exportCert(CERT_DST_BASE64);
    return UserCert;
}

function getSignCert(strContainerName)
{  
	var strDeviceType = getUserInfoByContainer(strContainerName, CERT_XML_DEVICETYPE);
	var KeyType = getUserInfoByContainer(strContainerName, CERT_XML_KEYTYPE);
	 
	if (strDeviceType == "BJSOFT") {
		//P12软算法
		if (KeyType == 1) {
			//单证书
		   var Cert = getUserInfoByContainer(strContainerName,CERT_XML_EXCHPATH);
		   importCert(Cert,CERT_SRC_FILE);
		}
		else if (KeyType == 2) {
			//双证书
		   var Cert = getUserInfoByContainer(strContainerName,CERT_XML_SIGNPATH);
		   importCert(Cert,CERT_SRC_FILE);
		}
		else {
			alert("配置文件错误1");
			return false;
		}
	}
 
	else {
		//智能卡
		 
		var strCSPName = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEPROVIDER);
		KeyType = getUserInfoByContainer_pnp(strContainerName, CERT_XML_KEYTYPE);
		 
		if (KeyType == 1) {
			//单证书
			importCert(strContainerName, CERT_SRC_CONTAINER_ENC, strCSPName);
		}
		else if (KeyType == 2) {
			//双证书
			importCert(strContainerName, CERT_SRC_CONTAINER_SIGN, strCSPName);
		}
		else {
			alert("配置文件错误3,KeyType="+KeyType+"strContainerName="+strContainerName);
			return false;
		}
	}
	
    var UserCert = exportCert(CERT_DST_BASE64);
    return UserCert;
}

 /*
Function:	getCertDetail  
Parameter:	strContainerName容器名
			ItemNo		    细目类型
 1	证书版本
2	证书序列号
4	证书发放者国家名
5	证书发放者组织名
6	证书发放者部门名
7	证书发放者省州名
8	证书发放者通用名
9	证书发放者城市名
10	证书发放者EMAIL地址
11	证书有效期起始
12	证书有效期截止
13	用户国家名
14	用户组织名
15	用户部门名
16	用户省州名
17	用户通用名
18	用户城市名
19	用户EMAIL地址
23	用户备用主题国家名
24	用户备用主题组织名
25	用户备用主题部门名
26	用户备用主题省州名
27	用户备用主题通用名
28	用户备用主题城市名
29	用户备用主题EMAIL地址


 */
//Parse Cert /////////////////////////////////////
function getCertDetail(strContainerName, ItemNo)
{
	var sCert = getUserCert(strContainerName);
	return getCertBasicInfo(sCert,ItemNo);
} 
 

 
function changeUserPassword(strContainerName,oldPwd,newPwd)
{
	var strP12Path = null;
	var rv = 0;
	var strDeviceType = getUserInfoByContainer(strContainerName, CERT_XML_DEVICETYPE);
	var KeyType = getUserInfoByContainer(strContainerName, CERT_XML_KEYTYPE);
	
	if (strDeviceType == "BJSOFT") {
		//P12软算法
		if (KeyType == 1) {
			//单证书
			strP12Path = getUserInfoByContainer(strContainerName, CERT_XML_EXCHPFXPATH);
			rv = modifyPFXPwd(strP12Path, oldPwd, newPwd);
		}
		else if (KeyType == 2) {
			//双证书
			strP12Path = getUserInfoByContainer(strContainerName, CERT_XML_SIGNPFXPATH);
			var strExchPath = getUserInfoByContainer(strContainerName, CERT_XML_EXCHPFXPATH);
			var rvtmp = modifyPFXPwd(strP12Path, oldPwd, newPwd);
			rv = modifyPFXPwd(strExchPath, oldPwd, newPwd);

		}
		else {
			alert("配置文件错误4");
			return -1;
		}
		setUserCfg(CRYPT_CFGTYPE_P12, strP12Path, newPwd, "");
	}
	 
	else {
		//智能卡
		
		var strCSPName = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEPROVIDER);
		var strExtLib = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEAFFIX);
	
		if (strExtLib == null)
			strExtLib = "Temp";
		rv = changeUserPin(strCSPName, strExtLib, oldPwd,newPwd);	
		setUserCfg(CRYPT_CFGTYPE_CSP, strCSPName, strExtLib, newPwd);
	}
	return rv;
}

function Login(strFormName,strContainerName,strPin) {
	var ret;
	var objForm = eval(strFormName);
  
	if (objForm == null) {
		alert("Form Error");
		return false;
	}
	if (strPin == null || strPin == "") {
		alert("请输入Key的保护口令");
		return false;
	}
	//alert(strServerSignedData);
	//alert(strServerCert);
	//alert(strServerRan);
	
	//Add a hidden item ...
	var strSignItem = "<input type=\"hidden\" name=\"UserSignedData\" value=\"\">";
	if (objForm.UserSignedData == null) {
		objForm.insertAdjacentHTML("BeforeEnd",strSignItem);
	}
	var strCertItem = "<input type=\"hidden\" name=\"UserCert\" value=\"\">";
	if (objForm.UserCert == null) {
		objForm.insertAdjacentHTML("BeforeEnd",strCertItem);
	}
	var strContainerItem = "<input type=\"hidden\" name=\"ContainerName\" value=\"\">";
	if (objForm.ContainerName == null) {
		objForm.insertAdjacentHTML("BeforeEnd",strContainerItem);
	}

	var strP12Path = null;
	
	var strDeviceType = getUserInfoByContainer(strContainerName, CERT_XML_DEVICETYPE);
	var KeyType = getUserInfoByContainer(strContainerName, CERT_XML_KEYTYPE);
  var strCAType = getUserInfoByContainer(strContainerName, CERT_XML_CATYPE);
 
	
	if (strDeviceType == "BJSOFT") {
		//P12软算法
		if (KeyType == 1) {
			//单证书
			strP12Path = getUserInfoByContainer(strContainerName, CERT_XML_EXCHPFXPATH);
		}
		else if (KeyType == 2) {
			//双证书
			strP12Path = getUserInfoByContainer(strContainerName, CERT_XML_SIGNPFXPATH);
		}
		else {
			alert("配置文件错误6");
			return false;
		}
		
		if (importCert(strP12Path, CERT_SRC_PKCS12, strPin) != 0) {
			alert("口令错误");
			return false;
		}
		setUserCfg(CRYPT_CFGTYPE_P12, strP12Path, strPin, "");
		var strClientSignedData = signedData(strServerRan,strContainerName);
	 
	}
	 
	else {
		//智能卡
		var strCSPName = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEPROVIDER);
		var strExtLib = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEAFFIX);
		var strUserName = getUserInfoByContainer_pnp(strContainerName, CERT_XML_SUBJECT);
	 KeyType = getUserInfoByContainer_pnp(strContainerName, CERT_XML_KEYTYPE);
		
		if (strExtLib == null)
			strExtLib = "Temp";
		ret = userLogin(strCSPName, strPin);

		if (ret != 0 ){
			var retryNum = getKeyRetrys(strExtLib);
			switch (retryNum) {
				case -1010:
					alert("未正确插入智能卡");
					return false;
					break;
				case -1011:
					alert("智能卡操作失败");
					return false;
					break;
				default:
					alert("口令错误,重试还剩下"+retryNum+"次");
					return false;
					break;
			}
		}
		
		if (KeyType == 1) {
			//单证书
			if(importCert(strContainerName, CERT_SRC_CONTAINER_ENC, strCSPName) != 0){
				alert("口令错误或未正确插入智能卡");
				return false;
			}
		}
		else if (KeyType == 2) {
			//双证书
			if(importCert(strContainerName, CERT_SRC_CONTAINER_SIGN, strCSPName)!= 0){
				alert("口令错误或未正确插入智能卡");
				return false;
			}
		}
		else {
			alert("配置文件错误8");
			return false;
		}
		 
	  
		setUserCfg(CRYPT_CFGTYPE_CSP, strCSPName, strExtLib, strPin);
		var strClientSignedData = signedData(strServerRan, strContainerName);
		 
	}
	if(verifySignedData(strServerSignedData,strServerCert,strServerRan)!=0)
	{
		alert("验证服务器签名失败！");
		return false;
	}
	//alert("验证服务器签名 OK！"); 

	objForm.UserSignedData.value = strClientSignedData;
	objForm.UserCert.value = exportCert(CERT_DST_BASE64);
	objForm.ContainerName.value = strContainerName;
  
	var rv = checkValidaty();
	return alertValidDay(rv);
	 

}

function alertValidDay(ret)
{
 	var ValidDay;
	ValidDay = parseInt(ret);
 
 
    if(parseInt(ret) > 365){
       // alert("证书还未生效!");
	   //return false;
	}
	
	if (parseInt(ret) <= 60 && parseInt(ret) > 0) {
		alert("您的证书还有" + ValidDay + "天过期，\n请您尽快到北京数字证书认证中心办理证书更新手续，\n否则会影响您的正常使用，造成不必要的麻烦和损失。\n证书用户注意查看告知事项，具体更新手续请登录:\nhttp://www.bjca.org.cn；咨询电话：82031677-8686。");
	}
	
	if(parseInt(ret) <= -45)
	{
	    alert("您的证书已过期 "+ -parseInt(ret) +" 天，超过了最后使用期限！\n请到北京数字证书认证中心办理证书更新手续！\n\n证书用户注意查看告知事项，具体更新手续请登录:\nhttp://www.bjca.org.cn；咨询电话：82031677-8686。");
	    return false;
	}
		
	if(parseInt(ret) <= 0){
	    alert("您的证书已过期 "+ -parseInt(ret) +" 天，\n请尽快到北京数字证书认证中心办理证书更新手续，\n否则会影响您的正常使用，造成不必要的麻烦和损失。\n证书用户注意查看告知事项，具体更新手续请登录:\nhttp://www.bjca.org.cn；咨询电话：82031677-8686。");
	}
	return true;
}
function getKeySN(strContainerName) 
 {
 	 //var strDevType = getUserInfoByContainer(strContainerName, CERT_XML_DEVICETYPE);
 	 var strExtLib = getUserInfoByContainer_pnp(strContainerName, CERT_XML_DEVICEAFFIX);
   var sn = oDevice.getKeySN(strExtLib);
    
   return sn;
 }
 
function PubKeyEncrypt(exchCert,inData)
{
	try
	{
		var ret = oCrypto.pubKeyEncrypt(exchCert,inData);
		return ret;
	}
 catch(e)
 {
	 
 }
}
function PriKeyDecrypt(sContainerName,inData)
{
	try
	{
		var ret = oCrypto.priKeyDecrypt(sContainerName,inData);
		return ret;
	}
 catch(e)
 {
	 
 }
}


function EncryptData(sKey,inData)
{
	try
	{
		var ret = oCrypto.encryptData(sKey,inData);
		return ret;
	}
 catch(e)
 {
	 
 }
}

function DecryptData(sKey,inData)
{
	try
	{
		var ret = oCrypto.decryptData(sKey,inData);
		return ret;
	}
 catch(e)
 {
	 
 }
}


