TrustedQSL C API

by Darryl Wagoner WA1GON

and

Jon Bloom KE3Z

Last update: 04 June 2002

Summary  

The TrustedQSL C API is a set of C++ methods with an ANSI C calling interface.  The API has both high level and low level functions.  For our purposes the differences being that low level functions are called by the high level functions.  For the most part the application programmer doesn't need to call the low level functions unless they wish to mimic a high level function.   One possible example might be create a new trusted file format or validating TrustedQSL from a database.

Requirements

Discussions

PKI Discussion

==============

When a certificate request is generated, the key pair is stored in a file in the key ring directory, with the private key encrypted via an operator-supplied pass phrase.

There are three certificate files in the certificate store: a file containing user certificates, a file containing CA certificates, and a file containing trusted (root) certificates.

When a certificate file is received, the root and CA certificates are first saved in their respective files. Then any user certificates are stored iff (1) their signatures can be verified using the available CA and root certificates, and (2) the public key in the certificate matches a key pair that's in the key ring. Matching user certificates are saved in the user-certificate file.

Note that certificates are opaque objects at the API level. And the application program never messes with -- or even sees -- the key pairs. It just passes the certificate objects supplied by tqsl_selectCertificates back to the library when it needs to sign or verify something, and the library takes care of selecting the private key needed.

Another detail that probably bears mention is that if a root certificate is being added, the operator should be prompted to accept it.

By the way, the code for a good chunk of the above is written and partially tested. :-)

Signing Discussion

==================

I don't think functions to sign ADIF or Cabrillo file belong in the core tQSL library. A separate utility (or library) that uses the tQSL library to convert an ADIF or Cabrillo file to Gabbi would be better. As several people have pointed out, ADIF is something of a moving target whose future direction is uncertain. To a lesser degree, the same is true of Cabrillo. It would be better to separate those functions from the core library IMHO.

We also need additional functions to create the Gabbi file of QSLs. Here's my cut:

< P >  

The application wanting to create a Gabbi submission of a log would do something like:

tQSL_Gabbi *g = tqsl_beginGabbi(<initialization parameters>);


<build station record>

tQSL_Cert **c = tqsl_selectCertificate(callsign, <qso date from first log record>, NULL);

if (<number_of_certs> > 1)

{

<select issuer to use for signing>

}

tqsl_Cert *cur_c = NULL;

for <each_log_record> {

<build contact record>

if (cur_c != NULL) {

if (!tqsl_checkCertificate(cur_c, callsign, qso_date)) {

tqsl_freeCertificate(cur_c);

cur_c = NULL;

}

}

if (cur_c == NULL) {

tqsl_Cert **c = tqsl_selectCertificates(callsign, qso_date, issuer);

if (*c == NULL) {

<no matching certs - can't sign this record>

}

cur_c = *c;

tqsl_beginSignVerify(cur_c);

}

tqsl_addGabbiQSLRecord(g, station, contact, cur_c);

}

tqsl_endGabbi();

if (cur_c != NULL) {

tqsl_freeCertificate(cur_c);

}

That leaves out quite a bit of detail, of course, but it shows the program flow as seen by the application.List of Functions and data structures.

All functions of the TrustedQSL API will be prefixed with tqsl_ and data structures will be prefixed with tQSL_. The C API will be only a set up of C wrappers for C++ class which will do the work. Data objects are opaque objects which can't be access except thru TrustedQSL functions.

Function categories

PKI functions:

tqsl_beginSignVerify(cert) - Using a callback to get the password, decrypts a copy of the private key which is kept in memory. (If has already been called with no intervening tqsl_endSignVerify, this becomes a no-op.)

tqsl_checkCertificate(cert, callsign, qso_date) - Returns TRUE if cert is valid for signing a QSO with the specified callsign and QSO date

tsql_createCertReq() - Generate key pair and certificate request file to send to CA. Uses a callback to get encryption pass phrase.

tqsl_endSignVerify(cert) - Blanks (zeroes) the copy of the unencrypted private key in memory.

tsql_freeCertificate(cert) - Frees any resources acquired by the library for the certificate object. Certificate object must not be used after this call. Implicitly calls tsql_endSignVerify.

tqsl_importCertFile() - Import a file of certificates. The file may consist of user, CA and/or root certificates. (See discussion below.)

tqsl_readCert() - Low level function, maybe private to API. Read Certificate (and add to certificate key ring ?)

tqsl_readPrivateKey() - Low level, and may use call back to vendor function.  Read a private key from private key ring. 

tqsl_rsaGenKey() - Create a RSA key pair.

tqsl_writePrivateKey() - Write a private key to private key ring.  Call back for pass phrase.

tqsl_selectCertificates(callsign, qso_date, issuer, with_expired) - Select one or more matching user certificates. Only active certs are returned unless with_expired == TRUE. If all three selection parameters are supplied and with_expired == FALSE, either 0 or 1 certificate will be returned: a certificate that can be used to sign a QSO with those parameters.

tqsl_sign* - TBD singing functions.

tqsl_signQSLRecord(tStation *, tContact *,tKeys *) - Low level function to sign a QSL record.  This will call the low level function tqsl_sign and tqsl_verify .

tqsl_validateTQSLRecord* - Low level function to validates a trustedQSL record.

Gabbi Signing Functions

tQSL_Gabbi g = tqsl_beginGabbi() - Initializes the Gabbi output. (What this exactly means is TBD, but at minimum it emits the Gabbi header. Have to set up the output stream/file, too.)

tqsl_addGabbiQSLRecord(tQSL_Gabbi*, tQSL_Station*, tQSL_Contact*, tQSL_Cert*) - Forms GABBI station, contact (w/signature) and cert records, as needed, and outputs them. This calls the low level function tqsl_signQSLRecord.

tqsl_endGabbi(tQSL_Gabbi*) - Cleans up the Gabbi output.

tqsl_validateGabbiQslFile(inputfile)  - Read a Gabbi file and validate the tQSL information.  Calls the low level function tqsl_validateTQSLRecord.

tqsl_validateGabbiEnumFile(inputfile) - Read and validate a Gabbi format enum file.

tqsl_validateGabbiSigListFile(inputfile) - Read and validate a Gabbi format signature list file.

Enumeration and Record Functions

tQSL_contact *tqsl_createContact() - return pointer to new contact record.

tQSL_signingList *tqsl_createSigningList() - returns pointer to a new signing list record. This is an object the has a list of fields for an award sponsor that must be signed if present. This list will also specify the required files for the award sponsor. This list is signed by the awards sponsor.

tQSL_station *tqsl_createStation() - returns pointer to a new station record.

tqsl_enumFields() - Returns a list of available field names.

tqsl_freeContact(tQSL_contact *) - frees the contact record.

tqsl_freeStation(tQSL_station *) - frees the station record.

tqsl_fieldType(tQSL_Station *, fieldName) - Given a field_name (from the list returned by enum_fields), returns:

  1.  A field type,

  2.  a maximum length,

  3.  an "enumerated" flag.

tqsl_setField(tQSL_Station, fieldName, value) - set the value of a field in the station_record that's being built. Parsing Functions:

 

Helper Functions. 

Helper functions are outside the TrustedQSL API, but maybe included for completeness. 

tqsl_signAdifFile(tQSL_station *,tQSL_privateKey, char *filename, char *gabbiOut,error Call back, tKeys) - Read in and sign each record of an ADIF file and write a corresponding Gabbi record to the output file.

tqsl_signCabrilloFile(tQSL_station *,tQSL_privateKey, char *filename, char *gabbiOut,error Callback, tKeys) - Read in and sign each record of an Cabrillo file and write a corresponding Gabbi record to the output file.