BOINC uses a public/private key pair for signing application code. Signing can only be done using the project's own key. By using certificates the signing process can be detached from the Project, and handled by a third entity (Application Certifier). This allows several things:
- The clients may choose to trust certain Application Certifiers instead of trusting every application they get from a given project.
- Applications may be automatically deployed on projects (no need to use the code signing key).
- A chain of trust may be built for any application which allows to
- identify the entities responsible for any given application
- trust application(s) from untrusted projects
Whom is it useful? Probably for most Projects the key based signing method is enough. In our case (SZTAKI) we are developed a method to interconnect different BOINC projects, and we needed to move not just work units but also applications belonging to them between projects. Using the key based signing method would have required to store the code signing private key on the project's (networked) machine to be able to sign any incoming application, which represents a great security risk. Instead we chose to implement a new signing method for BOINC in order to be able to move applications controlled between projects.
Verifying application signatures using X.509 certificates
Beside the project owned executable signing keys (code_sign_public, code_sign_private), OpenSSL RSA keys and X.509 certificates (in .pem format) may be used for signing and verification. This page describes how it can be done.
The .sig file
The .sig file beside any application binary may hold either the "traditional" signature of the file created with sign_executable, or a mixed version, or only signatures to be verified using certificates. When using either mixed or certificate only version, the .sig file should have the following structure:
<signatures>
<entry>
<signature>
%SIGNATURE_CREATED_WITH_OPENSSL%
</signature>
<subject>%SUBJECT_OF_CERTIFICATE%</subject>
<type>%MD5_OR_SHA1%</type>
<hash>%HASH_OF_CERTIFICATE%</hash>
</entry>
<entry>
...
</entry>
...
</signatures>
<file_signature>
%SIGNATURE_CREATED_BY_SIGN_EXECUTABLE%
</file_signature>
This structure needs to be filled with the following values:
- %SIGNATURE_CREATED_WITH_OPENSSL% - a signature created using an OpenSSL RSA key and the MD5 hash function
- %SUBJECT_OF_CERTIFICATE% - the subject of the certificate belonging to the key used to sign the binary
- %MD5_OR_SHA1% - should containt either 'md5' or 'sha1'. Currently not used, it is assumed that the signature was created using the MD5 hash function.
- %HASH_OF_CERTIFICATE% - should contain the hash of the certificate belonging to the key used for signing.
update_versions will know which type of signatures are in any .sig file and add them to xml_doc (in the database) correctly.
Creating certificates and keys
This example will describe how a self-signed certificate can be created. For production sites, no self-signed certificates should be used.
Firs step is to create an RSA key using OpenSSL issue the following command:
openssl genrsa -out my.key 1024
chmod 400 selfsigned.key
To create a certificate signing request using the key use the following:
openssl req -new -nodes -key my.key -out selfsigned.csr
It will ask for some information: country name, state name, locality name, organization, organization unit, your name, email address and a password which is optional. From the request the self-signed certificate can be created:
openssl x509 -req -days 365 -in selfsigned.csr -signkey my.key -out selfsigned.cert
This will create a certificate named "selfsigned.cert". To view the metadata incorporated in the certificate issue the following:
openssl x509 -noout -text -in selfsigned.cert
Signing code and getting information from the certificate
To sign a file issue the following command:
openssl dgst -md5 -sign my.key -out %MYFILE%.sig %MYFILE%
This will sign the file %MYFILE% and put the signature in %MYFILE%.sig. This signature file cannot be used yet by BOINC, since it expects a padded and hex converted format. Crypt_prog has been extended to be able to convert between OpenSSL and BOINC formats:
crypt_prog -convsig o2b %MYFILE%.sig %MYFILE%.sig.boinc
The content of %MYFILE%.sig.boinc can be used to put in the .sig file (to be put in the '%SIGNATURE_CREATED_WITH_OPENSSL%' part).
Getting the subject of a certificate
The command
openssl x509 -noout -in %MYFILE%.cert -subject
will print the subject.
Getting the hash of a certificate
The command
openssl x509 -noout -in %MYFILE%.cert -hash
will print the hash.
Configuration for the Core Client
Using certificates for verification on clients id disabled by default. The client configuration file (cc_config.xml) has two parameters which control the use of certificates:
<cc_config>
...
<options>
[ <use_certs>0|1</use_certs> ]
[ <use_certs_only>0|1</use_certs_only> ]
...
</options>
Setting use_certs to 1 will enable the use of certificates, and setting use_certs_only to 1 will allow only the verification of application files using certificates.
The client will look for certificates in its data directory in a directory named "certificates/". The certificates should be put there and renamed to %HASH_OF_CERTIFICATE%.<0..X> (e.g.: 72d63c7d.0 ). OpenSSL expects them to be in this format. Numbering should start from 0, and if the hash of two certificates are the same, one of them should be renamed to %HASH_OF_CERTIFICATE%.1 and so on.
Limitations
- the <type> field in .sig is not used currently, it is assumed that the hash was created using md5
- no certificate revocation