Developer Information: Digitally Signed Log File Structure
A Digitally Signed Log file is a gzip-compressed text file that contains four sections, each of which employs an ADIF-like syntax to convey information. Its filename extension is .TQ8.
The TQSL_IDENT section begins with a <TQSL_IDENT:n> tag, and specifies
- the version of TQSL used to created the file
- the version of TQSLLIB used to created the file
- the version of TQSL Configuration Data in use
- whether duplicate QSOs were enabled
The tCERT section begins with a <Rec_Type:5>tCERT tag and ends with an <eor> tag. This section's <CERTIFICATE:n> tag conveys the Callsign Certificate as a base64-encoded DER-format X.509 certificate.
The tSTATION section begins with <Rec_Type:8>tSTATION tag and ends with an <eor> tag. Its fields convey information from the Station Location from which each QSO was made.
The QSOs section conveys the QSOs in standard ADIF format; each QSO begins with <Rec_Type:8>tCONTACT and ends with <eor>, and includes <SIGNDATA:n> and <SIGN_LOTW_1.0> fields.
- SIGNDATA contains conveys a SHA-1 hash of the normalized QSO data
- SIGN_LOTW_1.0 conveys the QSO's base64-encoded digital signature
Normalized QSO data is a sequence of ADIF fields in the exact order specified by the tContact definition in the sigspecs section of TQSL's Configuration Data file:
- BAND
- BAND_RX (optional)
- FREQ (optional)
- FREQ_RX (optional)
- MODE
- PROP_MODE (optional)
- QSO_DATE
- QSO_TIME
- SAT_NAME (optional)
A QSO's digital signature is constructed by using the private key to encrypt the concatenation of its SIGNDATA with a timestamp.
A Digitally Signed Log file can be used to establish proof of identify: decrypt the base64-encoded digital signature in SIGN_LOTW_1.0 with the Callsign Certificate's public key, and compare the result to the SHA-1 hash of the information conveyed by SIGNDATA.
Example: verifying the signature of a QSO in a Unix environment
- Uncompress the TQ8 file into a text file
- Extract the <CERTIFICATE:n> field into a new file, called CALL.b64
- Decode the certificate using
base64 -d CALL.b64 >CALL.der
- Convert that certificate to PEM format
openssl x509 -in CALL.der -inform DER -outform PEM -out CALL.pem
- Extract the public key
openssl x509 -in CALL.pem -noout -pubkey >pubkey.pem
- Extract the <SIGN_LOTW_1.0:n> field into a file, called SIG.b64
- Decode the signature using
base64 -d SIG.b64 >signature
- Extract the <SIGNDATA:n> for a given QSO to file signdata.raw
- Remove the extra line ending
perl -pe 'chomp if eof' signdata.raw >signdata
- Verify the signature
openssl dgst -sha1 -verify pubkey.pem -signature signature signdata