totp

Simple cli tool for storing TOTP secrets and generating tokens
git clone https://git.inz.fi/totp/
Log | Files | Refs | Submodules

stress.sh (2185B)


      1 #!/bin/sh
      2 
      3 onexit() {
      4 	[ -n "$KEYFILE" ] && rm "$KEYFILE"
      5 	[ -n "$DBFILE" ] && rm "$DBFILE"
      6 	[ -n "$URIFILE" ] && rm "$URIFILE"
      7 	[ -n "$SEDITMP" ] && rm "$SEDITMP"
      8 }
      9 
     10 trap onexit EXIT
     11 KEYFILE="$(mktemp)"
     12 DBFILE="$(mktemp)"
     13 URIFILE="$(mktemp)"
     14 SEDITMP="$(mktemp)"
     15 
     16 sedi() {
     17 	sed "$@" >"$SEDITMP"
     18 	for last in "$@"; do :; done
     19 	cat "$SEDITMP" > "$last"
     20 }
     21 
     22 b32encode() {
     23 	od -vt u1 | awk '
     24 		BEGIN {
     25 			b32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
     26 		       	acc = 0;
     27 		       	n = 0;
     28 	       	}
     29 		{
     30 			for (i = 2; i <= NF; i++) {
     31 			       	acc = acc * 256 + $i;
     32 			       	n += 8;
     33 			       	while (n >= 5) {
     34 				       	printf("%s", substr(b32, int(acc / (2 ^ (n - 5))) + 1, 1));
     35 				       	acc %= (2 ^ (n - 5));
     36 				       	n -= 5;
     37 			       	}
     38 			}
     39 		} END {
     40 			if (n > 0)
     41 			       	printf("%s", substr(b32, acc * 2 ^ (5 - n) + 1, 1));
     42 			print "";
     43 	       	}'
     44 }
     45 
     46 readbytes() {
     47 	dd bs=1 count=$1 2>/dev/null
     48 }
     49 
     50 randuri() {
     51 	keysize="$(readbytes 1 | od -t u1 | awk 'NR == 1 { print 8 * (($2 % 31) + 1) }')"
     52 	key="$(readbytes "$keysize" | b32encode)"
     53 	digits="$(readbytes 1 | od -t u1 | awk 'NR == 1 { print (($2 % 3) + 6) }')"
     54 	algo="$(readbytes 1 | od -t u1 | awk 'BEGIN { arr[0] = "SHA1"; arr[1] = "SHA256"; arr[2] = "SHA512" } NR == 1 { print arr[$2 % 3] }')"
     55 	period="$(readbytes 1 | od -t u1 | awk 'NR == 1 { print 10 + ($2 % 240) }')"
     56 
     57 	echo "otpauth://totp/issuer$1:ident$1?secret=$key&issuer=issuer$1&algorithm=$algo&digits=$digits&period=$period"
     58 }
     59 
     60 rand() {
     61 	awk 'BEGIN {
     62 		srand();
     63 		while (1) {
     64 			printf("%c", rand() * 256);
     65 		}
     66 	}'
     67 }
     68 
     69 FirstKey=0
     70 LastKey=0
     71 
     72 rand | (
     73 	readbytes 16 | b32encode > "$KEYFILE"
     74 	rm "$DBFILE"
     75 	while true; do
     76 		case "$(readbytes 1 | od -t u1 | awk 'NR == 1 { print $2 % 3 }')" in
     77 		0)
     78 			Uri="$(randuri $((LastKey)))"
     79 			"$1" -K "$KEYFILE" -f "$DBFILE" -a "$Uri"
     80 			echo "$Uri" >>"$URIFILE"
     81 			LastKey="$((LastKey + 1))"
     82 			;;
     83 		1)
     84 			if ! test "$LastKey" = "$FirstKey"; then
     85 				"$1" -K "$KEYFILE" -f "$DBFILE" -d "issuer$FirstKey:ident$FirstKey"
     86 				sedi -e '1d' "$URIFILE"
     87 				FirstKey="$((FirstKey + 1))"
     88 			fi
     89 			;;
     90 		2)
     91 			if ! "$1" -K "$KEYFILE" -f "$DBFILE" -e | diff - "$URIFILE"; then
     92 				echo "Mismatch" >&2
     93 			fi
     94 			;;
     95 		esac
     96 	done
     97 )