c++安全传输平台——老师结构体编码与解码(ASN.1编码解码)

48 篇文章 3 订阅
本文详细介绍了如何使用C语言进行老师结构体的编码和解码,涉及`Teacher`结构体的内存管理、DER编码与解码过程,以及mywritefile函数和主函数的实现。通过实例展示了如何安全传输和持久化数据。
摘要由CSDN通过智能技术生成

安全传输平台之老师结构体编码与解码

老师结构体编码与解码

demo1


#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "itcast_asn1_der.h"
#include "itcastderlog.h"

//老师结构体
typedef struct _Teacher
{
	char name[64];
	int age;
	char *p;
	int plen;
}Teacher;

//释放内存
void freeTeacher(Teacher **pTeacher)
{
	if (pTeacher == NULL) {
		return;
	}
	if (pTeacher != NULL) {
		if ((*pTeacher)->p != NULL) {
			free((*pTeacher)->p);
			(*pTeacher)->p = NULL;
		}
		free(*pTeacher);
		*pTeacher = NULL;
	}
}


//解码
//int TeacherDecode(unsigned char *indata, int inLen, Teacher **pStruct)

//持久化
//int mywritefile(unsigned char *buf, int len)

//主函数
//int main(void)

主函数

int main(void)
{
	int					ret = 0;

	Teacher				t1;
	Teacher  *pt2 = NULL;

	unsigned char		*myOut = NULL;
	int					myOutlen = 0;

	t1.age = 10;
	strcpy(t1.name, "myName");
	t1.p = malloc(64);
	strcpy(t1.p, "aaaabbbb");
	t1.plen = strlen(t1.p);

	TeacherEncode(&t1, &myOut, &myOutlen);
	mywritefile(myOut, myOutlen);

	TeacherDecode(myOut, myOutlen, &pt2);

	if (strcmp(t1.name, pt2->name) == 0 &&
		memcmp(t1.p, pt2->p, pt2->plen) == 0) 
	{
		printf("编码 == 解码 \n");
	}
	else
	{
		printf("编码 != 解码 \n");
	}

	freeTeacher(&pt2);

	printf("hello...\n");
	system("pause");

	return 0;
}

mywritefile函数

int mywritefile(unsigned char *buf, int len)
{
	FILE *fp = NULL;
	fp = fopen("c:/itcast/teacher.ber", "wb+");
	if (fp == NULL)
	{
		printf("fopen file error \n");
		return -1;
	}
	fwrite(buf, 1, len, fp);
	fclose(fp);
	return 0;
}

解码

int TeacherDecode(unsigned char *indata, int inLen, Teacher **pStruct)
{
	int					ret = 0;
	ITCAST_ANYBUF		*pTmp = NULL, *pHead = NULL;
	ITCAST_ANYBUF		*pOutData = NULL;
	ITCAST_ANYBUF		*tmpAnyBuf = NULL;

	Teacher *pStrTeacher = NULL;

	// 转码 BER 报文 unsigned char * --> ITCAST_ANYBUF
	ret = DER_ITCAST_String_To_AnyBuf(&tmpAnyBuf, indata, inLen);
	if (ret != 0) {
		if (tmpAnyBuf != NULL) 
			DER_ITCAST_FreeQueue(tmpAnyBuf);

		printf(" Decode DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	// 解码大Teacher 结构体
	ret = DER_ItAsn1_ReadSequence(tmpAnyBuf, &pHead);
	if (ret != 0) {
		if (tmpAnyBuf != NULL)
			DER_ITCAST_FreeQueue(tmpAnyBuf);
		printf(" Decode DER_ItAsn1_ReadSequence error: %d\n", ret);
		return ret;
	}

	// 给Teacher 结构体 malloc 空间。
	if (pStrTeacher == NULL) {
		pStrTeacher = (Teacher *)malloc(sizeof(Teacher));
		if (pStrTeacher == NULL) {
			DER_ITCAST_FreeQueue(pHead);
			ret = -1;
			printf("Teacher malloc error: %d\n", ret);
			return ret;
		}
		memset(pStrTeacher, 0, sizeof(Teacher));
	}

	pTmp = pHead;

	// 解码 name
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pHead);
		freeTeacher(&pStrTeacher);

		printf(" Decode DER_ItAsn1_ReadPrintableString name error: %d\n", ret);
		return ret;
	}

	// ppPrintString -> pData; ---> name
	memcpy(pStrTeacher->name, pOutData->pData, pOutData->dataLen);
	
	pTmp = pTmp->next;
	// 解码age
	ret = DER_ItAsn1_ReadInteger(pTmp, &pStrTeacher->age);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pHead);
		freeTeacher(&pStrTeacher);
		printf(" Decode DER_ItAsn1_ReadInteger age error: %d\n", ret);
		return ret;
	}

	pTmp = pTmp->next;
	// 解码 p
	ret = DER_ItAsn1_ReadPrintableString(pTmp, &pOutData);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pHead);
		freeTeacher(&pStrTeacher);
		printf(" Decode DER_ItAsn1_ReadPrintableString p error: %d\n", ret);
		return ret;
	}
	// 给Teacher 结构体中的 p 指针开辟空间
	pStrTeacher->p = malloc(pOutData->dataLen + 1);
	if (pStrTeacher->p == NULL) {
		DER_ITCAST_FreeQueue(pHead);
		freeTeacher(&pStrTeacher);
		ret = -2;
		printf("Teacher->p malloc error: %d\n", ret);
		return ret;
	}
	memcpy(pStrTeacher->p, pOutData->pData, pOutData->dataLen);
	//pStrTeacher->p[pOutData->dataLen - 4] = 'R';
	pStrTeacher->p[pOutData->dataLen] = '\0';

	pTmp = pTmp->next;
	// 解码plen
	ret = DER_ItAsn1_ReadInteger(pTmp, &pStrTeacher->plen);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pHead);
		freeTeacher(&pStrTeacher);
		printf(" Decode DER_ItAsn1_ReadInteger plen error: %d\n", ret);
		return ret;
	}

	*pStruct = pStrTeacher;

	return 0;
}

编码

// 传入、传出、传入传出。
int TeacherEncode(Teacher *pThecher, unsigned char **out, int *outlen)
{
	int					ret = 0;
	ITCAST_ANYBUF		*pTmp = NULL, *pHeadBuf = NULL;
	ITCAST_ANYBUF		*pTmpBuf = NULL;
	ITCAST_ANYBUF		*pOutData = NULL;

	unsigned char		*tmpout = NULL;
	int					tmpoutlen = 0;

	//将 char * 类型的name 转换成 ITCAST_ANYBUF 类型
	ret = DER_ITCAST_String_To_AnyBuf(&pTmpBuf, pThecher->name, strlen(pThecher->name));
	if (ret != 0) {
		printf("DER_ITCAST_String_To_AnyBuf error: %d\n", ret);
		return ret;
	}

	// 编码 name  --> TLV
	ret = DER_ItAsn1_WritePrintableString(pTmpBuf, &pHeadBuf);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pTmpBuf);
		printf("DER_ItAsn1_WritePrintableString error: %d\n", ret);
		return ret;
	}
	DER_ITCAST_FreeQueue(pTmpBuf);

	pTmp = pHeadBuf;

	// 编码 age
	ret = DER_ItAsn1_WriteInteger(pThecher->age, &(pTmp->next));
	if (ret != 0) {
		printf("DER_ItAsn1_WriteInteger error: %d\n", ret);
		return ret;
	}
	pTmp = pTmp->next;

	//编码 p  char *
	ret = EncodeChar(pThecher->p, pThecher->plen, &pTmp->next);
	if (ret != 0) {
		printf("EncodeChar error: %d\n", ret);
		return ret;
	}
	pTmp = pTmp->next;

	//编码 plen
	ret = DER_ItAsn1_WriteInteger(pThecher->plen, &(pTmp->next));
	if (ret != 0) {
		printf("DER_ItAsn1_WriteInteger plen error: %d\n", ret);
		return ret;
	}

	//编码大结构体
	ret = DER_ItAsn1_WriteSequence(pHeadBuf, &pOutData);
	if (ret != 0) {
		DER_ITCAST_FreeQueue(pHeadBuf);
		printf("DER_ItAsn1_WriteSequence error: %d\n", ret);
		return ret;
	}



	*out = pOutData->pData;

	*outlen = pOutData->dataLen;

	return 0;
}

说明1

	// 编码 age
	ret = DER_ItAsn1_WriteInteger(pThecher->age, &(pTmp->next));

	//编码 p  char *
	ret = EncodeChar(pThecher->p, pThecher->plen, &pTmp->next);

这两段代码中,&(pTmp->next)&pTmp->next是一样的,因为后操作符优先。
说明2

    Teacher *pStrTeacher = NULL;
    
	// 给Teacher 结构体 malloc 空间。
	if (pStrTeacher == NULL) {
		pStrTeacher = (Teacher *)malloc(sizeof(Teacher));
		if (pStrTeacher == NULL) {
			DER_ITCAST_FreeQueue(pHead);
			ret = -1;
			printf("Teacher malloc error: %d\n", ret);
			return ret;
		}
		memset(pStrTeacher, 0, sizeof(Teacher));
	}

常用用malloc来开辟空间,memset来初始化空间。
C 库函数 - memset()

C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

C 库函数 - malloc()

C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。

itcast_asn1_der.h

部分关键代码

//别名
typedef int					ITCAST_INT ;
typedef unsigned char       ITCAST_UINT8;
typedef unsigned short      ITCAST_UINT16;
typedef unsigned long		ITCAST_UINT32;
typedef signed long         ITCAST_SINT32;

//结构体
typedef struct ITCAST_ANYBUF_{
	
    unsigned char 	  *pData;
    ITCAST_UINT32     dataLen;
    
    ITCAST_UINT32     unusedBits;  /* for bit string */  
    ITCAST_UINT32     memoryType;
    ITCAST_UINT32     dataType;
    struct ITCAST_ANYBUF_ *next;    /* for sequence and set */
    struct ITCAST_ANYBUF_ *prev;
    
}ITCAST_ANYBUF;
 
 //别名
typedef ITCAST_UINT8     ITASN1_BOOLEAN;
typedef ITCAST_ANYBUF    ITASN1_INTEGER;
typedef ITCAST_ANYBUF    ITASN1_OCTETSTRING;
typedef ITCAST_ANYBUF    ITASN1_BITSTRING;
typedef ITCAST_ANYBUF    ITASN1_PRINTABLESTRING;
/*begin of bmpstring*/
typedef ITCAST_ANYBUF	 ITASN1_BMPSTRING;
/*end of bmpstring*/
typedef ITCAST_ANYBUF    ITASN1_ENUMERATED;
typedef ITCAST_ANYBUF    ITASN1_IA5STRING;
typedef ITCAST_ANYBUF    ITASN1_SEQUENCE;
typedef ITCAST_ANYBUF    ITASN1_SET; 


//函数
ITCAST_INT
DER_ItAsn1_WriteInteger(ITCAST_UINT32 integer, ITASN1_INTEGER **ppDerInteger);

ITCAST_INT
DER_ItAsn1_ReadInteger(ITASN1_INTEGER *pDerInteger, ITCAST_UINT32 *pInteger);

ITCAST_INT
DER_ItAsn1_WriteBitString(ITASN1_BITSTRING *pBitString,ITASN1_BITSTRING **ppDerBitString);

ITCAST_INT
DER_ItAsn1_ReadBitString(ITASN1_BITSTRING *pDerBitString,ITASN1_BITSTRING **ppBitString);


ITCAST_INT
DER_ItAsn1_WritePrintableString(ITASN1_PRINTABLESTRING *pPrintString, 
ITASN1_PRINTABLESTRING **ppDerPrintString);

ITCAST_INT
DER_ItAsn1_ReadPrintableString(ITASN1_PRINTABLESTRING *pDerPrintString, 
ITASN1_PRINTABLESTRING **ppPrintString);

ITCAST_INT
DER_ItAsn1_WriteSequence(ITASN1_SEQUENCE *pSequence, ITCAST_ANYBUF **ppDerSequence);

ITCAST_INT
DER_ItAsn1_ReadSequence(ITCAST_ANYBUF *pDerSequence, ITASN1_SEQUENCE **ppSequence);

ITCAST_INT
DER_ItAsn1_WriteNull(ITCAST_ANYBUF ** ppDerNull);

ITCAST_INT
DER_ItAsn1_ReadNull(ITCAST_ANYBUF * ppDerNull, ITCAST_UINT8 * pInt);

ITCAST_INT 
DER_ITCAST_FreeQueue(ITCAST_ANYBUF *pAnyBuf);

ITCAST_INT
DER_ITCAST_String_To_AnyBuf(ITCAST_ANYBUF **pOriginBuf,	unsigned char *strOrigin, int strOriginLen);

int WriteNullSequence(ITCAST_ANYBUF **pOutData);

int EncodeChar(char *pData, int dataLen, ITCAST_ANYBUF **outBuf);

int EncodeUnsignedChar(unsigned char *pData, int dataLen, ITCAST_ANYBUF **outBuf);

int DecodeChar(ITCAST_ANYBUF *inBuf, char **Data, int *pDataLen);

itcast_asn1_der.c

DER_ITCAST_String_To_AnyBuf

ITCAST_INT
DER_ITCAST_String_To_AnyBuf(ITCAST_ANYBUF **pOriginBuf,
	unsigned char * strOrigin,
	int  strOriginLen)
{
	ITCAST_ANYBUF *pValueBuf;

	pValueBuf = malloc(sizeof(ITCAST_ANYBUF));
	if (pValueBuf == NULL)
	{
		ITDER_LOG(__FILE__, __LINE__,LogLevel[4], ITDER_MemoryErr,"malloc err");
		return ITDER_MemoryErr;
	}
	memset(pValueBuf,0,sizeof(ITCAST_ANYBUF));

	if(strOriginLen <= 0)
	{
		pValueBuf ->pData = NULL;
		strOriginLen = 0;
	}
	else
	{
		pValueBuf->pData =(unsigned char *)malloc(strOriginLen);
		if (pValueBuf->pData == NULL)
		{
			DER_ITCAST_Free(pValueBuf);
			ITDER_LOG(__FILE__, __LINE__,LogLevel[4], ITDER_LengthErr,"malloc err");
			return ITDER_MemoryErr;
		}	
		memcpy(pValueBuf->pData,strOrigin,strOriginLen); 
	}
	pValueBuf->dataLen =  strOriginLen;
	pValueBuf->dataType = ITCAST_DER_ID_STRING_PRINTABLE;
	pValueBuf->next = NULL;
 	pValueBuf->prev = NULL;
	pValueBuf->unusedBits = (strOriginLen % 8);
	pValueBuf->memoryType = 0;
	*pOriginBuf = pValueBuf; 
	return ITDER_NoErr;
}


DER_ItAsn1_WritePrintableString


//DER编码PrintableString类型数据
ITCAST_INT
DER_ItAsn1_WritePrintableString(
    ITASN1_PRINTABLESTRING *pPrintString,
    ITASN1_PRINTABLESTRING **ppDerPrintString)
{
	int iResult;
	
	if (pPrintString->dataType == ITCAST_DER_STRING_BMP)
	{
		iResult = DER_ItAsn1_WriteBmpString(pPrintString,ppDerPrintString);
        if (iResult != ITDER_NoErr)
		{
			ITDER_LOG(__FILE__, __LINE__,LogLevel[4], iResult,"func DER_ItAsn1_WriteBmpString() err");
			return  iResult;	
		}
	
	}
	else
    {
		iResult = DER_ItAsn1_WriteCharString(pPrintString,ppDerPrintString);
        if (iResult != ITDER_NoErr)
		{
			ITDER_LOG(__FILE__, __LINE__,LogLevel[4], iResult,"func DER_ItAsn1_WriteCharString() err");
			return  iResult;	
		}
	}
	
	return 0;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值