1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

set -e
set -u
set -o pipefail

VERBOSE="${SELFTESTS_VERBOSE:=0}"
LOG_FILE="$(mktemp /tmp/verify_sig_setup.log.XXXXXX)"

x509_genkey_content="\
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts

[ req_distinguished_name ]
CN = eBPF Signature Verification Testing Key

[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
"

usage()
{
	echo "Usage: $0 <setup|cleanup <existing_tmp_dir>"
	exit 1
}

setup()
{
	local tmp_dir="$1"

	echo "${x509_genkey_content}" > ${tmp_dir}/x509.genkey

	openssl req -new -nodes -utf8 -sha256 -days 36500 \
			-batch -x509 -config ${tmp_dir}/x509.genkey \
			-outform PEM -out ${tmp_dir}/signing_key.pem \
			-keyout ${tmp_dir}/signing_key.pem 2>&1

	openssl x509 -in ${tmp_dir}/signing_key.pem -out \
		${tmp_dir}/signing_key.der -outform der

	key_id=$(cat ${tmp_dir}/signing_key.der | keyctl padd asymmetric ebpf_testing_key @s)

	keyring_id=$(keyctl newring ebpf_testing_keyring @s)
	keyctl link $key_id $keyring_id
}

cleanup() {
	local tmp_dir="$1"

	keyctl unlink $(keyctl search @s asymmetric ebpf_testing_key) @s
	keyctl unlink $(keyctl search @s keyring ebpf_testing_keyring) @s
	rm -rf ${tmp_dir}
}

fsverity_create_sign_file() {
	local tmp_dir="$1"

	data_file=${tmp_dir}/data-file
	sig_file=${tmp_dir}/sig-file
	dd if=/dev/urandom of=$data_file bs=1 count=12345 2> /dev/null
	fsverity sign --key ${tmp_dir}/signing_key.pem $data_file $sig_file

	# We do not want to enable fsverity on $data_file yet. Try whether
	# the file system support fsverity on a different file.
	touch ${tmp_dir}/tmp-file
	fsverity enable ${tmp_dir}/tmp-file
}

fsverity_enable_file() {
	local tmp_dir="$1"

	data_file=${tmp_dir}/data-file
	fsverity enable $data_file
}

catch()
{
	local exit_code="$1"
	local log_file="$2"

	if [[ "${exit_code}" -ne 0 ]]; then
		cat "${log_file}" >&3
	fi

	rm -f "${log_file}"
	exit ${exit_code}
}

main()
{
	[[ $# -ne 2 ]] && usage

	local action="$1"
	local tmp_dir="$2"

	[[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1

	if [[ "${action}" == "setup" ]]; then
		setup "${tmp_dir}"
	elif [[ "${action}" == "cleanup" ]]; then
		cleanup "${tmp_dir}"
	elif [[ "${action}" == "fsverity-create-sign" ]]; then
		fsverity_create_sign_file "${tmp_dir}"
	elif [[ "${action}" == "fsverity-enable" ]]; then
		fsverity_enable_file "${tmp_dir}"
	else
		echo "Unknown action: ${action}"
		exit 1
	fi
}

trap 'catch "$?" "${LOG_FILE}"' EXIT

if [[ "${VERBOSE}" -eq 0 ]]; then
	# Save the stderr to 3 so that we can output back to
	# it incase of an error.
	exec 3>&2 1>"${LOG_FILE}" 2>&1
fi

main "$@"
rm -f "${LOG_FILE}"
无论今后遇到什么事情,都请不要后悔与我的相遇