Skip to content

Commit

Permalink
Import initial content
Browse files Browse the repository at this point in the history
Signed-off-by: Daiki Ueno <[email protected]>
Co-authored-by: Alexander Sosedkin <[email protected]>
Co-authored-by: Clemens Lang <[email protected]>
Co-authored-by: Simo Sorce <[email protected]>
  • Loading branch information
4 people committed Feb 10, 2023
1 parent 95df0e0 commit ea868ac
Show file tree
Hide file tree
Showing 28 changed files with 4,473 additions and 0 deletions.
1,641 changes: 1,641 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[workspace]

members = ["agent", "log-parser", "types"]
44 changes: 44 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2023 The crypto-auditing developers.

RELEASE ?= 0
TARGETDIR ?= target
CONFFILE ?= agent/agent.conf

ifeq ($(RELEASE),1)
PROFILE ?= release
CARGO_ARGS = --release
else
PROFILE ?= debug
CARGO_ARGS =
endif

systemdsystemunitdir := $(shell pkg-config systemd --variable=systemdsystemunitdir)

programs = \
${TARGETDIR}/${PROFILE}/crypto-auditing-agent \
${TARGETDIR}/${PROFILE}/crypto-auditing-log-parser

.PHONY: all
all: $(programs)

agent/src/bpf/vmlinux.h:
bpftool btf dump file /sys/kernel/btf/vmlinux format c > $@-t && mv $@-t $@

$(programs): agent/src/bpf/vmlinux.h
cargo build --target-dir="${TARGETDIR}" ${CARGO_ARGS}

.PHONY: install
install: all
mkdir -p /etc/crypto-auditing/
cp ${CONFFILE} /etc/crypto-auditing/agent.conf
for f in $(programs); do \
install -D -t ${DESTDIR}/usr/bin "$$f"; \
done
install -D -m 644 -t ${DESTDIR}$(systemdsystemunitdir) dist/systemd/system/crypto-auditing-agent.service

# This only runs tests without TPM access. See tests/run.sh for
# running full testsuite with swtpm.
.PHONY: check
check: all
cargo test --target-dir="${TARGETDIR}"
170 changes: 170 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# crypto-auditing

## Introduction

This project aims to create the infrastructure needed to audit crypto
operations performed by crypto libraries on a system. This is accomplished by
using BPF USDT probes to intercept specific entry points in crypto libraries,
as they are used by user space processes on the system, and collect data so that
it can be analyzed later.

The design documents can be found from the following links:

- [Objectives and high-level design](docs/objectives.md)
- [Architecture](docs/architecture.md)
- [Logging format for primary event logs](docs/logging-format.md)
- [USDT probe points](docs/probe-points.md)

## Compiling

1. Install the latest Rust toolchain
1. Install the dependencies (note that libbpf 1.1.1 or later is required)
```console
$ sudo dnf install bpftool make libbpf-devel llvm-devel rustfmt
```
1. Build the programs with `make`
```console
$ make
```

The first step requires `agent/src/bpf/vmlinux.h` to be populated. By
default it is done through BTF dump from the running kernel with
`bpftool`, but if it is not supported in your system, it is possible
to use `vmlinux.h` included in the `kernel-devel` package:

```console
$ sudo dnf install kernel-devel
$ cp $(rpm -ql kernel-devel | grep '/vmlinux.h$' | tail -1) agent/src/bpf
```

1. Install the programs with `make install` (optional)
```console
$ sudo make install
```

## Running

1. Compile the target crypto library with defined tracepoints are enabled
```console
$ git clone --depth=1 -b wip/dueno/usdt https://gitlab.com/dueno/gnutls.git
$ ./bootstrap
$ ./configure
$ make -j$(nproc)
```
2. Run the agent as root
```console
$ sudo ./target/debug/crypto-auditing-agent --library .../gnutls/lib/.libs/libgnutls.so.30.34.2
```
3. On another terminal, run any commands using the instrumented library
```console
$ ./src/gnutls-serv --x509certfile=doc/credentials/x509/cert-rsa-pss.pem --x509keyfile=doc/credentials/x509/key-rsa-pss.pem &
$ ./src/gnutls-cli --x509cafile=doc/credentials/x509/ca.pem localhost -p 5556
^C
$ ./src/gnutls-cli --x509cafile=doc/credentials/x509/ca.pem localhost -p 5556 --priority NORMAL:-VERS-TLS1.3
```

## Inspecting logs

By default, the log will be stored in `audit.cborseq` in a sequence of
CBOR objects, which can be parsed and printed as a tree with the
`log_parser` executable:
```console
$ cargo run --bin crypto-auditing-log-parser audit.cborseq
[
{
"context": "66cbb84ee07b90427845ee3d1ae087ba",
"events": {
"name": "tls::handshake_client",
"tls::ciphersuite": 4866,
"tls::protocol_version": 772
},
"map": [
[
"cc337d853f445ad282f4f2a0aec310d8",
{
"context": "cc337d853f445ad282f4f2a0aec310d8",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "2b87eeaf728e24e17ddb8de38d9a7925",
"events": {
"name": "tls::handshake_server",
"tls::ciphersuite": 4866,
"tls::protocol_version": 772
},
"map": [
[
"33650fafec0364c22fa284cbe9c5b809",
{
"context": "33650fafec0364c22fa284cbe9c5b809",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "56ef62bf96e87513e789538e9b880826",
"events": {
"name": "tls::handshake_client",
"tls::ciphersuite": 49200,
"tls::protocol_version": 771
},
"map": [
[
"7bcae3d1a6058293dd634220b266827f",
{
"context": "7bcae3d1a6058293dd634220b266827f",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
},
{
"context": "2b87eeaf728e24e17ddb8de38d9a7925",
"events": {
"name": "tls::handshake_server",
"tls::ciphersuite": 49200,
"tls::protocol_version": 771
},
"map": [
[
"0c6044428c70bc8678c5035d9a2eed37",
{
"context": "0c6044428c70bc8678c5035d9a2eed37",
"events": {
"name": "tls::certificate_verify",
"tls::signature_algorithm": 2057
}
}
]
]
}
]
```

To simply deserialize it, you can use the `cborseq2json.rb` script
from [cbor-diag](https://github.com/cabo/cbor-diag) package, which can
be installed with `gem install --user cbor-diag`.

## License

- `agent/src/bpf/audit.bpf.c`: GPL-2.0-or-later
- `agent/src/ringbuf.rs`: LGPL-2.1-only or BSD-2-Clause
- everything else: GPL-3.0-or-later

## Credits

- [libbpf-async](https://github.com/fujita/libbpf-async) for asynchronous BPF ringbuf implementation over libbpf-rs
- [rust-keylime](https://github.com/keylime/rust-keylime/) for permissions management code
28 changes: 28 additions & 0 deletions agent/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "crypto-auditing-agent"
description = "Event collector agent for crypto-auditing project"
version = "0.1.0"
edition = "2021"
license = "GPL-3.0-or-later"
authors = ["The crypto-auditing developers"]

[dependencies]
anyhow = "1.0"
bytes = "1.2"
clap = { version = "4", features=["cargo", "derive"] }
crypto-auditing-types = { path = "../types" }
futures = "0.3"
libbpf-rs = { git = "https://github.com/ueno/libbpf-rs.git", branch = "wip/usdt", features=["novendor"] }
libc = "0.2"
nix = "0.24"
openssl = "0.10"
page_size = "0.4"
serde = "1.0"
serde_cbor = "0.10"
time = { version = "0.3", features=["formatting", "local-offset", "macros"] }
tokio = { version = "1.23", features=["full"] }
tokio-uring = "0.4"
toml = "0.6"

[build-dependencies]
libbpf-cargo = { git = "https://github.com/ueno/libbpf-rs.git", branch = "wip/usdt", features=["novendor"] }
5 changes: 5 additions & 0 deletions agent/agent.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# library = ["/usr/lib64/libgnutls.so.30", "/usr/lib64/libssl.so.3"]
# log_file = /var/log/crypto-auditing/agent.log
# user = crypto-auditing-agent:crypto-auditing-agent
# coalesce_window = 100
# max_events = 1000000
17 changes: 17 additions & 0 deletions agent/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0

use libbpf_cargo::SkeletonBuilder;
use std::{env, path::PathBuf};

const SRC: &str = "src/bpf/audit.bpf.c";

fn main() {
let mut out =
PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR must be set in build script"));
out.push("audit.skel.rs");
SkeletonBuilder::new()
.source(SRC)
.build_and_generate(&out)
.unwrap();
println!("cargo:rerun-if-changed={}", SRC);
}
Loading

0 comments on commit ea868ac

Please sign in to comment.