远程证明(鲲鹏安全库)

介绍

本项目开发运行在鲲鹏处理器上的基础安全软件组件,前期主要聚焦在远程证明等可信计算相关领域,使能社区安全开发者。

软件架构

在未使能TEE的平台上,本项目可提供平台远程证明特性,其软件架构如下图所示:

img

在已使能TEE的平台上,本项目可提供TEE远程证明特性,其软件架构如下图所示:

img

安装配置

  1. 使用yum安装程序的rpm包,命令如下:

    shell
    # yum install kunpengsecl-ras kunpengsecl-rac kunpengsecl-rahub kunpengsecl-qcaserver kunpengsecl-attester kunpengsecl-tas kunpengsecl-devel
  2. 准备数据库环境:进入 /usr/share/attestation/ras 目录,执行 prepare-database-env.sh 脚本进行自动化的数据库环境配置。

  3. 程序运行时依赖的配置文件有三个路径,分别为:当前路径 ./config.yaml ,家路径 ${HOME}/.config/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml ,以及系统路径 /etc/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas)/config.yaml

  4. (可选)如果需要创建家目录配置文件,可在安装好rpm包后,执行位于 /usr/share/attestation/ras(rac)(rahub)(qcaserver)(attester)(tas) 下的脚本 prepare-ras(rac)(hub)(qca)(attester)(tas)conf-env.sh 从而完成家目录配置文件的部署。

相关参数

RAS启动参数

命令行输入 ras 即可启动RAS程序。请注意,在当前目录下需要提供ECDSA公钥并命名为 ecdsakey.pub 。相关参数如下:

shell
  -H  --https         http/https模式开关,默认为https(true)false=http
  -h  --hport         https模式下RAS监听的restful api端口
  -p, --port string   RAS监听的client api端口
  -r, --rest string   http模式下RAS监听的restful api端口
  -T, --token         生成一个测试用的验证码并退出
  -v, --verbose       打印更详细的RAS运行时日志信息
  -V, --version       打印RAS版本并退出

RAC启动参数

命令行输入 sudo raagent 即可启动RAC程序,请注意,物理TPM模块的开启需要sudo权限。相关参数如下:

shell
  -s, --server string   指定待连接的RAS服务端口
  -t, --test            以测试模式启动
  -v, --verbose         打印更详细的RAC运行时日志信息
  -V, --version         打印RAC版本并退出
  -i, --imalog          指定ima文件路径
  -b, --bioslog         指定bios文件路径
  -T, --tatest          以TA测试模式启动

注意:

1.若要使用TEE远程证明特性,需要以非TA测试模式启动RAC,并将待证明TA的uuid、是否使用TCB、mem_hash和img_hash按序放入RAC执行路径下的talist文件内。同时预装由TEE团队提供的libqca.so库和libteec.so库。talist文件格式如下:

text
e08f7eca-e875-440e-9ab0-5f381136c600 false ccd5160c6461e19214c0d8787281a1e3c4048850352abe45ce86e12dd3df9fde 46d5019b0a7ffbb87ad71ea629ebd6f568140c95d7b452011acfa2f9daf61c7a

2.若不使用TEE远程证明特性,则需要将 ${DESTDIR}/usr/share/attestation/qcaserver 目录下的libqca.so库和libteec.so库复制到 /usr/lib/usr/lib64 目录,并以TA测试模式启动RAC。

QCA启动参数

命令行输入 ${DESTDIR}/usr/bin/qcaserver 即可启动QCA程序,请注意,这里必须要使用qcaserver的完整路径以正常启动QTA,同时需要使QTA中的CA路径参数与该路径保持相同。相关参数如下:

shell
  -C, --scenario int    设置程序的应用场景,默认为no_as场景(0),1=as_no_daa场景,2=as_with_daa场景
  -S, --server string   指定开放的服务器地址/端口

ATTESTER启动参数

命令行输入 attester 即可启动ATTESTER程序。相关参数如下:

shell
  -B, --basevalue string   设置基准值文件读取路径
  -M, --mspolicy int       设置度量策略,默认为-1,需要手动指定。1=仅比对img-hash值,2=仅比对hash值,3=同时比对img-hash和hash两个值
  -S, --server string      指定待连接的服务器地址
  -U, --uuid int           指定待验证的可信应用
  -V, --version            打印程序版本并退出
  -T, --test               读取固定的nonce值以匹配目前硬编码的可信报告

TAS启动参数

命令行输入 tas 即可启动TAS程序。相关参数如下:

shell
  -T, --token         生成一个测试用的验证码并退出

注意:

1.若要启用TAS服务,需要先为TAS配置好私钥。可以按如下命令修改家目录下的配置文件:

shell
# cd ${HOME}/.config/attestation/tas
# vim config.yaml
# 如下DAA_GRP_KEY_SK_X和DAA_GRP_KEY_SK_Y的值仅用于测试,正常使用前请务必更新其内容以保证安全。
tasconfig:
 port: 127.0.0.1:40008
 rest: 127.0.0.1:40009
 akskeycertfile: ./ascert.crt
 aksprivkeyfile: ./aspriv.key
 huaweiitcafile: ./Huawei IT Product CA.pem
 DAA_GRP_KEY_SK_X: 65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c65a9bf91ac8832379ff04dd2c6def16d48a56be244f6e19274e97881a776543c
 DAA_GRP_KEY_SK_Y: 126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56126f74258bb0ceca2ae7522c51825f980549ec1ef24f81d189d17e38f1773b56

之后再输入tas启动TAS程序。

2.在有TAS环境中,为提高QCA配置证书的效率,并非每一次启动都需要访问TAS以生成相应证书,而是通过证书的本地化存储,即读取QCA侧 config.yaml 中配置的证书路径,通过 func hasAKCert(s int) bool 函数检查是否已有TAS签发的证书保存于本地,若成功读取证书,则无需访问TAS,若读取证书失败,则需要访问TAS,并将TAS返回的证书保存于本地。

接口定义

RAS接口

为了便于管理员对目标服务器、RAS以及目标服务器上部署的TEE中的用户 TA 进行管理,本程序设计了以下接口可供调用:

接口方法
/GET
/GET、POST、DELETE
/{from}/GET
/{id}/reportsGET
/{id}/reports/GET、DELETE
/{id}/basevaluesGET
/{id}/newbasevaluePOST
/{id}/basevalues/GET、POST、DELETE
/{id}/ta/{tauuid}/statusGET
/{id}/ta/{tauuid}/tabasevaluesGET
/{id}/ta/{tauuid}/tabasevalues/GET、POST、DELETE
/{id}/ta/{tauuid}/newtabasevaluePOST
/{id}/ta/{tauuid}/tareportsGET
/{id}/ta/{tauuid}/tareports/GET、POST、DELETE
/{id}/basevalues/GET、DELETE
/versionGET
/configGET、POST
/{id}/container/statusGET
/{id}/device/statusGET

上述接口的具体用法分别介绍如下。

若需要查询所有服务器的信息,可以使用"/"接口。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/

若需要查询目标服务器的详细信息,可以使用"/{id}"接口的GET方法,其中{id}是RAS为目标服务器分配的唯一标识号。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1

若需要修改目标服务器的信息,可以使用"/{id}"接口的POST方法,其中$AUTHTOKEN是事先使用ras -T自动生成的身份验证码。

go
type clientInfo struct {
 Registered   *bool `json:"registered"`  // 目标服务器注册状态
 IsAutoUpdate *bool `json:"isautoupdate"`// 目标服务器基准值更新策略
}
shell
# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1 -d '{"registered":false, "isautoupdate":false}'

若需要删除目标服务器,可以使用"/{id}"接口的DELETE方法。
注意:

使用该方法并非删除目标服务器的所有信息,而是把目标服务器的注册状态置为false

shell
# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1

若需要查询指定范围内的所有服务器信息,可以使用"/{from}/{to}"接口的GET方法。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/9

若需要查询目标服务器的所有可信报告,可以使用"/{id}/reports"接口的GET方法。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports

若需要查询目标服务器指定可信报告的详细信息,可以使用"/{id}/reports/{reportid}"接口的GET方法,其中{reportid}是RAS为目标服务器指定可信报告分配的唯一标识号。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/reports/1

若需要删除目标服务器指定可信报告,可以使用"/{id}/reports/{reportid}"接口的DELETE方法。
注意:

使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询!

shell
# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/reports/1

若需要查询目标服务器的所有基准值,可以使用"/{id}/basevalues"接口的GET方法。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues

若需要给目标服务器新增一条基准值信息,可以使用"/{id}/newbasevalue"接口的POST方法。

go
type baseValueJson struct {
 BaseType   string `json:"basetype"`   // 基准值类型
 Uuid       string `json:"uuid"`       // 容器或设备的标识号
 Name       string `json:"name"`       // 基准值名称
 Enabled    bool   `json:"enabled"`    // 基准值是否可用
 Pcr        string `json:"pcr"`        // PCR值
 Bios       string `json:"bios"`       // BIOS值
 Ima        string `json:"ima"`        // IMA值
 IsNewGroup bool   `json:"isnewgroup"` // 是否为一组新的基准值
}
shell
# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/newbasevalue -d '{"name":"test", "basetype":"host", "enabled":true, "pcr":"testpcr", "bios":"testbios", "ima":"testima", "isnewgroup":true}'

若需要查询目标服务器指定基准值的详细信息,可以使用"/{id}/basevalues/{basevalueid}"接口的GET方法,其中{basevalueid}是RAS为目标服务器指定基准值分配的唯一标识号。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1

若需要修改目标服务器指定基准值的可用状态,可以使用"/{id}/basevalues/{basevalueid}"接口的POST方法。

shell
# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/basevalues/1 -d '{"enabled":true}'

若需要删除目标服务器指定基准值,可以使用"/{id}/basevalues/{basevalueid}"接口的DELETE方法。
注意:

使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询!

shell
# curl -X DELETE -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/1/basevalues/1

若需要查询目标服务器上特定用户 TA 的可信状态,可以使用"/{id}/ta/{tauuid}/status"接口的GET方法。其中{id}是RAS为目标服务器分配的唯一标识号,{tauuid}是特定用户 TA 的身份标识号。

shell
# curl -X GET -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40002/1/ta/test/status

若需要查询目标服务器上特定用户 TA 的所有基准值信息,可以使用"/{id}/ta/{tauuid}/tabasevalues"接口的GET方法。

shell
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues

若需要查询目标服务器上特定用户 TA 的指定基准值的详细信息,可以使用"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"接口的GET方法。其中{tabasevalueid}是RAS为目标服务器上特定用户 TA 的指定基准值分配的唯一标识号。

shell
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tabasevalues/1

若需要修改目标服务器上特定用户 TA 的指定基准值的可用状态,可以使用"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"接口的POST方法。

shell
# curl -X POST -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN"  http://localhost:40002/1/ta/test/tabasevalues/1 --data '{"enabled":true}'

若需要删除目标服务器上特定用户 TA 的指定基准值,可以使用"/{id}/ta/{tauuid}/tabasevalues/{tabasevalueid}"接口的DELETE方法。
注意:

使用该方法将删除指定基准值的所有信息,将无法再通过接口对该基准值进行查询!

shell
# curl -X DELETE -H "Content-type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/tabasevalues/1

若需要给目标服务器上特定用户 TA 新增一条基准值信息,可以使用"/{id}/ta/{tauuid}/newtabasevalue"接口的POST方法。

go
type tabaseValueJson struct {
 Uuid      string `json:"uuid"`       // 用户 TA 的标识号
 Name      string `json:"name"`       // 基准值名称
 Enabled   bool   `json:"enabled"`    // 基准值是否可用
 Valueinfo string `json:"valueinfo"`  // 镜像哈希值和内存哈希值
}
shell
# curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" -k http://localhost:40002/1/ta/test/newtabasevalue -d '{"uuid":"test", "name":"testname", "enabled":true, "valueinfo":"test info"}'

若需要查询目标服务器上特定用户 TA 的所有可信报告,可以使用"/{id}/ta/{tauuid}/tareports"接口的GET方法。

shell
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports

若需要查询目标服务器上特定用户 TA 的指定可信报告的详细信息,可以使用"/{id}/ta/{tauuid}/tareports/{tareportid}"接口的GET方法,其中{tareportid}是RAS为目标服务器上特定用户 TA 的指定可信报告分配的唯一标识号。

shell
# curl -X GET -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2

若需要删除目标服务器上特定用户 TA 的指定可信报告,可以使用"/{id}/ta/{tauuid}/tareports/{tareportid}"接口的DELETE方法。
注意:

使用该方法将删除指定可信报告的所有信息,将无法再通过接口对该报告进行查询!

shell
# curl -X DELETE -H "Content-type: application/json" http://localhost:40002/1/ta/test/tareports/2

若需要获取本程序的版本信息,可以使用"/version"接口的GET方法。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/version

若需要查询目标服务器/RAS/数据库的配置信息,可以使用"/config"接口的GET方法。

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40002/config

若需要修改目标服务器/RAS/数据库的配置信息,可以使用"/config"接口的POST方法。

go
type cfgRecord struct {
  // 目标服务器配置
    HBDuration      string `json:"hbduration" form:"hbduration"`
    TrustDuration   string `json:"trustduration" form:"trustduration"`
    DigestAlgorithm string `json:"digestalgorithm" form:"digestalgorithm"`
  // RAS配置
    MgrStrategy     string `json:"mgrstrategy" form:"mgrstrategy"`
    ExtractRules    string `json:"extractrules" form:"extractrules"`
    IsAllupdate     *bool  `json:"isallupdate" form:"isallupdate"`
    LogTestMode     *bool  `json:"logtestmode" form:"logtestmode"`
}
shell
# curl -X POST -H "Authorization: $AUTHTOKEN" -H "Content-Type: application/json" http://localhost:40002/config -d '{"hbduration":"5s","trustduration":"20s","DigestAlgorithm":"sha256"}'

TAS接口

为了便于管理员对TAS服务的远程控制,本程序设计了以下接口可供调用:

接口方法
/configGET、POST

若需要查询TAS的配置信息,可使用"/config"接口的GET方法:

shell
# curl -X GET -H "Content-Type: application/json" http://localhost:40009/config

若需要修改TAS的配置信息,可使用"/config"接口的POST方法:

shell
curl -X POST -H "Content-Type: application/json" -H "Authorization: $AUTHTOKEN" http://localhost:40009/config -d '{"basevalue":"testvalue"}'

注意:

TAS的配置信息读取与修改目前仅支持基准值

FAQ

  1. RAS安装后,为什么无法启动?

    因为在当前RAS的设计逻辑中,程序启动后需要从当前目录查找一份名为 ecdsakey.pub 的文件进行读取并作为之后访问该程序的身份验证码,若当前目录没有该文件,则RAS启动会报错。

    解决方法一:运行 ras -T 生成测试用token后会生成 ecdsakey.pub 。 解决方法二:自行部署oauth2认证服务后,将对应JWT token生成方对应的验证公钥保存为 ecdsakey.pub

  2. 为什么RAS启动后,通过restapi无法访问?

    因为RAS默认以https模式启动,您需要向RAS提供合法的证书才能正常访问,而http模式下启动的RAS则不需要提供证书。