Skip to content

Commit

Permalink
Add more tests and measure coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
ctz committed Jul 19, 2017
1 parent 3cd6369 commit 8fba4e3
Show file tree
Hide file tree
Showing 29 changed files with 141 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
Cargo.lock
target/
*.gcda
*.gcno
*.info
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ sudo: required
env:
global:
# TODO Update this to match the name of your project.
- CRATE_NAME=trust
- CRATE_NAME=sct

matrix:
# TODO These are all the build jobs. Adjust as necessary. Comment out what you
Expand Down
63 changes: 63 additions & 0 deletions admin/coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python

import os
import glob
import subprocess

LLVM_PATH = glob.glob('/usr/lib/llvm-3.8/lib/clang/3.8.[0-9]/lib/linux/')[0]
COVERAGE_OPTIONS = '-Ccodegen-units=1 -Clink-dead-code -Cpasses=insert-gcov-profiling -Zno-landing-pads -L%s -lclang_rt.profile-x86_64' % LLVM_PATH
LCOVOPTS = '--gcov-tool ./admin/llvm-gcov --rc lcov_branch_coverage=1 --rc lcov_excl_line=assert'.split()

def lcov_exe(*args):
return ['lcov'] + LCOVOPTS + list(args)

def sh(cmd):
subprocess.check_call(cmd, shell = True)

def cleanup():
sh('cargo clean')
sh("rm -rf *.gcda *.gcno")

def run(which):
exe = filter(lambda x: '.d' not in x, glob.glob('target/debug/' + which + '-*'))[0]
sh('./' + exe)

def rustc(*args):
exe = ['cargo', 'rustc', '--all-features'] + list(args)
env = dict(os.environ)
env.update(RUSTC_WRAPPER = './admin/coverage-rustc',
COVERAGE_OPTIONS = COVERAGE_OPTIONS)
subprocess.check_call(exe, env = env)

def lcov(outfile):
exe = lcov_exe('--capture', '--directory', '.', '--base-directory', '.', '-o', outfile)
subprocess.check_call(exe)
return outfile

def merge(outfile, infiles):
arg = []
for i in infiles:
arg.append('--add')
arg.append(i)
arg.append('-o')
arg.append(outfile)
subprocess.check_call(lcov_exe(*arg))

def extract(outfile, infile):
subprocess.check_call(lcov_exe('--extract', infile, os.getcwd() + '/src/*', '-o', outfile))

def genhtml(outdir, infile):
subprocess.check_call(['genhtml', '--branch-coverage', '--demangle-cpp', '--legend',
infile, '-o', outdir, '--ignore-errors', 'source'])

all_infos = []

# unit tests
cleanup()
rustc('--profile', 'test', '--lib')
run('sct')
all_infos.append(lcov('sct.info'))

merge('coverage.info', all_infos)
extract('final.info', 'coverage.info')
genhtml('target/coverage/', 'final.info')
25 changes: 25 additions & 0 deletions admin/coverage-rustc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash -e

get_crate_name()
{
while [[ $# -gt 1 ]] ; do
v=$1
case $v in
--crate-name)
echo $2
return
;;
esac
shift
done
}

case $(get_crate_name "$@") in
sct)
EXTRA=$COVERAGE_OPTIONS
;;
*)
;;
esac

exec "$@" $EXTRA
2 changes: 2 additions & 0 deletions admin/llvm-gcov
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh -e
llvm-cov gcov $*
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ fn write_u16(v: u16, out: &mut Vec<u8>) {
out.push(v as u8);
}

#[derive(Debug)]
struct SCT<'a> {
log_id: &'a [u8],
timestamp: u64,
Expand Down Expand Up @@ -261,3 +260,5 @@ pub fn verify_sct(cert: &[u8],
mod tests_google;
#[cfg(test)]
mod tests_generated;
#[cfg(test)]
mod tests;
Binary file added src/testdata/ecdsa_p256-badsigalg-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-basic-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-future-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-junk-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-short-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-version-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-wrongcert-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-wrongext-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-wrongid-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p256-wrongtime-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p384-basic-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p384-wrongcert-sct.bin
Binary file not shown.
Binary file modified src/testdata/ecdsa_p384-wrongtime-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa3072-basic-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa3072-wrongcert-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa3072-wrongtime-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa4096-basic-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa4096-wrongcert-sct.bin
Binary file not shown.
Binary file modified src/testdata/rsa4096-wrongtime-sct.bin
Binary file not shown.
18 changes: 18 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use super::Error;

#[test]
fn test_unknown_log_is_not_fatal() {
assert_eq!(false, Error::UnknownLog.should_be_fatal());
}

#[test]
fn test_unknown_sct_version_is_not_fatal() {
assert_eq!(false, Error::UnsupportedSCTVersion.should_be_fatal());
}

#[test]
fn test_other_errors_are_fatal() {
assert_eq!(true, Error::MalformedSCT.should_be_fatal());
assert_eq!(true, Error::InvalidSignature.should_be_fatal());
assert_eq!(true, Error::TimestampInFuture.should_be_fatal());
}
13 changes: 12 additions & 1 deletion src/tests_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,25 @@ pub fn ecdsa_p256_wrongext() {
verify_sct(cert, sct, now, &logs));
}

#[test]
pub fn ecdsa_p256_badsigalg() {
let sct = include_bytes!("testdata/ecdsa_p256-badsigalg-sct.bin");
let cert = b"cert";
let logs = [&TEST_LOG_ECDSA_P256];
let now = 1235;

assert_eq!(Err(Error::InvalidSignature),
verify_sct(cert, sct, now, &logs));
}

#[test]
pub fn ecdsa_p256_short() {
let sct = include_bytes!("testdata/ecdsa_p256-short-sct.bin");
let cert = b"cert";
let logs = [&TEST_LOG_ECDSA_P256];
let now = 1234;

for l in 0..118 {
for l in 0..121 {
assert_eq!(Err(Error::MalformedSCT),
verify_sct(cert, &sct[..l], now, &logs));
}
Expand Down
2 changes: 2 additions & 0 deletions src/tests_google.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn test_google_sct0() {
let cert = include_bytes!("testdata/google-cert.bin");
let logs = [&GOOGLE_PILOT, &SYMANTEC_LOG];
let now = 1499619463644;
println!("Logs: {:?}", logs);

assert_eq!(0,
verify_sct(cert, sct, now, &logs)
Expand All @@ -36,6 +37,7 @@ fn test_google_sct1() {
let cert = include_bytes!("testdata/google-cert.bin");
let logs = [&GOOGLE_PILOT, &SYMANTEC_LOG];
let now = 1499619463644;
println!("Logs: {:?}", logs);

assert_eq!(1,
verify_sct(cert, sct, now, &logs)
Expand Down
16 changes: 13 additions & 3 deletions test/mktest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
SIGALG_ECDSA_SHA256 = 0x0403
SIGALG_ECDSA_SHA384 = 0x0503
SIGALG_RSA_SHA256 = 0x0401
SIGALG_RSA_SHA384 = 0x0501

SIGALG_HASH = {
SIGALG_RSA_SHA256: 'sha256',
SIGALG_RSA_SHA384: 'sha384',
SIGALG_ECDSA_SHA256: 'sha256',
SIGALG_ECDSA_SHA384: 'sha384',
}
Expand Down Expand Up @@ -118,8 +120,8 @@ def format_bytes(b):

algs = dict(
rsa2048 = SIGALG_RSA_SHA256,
rsa3072 = SIGALG_RSA_SHA256,
rsa4096 = SIGALG_RSA_SHA256,
rsa3072 = SIGALG_RSA_SHA384,
rsa4096 = SIGALG_RSA_SHA384,
ecdsa_p256 = SIGALG_ECDSA_SHA256,
ecdsa_p384 = SIGALG_ECDSA_SHA384
)
Expand Down Expand Up @@ -223,6 +225,14 @@ def emit_short_test(keyname, sctname, encoding, expect):
emit_test(name, 'wrongext',
sct.having(exts = '\x00\x01A').encode(),
expect = 'Err(Error::InvalidSignature)')
emit_test(name, 'badsigalg',
sct.having(sig = '\x01\x02' + sct.sig[2:]).encode(),
expect = 'Err(Error::InvalidSignature)')

# emit length test with extension, so we test length handling
sct_short = sct.having(exts = '\x00\x02AB')
sct_short.sign(priv, algs[name], 'cert')

emit_short_test(name, 'short',
sct.encode(),
sct_short.encode(),
expect = 'Err(Error::MalformedSCT)')

0 comments on commit 8fba4e3

Please sign in to comment.