FADE相关代码解析1

      前面我提到了怎么样搭建一个FADE,但是搭建FADE不是我的初衷。FADE是一个在Amazon下的基于策略的数据安全删除模式,现在的想法就是想把FADE实现思想搬到我们项目组-基于Amazon下的S3FS云平台。所以有必要对FADE相关思想、相关流程做一个简要的记录,所以在这里对相关函数以及流程做个简要记录,为以后的工作做铺垫。这次分析的代码是FADE Version2.0,这个版本跟Version1.0相比,修改了一些bug以及增加了相关界面。FADE主要是根据Client以及Server(key manager)两部分组成,Client跟Server(key manager)之间通过Socket进行通信。FADE主要分为Client以及key manager两部分进行分析。接下来对key manager进行分析。

    1.    Server:key manager作为可信的第三方,主要是进行密钥管理

            1.1    key manager:main.c

                 1.1.1    首先获取port:-pport   --port=port  port(将-p替换成port)

                        else if (!port && !strncmp(argv[i], "-p", 2))  else if (!port && !strncmp(argv[i], "--port=", 7)) else if (!port && !strcmp(argv[i], "-p")) 

                 1.1.2    为跟Client进行通信设置socket,它包括网络地址的设定,建立socket、设置socket的相关属性

                            Ephemerizer::instance()->initSocket(port ? port : DEFAULT_PORT);

                             initSocket(port){

                                  1).    网络地址设定:

                                    sockaddr_in addr;
                                    addr.sin_port = htons(port);
                                    addr.sin_addr.s_addr = INADDR_ANY;
                                    addr.sin_family = AF_INET;

                                  2).    建立Socket

                                  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)//TCP网络连接

                                   3).    socket相关属性设置

                                      if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)))
                                   4).    socket的相关操作:bind(绑定socket与网络地址)、listen(监听socket),

                                        如果操作不对劲的话,调用closesocket进行关闭socket。                            }  

                    1.1.3     key manager运行:Ephemerizer::instance()->run();{

                                1.    首先进行accept()操作,接收socket传送过来的数据。

                                2.    开启多线程模式pthread_create(....),其中pthread_create()调用了interact函数来进行相关操作。}

                    1.1.4    static void *interact(void *arg)

                        {

                            首先接收发送过来的数据长度recvn(*clientfd,&len,sizeof(len)),调整一个传输的长度,其中需要将len=ntohl(len)进行转换。

                            然后根据recvn(*clientfd,request,len)获取client给key manager发送的请求来判断要执行的操作。Client发送给key manager的操作主要分为五种,下面来简要的分析一下

                1. 加密操作(对应于Client::upload):    if (memcmp(request, "ENC ", 4) == 0)在这个操作方式中,request中前四个字节(操作类型三个外加一个空格),后面是policyName.然后调用PolicyForEphemerizer policy(policyName);进行相关操作,比方说BIGNUM *n = policy.getN();获取密钥的长度以及BIGNUM *e = policy.getE();密钥生成等等。*response = EPHEMERIZER_RESPONSE_OK;然后将response以及keylength发送给Client。

                2. 获取操作(对应于Client::download):    else if (memcmp(request, "GET ", 4) == 0)在这个方式中,跟前面ENC所使用的思想差不多,唯一的区别就是要先判断policyName是否存在,然后在进行相关操作。不然的话,直接将*response=EPHEMERIZER_RESPONSE_FAILED

                3. 解密操作(对应于Client::download):    else if (memcmp(request, "DEC ", 4) == 0)在这个方式中,跟GET一样,也需要判断policyName是否存在。如果policyName存在的话,就调用policy.decrypt()进行解密,keyLength = policy.decrypt(len - (key - request), key, key);//decrypt return keylength,将解码之后的密码写入key中//key以后的数据进行解密。

                if (Ephemerizer::instance()->getUseCpabe())//if you enforce access control with attribute-based encryption{

                    进行文件的相关操作,比方说在FILE *fp = fopen("keys/temp_cpabe", "w");fwrite(key, 1, keyLength, fp);snprintf(cmd, sizeof(cmd), "cpabe-enc keys/pub_key keys/temp_cpabe %s", policyName.c_str());
system(cmd);// system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。fp = fopen("keys/temp_cpabe.cpabe", "r");fseek(fp, 0, SEEK_END);
keyLength = ftell(fp);//返回当前文件位置,也就是说返回FILE指针当前位置。然后再将文件内的keylength长度的数据读取到response中。fread(response + 1, 1, keyLength, fp);最后再将文件给删除掉。}

                else   {    直接赋给*response=EPHEMERIZER_RESPONSE_OK,并且将密钥添加到response后面,为后面的操作做准备。}

                4. 删除操作(对应于Client::revoke):else if (memcmp(request, "DEL ", 4) == 0)//移走策略policy{

                        这个操作跟前面DEC操作相类似,唯一的区别可以说是在对   if (Ephemerizer::instance()->getUseCpabe())进行判断前,不需要判断policyName是否存在。最后生成所谓的*response等。

                5.    CHA操作(对应于CPABE):else if (memcmp(request, "CHA ", 4) == 0)判断是否为challenge?如果是的话,那就*response = (remove((string("keys/") + policyToBeRevoked + ".pem").c_str()) == 0) ? EPHEMERIZER_RESPONSE_OK : EPHEMERIZER_RESPONSE_FAILED;,然后设置memset(policyToBeRevoked, 0, sizeof(policyToBeRevoked));}
}最后就开始对将前面五个操作所生成的*response以及len传送给Client。
               

                         }

2.Client:客户端    main.c相关解析

这里只是对main.c的相关流程进行一个解析,详细分析在后面会提到。

int main(int argc, const char *argv[])
{
if (argc != 2 && argc != 3)
{
Panic::instance()->die("usage: %s config_file [command]\n", argv[0]);
}
Client::instance()->readConfig(argv[1]);?/ ./bin/client  /etc/config.xml
Client::instance()->readSecret();
if (argc == 3)//program name     config    policy-string
{
char *command = reinterpret_cast<char *>(calloc(strlen(argv[2]) + 1, sizeof(char)));
strcpy(command, argv[2]);
return process(command);
}
for (;;)//argc =2 main 本身占一个表示program name 。然后都是从FADE>>开始的
{
char *command = readline("FADE>> ");//FADE为提示语
add_history(command);
int ret = process(command);
free(command);
if (ret == COMMAND_QUIT)
{
break;
}
else if (ret == COMMAND_OK)
{
fputs("Succeeded.\n", stdout);
}
else if (ret == COMMAND_FAILED)
{
fputs("Failed.\n", stdout);
}
}
return 0;
}


上面是Client主要涉及到的几个部分,最主要的就是将command传送到process中去进行解析。process主要由:UPLOAD、DOWNLOAD、RENEW、REVOKE、GENSECRET、QUIT这六个部分组成。接下来就对process做一个简要的分析。

process(command)

{

const char *sep = " \t\n\r";
char *operation = strtok(command, sep);
char *filename = strtok(NULL, sep);
char *token = strtok(NULL, sep);
char *policy = NULL;
if (token && strcasecmp(token, "POLICY") == 0)//进行对字符串进行分解
{
policy = strtok(NULL, sep);
}
if (strcasecmp(operation, "UPLOAD") == 0)//UPLOAD操作

{

bool ret = Client::instance()->upload(filename, policy);

}

else if (strcasecmp(operation, "DOWNLOAD") == 0)

{

bool ret = Client::instance()->download(filename);

}

else if (strcasecmp(operation, "RENEW") == 0)

{

bool ret = Client::instance()->renew(filename, policy);

}

else if (strcasecmp(operation, "REVOKE") == 0)

{

bool ret = Client::instance()->revoke(filename);

}

else if (strcasecmp(operation, "GENSECRET") == 0)

{

bool ret = Client::instance()->generateSecret();

}

else if (strcasecmp(operation, "QUIT") == 0)


}


你可能感兴趣的:(FADE相关代码解析1)