安全传输平台项目——密钥协商服务器-密钥协商客户端

在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

10-安全传输平台项目-第05天(密钥协商服务器-密钥协商客户端)

目录:
一、复习
二、安全传输平台项目——密钥协商服务器-密钥协商客户端
1、密钥协商-物理组件集成
2、密钥协商-日志的使用
3、密钥协商客户端-模块划分
4、密钥协商客户端-框架实现
5、密钥协商客户端-Agree函数框架
6、密钥协商客户端-Agree函数实现
7、密钥协商客户端-Agree函数内存释放
8、密钥协商服务器-框架梳理
9、密钥协商服务器-业务逻辑实现
10、密钥协商服务器-Agree功能实现
11、总结

一、复习

1、线程传参
2、共享内存

二、安全传输平台项目——密钥协商服务器-密钥协商客户端

》密钥协商业务逻辑图

1、密钥协商-物理组件集成

》创建相应的文件夹及文件准备

>mkdir secmng
>cd secmng
>mkdir inc
>mkdir lib
>mkdir src

通过远程软件,将库文件:libitcastsocket.so和libmessagereal.so拷贝到新创建的lib目录下;

把(keymnglog.cmyipc_shm.c)2个文件放入到src目录下,把(keymng_msg.h—统一报文编码解码,对应lib库libmessagereal.so、keymnglog.h—日志,对应inc的keymnglog.c、myipc_shm.h—统一共享内存,对应inc的myipc_shm.c、poolsocket.h—统一通信,对应lib库libitcastsocket.so)4个文件放入到inc目录下。

>vi keymnglog.c

#define  _CRT_SECURE_NO_WARNINGS 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "keymnglog.h"

#define ITCAST_DEBUG_FILE_    "keymngclient.log"
#define ITCAST_MAX_STRING_LEN         10240

//Level类别
#define IC_NO_LOG_LEVEL            0
#define IC_DEBUG_LEVEL            1
#define IC_INFO_LEVEL            2
#define IC_WARNING_LEVEL        3
#define IC_ERROR_LEVEL            4

int  KeyMngLevel[5] = {IC_NO_LOG_LEVEL, IC_DEBUG_LEVEL, IC_INFO_LEVEL, IC_WARNING_LEVEL, IC_ERROR_LEVEL};

//Level的名称
char ICLevelName[5][10] = {"NOLOG", "DEBUG", "INFO", "WARNING", "ERROR"};

static int ITCAST_Error_GetCurTime(char* strTime)
{
    struct tm*        tmTime = NULL;
    size_t            timeLen = 0;
    time_t            tTime = 0;    
    
    tTime = time(NULL);
    tmTime = localtime(&tTime);
    //timeLen = strftime(strTime, 33, "%Y(Y)%m(M)%d(D)%H(H)%M(M)%S(S)", tmTime);
    timeLen = strftime(strTime, 33, "%Y.%m.%d %H:%M:%S", tmTime);
    
    return timeLen;
}

static int ITCAST_Error_OpenFile(int* pf)
{
    char    fileName[1024];
    
    memset(fileName, 0, sizeof(fileName));
#ifdef WIN32
    sprintf(fileName, "c:\itcast\%s",ITCAST_DEBUG_FILE_);
#else
    sprintf(fileName, "%s/log/%s", getenv("HOME"), ITCAST_DEBUG_FILE_);
#endif
    
    *pf = open(fileName, O_WRONLY|O_CREAT|O_APPEND, 0666);
    if(*pf < 0)
    {
        return -1;
    }
    
    return 0;
}

static void ITCAST_Error_Core(const char *file, int line, int level, int status, const char *fmt, va_list args)
{
    char str[ITCAST_MAX_STRING_LEN];
    int     strLen = 0;
    char tmpStr[64];
    int     tmpStrLen = 0;
    int  pf = 0;
    
    //初始化
    memset(str, 0, ITCAST_MAX_STRING_LEN);
    memset(tmpStr, 0, 64);
    
    //加入LOG时间
    tmpStrLen = ITCAST_Error_GetCurTime(tmpStr);
    tmpStrLen = sprintf(str, "[%s] ", tmpStr);
    strLen = tmpStrLen;

    //加入LOG等级
    tmpStrLen = sprintf(str+strLen, "[%s] ", ICLevelName[level]);
    strLen += tmpStrLen;
    
    //加入LOG状态
    if (status != 0) 
    {
        tmpStrLen = sprintf(str+strLen, "[ERRNO is %d] ", status);
    }
    else
    {
        tmpStrLen = sprintf(str+strLen, "[SUCCESS] ");
    }
    strLen += tmpStrLen;

    //加入LOG信息
    tmpStrLen = vsprintf(str+strLen, fmt, args);
    strLen += tmpStrLen;

    //加入LOG发生文件
    tmpStrLen = sprintf(str+strLen, " [%s]", file);
    strLen += tmpStrLen;

    //加入LOG发生行数
    tmpStrLen = sprintf(str+strLen, " [%d]
", line);
    strLen += tmpStrLen;
    
    //打开LOG文件
    if(ITCAST_Error_OpenFile(&pf))
    {
        return ;
    }
    
    //写入LOG文件
    write(pf, str, strLen);
    //IC_Log_Error_WriteFile(str);
    
    //关闭文件
    close(pf);
    
    return ;
}


void KeyMng_Log(const char *file, int line, int level, int status, const char *fmt, ...)
{
    va_list args;
    
    //判断是否需要写LOG
//    if(level!=IC_DEBUG_LEVEL && level!=IC_INFO_LEVEL && level!=IC_WARNING_LEVEL && level!=IC_ERROR_LEVEL)
    if(level == IC_NO_LOG_LEVEL)
    {
        return ;
    }
    
    //调用核心的写LOG函数
    va_start(args, fmt);
    ITCAST_Error_Core(file, line, level, status, fmt, args);
    va_end(args);
    
    return ;
}
keymnglog.c

>vi myipc_shm.c

#define    _OS_LINUX_

#if defined _OS_LINUX_
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <memory.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include "myipc_shm.h" 

#endif

int shmflag = 0;
int shmkey;


//创建共享内存 若共享内存不存在,则创建 若存在使用原来的
int IPC_CreatShm(int key, int shmsize, int *shmhdl)
{
    int        tmpshmhdl = 0;
    int     ret = 0;
     //    创建共享内存 
     //    若共享内存不存在则创建 
     //    若共享内存已存在使用原来的
    tmpshmhdl = shmget(key, shmsize, IPC_CREAT|0666);
    if (tmpshmhdl == -1)            //创建失败
    {
        ret = MYIPC_ParamErr;
        printf("func shmget() err :%d ", ret);
        return ret;
    }
    *shmhdl = tmpshmhdl;
    return ret;
}

//打开共享内存 若共享内存不存在,返回错误
//参数 无意义 可填写0
int IPC_OpenShm(int key, int shmsize, int *shmhdl)
{
    int        tmpshmhdl = 0;
    int     ret = 0;
     //    创建共享内存 
     //    若共享内存不存在则创建 
     //    若共享内存已存在使用原来的
    tmpshmhdl = shmget(key, 0, 0);
    if (tmpshmhdl == -1)            //打开失败
    {
        ret = MYIPC_NotEXISTErr;
        //printf("func shmget() err :%d ", ret);
        return ret;
    }
    *shmhdl = tmpshmhdl;
    return ret;
    
}

/***********************************************************************
  功能描述:    创建共享内存
  参数说明:    shmname  [in]  是共享内存名,系统中唯一标志
                shmsize  [in]  是要创建的共享内存的大小;
                shmhdl   [out] 共享内存的句柄.
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_CreatShmBySeedName(const char *shmseedfile, int shmsize, int *shmhdl)
{
    if(shmflag == 0)            //判断接口中共享内存key是否已经存在
    {
        shmkey = ftok(shmseedfile, 'c');
        if (shmkey == -1)
        {
            perror("ftok");
            return -1;
        }
            
        shmflag = 1;
    }
    
    //创建共享内存
    *shmhdl = shmget(shmkey,shmsize,IPC_CREAT|0666);
    if (*shmhdl == -1)            //创建失败
        return -2;
    return 0;

}
/***********************************************************************
  功能描述:    关联共享内存
  参数说明:    shmhdl    [in]  共享的句柄
                mapaddr [out] 共享内存首地址
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int
IPC_MapShm(int  shmhdl, void **mapaddr)
{
    void *tempptr = NULL;

    //连接共享内存
    tempptr = (void *)shmat(shmhdl,0,SHM_RND);
    if ((int)tempptr == -1)        //共享内存连接失败
        return -1;
    *mapaddr = tempptr;            //导出共享内存首指针

    return 0;
}
/***********************************************************************
  功能描述:    取消共享内存关联
  参数说明:    unmapaddr   [in] 共享内存首地址
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_UnMapShm(void *unmapaddr)
{
    int  rv;
    //取消连接共享内存 
    rv = shmdt((char *)unmapaddr);
    if (rv == -1)            //取消连接失败
        return -1;

    return 0;
}
/***********************************************************************
  功能描述:    删除共享内存
  参数说明:    shmhdl    [in]  共享的句柄
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_DelShm(int shmhdl)
{
    int  rv;
    //删除共享内存
    rv = shmctl(shmhdl,IPC_RMID,NULL);
    if(rv < 0)                //删除共享内存失败
        return -1;
        
    return 0;
}
myipc_shm.c

>vi keymng_msg.h

#ifndef _KEYMNG_MSG_H_
#define _KEYMNG_MSG_H_

#ifdef __cplusplus
extern "C" {
#endif

#define        KeyMng_ParamErr            200        //输入参数失败
#define        KeyMng_TypeErr            201        //输入类型失败
#define        KeyMng_MallocErr        202        //分配内存失败

#define        KeyMng_NEWorUPDATE        1        //1 密钥协商 
#define        KeyMng_Check            2        //2 密钥校验
#define        KeyMng_Revoke            3        //3 密钥注销
                 
#define  ID_MsgKey_Teacher  80
typedef struct _Teacher
{
    char name[64];
    int age;
    char *p;
    int plen;
}Teacher;


//密钥请求报文 --- 结构体
#define  ID_MsgKey_Req  60
typedef struct _MsgKey_Req
{
    //1 密钥协商      //2 密钥校验;     //3 密钥注销
    int                cmdType;        //报文命令码 
    char            clientId[12];    //客户端编号
    char            AuthCode[16];    //认证码
    char            serverId[12];    //服务器端I编号 
    char            r1[64];        //客户端随机数
    
}MsgKey_Req;


//密钥应答报文 --- 结构体
#define  ID_MsgKey_Res  61
typedef struct  _MsgKey_Res
{
    int                    rv;                //返回值
    char                clientId[12];    //客户端编号
    char                serverId[12];    //服务器编号
    unsigned char        r2[64];            //服务器端随机数
    int                    seckeyid;        //对称密钥编号 //modfy 2015.07.20
}MsgKey_Res;


/*
 pstruct :    输入的报文数据 ; (指向相应结构体的指针) 
 type :        输入的类型标识(函数内部通过type 得到 pstruct 所指向的报文类型)
 poutData:    输出的编码后的报文 ; 
 outlen :    输出的数据长度;
*/

int MsgEncode(
    void            *pStruct , /*in*/
    int                type,
    unsigned char    **outData, /*out*/
    int                *outLen );

/*
 inData        : 输入的编码后的数据;
 inLen        : 输入的数据长度 ;
 pstruct    : 输出的解码后的数据; (其空间是在内部开辟的,也需要用内部定义的free函数进行释放)
 type        : 结构的类型标识(返回类型标识,使得调用者通过flag进行判断,将pstruct 转换为相应的结构)
*/

int MsgDecode( 
    unsigned char *inData,/*in*/
    int           inLen,
    void          **pStruct /*out*/,
    int           *type /*out*/);


/*
释放 MsgEncode( )函数中的outData; 方法:MsgMemFree((void **)outData, 0); 
释放MsgDecode( )函数中的pstruct结构体,MsgMemFree((void **)outData, type);
type : 输入参数,便于函数判断调用哪个结构体的free函数
*/ 

int MsgMemFree(void **point, int type);

#ifdef __cplusplus
}
#endif


#endif
keymng_msg.h

>vi keymnglog.h

//keymnglog.h 日志头文件



// keymnglog.h

#ifndef _KEYMNG_LOG_H_
#define _KEYMNG_LOG_H_

/************************************************************************/
/* 
const char *file:文件名称
int line:文件行号
int level:错误级别
        0 -- 没有日志
        1 -- debug级别
        2 -- info级别
        3 -- warning级别
        4 -- err级别
int status:错误码
const char *fmt:可变参数
*/
/************************************************************************/
//实际使用的Level
extern int  KeyMngLevel[5];

void KeyMng_Log(const char *file, int line, int level, int status, const char *fmt, ...);

#endif
keymnglog.h

>vi myipc_shm.h

// myipc_shm.h
#ifndef _WBM_MY_SHM_H_
#define _WBM_MY_SHM_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __cplusplus 
extern "C" {
#endif

//共享内存错误码
#define        MYIPC_OK                0        //正确
#define        MYIPC_ParamErr            301        //输入参数失败
#define        MYIPC_NotEXISTErr        302        //共享内存不存在错误
#define        MYIPC_CreateErr            303        //创建共享内存错误

//创建共享内存 若共享内存不存在,则创建
int IPC_CreatShm(int key, int shmsize, int *shmhdl);

//打开共享内存 若共享内存不存在,返回错误
int IPC_OpenShm(int key, int shmsize, int *shmhdl);

/***********************************************************************
  功能描述:    关联共享内存
  参数说明:    shmhdl    [in]  共享的句柄
                mapaddr [out] 共享内存首地址
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_MapShm(int shmhdl, void **mapaddr);

/***********************************************************************
  功能描述:    取消共享内存关联
  参数说明:    unmapaddr   [in] 共享内存首地址
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_UnMapShm(void *unmapaddr);

/***********************************************************************
  功能描述:    删除共享内存
  参数说明:    shmhdl    [in]  共享的句柄
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_DelShm(int shmhdl);

/***********************************************************************
  功能描述:    创建共享内存 通过种子文件
  参数说明:    shmname  [in]  是共享内存名,系统中唯一标志
                shmsize  [in]  是要创建的共享内存的大小;
                shmhdl   [out] 共享内存的句柄.
  返回值:      返回0函数执行成功;非0返回错误码
************************************************************************/
int IPC_CreatShmBySeedName(const char *shmname, int shmsize, int *shmhdl);

#ifdef __cplusplus
}
#endif
#endif
myipc_shm.h

>vi poolsocket.h

#ifndef _poolsocket_H_
#define _poolsocket_H_

#ifdef __cplusplus
extern 'C'
{
#endif

//错误码定义  
#define Sck_Ok                 0
#define Sck_BaseErr           3000

#define Sck_ErrParam                    (Sck_BaseErr+1)
#define Sck_ErrTimeOut                    (Sck_BaseErr+2)
#define Sck_ErrPeerClosed               (Sck_BaseErr+3)
#define Sck_ErrMalloc                       (Sck_BaseErr+4)

#define Sck_Err_Pool_CreateConn                (Sck_BaseErr+20)  //创建连接池 (没有达到最大连接数)
#define Sck_Err_Pool_terminated                (Sck_BaseErr+21) //已终止
#define Sck_Err_Pool_GetConn_ValidIsZero    (Sck_BaseErr+22) //有效连接数是零
#define Sck_Err_Pool_HaveExist                (Sck_BaseErr+22) //连接已经在池中
#define Sck_Err_Pool_ValidBounds            (Sck_BaseErr+22) //有效连接数目超过了最大连接数


//客户端 初始化
int sckClient_init();

//客户端 连接服务器
int sckClient_connect(char *ip, int port, int connecttime, int *connfd);

//客户端 关闭和服务端的连接
int sckClient_closeconn(int connfd);

//客户端 发送报文
int sckClient_send(int connfd, int sendtime, unsigned char *data, int datalen);

//客户端 接受报文
int sckClient_rev(int connfd, int revtime, unsigned char **out, int *outlen); //1

//客户端 释放
int sckClient_destroy();



//释放内存
int sck_FreeMem(void **buf);



typedef struct _SCKClitPoolParam
{
    char     serverip[64];
    int     serverport;
    int     bounds; //池容量
    int     connecttime;
    int     sendtime;
    int     revtime;
}SCKClitPoolParam;


//客户端 socket池初始化
int sckCltPool_init(void **handle, SCKClitPoolParam *param);  //ip port 数量 

//客户端 socket池 获取一条连接 
int sckCltPool_getConnet(void *handle, int *connfd);

//客户端 socket池 发送数据 
int sckCltPool_send(void *handle, int connfd, unsigned char *data, int datalen);

//客户端 socket池 接受数据
int sckCltPool_rev(void *handle, int connfd, unsigned char **out, int *outlen); //1

//客户端 socket池 把连接放回 socket池中 
int sckCltPool_putConnet(void *handle, int connfd, int validFlag); //0正常 1

//客户端 socket池 销毁连接
int sckCltPool_destroy(void *handle);


//服务器端初始化
int sckServer_init(int port, int *listenfd);

int sckServer_accept(int listenfd, int timeout, int *connfd);

//服务器端发送报文
int sckServer_send(int connfd, int timeout, unsigned char *data, int datalen);

//服务器端端接受报文
int sckServer_rev(int  connfd, int timeout, unsigned char **out, int *outlen); //1

int sckServer_close(int connfd);

//服务器端环境释放 
int sckServer_destroy();


#ifdef __cpluspluse
}
#endif


#endif
poolsocket.h

2、密钥协商-日志的使用

>cd src
>touch keymngclient.c
>touch keymngserver.c
>vi keymngclient.c

#include "keymnglog.h"

int main(void)
{
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
    
    return 0;    
}
keymngclient.c

>gcc keymngclient.c keymnglog.c -o keymngclient -I ../inc
>./keymngclient

打开另一个终端,然后在家目录的log目录下查看日志

注意:0的时候没有日志,所以查看的时候只有4行。

3、密钥协商客户端-模块划分

》密钥协商客户端:        keymngclient.c
    显示菜单。
    接收用户选择。  num。
    客户端信息初始化。
    switch(num) {
        case 1协商:
            密钥协商。 建立连接、封装req结构体、编码、发送、接收、解码、生成密钥、写共享内存。
            _Agree();

        case 2校验:
            密钥校验。 建立连接、封装req结构体、编码、发送、接收、解码、展示结果给用户。
            _Check();    

        case 3查看:
            密钥查看。 建立连接、封装req结构体、编码、发送、接收、解码、展示密钥相关信息给用户。
            _View();
        。。。。
    }

    将结果展示给用户。

》模块划分:
    业务逻辑:
        keymngclient.c
    业务功能:
        keymngclientop.c            -->           keymngclientop.h
        实现 客户端信息初始化。                客户端信息初始化声明。             
        实现 客户端密钥协商。                。。。。
        实现 客户端密钥校验。

        struct clientInfo { serverIp, serverPort, clientID, serverID, Autocode, shmkey, shmid, maxnode }

  int keymng_initInfo(struct clientInfo *pInfo);传出参数

        int keymng_Agree(struct clientInfo *pInfo)
        int keymng_Check(struct clientInfo *pInfo);
        int keymng_Revoke(struct clientInfo *pInfo);

====================================================================
》密钥协商服务器:
    keymngserverop.c         keymngserverop.h        功能实现
    实现 服务器信息初始化。        服务器信息初始化声明。             
    实现 服务器密钥协商。        。。。。
    实现 服务器密钥校验。   
    实现 服务器密钥注销。

4、密钥协商客户端-框架实现

》文件准备:

// keymngclientop.h

#ifndef _KEYMNG_CLIENTOP_H_
#define _KEYMNG_CLIENTOP_H_

#ifdef __cplusplus
extern "C" {
#endif

#define        MngClt_OK                0            //正确
#define        MngClt_ParamErr            301            //输入参数失败
#define        MngClt_NoNetPointErr    302            //共享内存中,没有找到网点信息
#define        MngClt_NodeMaxCount        303            //共享内存中,超过最大网点

typedef struct _MngClient_Info
{
    char            clientId[12];    //客户端编号
    char            AuthCode[16];    //认证码
    char            serverId[12];    //服务器端编号
    
    char            serverip[32];
    int             serverport;
    
    int                maxnode;         //最大网点数 客户端默认1个
    int             shmkey;             //共享内存keyid 创建共享内存时使用     
    int             shmhdl;         //共享内存句柄    
}MngClient_Info;


//初始化客户端 全局变量
int MngClient_InitInfo(MngClient_Info *pCltInfo);

int MngClient_Quit(MngClient_Info *pCltInfo);

int MngClient_Agree(MngClient_Info *pCltInfo);

int MngClient_Check(MngClient_Info *pCltInfo);

int MngClient_Revoke(MngClient_Info *pCltInfo);

int MngClient_view(MngClient_Info *pCltInfo);


#ifdef __cplusplus
}
#endif

#endif
keymngclientop.h

将keymngclientop.h放入ins目录下,然后在src新建keymngclientop.c,进行开发

>touch keymngclientop.c

>vi keymngclientop.c

#include <stdio.h>
#include <stdlib.h>
#include "keymngclientop.h"

int MngClient_InitInfo(MngClient_Info *pCltInfo)
{
    strcpy(pCltInfo->clientId, "1111");
    strcpy(pCltInfo->AuthCode, "1111");
    strcpy(pCltInfo->serverId, "0001");
    strcpy(pCltInfo->serverip, "127.0.0.1");
    pCltInfo->serverport = 8001;
    
    pCltInfo->maxnode = 1;
    pCltInfo->shmkey = 0x0011;
    pCltInfo->shmhdl = 0;    
    
    return 0;
}

int MngClient_Agree(MngClient_Info *pCltInfo)
{
    
    return 0;
}
keymngclientop.c

5、密钥协商客户端-Agree函数框架

>keymngclient.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "keymngclientop.h"
#include "keymng_msg.h"
#include "keymnglog.h"

int main111(void)
{
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
    
    return 0;    
}

int Usage()
{
    int nSel = -1;
    
    system("clear");    
    printf("
  /*************************************************************/");
    printf("
  /*************************************************************/");
    printf("
  /*     1.密钥协商                                            */");
    printf("
  /*     2.密钥校验                                            */");
    printf("
  /*     3.密钥注销                                            */");
    printf("
  /*     4.密钥查看                                            */");
    printf("
  /*     0.退出系统                                            */");
    printf("
  /*************************************************************/");
    printf("
  /*************************************************************/");
    printf("

  选择:");
    scanf("%d", &nSel);
    while(getchar() != '
'); //把应用程序io缓冲器的所有的数据 都读走,避免影响下一次 输入
    
    return nSel;
}

int main()
{
    int                 ret = 0;
    int                 nSel = 0;
    
    MngClient_Info        mngClientInfo;
    memset(&mngClientInfo, 0, sizeof(MngClient_Info));

    // 初始化客户端结构体信息
    ret = MngClient_InitInfo(&mngClientInfo);
    if (ret != 0)
    {
        printf("func MngClient_InitInfo() err:%d 
 ", ret);
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MngClient_InitInfo() err:%d", ret);
    }
    
    while (1)
    {
        // 显示菜单  接收用户选择
        nSel = Usage();
        
        switch (nSel)
        {
        case KeyMng_NEWorUPDATE:    
            //密钥协商
            ret =  MngClient_Agree(&mngClientInfo);
            break;
        case KeyMng_Check:    
            //ret = MngClient_Check(&mngClientInfo);
            break;
        case KeyMng_Revoke:    
            //密钥注销
            break;
        case 0:    
            //退出
            return 0;
            
        default :
            printf("选项不支持
");
            break;
        }
        
        // 结果展示给用户。
        if (ret)
        {
            printf("
!!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!");
            printf("
错误码是:%x
", ret);
        }
        else
        {
            printf("
!!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!
");
        }    
        getchar();    
    }
    
    return 0;
}
keymngclient.c

>keymngclientop.c

int MngClient_Agree(MngClient_Info *pCltInfo)
{
    //组织密钥请求结构体 req

    //编码密钥请求结构体 req --> TLV

    //初始化连接 --> listenfd

    //建立连接 --> connfd

    //发送请求报文 --> TLV send

    //接收应答报文 --> 服务器TLV res

    //解析应答报文 --> TLV --> Struct --> rv / r2

    //生成密钥 --> r1 r2 算法 --> 密钥

    //写共享内存。--> 存储
   
    return 0;
}

>vi keymngclientop.c

#include <stdio.h>
#include <stdlib.h>
#include "keymngclientop.h"

int MngClient_InitInfo(MngClient_Info *pCltInfo)
{
    strcpy(pCltInfo->clientId, "1111");
    strcpy(pCltInfo->AuthCode, "1111");
    strcpy(pCltInfo->serverId, "0001");
    strcpy(pCltInfo->serverip, "127.0.0.1");
    pCltInfo->serverport = 8001;
    
    pCltInfo->maxnode = 1;
    pCltInfo->shmkey = 0x0011;
    pCltInfo->shmhdl = 0;    
    
    return 0;
}

int MngClient_Agree(MngClient_Info *pCltInfo)
{
    //组织密钥请求结构体

    //编码密钥请求结构体

    //初始化连接

    //建立连接

    //发送请求报文

    //接收应答报文

    //解析应答报文

    //生成密钥

    //写共享内存。
    
    
    return 0;
}
keymngclientop.c

6、密钥协商客户端-Agree函数实现

>keymngclient.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "keymngclientop.h"
#include "keymng_msg.h"
#include "keymnglog.h"

int main111(void)
{
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
    KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
    
    return 0;    
}

int Usage()
{
    int nSel = -1;
    
    system("clear");    
    printf("
  /*************************************************************/");
    printf("
  /*************************************************************/");
    printf("
  /*     1.密钥协商                                            */");
    printf("
  /*     2.密钥校验                                            */");
    printf("
  /*     3.密钥注销                                            */");
    printf("
  /*     4.密钥查看                                            */");
    printf("
  /*     0.退出系统                                            */");
    printf("
  /*************************************************************/");
    printf("
  /*************************************************************/");
    printf("

  选择:");
    scanf("%d", &nSel);
    while(getchar() != '
'); //把应用程序io缓冲器的所有的数据 都读走,避免影响下一次 输入
    
    return nSel;
}

int main()
{
    int                 ret = 0;
    int                 nSel = 0;
    
    MngClient_Info        mngClientInfo;
    memset(&mngClientInfo, 0, sizeof(MngClient_Info));

    // 初始化客户端结构体信息
    ret = MngClient_InitInfo(&mngClientInfo);
    if (ret != 0)
    {
        printf("func MngClient_InitInfo() err:%d 
 ", ret);
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MngClient_InitInfo() err:%d", ret);
    }
    
    while (1)
    {
        // 显示菜单  接收用户选择
        nSel = Usage();
        
        switch (nSel)
        {
        case KeyMng_NEWorUPDATE:    
            //密钥协商
            ret =  MngClient_Agree(&mngClientInfo);
            break;
        case KeyMng_Check:    
            //ret = MngClient_Check(&mngClientInfo);
            break;
        case KeyMng_Revoke:    
            //密钥注销
            break;
        case 0:    
            //退出
            return 0;
            
        default :
            printf("选项不支持
");
            break;
        }
        
        // 结果展示给用户。
        if (ret)
        {
            printf("
!!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!");
            printf("
错误码是:%x
", ret);
        }
        else
        {
            printf("
!!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!
");
        }    
        getchar();    
    }
    
    return 0;
}
keymngclient.c

>keymngclientop.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "keymnglog.h"
#include "poolsocket.h"
#include "keymng_msg.h"
#include "keymngclientop.h"

int MngClient_InitInfo(MngClient_Info *pCltInfo)
{
    strcpy(pCltInfo->clientId, "1111");
    strcpy(pCltInfo->AuthCode, "1111");
    strcpy(pCltInfo->serverId, "0001");
    strcpy(pCltInfo->serverip, "127.0.0.1");
    pCltInfo->serverport = 8001;
    
    pCltInfo->maxnode = 1;
    pCltInfo->shmkey = 0x0011;
    pCltInfo->shmhdl = 0;    
    
    return 0;
}

int MngClient_Agree(MngClient_Info *pCltInfo)
{
    int i = 0; 
    int ret = 0; 
    int time = 3;
    
    int connfd = -1;
    
    // 存放编码 TLV 完成的 req
    unsigned char    *msgKey_Req_Data = NULL;   
    int             msgKey_Req_DataLen = 0;
    
    // 存放编码 TLV 完成的 res
    unsigned char    *msgKey_Res_Data = NULL;
    int             msgKey_Res_DataLen = 0;
    
    MsgKey_Res         *pStruct_Res = NULL;
    int             iType = 0;

    // 初始化密钥请求结构体
    MsgKey_Req msgKey_req;
    msgKey_req.cmdType = KeyMng_NEWorUPDATE;
    strcpy(msgKey_req.clientId, pCltInfo->clientId);
    strcpy(msgKey_req.AuthCode, pCltInfo->AuthCode);
    strcpy(msgKey_req.serverId, pCltInfo->serverId);    
    
    // 产生随机数         abcdefg
    for (i = 0; i < 64; i++) {
        msgKey_req.r1[i] = 'a' + i;    
    }
    
    // 编码密钥请求 结构体 req
    ret = MsgEncode(&msgKey_req, ID_MsgKey_Req, &msgKey_Req_Data, &msgKey_Req_DataLen);
    if (ret != 0) {        
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgEncode() err:%d", ret);
        return 0;    
    }
    
    // 初始化建立连接函数
    ret = sckClient_init();
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_init() err:%d", ret);
        return 0;    
    }
        
    // 创建连接。
    ret = sckClient_connect(pCltInfo->serverip, pCltInfo->serverport, time, &connfd);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_connect() err:%d", ret);
        return 0;    
    }
        
    // 发送数据
    ret = sckClient_send(connfd, time, msgKey_Req_Data, msgKey_Req_DataLen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_send() err:%d", ret);
        return 0;    
    }
        
    // ---- 等待服务器回发数据
    
    // 接收数据
    ret = sckClient_rev(connfd, time, &msgKey_Res_Data, &msgKey_Res_DataLen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_rev() err:%d", ret);
        return 0;    
    }    
    
    // 解码密钥应答 结构体 res ---> rv r2
    ret = MsgDecode(msgKey_Res_Data, msgKey_Res_DataLen, (void **)&pStruct_Res, &iType);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgDecode() err:%d", ret);
        return 0;    
    }    
    
    if (pStruct_Res->rv != 0) {
        ret    = -1;
        return 0;
    } else if (pStruct_Res->rv == 0) {
        ret = 0;
        printf("---当前生成的密钥编号为:%d
", pStruct_Res->seckeyid);    
        return 0;
    }
    
    // --利用 r1 r2 生成密钥
    
    // --写入共享内存。
    

    
    return ret;    
}
keymngclientop.c

注意:生成密钥 --> r1 r2 算法 --> 密钥 和 写共享内存。--> 存储 暂不实现。

7、密钥协商客户端-Agree函数内存释放

>free——MsgMemFree

>keymngclientop.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "keymnglog.h"
#include "poolsocket.h"
#include "keymng_msg.h"
#include "keymngclientop.h"

int MngClient_InitInfo(MngClient_Info *pCltInfo)
{
    strcpy(pCltInfo->clientId, "1111");
    strcpy(pCltInfo->AuthCode, "1111");
    strcpy(pCltInfo->serverId, "0001");
    strcpy(pCltInfo->serverip, "127.0.0.1");
    pCltInfo->serverport = 8001;
    
    pCltInfo->maxnode = 1;
    pCltInfo->shmkey = 0x0011;
    pCltInfo->shmhdl = 0;    
    
    return 0;
}

int MngClient_Agree(MngClient_Info *pCltInfo)
{
    int i = 0; 
    int ret = 0; 
    int time = 3;
    
    int connfd = -1;
    
    // 存放编码 TLV 完成的 req
    unsigned char    *msgKey_Req_Data = NULL;   
    int             msgKey_Req_DataLen = 0;
    
    // 存放编码 TLV 完成的 res
    unsigned char    *msgKey_Res_Data = NULL;
    int             msgKey_Res_DataLen = 0;
    
    MsgKey_Res         *pStruct_Res = NULL;
    int             iType = 0;

    // 初始化密钥请求结构体
    MsgKey_Req msgKey_req;
    msgKey_req.cmdType = KeyMng_NEWorUPDATE;
    strcpy(msgKey_req.clientId, pCltInfo->clientId);
    strcpy(msgKey_req.AuthCode, pCltInfo->AuthCode);
    strcpy(msgKey_req.serverId, pCltInfo->serverId);    
    
    // 产生随机数         abcdefg
    for (i = 0; i < 64; i++) {
        msgKey_req.r1[i] = 'a' + i;    
    }
    
    // 编码密钥请求 结构体 req
    ret = MsgEncode(&msgKey_req, ID_MsgKey_Req, &msgKey_Req_Data, &msgKey_Req_DataLen);
    if (ret != 0) {        
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgEncode() err:%d", ret);
        goto END;    
    }
    
    // 初始化建立连接函数
    ret = sckClient_init();
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_init() err:%d", ret);
        goto END;    
    }
        
    // 创建连接。
    ret = sckClient_connect(pCltInfo->serverip, pCltInfo->serverport, time, &connfd);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_connect() err:%d", ret);
        goto END;    
    }
        
    // 发送数据
    ret = sckClient_send(connfd, time, msgKey_Req_Data, msgKey_Req_DataLen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_send() err:%d", ret);
        goto END;    
    }
        
    // ---- 等待服务器回发数据
    
    // 接收数据
    ret = sckClient_rev(connfd, time, &msgKey_Res_Data, &msgKey_Res_DataLen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_rev() err:%d", ret);
        goto END;    
    }    
    
    // 解码密钥应答 结构体 res ---> rv r2
    ret = MsgDecode(msgKey_Res_Data, msgKey_Res_DataLen, (void **)&pStruct_Res, &iType);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgDecode() err:%d", ret);
        goto END;    
    }    
    
    if (pStruct_Res->rv != 0) {
        ret    = -1;
        goto END;
    } else if (pStruct_Res->rv == 0) {
        ret = 0;
        printf("---当前生成的密钥编号为:%d
", pStruct_Res->seckeyid);    
        goto END;
    }
    
    // --利用 r1 r2 生成密钥
    
    // --写入共享内存。
    
END:
    if (msgKey_Req_Data != NULL) 
        MsgMemFree((void **)&msgKey_Req_Data, 0);
    if (msgKey_Res_Data != NULL) 
        MsgMemFree((void **)&msgKey_Res_Data, 0);
    if (pStruct_Res != NULL) 
        MsgMemFree((void **)&pStruct_Res, iType);
    
    return ret;    
}
keymngclientop.c

8、密钥协商服务器-框架梳理

》密钥协商服务器:

    void *callback(void *arg)
    {
        // 接收客户端 密钥请求报文 --- TLV req

        // 解码客户端 密钥请求报文 ---> cmdType

        switch(cmdType) {
            case 密钥协商:
                mngServer_Agree();
          break;
            case 密钥校验:
                mngServer_Check();
                break;
            case 密钥注销:
                mngServer_Revoke();
          break;
defaultbreak; } // 发送应答报文 } keymngserver.c -------业务逻辑 { // 服务器信息初始化。 // 监听客户端连接请求 while(1) { // 启动线程 与客户端 进行通信 fd pthread_create(, (void *)fd); } }

注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!

服务器的发送应答报文放到Agree函数外边,所以服务器的Agree函数的接口与客户端Agree函数接口不同。(两种都可以,根据需求都可以做。)

    keymngserverop.c         keymngserverop.h        功能实现
    实现 服务器信息初始化。        服务器信息初始化声明。             
    实现 服务器密钥协商。        。。。。
    实现 服务器密钥校验。   
    实现 服务器密钥注销。

    struct serverInfo {serverIp, serverPort, serverID, shmkey, shmid, maxnode, dbuser, dbpasswd, dbname, maxnum} 不变

    int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    {
        // 生成随机数 r2

        // 结合 r1 r2 生成密钥  ---> 成功、失败 rv

        // 组织 应答结构体 res : rv r2 clientId serverId  seckeyid

        // 写共享内存

        // 写数据库

        // 编码应答报文  传出
    }

9、密钥协商服务器-业务逻辑实现

>keymngserverop.h

// keymngserverop.h
#ifndef _KEYMNG_ServerOp_H_
#define _KEYMNG_ServerOp_H_

#include "keymng_msg.h"

#ifdef __cplusplus
extern "C" {
#endif

//keymngserver 错误码

#define        MngSvr_OK                0        //正确
#define        MngSvr_ParamErr            301        //输入参数失败
#define        MngSvr_NoNetPointErr    302        //共享内存中,没有找到网点信息
#define        MngSvr_NodeMaxCount        303        //共享内存中,超过最大网点
#define        MngSvr_CheckErr            304        //共享内存中,超过最大网点

typedef struct _MngServer_Info
{
    char            serverId[12];    //服务器端编号
    
    //数据库连接池句柄    
    char            dbuse[24];         //数据库用户名
    char            dbpasswd[24];     //数据库密码
    char            dbsid[24];         //数据库sid
    int                dbpoolnum;         //数据库池 连接数
    
    char            serverip[24];
    int             serverport;
    
    //共享内存配置信息
    int                maxnode; //最大网点树 客户端默认1个
    int             shmkey;     //共享内存keyid 创建共享内存时使用     
    int             shmhdl; //共享内存句柄    
}MngServer_Info;



//初始化服务器 全局变量
int MngServer_InitInfo(MngServer_Info *svrInfo);

int MngServer_Quit(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);

//服务端 密钥协商应答流程
int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
//int keymngsever_agree(MngServer_Info *pServferInfo, MsgKey_Req *pMsgKeyReq ,  unsigned char **pMsgKeyResData, int *pMsgKeyResDataLen)
   
int MngServer_Check(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);

int MngServer_Revoke(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);

int MngServer_view(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);


#ifdef __cplusplus
}
#endif

#endif
keymngserverop.h

>keymngserverop.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "keymngserverop.h"
#include "keymng_msg.h"
#include "keymnglog.h" 


int MngServer_InitInfo(MngServer_Info *svrInfo)
{
    strcpy(svrInfo->serverId, "0001");
    strcpy(svrInfo->dbuse, "SECMNG");
    strcpy(svrInfo->dbpasswd, "SECMNG");
    strcpy(svrInfo->dbsid, "orcl");
    svrInfo->dbpoolnum = 8;    
    strcpy(svrInfo->serverip, "127.0.0.1");
    svrInfo->serverport = 8001;
    svrInfo->maxnode = 10;
    svrInfo->shmkey = 0x0001;
    svrInfo->shmhdl = 0;
    
    return 0;    
}

int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
{
    
    return 0;    
}
keymngserverop.c

>keymngserver.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
 
#include "poolsocket.h"  
#include "keymngserverop.h"
#include "keymng_msg.h"
#include "keymnglog.h"  

MngServer_Info serverInfo;
 
void *start_routine(void * arg)
{
     int ret;
     int timeout = 3;
     int connfd = (int)arg;
     
     unsigned char *out = NULL;
     int outlen = 0;
     
     MsgKey_Req *pStruct_req = NULL;
     int iType = 0;
     
     unsigned char *res_outData = NULL;
     int res_outDataLen = 0;
     
     while (1) {

        //服务器端端接受报文
        ret = sckServer_rev(connfd, timeout, &out, &outlen); 
        if (ret == Sck_ErrPeerClosed) {
            // 检测到 对端关闭,关闭本端。
            printf("----------------ErrPeerClosed 关闭服务器
");
            break;
        } else if (ret == Sck_ErrTimeOut) {
            printf("---服务器检测到客户端发送数据 超时 
");
            continue;
        } else if (ret != 0) {
            printf("未知错误
");
            break;
        }

        // 解码客户端 密钥请求报文 ---> cmdType
        ret = MsgDecode(out, outlen, (void **)&pStruct_req, &iType);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MsgDecode() err:%d", ret);    
            return ret;    
        }

        switch(pStruct_req->cmdType) {
            case KeyMng_NEWorUPDATE:
                ret = MngServer_Agree(&serverInfo, pStruct_req, &res_outData, &res_outDataLen);
            /*
            case 密钥校验:
                mngServer_Agree();
                
            case 密钥注销:
                mngServer_Agree();
                */
            default:
                break;
        }
        if (ret != 0) {        
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MngServer_Agree() err:%d", ret);                
        }

         //服务器端发送报文
        ret = sckServer_send(connfd, timeout, res_outData, res_outDataLen);
         if (ret == Sck_ErrPeerClosed) {
            // 检测到 对端关闭,关闭本端。
            printf("---ErrPeerClosed 
");
            break;
        } else if (ret == Sck_ErrTimeOut) {
            printf("---服务器检测到本端发送数据 超时 
");
            continue;
        } else if (ret != 0) {
            printf("未知错误
");
            break;
        }
    }
    
    sckServer_close(connfd);
    
     return NULL;
}


int main(void)
{
    int listenfd;
    int ret = 0;
    
    int timeout = 3;
    int connfd = -1;
    
    pthread_t pid;
    
    // 服务器信息初始化。
    ret = MngServer_InitInfo(&serverInfo);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MngServer_InitInfo() err:%d", ret);    
        return ret;
    }
    
    //服务器端初始化
    ret = sckServer_init(serverInfo.serverport, &listenfd);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "sckServer_init() err:%d", ret);    
        return ret;
    }
    
    while (1) {
        ret = sckServer_accept(listenfd, timeout, &connfd);
        if (ret == Sck_ErrTimeOut){
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], ret, "---等待客户端连接超时---");
            continue;    
        } else if(ret != 0)  {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "sckServer_accept() err:%d", ret);    
            return ret;
        }
        ret = pthread_create(&pid, NULL, start_routine, (void *)connfd);                    
    }
     
     //服务器端环境释放 
    sckServer_destroy();

    return 0;    
}
keymngserver.c

>报错1:程序中有游离的“357”

>报错2:[ERRNO is 98]func bind() err

端口占用问题;>ps aux | grep keymngserver查看pid;然后kill pid

>vi makefile

.PHONY:clean all

WORKDIR=.
VPATH = ./src

CC=gcc
CFLGS= -Wall -g -I$(WORKDIR)/inc/
LIBFLAG = -L$(HOME)/lib


BIN = keymngclient  keymngserver 


all:$(BIN)
#myipc_shm.o keymng_shmop.o
keymngclient:keymngclient.o  keymnglog.o  keymngclientop.o  
    $(CC) $(LIBFLAG) -lpthread -litcastsocket -lmessagereal $^ -o $@ 

#myipc_shm.o  keymng_shmop.o  keymng_dbop.o         -lclntsh  -licdbapi
keymngserver:keymngserver.o  keymngserverop.o  keymnglog.o  
    $(CC) $(LIBFLAG) $^ -o $@ -lpthread -litcastsocket -lmessagereal  
 
#testdbapi:testdbapi.o  
#    $(CC) $(LIBFLAG) $^ -o $@ -lpthread  -lclntsh  -licdbapi
        
%.o:%.c
    $(CC) $(CFLGS) -c $< -o $@    

clean:
    rm -f *.o $(BIN)
    
makefile

>make

>./keymngclient

打开另一个终端,执行>./keymngserver,

原终端情况:

服务器端情况:

10、密钥协商服务器-Agree功能实现

>vi keymngserver.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "keymngserverop.h"
#include "keymng_msg.h"
#include "keymnglog.h" 

static int    seckeyid = 100;

int MngServer_InitInfo(MngServer_Info *svrInfo)
{
    strcpy(svrInfo->serverId, "0001");
    strcpy(svrInfo->dbuse, "SECMNG");
    strcpy(svrInfo->dbpasswd, "SECMNG");
    strcpy(svrInfo->dbsid, "orcl");
    svrInfo->dbpoolnum = 8;    
    strcpy(svrInfo->serverip, "127.0.0.1");
    svrInfo->serverport = 8001;
    svrInfo->maxnode = 10;
    svrInfo->shmkey = 0x0001;
    svrInfo->shmhdl = 0;
    
    return 0;    
}

int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
{
    int ret = 0;
    int i = 0;
    MsgKey_Res msgKey_Res;
    
    // --结合 r1 r2 生成密钥  ---> 成功、失败 rv
        
    if (strcmp(svrInfo->serverId, msgkeyReq->serverId) != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "客户端访问了错误的服务器");
        return -1;    
    }
    
    // 组织 应答结构体 res : rv r2 clientId serverId  seckeyid
    msgKey_Res.rv = 0;     //0 成功 1 失败。
    strcpy(msgKey_Res.clientId, msgkeyReq->clientId); 
    strcpy(msgKey_Res.serverId, msgkeyReq->serverId); 
    // 生成随机数 r2
    for (i = 0; i < 64; i++) {
        msgKey_Res.r2[i] = 'a' + i;            //
    }    
    msgKey_Res.seckeyid = seckeyid++;

    // --写共享内存

    // --写数据库

    // 编码应答报文  传出
    ret = MsgEncode(&msgKey_Res, ID_MsgKey_Res, outData, datalen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "serverAgree MsgEncode() err:%d", ret);    
        return ret;
    }
    
    return 0;    
}
keymngserverop.c

注意:结合 r1 r2 生成密钥、写共享内存、写数据库 暂不实现。

>make

>./keymngclient

打开另一个终端,执行>./keymngserver,分别查看终端执行情况。

客户端情况:(输入:1)

点击“Enter”后,再次输入:1

服务器端情况:

11、总结

》客户端:keymngclient.c—负责业务逻辑;keymngclientop.c—负责功能实现

》服务器:keymngserver.c—负责业务逻辑;keymngserverop.c—负责功能实现

注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!

在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_SecureTransmissionPlatform_Project05.html