"Finite Field Arithmetic." Chapter 20D: "Litmus" Errata: Support for Nested Clearsigned Texts.

This article is part of a series of hands-on tutorials introducing FFA, or the Finite Field Arithmetic library. FFA differs from the typical "Open Sores" abomination, in that -- rather than trusting the author blindly with their lives -- prospective users are expected to read and fully understand every single line. In exactly the same manner that you would understand and pack your own parachute. The reader will assemble and test a working FFA with his own hands, and at the same time grasp the purpose of each moving part therein.

You will need:

Add the above vpatches and seals to your V-set, and press to ffa_ch20d_litmus_nested_fix.kv.vpatch.

As of Chapter 20D, the versions of Peh and FFA are 250 and 253, respectively. FFA and Peh themselves have not changed from Chapter 19.

Compile Peh:

cd ffacalc
gprbuild

... and install it to a path visible in your shell (e.g. /usr/bin.)


Litmus as given in the previous chapter would choke (failing safe, i.e. rejecting the signature) when fed "nested" clearsigned texts. This bug has been fixed:


litmus.sh:

# 'ASCII-Armoured' PGP signatures have mandatory start and end markers:
START_MARKER="^\-\-\-\-\-BEGIN PGP SIGNATURE\-\-\-\-\-"
END_MARKER="^\-\-\-\-\-END PGP SIGNATURE\-\-\-\-\-"
 
.......
 
CLEAR_MARKER="^\-\-\-\-\-BEGIN PGP SIGNED MESSAGE\-\-\-\-\-"
 
.......


To test, invoke Litmus with two arguments: the public key, followed by the input file:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
 
- -----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
 
This is a test-fire GPG 'clearsigned' document written for
FFA Chapter 20C.
- -----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
 
iQEcBAEBCgAGBQJeGimSAAoJELmCKKABq//HfgsH/1bg0zpL1PoApHE5BMNXmJ7U
7vWKQJ3ZCsGvkUSIgIZESTp6EpGDclBQqvBsdBZ9KVnBpGiIbmKbNjDNlZU5YcWt
WQ7FO+r4LiUZOJRiPADWMM7tpI3azXelPyuge7hFe6o3UG0aErSceKXcoFGKFDO2
MCZXkR6Lfd3rYKHcySOEvkoCMQ4ytbEQM4IBE57AqQIpmnI7Mo1033TnDgL2KdXd
PHLtedNyaKwzVJw08BtKjzole130GvElSMmxilrHZ0w+2J4uHRuBELyZbJ55vu+x
Bx+Q5OpMwz0ZG4vjz8ncZE/nCvK/sZv/RXsdNow95fETH5DKC9HfIP279kKlBRg=
=3ozu
- -----END PGP SIGNATURE-----
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
 
iQEcBAEBCgAGBQJeHgg9AAoJELmCKKABq//HHywH/3cfUfV8SH2yuxHNBPmk3Yha
Nw/40YK52/DJ/H+RUY6Zei2X3tJPYe3vDN2P3iRqKBycpUPtNnCDaF3BAvg7cyRQ
PghpykoSeERxIQZaIQWTUyMQRBwoMF90wiQpcgCEXRH3xZo/p0M3M6zPrqKElXf4
essZmM3jsvfU9T8JGho0RPyK1J42fTBCiRb0Y++ZQGWVEwJugtVnQOL76fYmSUpW
vDBKgNJfvGOMNTCTLemqD2nn6DZzLN9TOrRlmLvfr0lbzu9rSGAMtRKqozhZeCXf
LiTWWVZkCUGr/SEk5olhbHQnfoYMH1V071qJnpv1/5QqIiZ1z2KbP65Ba/i3i0A=
=o/9T
-----END PGP SIGNATURE-----

./litmus.sh asciilifeform.peh asciilifeform-clearsigned-twice.txt

... which will yield the output:

VALID GPG RSA signature from asciilifeform <stas@loper-os.org>

Naturally, no verification is performed on the embedded clearsigned text (just as in traditional GPG. If you want to operate on the embedded text, you must extract it.)


~To be continued!~

"Finite Field Arithmetic." Chapter 20C: Support for 'Clearsigned' GPG texts in "Litmus."

This article is part of a series of hands-on tutorials introducing FFA, or the Finite Field Arithmetic library. FFA differs from the typical "Open Sores" abomination, in that -- rather than trusting the author blindly with their lives -- prospective users are expected to read and fully understand every single line. In exactly the same manner that you would understand and pack your own parachute. The reader will assemble and test a working FFA with his own hands, and at the same time grasp the purpose of each moving part therein.

You will need:

Add the above vpatches and seals to your V-set, and press to ffa_ch20c_litmus_clearsigned.kv.vpatch.

As of Chapter 20C, the versions of Peh and FFA are 250 and 253, respectively. FFA and Peh themselves have not changed from Chapter 19.

Compile Peh:

cd ffacalc
gprbuild

... and install it to a path visible in your shell (e.g. /usr/bin.)


Litmus now supports GPG "clearsigned" texts. Compatibility with the program given in the previous chapter is retained. The "clearsigned" mode of operation is selected simply by invoking the script with two arguments instead of the usual three:


litmus.sh:

.......
 
# Whether we are working on a 'clearsigned text'
CLEARSIGN_MODE=false
 
# Set up in the selected mode:
case $ARGCOUNT in
    2) # If given two arguments, verify a 'clearsigned' text file:
        CLEARSIGN_MODE=true
        # The processed payload will end up in a temporary file:
        DATAFILE=$(mktemp) || { echo "Failed to create temp file!" >&2; \
            exit $RET_EGGOG; }
        # On exit, if in 'clearsign' mode, remove temporary file with payload:
        trap remove_temp_file EXIT
        # Expect 'Canonical Text Signature' in GPG sig packet turd
        expect_sig_class=1
        ;;
    3) # Verify Detached Signature on given Data File (third argument is path):
        # The given Data file to be verified against the Signature
        DATAFILE=$3 # i.e. path given on command line
        # Expect 'Detached Binary Signature' in GPG sig packet turd
        expect_sig_class=0
        ;;
    *) # If invalid arg count -- print usage and abort:
        echo "Usage: $0 publickey.peh signature.sig datafile"
        echo "   or: $0 publickey.peh clearsigned.txt"
        exit $RET_EGGOG
        ;;
esac
.......


RFC4880 (the document GPG nominally conforms to) specifies certain transformations required to obtain the hashable payload from the document (e.g. imposition of MSDOS-style line endings) which were implemented as follows:


litmus.sh:

.......
 
# If we are operating on a 'clearsigned' text file, $DATAFILE will be
# an empty temporary file, and the payload is to be extracted to it,
 
.......
 
if [ $CLEARSIGN_MODE == true ]
then
    # Find position of 'clearsign' payload start marker:
    CLEAR_MARKER="\-\-\-\-\-BEGIN PGP SIGNED MESSAGE\-\-\-\-\-"
    start_clr=$(grep -m 1 -n "$CLEAR_MARKER" $SIGFILE | cut -d ':' -f1)
 
    # If payload start marker was not found:
    if [ "$start_clr" == "" ]
    then
        eggog_broken_clearsigned
    fi
 
    # Discard the start marker:
    start_clr=$(($start_clr + 1))
 
    # The payload ends with the line preceding the sig start:
    end_clr=$((start_ln - 2))
 
    # Find any 'Hash:' headers:
    start_body=$(tail -n "+$start_clr" $SIGFILE | \
        grep -v -n -m 1 "^Hash:" | cut -d ':' -f1)
 
    # Skip the above headers and mandatory empty line:
    start_clr=$(($start_clr + $start_body))
 
    # If there is no payload, or the markers are misplaced, abort:
    if [ $start_clr -ge $end_clr ]
    then
        eggog_broken_clearsigned
    fi
 
    # Extract the 'clearsign' payload to the temporary file:
    cat $SIGFILE | sed -n "$start_clr,$end_clr p" | \
        sed 's/[ \t]*$//; s/^- //' | \
        awk '{printf("%s\r\n",$0)}' \
            > $DATAFILE
 
    # Remove the trailing CR,LF ending:
    truncate -s -2 $DATAFILE
 
    # After this, proceed exactly like with 'detached' sigs, but
    # with the expected 'class' being 1 rather than 0.
fi
 
.......


To verify a "clearsigned" message, invoke Litmus with two arguments: the public key, followed by the input file, e.g.:

./litmus.sh asciilifeform.peh asciilifeform-clearsigned.txt

... which will yield the output:

VALID GPG RSA signature from asciilifeform <stas@loper-os.org>


~To be continued!~

"Finite Field Arithmetic." Chapter 20B: Support for Selected Ancient Hash Algos in "Litmus."

This article is part of a series of hands-on tutorials introducing FFA, or the Finite Field Arithmetic library. FFA differs from the typical "Open Sores" abomination, in that -- rather than trusting the author blindly with their lives -- prospective users are expected to read and fully understand every single line. In exactly the same manner that you would understand and pack your own parachute. The reader will assemble and test a working FFA with his own hands, and at the same time grasp the purpose of each moving part therein.

You will need:

Add the above vpatches and seals to your V-set, and press to ffa_ch20b_litmus_legacy_hashes.kv.vpatch.

As of Chapter 20B, the versions of Peh and FFA are 250 and 253, respectively. FFA and Peh themselves have not changed from Chapter 19.

Compile Peh:

cd ffacalc
gprbuild

... and install it to a path visible in your shell (e.g. /usr/bin.)


In the course of experimenting with the subject of the previous Chapter, I found that a number of current and past Vtronicists had misconfigured their GPG, and emit suboptimal signatures (i.e. not SHA-512, the strongest of the ancient hashes supported by that utility). And so I added support for these. (Litmus will emit a warning if such a signature is encountered.)

The following routine has been added to Litmus:


litmus.sh:

# If Sig was made with an unsupported hash algo:
eggog_unsupported_hash() {
    algo=$1
    echo "This sig uses an unsupported Digest Algo: $1 !" >&2
    exit $RET_EGGOG
}
 
.......
 
# Warnings:
achtung() {
    echo "WARNING: $1" >&2
}
 
.......
 
# Digest Algo (only certain hash algos are supported)
get_sig_bytes 1
turd+=$r
hex_to_int
sig_digest_algo=$r
 
# If hash algo is supported, get ASN turd and MD_LEN; and if not, eggog:
case $sig_digest_algo in
    1)  ## MD5 -- NOT SUPPORTED ##
        eggog_unsupported_hash "MD5"
        ;;
 
    2)  ## SHA1 ##
        achtung "This sig was made with SHA-1, which is cheaply breakable!"
        achtung "Please contact the signer ($pubkey_owner) !"
        HASHER="shasum -a 1 -b"
        ASN="3021300906052b0e03021a05000414"
        MD_LEN=20
        ;;
 
    3)  ## RIPE-MD/160 -- NOT SUPPORTED ##
        eggog_unsupported_hash "RIPE-MD/160"
        ;;
 
    8)  ## SHA256 ##
        achtung "This sig was made with SHA-256; GPG supports SHA-512."
        achtung "Please contact the signer ($pubkey_owner) !"
        HASHER="shasum -a 256 -b"
        ASN="3031300d060960864801650304020105000420"
        MD_LEN=32
        ;;
 
    9)  ## SHA384 ##
        achtung "This sig was made with SHA-384; GPG supports SHA-512."
        achtung "Please contact the signer ($pubkey_owner) !"
        HASHER="shasum -a 384 -b"
        ASN="3041300d060960864801650304020205000430"
        MD_LEN=48
        ;;
 
    10) ## SHA512 ##
        HASHER="shasum -a 512 -b"
        ASN="3051300D060960864801650304020305000440"
        MD_LEN=64 # 512 / 8 == 64 bytes
        ;;
 
    11) ## SHA224 ##
        achtung "This sig was made with SHA-224; GPG supports SHA-512."
        achtung "Please contact the signer ($pubkey_owner) !"
        HASHER="shasum -a 224 -b"
        ASN="302D300d06096086480165030402040500041C"
        MD_LEN=28
        ;;
 
    *)  ## Unknown Digest Type ##
        eggog_unsupported_hash "UNKNOWN (type $sig_digest_algo)"
        ;;
esac
 
# Calculate length (bytes) of the ASN turd for the digest used in the sig:
ASN_LEN=$((${#ASN} / 2))
 
.......


To test, for instance, verification of SHA-1 signatures (please stop using SHA-1, people! see e.g. here), download this Litmus-converted GPG public key of former contributor Diana Coman, and verify her signature of Chapter 1:

./litmus.sh diana_coman.peh ffa_ch1_genesis.kv.vpatch.diana_coman.sig ffa_ch1_genesis.kv.vpatch

... which will yield the output:

WARNING: This sig was made with SHA-1, which is cheaply breakable!
WARNING: Please contact the signer (Diana Coman <office@dianacoman.com>) !
VALID GPG RSA signature from Diana Coman <office@dianacoman.com>


~To be continued!~

"Finite Field Arithmetic." Chapter 20: "Litmus", a Peh-Powered Verifier for GPG Signatures.

This article is part of a series of hands-on tutorials introducing FFA, or the Finite Field Arithmetic library. FFA differs from the typical "Open Sores" abomination, in that -- rather than trusting the author blindly with their lives -- prospective users are expected to read and fully understand every single line. In exactly the same manner that you would understand and pack your own parachute. The reader will assemble and test a working FFA with his own hands, and at the same time grasp the purpose of each moving part therein.

You will need:

Add the above vpatches and seals to your V-set, and press to ffa_ch20_litmus.kv.vpatch.

As of Chapter 20, the versions of Peh and FFA are 250 and 253, respectively. FFA and Peh themselves have not changed from Chapter 19.

Compile Peh:

cd ffacalc
gprbuild

... and install it to a path visible in your shell (e.g. /usr/bin.)


The subject of this chapter is Litmus: a simple and practical demonstration program powered by Peh. It is expected to work on all reasonable Unix-like systems, so long as the required command-line utilities (see EXTERNALS) are present.

Litmus verifies traditional GPG public key signatures (presently, only of the "detached" type, with RSA and SHA512 hash -- the optimal knob settings available in GPG) and is suitable for use in e.g. Vtronics.

The source code of Litmus appears below in its entirety:


litmus.sh:

#!/bin/sh
 
############################################################################
# 'Litmus' Utility. Verifies traditional GPG RSA signatures using Peh.     #
#                                                                          #
# Usage: ./litmus.sh publickey.peh signature.sig datafile                  #
#                                                                          #
# Currently, supports only RSA 'detached' signatures that use SHA512 hash. #
# See instructions re: converting traditional GPG public keys for use with #
# this program.                                                            #
#                                                                          #
# Peh, xxd, hexdump, shasum, and a number of common utils (see EXTERNALS)  #
# must be present on your machine.                                         #
#                                                                          #
# (C) 2020 Stanislav Datskovskiy ( www.loper-os.org )                      #
# http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html     #
#                                                                          #
# You do not have, nor can you ever acquire the right to use, copy or      #
# distribute this software ; Should you use this software for any purpose, #
# or copy and distribute it to anyone or in any manner, you are breaking   #
# the laws of whatever soi-disant jurisdiction, and you promise to         #
# continue doing so for the indefinite future. In any case, please         #
# always : read and understand any software ; verify any PGP signatures    #
# that you use - for any purpose.                                          #
############################################################################
 
# External programs that are required (if not found, will eggog) :
EXTERNALS="peh xxd hexdump base64 shasum cut tr sed wc grep printf"
 
 
# Return Codes:
 
# Signature is VALID for given Sig, Data File, and Public Key:
RET_VALID_SIG=0
 
# Signature is INVALID:
RET_BAD_SIG=1
 
# All Other Cases:
RET_EGGOG=-1
 
 
# Terminations:
 
# Success (Valid RSA signature) :
done_sig_valid() {
    echo "VALID $pubkey_algo signature from $pubkey_owner"
    exit $RET_VALID_SIG
}
 
# Failure (INVALID RSA signature) :
done_sig_bad() {
    echo "Signature is INVALID for this public key and input file!"
    exit $RET_BAD_SIG
}
 
# Failure in decoding 'GPG ASCII armour' :
eggog_sig_armour() {
    echo "$SIGFILE could not decode as a GPG ASCII-Armoured Signature!" >&2
    exit $RET_EGGOG
}
 
# Failure from corrupt signature :
eggog_sig_corrupt() {
    echo "$SIGFILE is corrupt!" >&2
    exit $RET_EGGOG
}
 
 
# Failure from bad Peh :
eggog_peh() {
    echo "EGGOG in executing Peh tape! Please check Public Key." >&2
    exit $RET_EGGOG
}
 
 
# Number of Arguments required by this program:
REQD_ARGS=3
 
# If invalid arg count, print usage and abort:
if [ "$#" -ne $REQD_ARGS ]; then
    echo "Usage: $0 publickey.peh signature.sig datafile"
    exit $RET_EGGOG
fi
 
 
# We only support SHA512. Parameters for it:
HASHER="shasum -a 512 -b"
 
# For 'PKCS' encoding, the ASN magic turd corresponding to SHA512:
ASN="3051300D060960864801650304020305000440"
ASN_LEN=$((${#ASN} / 2))
MD_LEN=64 # 512 / 8 == 64 bytes
 
 
# Minimal Peh Width (used for non-arithmetical ops, e.g. 'Owner')
MIN_PEH_WIDTH=256
 
 
# The given public key file (a Peh tape, see docs)
PUBFILE=$1
 
# The given Detached GPG Signature file to be verified
SIGFILE=$2
 
# The given Data file to be verified against the Signature
DATAFILE=$3
 
# Verify that each of the given input files exists:
FILES=($PUBFILE $SIGFILE $DATAFILE)
for f in ${FILES[@]}; do
    if ! [ -f $f ]; then
        echo "$f does not exist!" >&2
        exit $RET_EGGOG
    fi
done
 
# Calculate length of the pubkey file:
PUBFILE_LEN=$(wc -c $PUBFILE | cut -d ' ' -f1)
 
 
# Peh's Return Codes
PEH_YES=1
PEH_NO=0
PEH_MU=255
PEH_EGGOG=254
 
# Execute given Peh tape, with given FFA Width and Height,
# on top of the pubkey tape; returns output in $peh_res and $peh_code.
run_peh_tape() {
    # The tape itself
    tape=$1
 
    # FFA Width for the tape
    peh_width=$2
 
    # FFA Stack Height for the tape
    peh_height=$3
 
    # Compute the length of the given tape
    tape_len=${#tape}
 
    # Add the length of the Public Key tape to the above
    tape_len=$(($tape_len + $PUBFILE_LEN))
 
    # Max Peh Life for all such tapes
    peh_life=$(($tape_len * 2))
 
    # Execute the tape:
    peh_res=$((cat $PUBFILE; echo $tape) | \
        peh $peh_width $peh_height $tape_len $peh_life);
    peh_code=$?
 
    # # If Peh returned PEH_EGGOG:
    if [ $peh_code -eq $PEH_EGGOG ]
    then
        # Abort: likely, coarse error of pilotage in the public key tape.
        eggog_peh
    fi
}
 
# Ask the public key about the Owner:
run_peh_tape "@Algo!QY" $MIN_PEH_WIDTH 1
pubkey_algo=$peh_res
 
# Ask the public key about Algo Type:
run_peh_tape "@Owner!QY" $MIN_PEH_WIDTH 1
pubkey_owner=$peh_res
 
# The only supported algo is GPG RSA:
if [ "$pubkey_algo" != "GPG RSA" ]
then
    echo "This public key specifies algo '$pubkey_algo';" >&2
    echo "The only algo supported is 'GPG RSA' !" >&2
    exit $RET_EGGOG
fi
 
# Verify that all of the necessary external programs in fact exist:
for i in $EXTERNALS
do
    command -v $i >/dev/null && continue || \
        { echo "$i is required but was not found! Please install it."; \
        exit $RET_EGGOG; }
done
 
# 'ASCII-Armoured' PGP signatures have mandatory start and end markers:
START_MARKER="\-\-\-\-\-BEGIN PGP SIGNATURE\-\-\-\-\-"
END_MARKER="\-\-\-\-\-END PGP SIGNATURE\-\-\-\-\-"
 
# Determine start and end line positions for payload:
start_ln=$(grep -m 1 -n "$START_MARKER" $SIGFILE | cut -d ':' -f1)
end_ln=$(grep -m 1 -n "$END_MARKER" $SIGFILE | cut -d ':' -f1)
 
# Both start and end markers must exist :
if [ "$start_ln" == "" ] || [ "$end_ln" == "" ]
then
    echo "$SIGFILE does not contain ASCII-armoured PGP Signature!" >&2
    exit $RET_EGGOG
fi
 
# Discard the markers:
start_ln=$(($start_ln + 1))
end_ln=$(($end_ln - 1))
 
# If there is no payload, or the markers are misplaced, abort:
if [ $start_ln -ge $end_ln ]
then
    eggog_sig_armour
fi
 
# Extract sig payload:
sig_payload=$(sed -n "$start_ln,$end_ln p" < $SIGFILE | \
    sed -n "/^Version/!p" | sed -n "/^=/!p" | tr -d " \t\n\r")
 
# If eggog -- abort:
if [ $? -ne 0 ]
then
    eggog_sig_armour
fi
 
# Obtain the sig bytes:
sig_bytes=($(echo $sig_payload | base64 -d | hexdump -ve '1/1 "%.2x "'))
 
# If eggog -- abort:
if [ $? -ne 0 ]
then
    eggog_sig_armour
fi
 
# Number of bytes in the sig file
sig_len=${#sig_bytes[@]}
 
 
# Test that certain fields in the Sig have their mandatory value
sig_field_mandatory() {
    f_name=$1
    f_value=$2
    f_mandate=$3
    if [ "$f_value" != "$f_mandate" ]
    then
        reason="$f_name must equal $f_mandate; instead is $f_value."
        echo "$SIGFILE is UNSUPPORTED : $reason" >&2
        echo "Only RSA and SHA512 hash are supported !" >&2
        exit $RET_EGGOG
    fi
}
 
 
# Starting Position for get_sig_bytes()
sig_pos=0
 
# Extract given # of sig bytes from the current sig_pos; advance sig_pos.
get_sig_bytes() {
    # Number of bytes requested
    count=$1
 
    # Result: $count bytes from current $sig_pos (contiguous hex string)
    r=$(echo ${sig_bytes[@]:$sig_pos:$count} | sed "s/ //g" | tr 'a-z' 'A-Z')
 
    # Advance $sig_pos by $count:
    sig_pos=$(($sig_pos + $count))
 
    # If more bytes were requested than were available in sig_bytes:
    if [ $sig_pos -gt $sig_len ]
    then
        # Abort. The signature was mutilated somehow.
        eggog_sig_corrupt
    fi
}
 
# Convert the current sig component to integer
hex_to_int() {
    r=$((16#$r))
}
 
# Turd to be composed of certain values from the sig, per RFC4880.
# Final hash will run on the concatenation of DATAFILE and this turd.
turd=""
 
## Parse all of the necessary fields in the GPG Signature:
 
# CTB (must equal 0x89)
get_sig_bytes 1
sig_ctb=$r
sig_field_mandatory "Version" $sig_ctb 89
 
# Length
get_sig_bytes 2
hex_to_int
sig_length=$r
 
# Version (only Version 4 -- what GPG 1.4.x outputs -- is supported)
get_sig_bytes 1
turd+=$r
sig_version=$r
sig_field_mandatory "Version" $sig_version 04
 
# Class (only class 0 is supported)
get_sig_bytes 1
turd+=$r
sig_class=$r
sig_field_mandatory "Class" $sig_class 00
 
# Public Key Algo (only RSA is supported)
get_sig_bytes 1
turd+=$r
sig_pk_algo=$r
sig_field_mandatory "Public Key Algo" $sig_pk_algo 01
 
# Digest Algo (only SHA512 is supported)
get_sig_bytes 1
turd+=$r
sig_digest_algo=$r
sig_field_mandatory "Digest Algo" $sig_digest_algo 0A
 
# Hashed Section Length
get_sig_bytes 2
turd+=$r
hex_to_int
sig_hashed_len=$r
 
# Hashed Section (typically: timestamp)
get_sig_bytes $sig_hashed_len
turd+=$r
sig_hashed=$r
 
# Unhashed Section Length
get_sig_bytes 1
hex_to_int
sig_unhashed_len=$r
 
# Unhashed Section (discard)
get_sig_bytes $sig_unhashed_len
 
# Compute Byte Length of Hashed Header (for last field)
hashed_header_len=$((${#turd} / 2))
 
# Final section of the hashed turd (not counted in hashed_header_len)
turd+=$sig_version
turd+="FF"
turd+=$(printf "%08x" $hashed_header_len)
 
# Compute the hash of data file and the hashed appendix from sig :
hash=$((cat $DATAFILE; xxd -r -p < << $turd) | $HASHER | cut -d ' ' -f1)
# Convert to upper case
hash=$(echo $hash | tr 'a-z' 'A-Z')
 
# Parse the RSA Signature portion of the Sig file:
 
# RSA Packet Length (how many bytes to read)
get_sig_bytes 1
hex_to_int
rsa_packet_len=$r
 
# The RSA Packet itself
get_sig_bytes $rsa_packet_len
rsa_packet=$r
 
# Digest Prefix (2 bytes)
get_sig_bytes 2
digest_prefix=$r
 
# See whether it matches the first two bytes of the actual computed hash :
computed_prefix=$(printf "%.4s" $hash)
 
if [ "$digest_prefix" != "$computed_prefix" ]
then
    # It didn't match, so we can return 'bad signature' immediately:
    done_sig_bad
fi
 
# If prefix matched, we will proceed to do the actual RSA operation.
 
# RSA Bitness given in Sig
get_sig_bytes 2
hex_to_int
rsa_bitness=$r
 
# Compute RSA Byteness from the above
rsa_byteness=$((($rsa_bitness + 7) / 8))
 
# RSA Bitness for use in determining required Peh width:
rsa_width=$(($rsa_byteness * 8))
 
# Only traditional GPG RSA widths are supported:
if [ $rsa_width != 2048 ] && [ $rsa_width != 4096 ] && [ $rsa_width != 8192 ]
then
    reason="Only 2048, 4096, and 8192-bit RSA are supported."
    echo "$SIGFILE is UNSUPPORTED : $reason" >&2
    exit $RET_EGGOG
fi
 
# RSA Signature per se (final item read from sig file)
get_sig_bytes $rsa_byteness
rsa_sig=$r
 
# Per RFC4880, 'PKCS' encoding of hash is as follows:
# 0 1 [PAD] 0 [ASN] [MD]
 
# First two bytes of PKCS-encoded hash will always be 00 01 :
pkcs="0001"
 
# Compute necessary number of padding FF bytes :
pkcs_pad_bytes=$(($rsa_byteness - $MD_LEN - $ASN_LEN - 3))
 
# Attach the padding bytes:
for ((x=1; x< =$pkcs_pad_bytes; x++)); do
    pkcs+="FF"
done
 
# Attach the 00 separator between the padding and the ASN:
pkcs+="00"
 
# Attach the ASN ('magic' corresponding to the hash algo) :
pkcs+=$ASN
 
# Finally, attach the computed (from Data file) hash itself :
pkcs+=$hash
 
# Generate a Peh tape which will attempt to verify $rsa_sig against the pubkey,
# computing the expression $rsa_sig ^ PUB_E mod PUB_M and comparing to $pkcs.
# Outputs 'Valid' and returns Yes_Code (1) if and only if signature is valid.
tape=".$rsa_sig@Public-Op!.$pkcs={[Valid]QY}{[Invalid]QN}_"
 
# Execute the tape:
run_peh_tape $tape $rsa_width 3
 
# 'Belt and suspenders' -- test both output and return code:
# If verification succeeded, return code will be 1, and output 'Valid':
if [ $peh_code -eq $PEH_YES ] && [ "$peh_res" == "Valid" ]
then
    # Valid RSA signature:
    done_sig_valid
else
    # Signature was not valid:
    done_sig_bad
fi
# The end.

Public keys for use with Litmus are Peh tapes, and their format is illustrated here. Mine (converted from my GPG public key using, for the time being, PGPDump and a few minutes of elbow grease) appears below:


asciilifeform.peh:

(----------------------------------------------------------------------------)
( Public key converted from GPG key 17215D118B7239507FAFED98B98228A001ABFFC7 )
(----------------------------------------------------------------------------)
@RSA-Public-Modulus@
        .
        CDD49A674BAF76D3B73E25BC6DF66EF3ABEDDCA461D3CCB6416793E3437C7806562694
        73C2212D5FD5EED17AA067FEC001D8E76EC901EDEDF960304F891BD3CAD7F9A335D1A2
        EC37EABEFF3FBE6D3C726DC68E599EBFE5456EF19813398CD7D548D746A30AA47D4293
        968BFBAFCBF65A90DFFC87816FEE2A01E1DC699F4DDABB84965514C0D909D54FDA7062
        A2037B50B771C153D5429BA4BA335EAB840F9551E9CD9DF8BB4A6DC3ED1318FF3969F7
        B99D9FB90CAB968813F8AD4F9A069C9639A74D70A659C69C29692567CE863B88E191CC
        9535B91B417D0AF14BE09C78B53AF9C5F494BCF2C60349FFA93C81E817AC682F0055A6
        07BB56D6A281C1A04CEFE1
;
(----------------------------------------------------------------------------)
@RSA-Public-Exponent@
        .
        10001
;
LC
(----------------------------------------------------------------------------)
@Public-Op@
        (N is on stack) @RSA-Public-Exponent! @RSA-Public-Modulus! MX
;
(----------------------------------------------------------------------------)
@Algo@[GPG RSA];
(----------------------------------------------------------------------------)
@Owner@[asciilifeform <stas@loper-os.org>];
(----------------------------------------------------------------------------)
RC


Now verify the vpatch of this chapter and its signature using Litmus:

./litmus.sh asciilifeform.peh ffa_ch20_litmus.kv.vpatch.asciilifeform.sig ffa_ch20_litmus.kv.vpatch

... which should yield the output:

VALID GPG RSA signature from asciilifeform <stas@loper-os.org>

If you find that Litmus balks on your GPG signatures, ensure that SHA512 (the longest hash supported by old rotten GPG) is selected in your config (typically ~/.gnupg/gpg.conf) :

personal-digest-preferences SHA512
cert-digest-algo SHA512


In Chapter 21, we will discuss the astonishing ugliness of the GPG data format, and construct a means for semi-automatic conversion of traditional GPG public keys into the format used by Litmus.


~To be continued!~

Thank you, first 'Dulap' Subscriber!

Congratulations to the very first 'Dulap' subscriber of my machine rack service!

Dulap

... installed with a colocated customer-owned FG (this service carries no additional charge!) :

Colo FG

Colo FG Connection

Thank you for your business!

Thank you, Subscriber No. 1.

1stblood

Congratulations to the first paying subscriber of my machine rack service! Thank you for your business.

Rack Service Launch.


Note: this the third and final draft of the machine colocation rack costs sheet and service terms. Prices have not changed since the last revision. The service is now live.

Rack space, as described below, is immediately and henceforth available exclusively to my L1 and L2 WoT (presently visible here.) If you, reader, are not in this roster, or not interested in purchasing rack service from me, you may safely skip this article.

(more...)

The Boneyard.

Update: As of 26 Nov 2019, all of the auction items in my boneyard have been sold and sent to their purchasers.

0

I have been asked to catalogue certain contents of my machine boneyard which are due to change hands on account of imminent liquidations of two operations in which I took part.

The items pictured below are presently in my possession, and believed to be functional for the uses for which they were made, though I am unable to offer a proper guarantee of this.

At the end of this article, can be seen two PGP-signed texts, listing these and certain other (presently located in Montevideo, Uruguay) pertinent inventory items.

All parties with claims to these irons who believe the lists to be incomplete or inaccurate, are asked to leave signed comments here; or at the very least to inquire in #pizarro or #asciilifeform.


1. Photocatalogue: S.NSA.

Mircea Popescu, chairman of S.NSA, requested an inventory. Below appear photographs of the items in this inventory currently in my possession; and a PGP-signed inventory of these and other (presently in BingoBoingo's storage) items, which I believe to be complete.



(QTY 2) FG Spare Units (w/out screws or cabling.) (factory tailings, 2016).


1




(QTY 10) FG Spare Analogue TRNG Sources. (factory tailings, 2016).


2




(QTY 1) FG Analogue TRNG Source. (no cover.) Was utilized for destructive tests, but presently believed to function.


3




(QTY 1) FG Analogue TRNG Source. Prototype, 2014. Hand-assembled author's copy. Presently believed to function.


4




(QTY 3) Samsung 256GB SATA SSD, heavily worn (2+y of contin. service.)


5



Disk #2 was apparently stolen in the mails. In its place, arrived an empty envelope (not to be considered a part of the inventory) :


6


7


2. Photocatalogue: Pizarro.

BingoBoingo (Chairman) already created a preliminary inventory. However the following, to the best of my knowledge, is also to be included in Pizarro's inventory as it currently stands:



(QTY 2) FG Spare Units (inspected, recertified, sealed, in 2018.) Without cabling.


6


3. Signed Manifest: S.NSA.

(Can also download here.)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
 
1 Nov 2019, block 601925.
 
To the best of my knowledge, the inventory of S.NSA presently consists of:
 
(1) (QTY 1) 'Dulap'.
    Location: Montevideo, Uruguay.
    2.3GHz x 32core (Opteron 6376) RAM Installed: 256G RAM Max: 256G
    Additionally containing: (QTY 2) FG and associated cabling.
 
(2) (QTY 1) 'Dulap-Spare'.
    Location: Montevideo, Uruguay.
    1.9GHz x 24core (Opteron 6168) RAM Installed: 24G RAM Max: 256G
    Additionally containing: (QTY 2) spare FG, without cabling.
 
(3) (QTY 3) Samsung 256GB SATA SSD, heavily worn (2+y of contin. service.)
    Location: my graveyard / USA
 
(4) (QTY 2) FG Spare Units (w/out screws or cabling.) (factory tailings, 2016).
    Location: my graveyard / USA
 
(5) (QTY 10) FG Spare Analogue TRNG Sources. (factory tailings, 2016).
    Location: my graveyard / USA
 
(6) (QTY 1) FG Analogue TRNG Source. (no cover.)
    Was utilized for destructive tests, but presently believed to function.
    Location: my graveyard / USA
 
(7) (QTY 1) FG Analogue TRNG Source. Prototype, 2014.
    Hand-assembled author's copy. Presently believed to function.
 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
 
iQEcBAEBCgAGBQJdvFyfAAoJELmCKKABq//HpowH/i3n2njZuRSoUn9iCiyU3xlM
CcrBrVusvVfOFO1mZ5xgytfrc04Dk02V5g7qt1DGw1Id4p8E1iRq37ENNPB7YfRU
b8A/lxNjqUjkNC6s//HOoDZbMdFbd7HcHAh5NhQSGhvkK8yJ2sS6UhqQm8OeQVh5
1KZEwSGORPGZdhKoyF0PlhmM66xYVNidUwvbwJYOcMh5URc8SFGiojLNG1Nq0uAF
fPcFU+1iSR55cqyRG7bWDjWdImN+8QhhH87HAYSRqDju070BLHw7hIs9mAUH8YTv
sPUXG4lrL3mZSpjBpG7jMtgHh6OhHM1J3lsIQm+C4zoKz4EF2DjOnKVEY9a5FY0=
=A7fy
-----END PGP SIGNATURE-----

4. Signed Manifest: Pizarro.

(Can also download here.)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
 
1 Nov 2019, block 601925.
 
To the best of my knowledge, the inventory of Pizarro, IN ADDITION to the items
catalogued by BingoBoingo last week [1], also currently contains:
 
(QTY 2) FG Spare Units (inspected, recertified, sealed, in 2018)
        Without cabling.
        Location: my graveyard / USA
 
[1] http://bingology.net/2019/10/29/preliminary-inventory-of-items-once-hosted-by-pizarro-and-presently-in-my-care/
 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
 
iQEcBAEBCgAGBQJdvF05AAoJELmCKKABq//HeCEIAL14d4Wg6+fT1eX+E3AOcYU1
3hTNWJKZQBNd2BI6Mb9geYHa8QpdmrmgaNJVxWZx5nn0cKt0FOQtaqMROGRjYui9
anQUlPAVzcPoAWAswzAdgMY70BH/GDVfphr4iT8pI1YI/bHsisvWgU+LODdrWkPw
HA+pmzsiXG3jNyE+8xkQPqV07ZA1qJIA79xKzBDz1Voiow0Sx8y3I50DuvOnnAgT
bDg88PYkqM19Aa8RwODrrE0G0c4/Bhru9vzZ81WVdPTZSZ4oPphpQ3IFtr18ZrQe
Rmz8Nyvy+1iymsj39cJ3qQp7Ft6fLRCn1NaIxGBJAE8ucJgi+VCodgW396uaJc0=
=uAzY
-----END PGP SIGNATURE-----

5. Where they go and how.

All requests for the physical movement of the listed inventory items are to be PGP-signed by their new owners and posted as comments here. The person requesting transfer is responsible for all postage expense, payable via Deedbot. Auctions have ended, all purchases sent.

TMSR North Ameristan Rack Prospectus: Second, Revised Draft.


Note: this the second, revised draft of the prospectus, incorporating feedback from prospective customers. The previous draft can be seen here.

I have provisioned a machine colocation rack for the exclusive use of The Most Serene Republic, as represented by the WoT L1 and L2. If you, reader, are not in this roster, you may safely skip this article.

(more...)

TMSR North Ameristan Rack Prospectus: Initial Draft.


Edit (27 Oct 2019) : This document is supplanted by the second draft of the prospectus.

I have provisioned a machine colocation rack for the exclusive use of The Most Serene Republic, as represented by the WoT L1 and L2. If you, reader, are not in this roster, you may safely skip this article.

(more...)

// Script to allow anchoring of user-selected content on html pages. // Original idea deployed by http://archive.today // Packaged for WordPress on http://trilema.com/2015/that-spiffy-selection-thing/