我们有一个C / C ++项目,我们希望加密(使用GPG)每个源文件,并使make(特别是GNU Make)无缝工作(就像现在使用未加密的源一样)。
如果我们只加密C或C ++文件,使用这样的规则似乎很容易实现:
%.o : %.cc.gpg %.hh
$(GPG) --decrypt $< | $(CXX) $(CFLAGS) -x c++ -c -o $@ -
但是,如果我们开始加密头文件,它会变得更加棘手,因为C文件可能#include任意数量的头文件。所以在我看来,首先我需要生成一个依赖列表,然后解密每一个加密的,并编译。理想情况下,解密将在内存中完成,而不是在编译时留下解密文件。
有些说明,期待我得到的评论:
答案 0 :(得分:1)
您有两个问题:1)在构建过程中解密文件,2)将明文保存在RAM中。第二个是我的领域;我建议使用带有夜间光盘擦洗功能的气隙工作站和非常好的审核系统,任何指出安全漏洞的人都会获得奖励,而不是受到惩罚。无论如何,让我们假设你已经解决了这个问题。 (此时你可以解密整个代码库并正常工作,但让我们试着找到更严格的解决方案。)
对于解密,你已经到了一半。我没有在%.o
规则中解密,而是将其分解为单独的规则:
%.cc : %.cc.gpg
$(GPG) --decrypt $<
%.o : %.cc %.hh
$(CXX) $(CFLAGS) -x c++ -c -o $@ -
现在如你所说,你所要做的就是生成依赖列表。然后,您可以扩展第一条规则以涵盖加密的标题,您就是黄金。
如果您正在使用像g ++这样的文明编译器,您可以(通常)使用g++ -M
生成依赖关系列表,并使用它来编写“智能”%.o
规则,例如描述{ {3}},它将自动和无形地处理所有依赖问题。
问题在于你最初不能使用g++ -M
,因为你处于一个粘稠的圈子里:你不想解密所有的标题,只需要你需要的标题,所以你可以直到你知道你需要哪些头文件才进行解密,但是在生成依赖文件之前你不会知道这一点,这意味着运行g ++,但是g ++会抛出一个错误并在没有所需的头文件时退出。
所以我们会作弊。假设我们有一个单独的目录,其中包含与真实头文件同名的空头文件(使用Make进行构建/维护很简单)。我们可以指示g ++(和Make)查找它在通常位置找不到的任何头文件。这还不足以实际编译对象,但 足以运行g++ -M
而没有错误。它构造的依赖列表将是不完整的(因为真正的头可能彼此#include
)但是第一次迭代足够。 Make可以解密那些标题,然后重新开始;当g++ -M
的结果与上一次迭代的列表相同时,该过程完成,所有需要的标题都已解密,编译可以开始。
这个轮廓是否足够,或者你需要螺母和螺栓的帮助?