/******************************************************************************
版权所有：	
文件名称：	base64.c
文件版本：	01.01
创建作者：	xxxxxx
创建日期：	2015-07-04
功能说明：	base64解码实现文件.	
								
其它说明：
修改记录：
*/

/*
X.509证书的结构
1、X.509证书基本部分
1.1.        版本号.
标识证书的版本（版本1、版本2或是版本3）。
1.2.        序列号
标识证书的唯一整数，由证书颁发者分配的本证书的唯一标识符。
1.3.        签名
用于签证书的算法标识，由对象标识符加上相关的参数组成，用于说明本证书所用的数字签名算法。例如，SHA-1和RSA的对象标识符就用来说明该数字签名是利用RSA对SHA-1杂凑加密。
1.4.        颁发者
证书颁发者的可识别名（DN）。
1.5.        有效期
证书有效期的时间段。本字段由”Not Before”和”Not After”两项组成，它们分别由UTC时间或一般的时间表示（在RFC2459中有详细的时间表示规则）。
1.6.        主体
证书拥有者的可识别名，这个字段必须是非空的，除非你在证书扩展中有别名。
1.7.        主体公钥信息
主体的公钥（以及算法标识符）。
1.8.        颁发者唯一标识符
标识符—证书颁发者的唯一标识符，仅在版本2和版本3中有要求，属于可选项。
1.9.        主体唯一标识符
证书拥有者的唯一标识符，仅在版本2和版本3中有要求，属于可选项。
2、X.509证书扩展部分
可选的标准和专用的扩展（仅在版本2和版本3中使用），扩展部分的元素都有这样的结构：
   Extension ::= SEQUENCE {
        extnID      OBJECT IDENTIFIER,
        critical    BOOLEAN DEFAULT FALSE,
        extnValue   OCTET STRING }
extnID：表示一个扩展元素的OID
critical：表示这个扩展元素是否极重要
extnValue：表示这个扩展元素的值，字符串类型。
扩展部分包括：
2.1.        发行者密钥标识符
证书所含密钥的唯一标识符，用来区分同一证书拥有者的多对密钥。
2.2.        密钥使用
一个比特串，指明（限定）证书的公钥可以完成的功能或服务，如：证书签名、数据加密等。
如果某一证书将 KeyUsage 扩展标记为“极重要”，而且设置为“keyCertSign”，则在 SSL 通信期间该证书出现时将被拒绝，因为该证书扩展表示相关私钥应只用于签写证书，而不应该用于 SSL。
2.3.        CRL分布点
指明CRL的分布地点。
2.4.        私钥的使用期
指明证书中与公钥相联系的私钥的使用期限，它也有Not Before和Not After组成。若此项不存在时，公私钥的使用期是一样的。
2.5.        证书策略
由对象标识符和限定符组成，这些对象标识符说明证书的颁发和使用策略有关。
2.6.        策略映射
表明两个CA域之间的一个或多个策略对象标识符的等价关系，仅在CA证书里存在。
2.7.        主体别名
指出证书拥有者的别名，如电子邮件地址、IP地址等，别名是和DN绑定在一起的。
2.8.        颁发者别名
指出证书颁发者的别名，如电子邮件地址、IP地址等，但颁发者的DN必须出现在证书的颁发者字段。
2.9.        主体目录属性
指出证书拥有者的一系列属性。可以使用这一项来传递访问控制信息。
三、 X.509证书详细描述
   Certificate ::= SEQUENCE {
        tbsCertificate       TBSCertificate, -- 证书主体
        signatureAlgorithm   AlgorithmIdentifier, -- 证书签名算法标识
        signatureValue       BIT STRING --证书签名值,是使用signatureAlgorithm部分指定的签名算法对tbsCertificate证书主题部分签名后的值.
         }
   TBSCertificate ::= SEQUENCE {
        version         [0] EXPLICIT Version DEFAULT v1, -- 证书版本号
        serialNumber         CertificateSerialNumber, -- 证书序列号，对同一CA所颁发的证书，序列号唯一标识证书
        signature            AlgorithmIdentifier, --证书签名算法标识
        issuer               Name,                --证书发行者名称
        validity             Validity,            --证书有效期
        subject              Name,                --证书主体名称
        subjectPublicKeyInfo SubjectPublicKeyInfo,--证书公钥
        issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
                             -- 证书发行者ID(可选)，只在证书版本2、3中才有
        subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
                             -- 证书主体ID(可选)，只在证书版本2、3中才有
        extensions      [3] EXPLICIT Extensions OPTIONAL
                             -- 证书扩展段（可选），只在证书版本3中才有
        }
   Version ::= INTEGER { v1(0), v2(1), v3(2) }
   CertificateSerialNumber ::= INTEGER
 
   AlgorithmIdentifier ::= SEQUENCE {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL }
   parameters:
   Dss-Parms ::= SEQUENCE { -- parameters ，DSA(DSS)算法时的parameters,

RSA算法没有此参数
        p             INTEGER,
        q             INTEGER,
        g             INTEGER }
 
signatureValue：
Dss-Sig-Value ::= SEQUENCE { -- sha1DSA签名算法时,签名值
                   r       INTEGER,
                      s       INTEGER }
 
   Name ::= CHOICE {
     RDNSequence }
   RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
   RelativeDistinguishedName ::=
     SET OF AttributeTypeAndValue
   AttributeTypeAndValue ::= SEQUENCE {
     type     AttributeType,
     value    AttributeValue }
   AttributeType ::= OBJECT IDENTIFIER
   AttributeValue ::= ANY DEFINED BY AttributeType
 
   Validity ::= SEQUENCE {
        notBefore      Time,  -- 证书有效期起始时间
        notAfter       Time  -- 证书有效期终止时间
        }
   Time ::= CHOICE {
        utcTime        UTCTime,
        generalTime    GeneralizedTime }
   UniqueIdentifier ::= BIT STRING
   SubjectPublicKeyInfo ::= SEQUENCE {
        algorithm            AlgorithmIdentifier, -- 公钥算法
        subjectPublicKey     BIT STRING            -- 公钥值
        }
subjectPublicKey:
RSAPublicKey ::= SEQUENCE { -- RSA算法时的公钥值
         modulus            INTEGER, -- n
         publicExponent     INTEGER -- e -- }
 
   Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
   Extension ::= SEQUENCE {
        extnID      OBJECT IDENTIFIER,
        critical    BOOLEAN DEFAULT FALSE,
        extnValue   OCTET STRING }


*/
#include "head.h"

#ifdef ENCRYPT_X509

#ifdef LINUX_KERNEL_APP
#include "x509.h" 
#include "base64.h"

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/wait.h> 
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/ioctls.h>
#include <linux/syscalls.h> 
#include <termios.h>
#else
#include "head.h"
#include "x509.h" 
#include "base64.h"
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/wait.h> 
#include <asm/ioctls.h>
#include <termios.h>
#endif

//#define   X509_DEBUG

#define V_ASN1_UTCTIME                  23			//UTC时间类型
#define V_ASN1_GENERALIZEDTIME          24     //非UTC时间类型 


#define	SM2_PUBKEY_LENTH			68		//SM2公钥长度

typedef struct{

	unsigned char type[128];  			//类型
	unsigned char value[128]; 			//值

	int type_len;								//类型长度
	int value_len;							//值长度
	
} TName;   


//证书有效期
typedef struct{
	unsigned char notBefore[32];  //起始时间
	unsigned char notAfter[32]; 	//结束时间
	int notBefore_len;						//起始时间长度
	int notAfter_len;							//结束时间长度
} Validity;    
      
//证书算法标示    
typedef struct {

	unsigned char algorithm[64];		//算法
	unsigned char	parameters[64];		//参数
	int algorithm_len;						//长度
	int parameters_len;						//长度
} AlgorithmIdentifier;      
 
//x509 V3扩展域         
typedef struct{
	unsigned char signature_a[64];  //签名算法
	unsigned char signature_v[256];  //签名值
	int signature_a_len;			//长度
	int signature_v_len;			//长度
//	unsigned char extnID[64];	
//	unsigned char critical[64];	
//	unsigned char extnValue[64];
		
//	int extnID_len;
//	int critical_len;
//	int extnValue_len;
} Extension;         
 
//证书公钥   
typedef struct{
	
	AlgorithmIdentifier  algorithm;  //算法表示
	unsigned char subjectPublicKey[256];//公钥
	int subjectPublicKey_len;  //公钥长度
	
} SubjectPublicKeyInfo; 
  
  
// 证书主体      
typedef struct
{
	unsigned int  version;					//证书版本号
	unsigned char serialNumber[64];	//证书序列号，对同一CA所颁发的证书，序列号唯一标识证书
	unsigned char signature[64];   //证书签名算法标识
	TName issuer[8];								//证书发行者名称
	Validity validity;						//	证书有效期
	TName subject[8];								//证书主体名称
	SubjectPublicKeyInfo subjectPublicKeyInfo;  //证书公钥
//	unsigned char issuerUniqueID [64];
//	unsigned char subjectUniqueID[64];
	Extension  extensions;							//证书扩展段
	

	int serialNumber_len;			//长度
	int signature_len;
	int issuer_len;
	int subject_len;
	
	
}TBSCertificate;

//X.509证书详细描述 
struct Certificate
{
	TBSCertificate tbsCertificate;					//证书主体
	AlgorithmIdentifier signatureAlgorithm; //证书签名算法标识	
	unsigned char *signatureValue; 									//证书签名值,是使用signatureAlgorithm部分指定的签名算法对tbsCertificate证书主题部分签名后的值
}; 


struct x509tm{
	uint32_t begin_time;
	uint32_t end_time;
};
 

//X.509证书全局变量
static struct Certificate g_Certificate;

//OID标示
static char *OID[]=
{
	"CN",
	"SP",
	"LO",
	"OU",
	"UN",
	"CM"	
};


static struct x509tm  g_x509tm[4];
static int g_x509_cer_file_flag = 0;


int x509_isvalid_time(int no,  uint32_t locat_time)
{
	struct timespec ts;
	struct rtc_time_t tm;
	char tmbuf[128];
	
	if((no > 3) || (no < 0))
	{
		rt_printf("%s: invalid no\n", __func__);
		return -1;
	}
	
	
	if(g_x509_cer_file_flag==0)
	{
		return 0;
	}

	if((g_x509tm[no].begin_time > locat_time)  ||  (g_x509tm[no].end_time <  locat_time))
	{
		rt_printf("%s: invalid time:\r\n", __func__);	
		ts.tv_nsec = 0;
		ts.tv_sec = (long) g_x509tm[no].begin_time ;
		timespec_to_rtc(ts, &tm, 0);
		sprintf(tmbuf,"BEGIN TIME:20%02hu-%02hu-%02hu %02hu:%02hu:%02hu \r\n",tm.year,tm.month,tm.day,tm.hour,tm.min,tm.ms/1000);
		rt_printf(tmbuf);
		ts.tv_sec = (long) g_x509tm[no].end_time ;
		timespec_to_rtc(ts, &tm, 0);
		sprintf(tmbuf,"END TIME:20%02hu-%02hu-%02hu %02hu:%02hu:%02hu \r\n",tm.year,tm.month,tm.day,tm.hour,tm.min,tm.ms/1000);
		rt_printf(tmbuf);	
		ts.tv_sec = (long)locat_time ;
		timespec_to_rtc(ts, &tm, 0);
		sprintf(tmbuf,"LOCAL TIME:20%02hu-%02hu-%02hu %02hu:%02hu:%02hu \r\n",tm.year,tm.month,tm.day,tm.hour,tm.min,tm.ms/1000);
		rt_printf(tmbuf);			
		return -1;	
		
	}
	
	return 0;
}

int x509_time_init(void)
{
	int fd;
	int ret;

	memset(g_x509tm, 0, sizeof(g_x509tm));
	
	fd = sys_open(FILENAME_X509_TIME0, O_RDONLY, 0);	
	if(fd < 0)
	{
		//rt_printf("%s:open %s error\n",__func__, FILENAME_X509_TIME0);
	}
	else
	{

		ret = sys_read(fd, (char *)&g_x509tm[0], 8);	
		if(ret!=8)
		{
			rt_printf("%s:sys_read %s error\n",__func__, FILENAME_X509_TIME0);
		}

		sys_close(fd);
		g_x509_cer_file_flag = 1;	
	}


	fd = sys_open(FILENAME_X509_TIME1, O_RDONLY, 0);	
	if(fd < 0)
	{
		//rt_printf("%s:open %s error\n",__func__, FILENAME_X509_TIME1);
	}
	else
	{

		ret = sys_read(fd, (char *)&g_x509tm[1], 8);	
		if(ret!=8)
		{
			rt_printf("%s:sys_read %s error\n",__func__, FILENAME_X509_TIME1);
		}

		sys_close(fd);
		g_x509_cer_file_flag = 1;	
			
	}

	fd = sys_open(FILENAME_X509_TIME2, O_RDONLY, 0);	
	if(fd < 0)
	{
		//rt_printf("%s:open %s error\n",__func__, FILENAME_X509_TIME2);
	}
	else
	{

		ret = sys_read(fd, (char *)&g_x509tm[2], 8);	
		if(ret!=8)
		{
			rt_printf("%s:sys_read %s error\n",__func__, FILENAME_X509_TIME2);
		}

		sys_close(fd);
		g_x509_cer_file_flag = 1;	
			
	}
	
	fd = sys_open(FILENAME_X509_TIME3, O_RDONLY, 0);	
	if(fd < 0)
	{
		//rt_printf("%s:open %s error\n",__func__, FILENAME_X509_TIME3);
	}
	else
	{

		ret = sys_read(fd, (char *)&g_x509tm[3], 8);	
		if(ret!=8)
		{
			rt_printf("%s:sys_read %s error\n",__func__, FILENAME_X509_TIME3);
		}

		sys_close(fd);
		g_x509_cer_file_flag = 1;	
			
	}

	//x509_isvalid_time(0, g_x509tm[0].begin_time);
	//x509_isvalid_time(1, g_x509tm[1].begin_time);
	//x509_isvalid_time(2, g_x509tm[2].begin_time);
	//x509_isvalid_time(3, g_x509tm[3].begin_time);

	return 0;

}
 
/******************************************************************************
函数名称：	from_s_to_d
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	从字符串转整数.						
参数说明：	
						str:要转的字符串
						len:字符串长度
返回值：  	整数值。
修改记录：	
*/
static unsigned int from_s_to_d(unsigned char *str, int len)
{
	unsigned int value = 0;

	switch(len)
	{
	case 1:
		value = (unsigned int)str[0];
		break;
	case 2:
		value = (unsigned int)str[0] << 8;
		value |= (unsigned int)str[1] ;
		break;
	case 3:
		value = (unsigned int)str[0] << 16;
		value |= (unsigned int)str[1] << 8 ;	
		value |= (unsigned int)str[2] ;		
		break;
	case 4:
		value = (unsigned int)str[0] << 24;
		value |= (unsigned int)str[1] << 16;	
		value |= (unsigned int)str[2] << 8;	
		value |= (unsigned int)str[3] ;		
		break;
	default:
		break;			
					
	}
	
	return value;	

}

/******************************************************************************
函数名称：	get_oid_from_str
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	从字符串得到OID.						
参数说明：	
						data:要转的字符串
返回值：  	OID值。
修改记录：	
*/
static char * get_oid_from_str(char *data)
{
	if((data[0]==0x55) && (data[1]==0x04))	
	{
	
		if(data[2]==0x06)
		{
			return OID[0];
		}
		else if(data[2]==0x0A)
		{
			return OID[3];	
		}
		else if(data[2]==0x0B)
		{
			return OID[4];		
		}
		else if(data[2]==0x03)
		{
			return OID[5];		
		}	
		else if(data[2]==0x07)
		{
			return OID[2];	
		} 
		else
		{
			return OID[1];	
		}
		
	}
	
	return OID[0];		
}

/******************************************************************************
函数名称：	ASN1_GENERALIZEDTIME_check
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	检查时间的合法性(非UTC时间).						
参数说明：	
						data:时间字符串
						data_len:字符串长度
						timetype:时间类型	
返回值：  	成功返回1，失败返回0。
修改记录：	
*/
static int ASN1_GENERALIZEDTIME_check(unsigned char *data, int data_len, int timetype)
{
    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
    char *a;
    int n, i, l, o;

    if (timetype != V_ASN1_GENERALIZEDTIME)
        return (0);
    l = data_len;
    a = (char *)data;
    o = 0;
    /*
     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
     * as YYYY. This stuff treats everything as a two digit field so make
     * first two fields 00 to 99
     */
    if (l < 13)
        goto err;
    for (i = 0; i < 7; i++) {
        if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
            i++;
            break;
        }
        if ((a[o] < '0') || (a[o] > '9'))
            goto err;
        n = a[o] - '0';
        if (++o > l)
            goto err;

        if ((a[o] < '0') || (a[o] > '9'))
            goto err;
        n = (n * 10) + a[o] - '0';
        if (++o > l)
            goto err;

        if ((n < min[i]) || (n > max[i]))
            goto err;
    }
    /*
     * Optional fractional seconds: decimal point followed by one or more
     * digits.
     */
    if (a[o] == '.') {
        if (++o > l)
            goto err;
        i = o;
        while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
            o++;
        /* Must have at least one digit after decimal point */
        if (i == o)
            goto err;
    }

    if (a[o] == 'Z')
        o++;
    else if ((a[o] == '+') || (a[o] == '-')) {
        o++;
        if (o + 4 > l)
            goto err;
        for (i = 7; i < 9; i++) {
            if ((a[o] < '0') || (a[o] > '9'))
                goto err;
            n = a[o] - '0';
            o++;
            if ((a[o] < '0') || (a[o] > '9'))
                goto err;
            n = (n * 10) + a[o] - '0';
            if ((n < min[i]) || (n > max[i]))
                goto err;
            o++;
        }
    } else {
        /* Missing time zone information. */
        goto err;
    }
    return (o == l);
 err:
    return (0);
}

/******************************************************************************
函数名称：	ASN1_UTCTIME_check
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	检查时间的合法性(UTC时间).						
参数说明：	
						data:时间字符串
						data_len:字符串长度
						timetype:时间类型	
返回值：  	成功返回1，失败返回0。
修改记录：	
*/
static int ASN1_UTCTIME_check(unsigned char *data, int data_len, int timetype)
{
    static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
    static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
    char *a;
    int n, i, l, o;

    if (timetype != V_ASN1_UTCTIME)
        return (0);
    l = data_len;
    a = (char *)data;
    o = 0;
    
    if (l < 11)
        goto err;
    for (i = 0; i < 6; i++) {
        if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
            i++;
            break;
        }
        if ((a[o] < '0') || (a[o] > '9'))
            goto err;
        n = a[o] - '0';
        if (++o > l)
            goto err;

        if ((a[o] < '0') || (a[o] > '9'))
            goto err;
        n = (n * 10) + a[o] - '0';
        if (++o > l)
            goto err;

        if ((n < min[i]) || (n > max[i]))
            goto err;
    }
    if (a[o] == 'Z')
        o++;
    else if ((a[o] == '+') || (a[o] == '-')) {
        o++;
        if (o + 4 > l)
            goto err;
        for (i = 6; i < 8; i++) {
            if ((a[o] < '0') || (a[o] > '9'))
                goto err;
            n = a[o] - '0';
            o++;
            if ((a[o] < '0') || (a[o] > '9'))
                goto err;
            n = (n * 10) + a[o] - '0';
            if ((n < min[i]) || (n > max[i]))
                goto err;
            o++;
        }
    }
    return (o == l);
 err:
    return (0);
}



/******************************************************************************
函数名称：	x509_get_one_blk_data
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	获取一个数据块.						
参数说明：	
						src_data:源数据
						data_len:数据内容的长度
返回值：  	数据块内容的首地址。
修改记录：	
*/
static unsigned char *x509_get_one_blk_data(unsigned char *src_data, unsigned int *data_len)
{
	unsigned char *p=src_data;
	int pos = 0;
	unsigned int total_len = 0;
 	unsigned char byte_d[8]={0};
 	int byte_cnt = 0;
 	int i = 0;
 				
	//多字节的情况
	if(p[1] & 0x80)
	{
		byte_cnt= (int)(p[1] & 0x7F);
		
		for(i=0;(i<4) && (i<byte_cnt); i++)
		{
			byte_d[i]=p[2+i];		
			
		}
		
		if(byte_cnt) //长度固定的情况
		{
			total_len=from_s_to_d(byte_d, byte_cnt);
			pos=2+ byte_cnt;  
		}	
		else
		{
			//长度不固定的情况
			pos = 2;	
		}				
	}
	else //单字节的情况
	{
		byte_cnt=(int)(p[1] & 0x7F);
		
		if(byte_cnt) //长度固定的情况
		{
			total_len=from_s_to_d(&p[1], 1);
			pos=2;  
		}	
		else
		{
			//长度不固定的情况
			pos = 2;	
		}							
	}
	
	*data_len = total_len;
		
	return (unsigned char *)(p+pos);
}



/******************************************************************************
函数名称：	x509_decode
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	X509证书解码.						
参数说明：	
						data:证书内容
						data_len:证书长度
返回值：  	成功返回0，失败返回-1
修改记录：	
*/
static int x509_decode(unsigned char *data, int data_len)
{
	unsigned char *p=data;
	unsigned char *ptr_begin=data;
	unsigned char *ptr_end;
	int i = 0;
	//int j = 0;
	unsigned int total_len = 0;
	unsigned int len_tmp = 0;



	//Certificate ::= SEQUENCE 
	if(p[0]!=0x30)
	{
		rt_printf("%s:head error\n",__func__);
		return -1;	
	}

	//Certificate    
	p = x509_get_one_blk_data(p, &total_len);


	//tbsCertificate	 证书主体
	p = x509_get_one_blk_data(p, &len_tmp);
	ptr_begin = p;
	
	
	//version    证书版本号
	p = x509_get_one_blk_data(p, &len_tmp);
	
	if(ptr_begin[0]!=0xA0)
	{
		rt_printf("%s:not version type\n",__func__);
		return -1;		
	}
	p = x509_get_one_blk_data(p, &len_tmp);
	
	//版本号
	g_Certificate.tbsCertificate.version = from_s_to_d(p, len_tmp);
	
	if(g_Certificate.tbsCertificate.version > 2)
	{
		rt_printf("%s:not valid version\n",__func__);
		return -1;		
	}

	#ifdef X509_DEBUG 
	rt_printf("Version:\n%d\n", g_Certificate.tbsCertificate.version);
	#endif
	
	p=&p[len_tmp];

	
	
	//serialNumber   证书序列号，对同一CA所颁发的证书，序列号唯一标识证书
	p = x509_get_one_blk_data(p, &len_tmp);

	//序列号
	g_Certificate.tbsCertificate.serialNumber_len =len_tmp;
	memcpy(g_Certificate.tbsCertificate.serialNumber, p, len_tmp);
	#ifdef X509_DEBUG 
	rt_printf("serialNumber:\n");
	for(i=0;i<g_Certificate.tbsCertificate.serialNumber_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.serialNumber[i]);	
	}
	rt_printf("\n");
	#endif
	
	p=&p[len_tmp];

	
	
	//signature  证书签名算法标识
	p = x509_get_one_blk_data(p, &len_tmp);
	
	ptr_end = &p[len_tmp]; //下一个数据块的内容指针
	p = x509_get_one_blk_data(p, &len_tmp);
	g_Certificate.tbsCertificate.signature_len =len_tmp;
	memcpy(g_Certificate.tbsCertificate.signature, p, len_tmp);
	#if 0
	rt_printf("signature:\n");
	for(i=0;i<g_Certificate.tbsCertificate.signature_len;i++)
	{
		rt_printf("%02x ",g_Certificate.tbsCertificate.signature[i]);		
	}
	rt_printf("\n");
	#endif
 	p = ptr_end;
 	
 	
	//issuer 证书发行者名称
	
	// Name ::= CHOICE {
  //   RDNSequence }
 	p = x509_get_one_blk_data(p, &len_tmp);
 	ptr_end = &p[len_tmp]; //下一个数据块的内容指针

	#ifdef X509_DEBUG 
	rt_printf("issuer:\n");
	#endif
 	for(i=0; (i<6) && (ptr_end > p); i++)
 	{
	 	//RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
	 	//RelativeDistinguishedName ::=
	  //   SET OF AttributeTypeAndValue
	 	p = x509_get_one_blk_data(p, &len_tmp);	
	 	
	 //AttributeTypeAndValue ::= SEQUENCE {
	  //   type     AttributeType,
	  //   value    AttributeValue }
	 	p = x509_get_one_blk_data(p, &len_tmp);
	

	 	//   type     AttributeType,
	 	p = x509_get_one_blk_data(p, &len_tmp);	
	 	memcpy(g_Certificate.tbsCertificate.issuer[i].type, p, len_tmp); 
	 	g_Certificate.tbsCertificate.issuer[i].type_len = len_tmp;
	  p = &p[len_tmp];
	  
	  //value    AttributeValue
	 	p = x509_get_one_blk_data(p, &len_tmp);
	 	memcpy(g_Certificate.tbsCertificate.issuer[i].value, p, len_tmp); 
	 	g_Certificate.tbsCertificate.issuer[i].value_len = len_tmp; 	
		p = &p[len_tmp];
		
		#if 0
		for(j=0;j<g_Certificate.tbsCertificate.issuer[i].type_len;j++)
		{
			rt_printf("%02x ", g_Certificate.tbsCertificate.issuer[i].type[j]);	
		}
		rt_printf("\n");
		
		for(j=0;j<g_Certificate.tbsCertificate.issuer[i].value_len;j++)
		{
			rt_printf("%02x ", g_Certificate.tbsCertificate.issuer[i].value[j]);	
		}
		rt_printf("\n\n");
		#else
		#ifdef X509_DEBUG 
		rt_printf("%s:", get_oid_from_str(g_Certificate.tbsCertificate.issuer[i].type));
		rt_printf("%s\n", g_Certificate.tbsCertificate.issuer[i].value);
		#endif
		#endif

		g_Certificate.tbsCertificate.issuer_len++;
		
 	}
 	p=ptr_end;
 	
 	
 	
 	
 	
	//	validity             Validity,            --证书有效期
	
 	//notBefore 
 	p = x509_get_one_blk_data(p, &len_tmp);
 	ptr_end = &p[len_tmp]; //下一个数据块的内容指针
 	
 	//检查证书有效期起始时间的合法性
 	if(!ASN1_UTCTIME_check(p+2, (int)p[1], (int)p[0]))
 	{
 		if(!ASN1_GENERALIZEDTIME_check(p+2, (int)p[1], (int)p[0]))
 		{
 			rt_printf("%s:notBefore time error\n",__func__);	
 			return -1;	
 		}		
 	}
 	
 	memcpy(g_Certificate.tbsCertificate.validity.notBefore, p+2, (int)p[1]-1); 
 	g_Certificate.tbsCertificate.validity.notBefore_len = (int)p[1]-1;
 	
	//notAfter 	
 	p=&p[g_Certificate.tbsCertificate.validity.notBefore_len+2+1];
 		
 	//检查证书有效期结束时间的合法性
 	if(!ASN1_UTCTIME_check(p+2, (int)p[1], (int)p[0]))
 	{
 		if(!ASN1_GENERALIZEDTIME_check(p+2, (int)p[1], (int)p[0]))
 		{
 			rt_printf("%s:notBefore time error\n",__func__);	
 			return -1;	
 		}		
 	}
 	
 	memcpy(g_Certificate.tbsCertificate.validity.notAfter, p+2, (int)p[1]-1); 
 	g_Certificate.tbsCertificate.validity.notAfter_len = (int)p[1]-1; 		
	p = ptr_end;
	#ifdef X509_DEBUG 
	rt_printf("Start Time(%d):\r\n", g_Certificate.tbsCertificate.validity.notBefore_len);
 	{
 		char *pp = g_Certificate.tbsCertificate.validity.notBefore;
		rt_printf("20%c%c-%c%c-%c%c %c%c:%c%c:%c%c\n", pp[0], pp[1], pp[2], pp[3],pp[4], pp[5], pp[6], pp[7], pp[8], pp[9],pp[10], pp[11]);  
 	}
	 
	rt_printf("End Time(%d):\r\n", g_Certificate.tbsCertificate.validity.notAfter_len);
 	{
 		char *pp = g_Certificate.tbsCertificate.validity.notAfter;
		rt_printf("20%c%c-%c%c-%c%c %c%c:%c%c:%c%c\n", pp[0], pp[1], pp[2], pp[3],pp[4], pp[5], pp[6], pp[7], pp[8], pp[9],pp[10], pp[11]);  
 	}	
	#endif

	#ifdef X509_DEBUG 
	rt_printf("subject: \r\n");
	#endif
	//subject  证书主体名称	
	// Name ::= CHOICE {
  //   RDNSequence }
 	p = x509_get_one_blk_data(p, &len_tmp);
 	ptr_end = &p[len_tmp]; //下一个数据块的内容指针
 	
 	for(i=0; (i<6) && (ptr_end > p); i++)
 	{
	 	//RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
	 	//RelativeDistinguishedName ::=
	  //   SET OF AttributeTypeAndValue
	 	p = x509_get_one_blk_data(p, &len_tmp);	
	 	
	 //AttributeTypeAndValue ::= SEQUENCE {
	  //   type     AttributeType,
	  //   value    AttributeValue }
	 	p = x509_get_one_blk_data(p, &len_tmp);
	

	 	//   type     AttributeType,
	 	p = x509_get_one_blk_data(p, &len_tmp);	
	 	memcpy(g_Certificate.tbsCertificate.subject[i].type, p, len_tmp); 
	 	g_Certificate.tbsCertificate.subject[i].type_len = len_tmp;
	  p = &p[len_tmp];
	  
	  //value    AttributeValue
	 	p = x509_get_one_blk_data(p, &len_tmp);
	 	memcpy(g_Certificate.tbsCertificate.subject[i].value, p, len_tmp); 
	 	g_Certificate.tbsCertificate.subject[i].value_len = len_tmp; 	
		p = &p[len_tmp];
		
		#if 0
		for(j=0;j<g_Certificate.tbsCertificate.subject[i].type_len;j++)
		{
			rt_printf("%02x ", g_Certificate.tbsCertificate.subject[i].type[j]);	
		}
		rt_printf("\n");
		
		for(j=0;j<g_Certificate.tbsCertificate.subject[i].value_len;j++)
		{
			rt_printf("%02x ", g_Certificate.tbsCertificate.subject[i].value[j]);	
		}
		rt_printf("\n\n");
		#else
		#ifdef X509_DEBUG 
		rt_printf("%s:", get_oid_from_str(g_Certificate.tbsCertificate.subject[i].type));
		rt_printf("%s\n", g_Certificate.tbsCertificate.subject[i].value);	
		#endif
		#endif
		g_Certificate.tbsCertificate.subject_len++;
 	}
 	p=ptr_end; 		
 	
 	
 	// subjectPublicKeyInfo SubjectPublicKeyInfo,--证书公钥
 	p = x509_get_one_blk_data(p, &len_tmp);	
 	ptr_end = &p[len_tmp]; //下一个数据块的内容指针
	
	//	algorithm            AlgorithmIdentifier, -- 公钥算法
	p = x509_get_one_blk_data(p, &len_tmp);	
	ptr_begin = p;
	p = x509_get_one_blk_data(ptr_begin, &len_tmp);		
	
	memcpy(g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm, p, len_tmp);
	g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm_len = len_tmp;
	
	
	p=&p[len_tmp];

	#if 0
	rt_printf("algorithm: \r\n");
	for(i=0;i<g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm[i]);
	}
	rt_printf("\n\n");	
	#endif
	
	//parameters
	p = x509_get_one_blk_data(p, &len_tmp);			
	memcpy(g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters, p, len_tmp);	
	g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters_len = len_tmp;
	p=&p[len_tmp];
	
	#if 0
	rt_printf("parameters: \r\n");
	for(i=0;i<g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters[i]);
	}
	rt_printf("\n\n");	
	#endif
	
	//subjectPublicKey     BIT STRING            -- 公钥值
	
	p = x509_get_one_blk_data(p, &len_tmp);	
	
	memcpy(g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey, p, len_tmp);	
	g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len = len_tmp;
	p=ptr_end;	
	#ifdef X509_DEBUG 
	rt_printf("subjectPublicKey: \r\n");
	for(i=0;i<g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey[i]);
	}
	rt_printf("\n\n");
	#endif
	
	//    extensions      [3] EXPLICIT Extensions OPTIONAL
 	//                            -- 证书扩展段（可选），只在证书版本3中才有	
	
	//扩展域只解释签名算法和签名值(最后两个域)
	
	//已经到数据末端,返回
	if((p - data) <= 0)
	{
		
		return 0;	
	}

	//非扩展域,返回
	if(p[0]!=0xA3)
	{
		rt_printf("%s:no extensions(%d)\n",__func__, (int)p[0]);	
		return 0;		
	}
	//Extension ::= SEQUENCE 
	p = x509_get_one_blk_data(p, &len_tmp);	
	
	p = &p[len_tmp];
	
	p = x509_get_one_blk_data(p, &len_tmp);
	ptr_begin = &p[len_tmp];
	
	p = x509_get_one_blk_data(p, &len_tmp);
	
	memcpy(g_Certificate.tbsCertificate.extensions.signature_a, p, len_tmp);
	g_Certificate.tbsCertificate.extensions.signature_a_len = len_tmp;
	
	ptr_end=data+data_len;
	memcpy(g_Certificate.tbsCertificate.extensions.signature_v, ptr_begin, (int)(ptr_end-ptr_begin));
	g_Certificate.tbsCertificate.extensions.signature_v_len = (int)(ptr_end-ptr_begin);

	#ifdef X509_DEBUG 	
	rt_printf("Extension signature:\n");
	for(i=0;i<g_Certificate.tbsCertificate.extensions.signature_a_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.extensions.signature_a[i]);		
	}
	rt_printf("\n\n");
	
	rt_printf("Extension signature Value:\n");
	for(i=0;i<g_Certificate.tbsCertificate.extensions.signature_v_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.extensions.signature_v[i]);		
	}
	rt_printf("\n\n");	
	#endif
	 
	return 0;	
}

/******************************************************************************
函数名称：	x509_cer_to_sm2keybin
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	从cer文件(二进制格式)解码生成sm2keybin 文件.						
参数说明：	
						srcfile:cer文件源文件(base64格式)
						f_cer:cer文件(二进制格式)
						f_sm2keybin:sm2keybin文件
返回值：  	成功返回0，失败返回-1
修改记录：	
*/
static int x509_cer_to_sm2keybin(char *srcfile, char  *f_cer,  char * f_sm2keybin)
{
	struct stat s;	
	char *file_data;
	int fd ;
	int ret;
	
	memset(&g_Certificate, 0, sizeof(g_Certificate));
	
	//获取文件属性
	if(sys_newstat(f_cer,&s))
	{
		rt_printf("%s:sys_newstat error\n",__func__);
		return -1;
	}		
	
	//分配内存
	file_data = rt_malloc(s.st_size);
	
	if(!file_data)
	{
		rt_printf("%s:rt_malloc error\n",__func__);
		return -1;	
	}		
	
	//打开文件
	fd = sys_open(f_cer, O_RDONLY, 0);	
	
	if(fd < 0)
	{
		rt_printf("%s:sys_open %s error\n",__func__ , f_cer);
		rt_free(file_data);
		return -1;
	}	
	
	//读取整个文件内容
	ret = sys_read(fd, file_data, s.st_size);
	
	if(ret!=s.st_size)
	{
		rt_printf("%s:sys_read error\n",__func__);
		sys_close(fd);
		rt_free(file_data);
		return -1;	
	}	
	
	sys_close(fd);
	
	
	ret=x509_decode(file_data, (int)s.st_size);
	if(ret==0)
	{
		rt_printf("%s:%s x509_decode OK\n",__func__, srcfile);	
	}
	else
	{
		rt_printf("%s:%s x509_decode error!\n",__func__, srcfile);	
		rt_free(file_data);	
		return -1;
	}
		
	
	rt_free(file_data);	

	//大于68字节不生成文件
	if(g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len > SM2_PUBKEY_LENTH)
	{
	
		rt_printf("%s:PublicKey too big (%d)t\n",__func__, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len);		
		return -1;
	}

	fd = sys_open(f_sm2keybin, O_CREAT|O_RDWR | O_TRUNC|O_SYNC, 0777);	
	if(fd < 0)
	{
		rt_printf("%s:creat file %s error\n",__func__, f_sm2keybin);
		return  -1;
	}			

	if(g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len < SM2_PUBKEY_LENTH)
	{
		int  fillzero = SM2_PUBKEY_LENTH - g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len; 
		 
		//分配内存
		file_data = rt_malloc(fillzero);	
		if(!file_data)
		{
			rt_printf("%s:rt_malloc error fillzero\n",__func__);
			sys_close(fd);
			return -1;	
		}	

		memset(file_data, 0, fillzero);

		//填充0
		ret = sys_write(fd, file_data, fillzero);
		rt_free(file_data);//sunxi 20180719 added
		if(ret != fillzero)
		{
			rt_printf("%s:sys_write error fillzero\n",__func__);
			sys_close(fd);
			return -1;	
		}

		ret = sys_write(fd, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len);

		if(ret !=  g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len)
		{
			rt_printf("%s:sys_write error subjectPublicKey\n",__func__);
			sys_close(fd);
			return -1;	
		}		
	}
	else
	{
		ret = sys_write(fd, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len);

		if(ret !=  g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len)
		{
			rt_printf("%s:sys_write error subjectPublicKey\n",__func__);
			sys_close(fd);
			return -1;	
		}			
	}

	sys_close(fd);	


	return 0;
	
}

/******************************************************************************
函数名称：	write_data_to_file
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	写数据到文件中.						
参数说明：	
						filename:文件名
						data:要写的数据
						len: 数据长度
返回值：  	成功返回0，失败返回-1
修改记录：	
*/
static int write_data_to_file(char *filename, char *data, int len)
{
	int fd;
	int ret  = 0;

	fd = sys_open(filename, O_CREAT|O_RDWR | O_TRUNC|O_SYNC, 0777);	
	if(fd < 0)
	{
		rt_printf("%s:creat file %s error\n",__func__,  filename);
		return  -1;
	}	

	ret = sys_write(fd, data, len);

	if(ret != len)
	{
		rt_printf("%s:creat file %s error\n",__func__,  filename);
		return  -1;
	}

	sys_close(fd);

	return 0;	

}
 
/******************************************************************************
函数名称：	x509_parse
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	解码x509证书并打印内容.						
参数说明：	
						srcfile:cer文件源文件(base64格式)
						filename:cer文件(二进制格式)
返回值：  	成功返回0，失败返回-1
修改记录：	
*/ 
static int x509_parse(char *srcfile,  char *filename)
{
	struct stat s;	
	char *file_data;
	int fd ;
	int ret;
	int i = 0;
	char *pp; 
	
	memset(&g_Certificate, 0, sizeof(g_Certificate));
	
	//获取文件属性
	if(sys_newstat(filename,&s))
	{
		rt_printf("%s:sys_newstat error\n",__func__);
		return -1;
	}		
	
	//分配内存
	file_data = rt_malloc(s.st_size);
	
	if(!file_data)
	{
		rt_printf("%s:rt_malloc error\n",__func__);
		return -1;	
	}		
	
	//打开文件
	fd = sys_open(filename, O_RDONLY, 0);	
	
	if(fd < 0)
	{
		rt_printf("%s:sys_open %s error\n",__func__ , filename);
		rt_free(file_data);
		return -1;
	}	
	
	//读取整个文件内容
	ret = sys_read(fd, file_data, s.st_size);
	
	if(ret!=s.st_size)
	{
		rt_printf("%s:sys_read error\n",__func__);
		sys_close(fd);
		rt_free(file_data);
		return -1;	
	}	
	
	sys_close(fd);
	
	
	ret=x509_decode(file_data, (int)s.st_size);
	if(ret==0)
	{
		//rt_printf("%s:x509_decode OK\n",__func__);	
	}
	else
	{
		rt_printf("%s:x509_decode %s error!\n",__func__, filename);	
		rt_free(file_data);	
		return -1;
	}
		
	
	rt_free(file_data);	

	rt_printf("文件名:%s\n", srcfile);
	rt_printf("版本:\n");		
	rt_printf("%d\n", g_Certificate.tbsCertificate.version);	
	rt_printf("证书序列号:\n");		
	
	for(i=0;i<g_Certificate.tbsCertificate.serialNumber_len;i++)
	{
		rt_printf("%02x ", g_Certificate.tbsCertificate.serialNumber[i]);	
	}
	rt_printf("\n");
	
	rt_printf("颁发者信息:\n");	
	
	for(i=0;i<g_Certificate.tbsCertificate.issuer_len;i++)
	{
		rt_printf("%s:", get_oid_from_str(g_Certificate.tbsCertificate.issuer[i].type));
		rt_printf("%s\n", g_Certificate.tbsCertificate.issuer[i].value);			
	}	

	rt_printf("有效期:\n");	
	rt_printf("起始时间:");
	pp = g_Certificate.tbsCertificate.validity.notBefore;	
	rt_printf("20%c%c-%c%c-%c%c %c%c:%c%c:%c%c\n", pp[0], pp[1], pp[2], pp[3],pp[4], pp[5], pp[6], pp[7], pp[8], pp[9],pp[10], pp[11]);
	rt_printf("结束时间:");	
	pp = g_Certificate.tbsCertificate.validity.notAfter;
	rt_printf("20%c%c-%c%c-%c%c %c%c:%c%c:%c%c\n", pp[0], pp[1], pp[2], pp[3],pp[4], pp[5], pp[6], pp[7], pp[8], pp[9],pp[10], pp[11]);

	rt_printf("主题:\n");	

	for(i=0;i<g_Certificate.tbsCertificate.subject_len;i++)
	{
		rt_printf("%s:", get_oid_from_str(g_Certificate.tbsCertificate.subject[i].type));
		rt_printf("%s\n", g_Certificate.tbsCertificate.subject[i].value);			
	}

	rt_printf("公钥:\n");	
	//for(i=0;i<g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len;i++)
	//{
	//	rt_printf("%02x ", g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey[i]);
	//}
	print_msg("",  g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey, g_Certificate.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey_len);
	//rt_printf("\n");
	
	rt_printf("签名算法:\n");	
	//for(i=0;i<g_Certificate.tbsCertificate.signature_len;i++)
	//{
	//	rt_printf("%02x ",g_Certificate.tbsCertificate.signature[i]);		
	//}
	print_msg("", g_Certificate.tbsCertificate.signature, g_Certificate.tbsCertificate.signature_len);
	//rt_printf("\n");
	
	rt_printf("签名值:\n");		
	//for(i=0;i<g_Certificate.tbsCertificate.extensions.signature_v_len;i++)
	//{
	//	rt_printf("%02x ", g_Certificate.tbsCertificate.extensions.signature_v[i]);		
	//}
	print_msg("", g_Certificate.tbsCertificate.extensions.signature_v, g_Certificate.tbsCertificate.extensions.signature_v_len);
	rt_printf("\n\n");		
	
	return 0;
}

/******************************************************************************
函数名称：	x509_print
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	打印证书内容.						
参数说明：	
						base64file:cer文件源文件(base64格式)
						binfile:cer文件(二进制格式)
返回值：  	成功返回0，失败返回-1
修改记录：	
*/ 
static int x509_print(char * base64file, char * binfile)
{

	int ret;
	ret = base64file_to_binfile(base64file,  binfile);
	if(ret!=0)
	{
		rt_printf("%s: convert	 %s to  bin error\n",__func__ , base64file);	
		return -1;
	}	
	
	x509_parse(base64file, binfile);

	return 0;	
}

 int  x509_show_all(void)
 {

	x509_print(FILENAME_X509_CER_0, FILENAME_X509_CER_TMP_0);	
	x509_print(FILENAME_X509_CER_1, FILENAME_X509_CER_TMP_1);	
	x509_print(FILENAME_X509_CER_2, FILENAME_X509_CER_TMP_2);	
	x509_print(FILENAME_X509_CER_3, FILENAME_X509_CER_TMP_3);	

	return 0;

 }

static int x509_writetime_to_file(char *filename, char * time_begin, int time_begin_len, char * time_end, int time_end_len)
{
	struct rtc_time_t  rt;
	struct timespec ts;
	char c_tm[32];
	int i = 0;
	int fd;
	int ret = 0;
	

	fd = sys_open(filename, O_CREAT|O_RDWR | O_TRUNC|O_SYNC, 0777);	
	

	if(fd < 0)
	{
		rt_printf("%s:creat file %s error\n",__func__, filename);
		return  -1;
	}

	
	for(i=0;i<time_begin_len;i++)
	{
		c_tm[i] = time_begin[i] - '0';
		
	}


	rt.year = (unsigned short)c_tm[0]*10+ (unsigned short)c_tm[1] ;
	rt.month = (unsigned char)c_tm[2]*10+ (unsigned char)c_tm[3];
	rt.day = (unsigned char)c_tm[4]*10+ (unsigned char)c_tm[5]; 
	rt.hour= (unsigned char)c_tm[6]*10+ (unsigned char)c_tm[7]; 
	rt.min=  (unsigned char)c_tm[8]*10+ (unsigned char)c_tm[9]; 
	rt.ms= (unsigned short)c_tm[10]*10+ (unsigned short)c_tm[11] ;
	rt.ms = rt.ms *1000;

	rtc_to_timespec(&rt, &ts);

	ret=sys_write(fd, (char *)&ts.tv_sec, sizeof(ts.tv_sec));
	if(ret != sizeof(ts.tv_sec))
	{
		rt_printf("%s:sys_write error\n",__func__);
		sys_close(fd);
		return  -1;		
	}
	


	for(i=0;i<time_end_len;i++)
	{
		c_tm[i] = time_end[i] - '0';
		
	}


	rt.year = (unsigned short)c_tm[0]*10+ (unsigned short)c_tm[1] ;
	rt.month = (unsigned char)c_tm[2]*10+ (unsigned char)c_tm[3];
	rt.day = (unsigned char)c_tm[4]*10+ (unsigned char)c_tm[5]; 
	rt.hour= (unsigned char)c_tm[6]*10+ (unsigned char)c_tm[7]; 
	rt.min=  (unsigned char)c_tm[8]*10+ (unsigned char)c_tm[9]; 
	rt.ms= (unsigned short)c_tm[10]*10+ (unsigned short)c_tm[11] ;
	rt.ms = rt.ms *1000;

	rtc_to_timespec(&rt, &ts);

	ret=sys_write(fd, (char *)&ts.tv_sec, sizeof(ts.tv_sec));
	if(ret != sizeof(ts.tv_sec))
	{
		rt_printf("%s:sys_write error\n",__func__);
		sys_close(fd);
		return  -1;		
	}

	sys_close(fd);
		
	return 0;
}

/******************************************************************************
函数名称：	x509_init
函数版本：	01.01
创建作者：	 
创建日期：	2015-07-04
函数说明：	X509证书初始化.						
参数说明：	

返回值：  	成功返回0，失败返回-1
修改记录：	
*/ 
int x509_init(void)
{
	int ret = 0;
	struct stat s;	
	extern unsigned  char UserId[16];
	
	//检查文件是否存在
	if(sys_newstat(FILENAME_SM2_KEY_0,&s)==0)
	{
		return 0;		
	}

	if(sys_newstat(FILENAME_SM2_KEY_1,&s) == 0)
	{
		return 0;		
	}
	
	if(sys_newstat(FILENAME_SM2_KEY_2,&s)==0)
	{
		return 0;		
	}	
	
	if(sys_newstat(FILENAME_SM2_KEY_3,&s)==0)
	{
		return 0;		
	}	

	if(sys_newstat(FILENAME_X509_CER_0,&s) != 0)
	{
		return 0;		
	}

	if(sys_newstat(FILENAME_X509_CER_1,&s) != 0)
	{
		return 0;		
	}
	
	if(sys_newstat(FILENAME_X509_CER_2,&s) != 0)
	{
		return 0;		
	}	
	
	if(sys_newstat(FILENAME_X509_CER_3,&s) != 0)
	{
		return 0;		
	}	

	
	ret = base64file_to_binfile(FILENAME_X509_CER_0, FILENAME_X509_CER_TMP_0);
	if(ret!=0)
	{
		rt_printf("%s: convert %s to bin error\n",__func__ , FILENAME_X509_CER_0);	
		goto ERR;
	}
	ret = base64file_to_binfile(FILENAME_X509_CER_1, FILENAME_X509_CER_TMP_1);
	if(ret!=0)
	{
		rt_printf("%s: convert %s to bin error\n",__func__ , FILENAME_X509_CER_1);		
		goto ERR;
	}	
	ret = base64file_to_binfile(FILENAME_X509_CER_2, FILENAME_X509_CER_TMP_2);
	if(ret!=0)
	{
		rt_printf("%s: convert %s to bin error\n",__func__ , FILENAME_X509_CER_2);		
		goto ERR;
	}		
	ret = base64file_to_binfile(FILENAME_X509_CER_3, FILENAME_X509_CER_TMP_3);
	if(ret!=0)
	{
		rt_printf("%s: convert %s to bin error\n",__func__ , FILENAME_X509_CER_3);		
		goto ERR;
	}		

	ret = x509_cer_to_sm2keybin(FILENAME_X509_CER_0, FILENAME_X509_CER_TMP_0, FILENAME_SM2_KEY_0);
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_SM2_KEY_0);		
		goto ERR;
	}

	ret=x509_writetime_to_file(FILENAME_X509_TIME0,  g_Certificate.tbsCertificate.validity.notBefore,  g_Certificate.tbsCertificate.validity.notBefore_len,  g_Certificate.tbsCertificate.validity.notAfter,  g_Certificate.tbsCertificate.validity.notAfter_len);	
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_X509_TIME0);		
		goto ERR;
	}

	ret = x509_cer_to_sm2keybin(FILENAME_X509_CER_1, FILENAME_X509_CER_TMP_1, FILENAME_SM2_KEY_1);
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_SM2_KEY_1);		
		goto ERR;
	}

	ret=x509_writetime_to_file(FILENAME_X509_TIME1,  g_Certificate.tbsCertificate.validity.notBefore,  g_Certificate.tbsCertificate.validity.notBefore_len,  g_Certificate.tbsCertificate.validity.notAfter,  g_Certificate.tbsCertificate.validity.notAfter_len);	
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_X509_TIME1);		
		goto ERR;
	}

	
	ret = x509_cer_to_sm2keybin(FILENAME_X509_CER_2, FILENAME_X509_CER_TMP_2, FILENAME_SM2_KEY_2);
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_SM2_KEY_2);		
		goto ERR;
	}

	ret=x509_writetime_to_file(FILENAME_X509_TIME2,  g_Certificate.tbsCertificate.validity.notBefore,  g_Certificate.tbsCertificate.validity.notBefore_len,  g_Certificate.tbsCertificate.validity.notAfter,  g_Certificate.tbsCertificate.validity.notAfter_len);	
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_X509_TIME2);		
		goto ERR;
	}

	
	ret = x509_cer_to_sm2keybin(FILENAME_X509_CER_3, FILENAME_X509_CER_TMP_3, FILENAME_SM2_KEY_3);
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_SM2_KEY_3);		
		goto ERR;
	}

	ret=x509_writetime_to_file(FILENAME_X509_TIME3,  g_Certificate.tbsCertificate.validity.notBefore,  g_Certificate.tbsCertificate.validity.notBefore_len,  g_Certificate.tbsCertificate.validity.notAfter,  g_Certificate.tbsCertificate.validity.notAfter_len);	
	if(ret!=0)
	{
		rt_printf("%s: generate %s error\n",__func__ , FILENAME_X509_TIME3);		
		goto ERR;
	}

	ret = write_data_to_file(FILENAME_USERID, UserId, sizeof(UserId));
	if(ret!=0)
	{
		rt_printf("%s: write_data_to_file %s  error\n",__func__ , FILENAME_USERID);		
		goto ERR;
	}
	
	
ERR:

	if(ret!=0)
	{
		rt_file_del(FILENAME_SM2_KEY_0);
		rt_file_del(FILENAME_SM2_KEY_1);
		rt_file_del(FILENAME_SM2_KEY_2);
		rt_file_del(FILENAME_SM2_KEY_3);
	}

	return ret;
}

#endif
