add: 增加证书相关的一些接口:1. 安装证书到redis;2.从redis移除证书;3. 验证兴趣包签名;4.验证数据包签名

This commit is contained in:
SunnyQjm committed 2020-05-30 19:50:15 +08:00
1 parent 2ae7003e27
commit 0df5cca9a6
7 files changed
+296

No files matched your search

+1
View File
@@ -1,2 +1,3 @@
# Project exclude paths
/cmake-build-debug/
.idea/
+6
View File
@@ -5,3 +5,9 @@ set(CMAKE_CXX_STANDARD 14)
add_executable(MIRCertificationManager main.cpp utils/RedisUtil.cpp)
target_link_libraries(MIRCertificationManager hiredis)
add_executable(installCertificate installCertificate.cpp
utils/FileUtils.cpp
utils/RedisUtil.cpp
utils/NDNCertificationUtil.cpp)
target_link_libraries(installCertificate ndn-cxx boost_system hiredis)
+22
View File
@@ -0,0 +1,22 @@
//
// Created by mingj on 2020/5/30.
//
#include "utils/RedisUtil.h"
#include "utils/FileUtils.h"
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
if (argc < 3) {
cout << "Usage : ./installCert -f <filename> " << endl;
}
// 读取文件里的证书为字符串
string certStr = FileUtils::readFile2String(argv[2]);
cout << "Read cert: " << endl << certStr << endl;
RedisUtil redisUtil;
}
+14
View File
@@ -0,0 +1,14 @@
//
// Created by mingj on 2020/5/30.
//
#include "FileUtils.h"
#include <fstream>
#include <sstream>
std::string FileUtils::readFile2String(const std::string &filename) {
std::ifstream ifile(filename);
std::stringstream ss;
ss << ifile.rdbuf();
return ss.str();
}
+16
View File
@@ -0,0 +1,16 @@
//
// Created by mingj on 2020/5/30.
//
#ifndef MIRCERTIFICATIONMANAGER_FILEUTILS_H
#define MIRCERTIFICATIONMANAGER_FILEUTILS_H
#include <string>
class FileUtils {
public:
static std::string readFile2String(const std::string &filename);
};
#endif //MIRCERTIFICATIONMANAGER_FILEUTILS_H
+147
View File
@@ -0,0 +1,147 @@
//
// Created by mingj on 2020/5/30.
//
#include "NDNCertificationUtil.h"
/**
* 验证一个包含证书的字符串是不是一个合法的NDN证书
* @param certStr
* @return true => certStr是一个合法的NDN证书字符串
* false => certStr不是一个合法的NDN证书字符串
*/
bool NDNCertificationUtil::isValidBlock(const std::string &certStr) {
namespace t = ndn::security::transform;
try {
ndn::OBufferStream os;
std::istringstream is(certStr);
t::streamSource(is) >> t::stripSpace("\n") >> t::base64Decode(false)
>> t::streamSink(os);
ndn::Block b(os.buf());
} catch (...) {
return false;
}
return true;
}
/**
* 连接到redis server
* @param host ip
* @param port 端口
* @return
*/
bool NDNCertificationUtil::connect(const std::string &host, int port) {
return redisUtil.connect(host, port);
}
/**
* 安装证书操作
* 1. 传入一个NDN生成的证书base64编码后的字符串;
* 2. 首先会验证是否是一个格式正确的证书;
* 3. 尝试将证书的信息存到redis中
* @param certStr NDN生成的证书base64编码后的字符串
* @param forceUpdate 强制更新(如果指定强制更新,则证书已经存在的情况下会覆盖旧的记录)
* @return 0 -> 成功
* -1 -> 证书无效
* -2 -> 已经存在
*/
int NDNCertificationUtil::installCert(const std::string &certStr, bool forceUpdate) {
// 首先验证证书是否有效
if (!isValidBlock(certStr))
return -1;
// 接着构造证书
std::stringstream ss(certStr);
ndn::security::v2::Certificate cert =
*(ndn::io::load<ndn::security::v2::Certificate>(ss));
if (!forceUpdate && redisUtil.exist(cert.getName().toUri()) > 0) {
return -2;
}
return redisUtil.set(cert.getName().toUri(), certStr) == 0;
}
/**
* 卸载证书操作
* 1. 传入一个NDN生成的证书base64编码后的字符串;
* 2. 首先会验证是否是一个格式正确的证书;
* 3. 尝试根据证书中的Name字段查询redis,并移除
* @param certStr NDN生成的证书base64编码后的字符串
* @return >=0 -> 成功,其值表示redis中受影响的条目
* -1 -> 证书无效
* -2 -> 没有对应的条目
*/
int NDNCertificationUtil::uninstallCert(const std::string &certStr) {
// 首先验证证书是否有效
if (!isValidBlock(certStr))
return -1;
// 接着构造证书
std::stringstream ss(certStr);
ndn::security::v2::Certificate cert =
*(ndn::io::load<ndn::security::v2::Certificate>(ss));
return redisUtil.del(cert.getName().toUri());
}
/**
* 根据keyName查询redis,得到对应的证书字符串
* @param keyName
* @return
* 如果key对应的条目存在,则返回条目对应的值
* 如果key对应的条目不存在,则会返回空字符串(所以如果要判定当前key对应的条目是否存在,则可以调用 RedisUtil::exists )
*/
std::string NDNCertificationUtil::getCertStrByKeyName(const std::string &keyName) {
return redisUtil.get(keyName);
}
/**
* 验证兴趣包签名是否有效
* @param interest
* @return
*/
bool NDNCertificationUtil::verifyInterest(const ndn::Interest &interest) {
// 首先提取兴趣包的签名信息
std::string keyLocatorStr;
try {
ndn::SignatureInfo signInfo(interest.getName()[ndn::signed_interest::POS_SIG_INFO].blockFromValue());
//SignatureInfo signInfo(interest.getName[-2]
keyLocatorStr = signInfo.getKeyLocator().getName().toUri();
} catch (...) {
return false;
}
// 接着从redis中取出对应的证书,如果有的话
std::string certStr = this->getCertStrByKeyName(keyLocatorStr);
if (certStr.size() <= 10) return false;
// 接着用证书验证兴趣包的签名
std::stringstream ss(certStr);
ndn::security::v2::Certificate cert =
*(ndn::io::load<ndn::security::v2::Certificate>(ss));
auto result = ndn::security::verifySignature(interest, cert);
return result;
}
/**
* 验证数据包签名是否有效
* @param data
* @return
*/
bool NDNCertificationUtil::verifyData(const ndn::Data &data) {
// 首先提取数据包的签名信息
std::string keyLocatorStr;
try {
keyLocatorStr = data.getSignature().getKeyLocator().getName().toUri();
} catch (...) {
return false;
}
// 接着从redis中取出对应的证书,如果有的话
std::string certStr = this->getCertStrByKeyName(keyLocatorStr);
if (certStr.size() <= 10) return false;
// 接着用证书验证兴趣包的签名
std::stringstream ss(certStr);
ndn::security::v2::Certificate cert =
*(ndn::io::load<ndn::security::v2::Certificate>(ss));
auto result = ndn::security::verifySignature(data, cert);
return result;
}
+90
View File
@@ -0,0 +1,90 @@
//
// Created by mingj on 2020/5/30.
//
#ifndef MIRCERTIFICATIONMANAGER_NDNCERTIFICATIONUTIL_H
#define MIRCERTIFICATIONMANAGER_NDNCERTIFICATIONUTIL_H
#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/verification-helpers.hpp>
#include <ndn-cxx/security/transform.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/data.hpp>
#include <string>
#include "RedisUtil.h"
/**
* NDN证书相关的工具函数
*/
class NDNCertificationUtil {
public:
/**
* 验证一个包含证书的字符串是不是一个合法的NDN证书
* @param certStr
* @return true => certStr是一个合法的NDN证书字符串
* false => certStr不是一个合法的NDN证书字符串
*/
static bool isValidBlock(const std::string &certStr);
/**
* 连接到redis server
* @param host ip
* @param port 端口
* @return
*/
bool connect(const std::string &host, int port);
/**
* 安装证书操作
* 1. 传入一个NDN生成的证书base64编码后的字符串;
* 2. 首先会验证是否是一个格式正确的证书;
* 3. 尝试将证书的信息存到redis中
* @param certStr NDN生成的证书base64编码后的字符串
* @param forceUpdate 强制更新(如果指定强制更新,则证书已经存在的情况下会覆盖旧的记录)
* @return 0 -> 成功
* -1 -> 证书无效
* -2 -> 已经存在
*/
int installCert(const std::string &certStr, bool forceUpdate = false);
/**
* 卸载证书操作
* 1. 传入一个NDN生成的证书base64编码后的字符串;
* 2. 首先会验证是否是一个格式正确的证书;
* 3. 尝试根据证书中的Name字段查询redis,并移除
* @param certStr NDN生成的证书base64编码后的字符串
* @return >=0 -> 成功,其值表示redis中受影响的条目
* -1 -> 证书无效
* -2 -> 没有对应的条目
*/
int uninstallCert(const std::string &certStr);
/**
* 根据keyName查询redis,得到对应的证书字符串
* @param keyName
* @return
*/
std::string getCertStrByKeyName(const std::string &keyName);
/**
* 验证兴趣包签名是否有效
* @param interest
* @return
*/
bool verifyInterest(const ndn::Interest &interest);
/**
* 验证数据包签名是否有效
* @param data
* @return
*/
bool verifyData(const ndn::Data &data);
private:
RedisUtil redisUtil;
};
#endif //MIRCERTIFICATIONMANAGER_NDNCERTIFICATIONUTIL_H