安全传输平台之老师结构体编码与解码
老师结构体编码与解码
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;
}