Introduction
After spending last weekend studying the PKCS #7 and CMS (RFC 3852) specifications, I dedicated this weekend to assembling a Bacula ASN.1 syntax for signing file data and implementing the requisite changes in the backup, verification , and digest handling code paths.
While I would have liked to make use of either PKCS #7 or RFC 3852, OpenSSL's current BER encoder and PKCS #7 API
are not capable of handling streaming encoding and decoding. As such, I've designed an ASN.1 syntax inspired
by RFC 3852, working around the lack of streaming support by using detached signatures and session key information.
Additionally, I've added support for SHA-256 and SHA-512 digests when using OpenSSL 0.9.8 or greater and completed a great deal of code cleanup.
You can find the full ChangeLog below.
Next Up:
- Implement support for negotiating per-job digest algorithms, allowing for upgrade/downgrade by the file daemon
- Store the file digest type on a per-job/per-fileset basis on both tape and in the catalog to allow for later verification
- Implement validation of message digests (and signatures) in the File Daemon at restore time
- Merge in ASN.1/DER signature code
- Certificate location in an x509 certificate store given the signer's subjectKeyIdentifier
The latest patchset is available here: bacula-crypto-3.diff.gz
bacula-crypto-3 Change Log
- Changed all 'signature' references to 'digest' to avoid confusion with message signing support:
- Renamed the director FileSet option from 'signature' to 'digest'
- Renamed STREAM_MD5_SIGNATURE and STREAM_SHA1_SIGNATURE to STREAM_MD5_DIGEST and STREAM_SHA1_SIGNATURE, respectively
- Renamed the SIG, Sig, and SigType members of the ATTR_DBR and FILE_DBR structures
- Renamed db_add_SIG_to_file_record() to db_add_digest_to_file_record()
- Changed all references to 'signatures' in code comments
- Dropped SIG_MD5 and SIG_SHA1, replacing with CRYPTO_DIGEST_x defines in crypto.h. The values for CRYPTO_DIGEST_MD5 and CRYPTO_DIGEST_SHA1 match those of SIG_MD5 and SIG_SHA1, avoiding compatibility problems with existing backups
- Added constants for message digest sizes in crypto.h and replaced all known instances of 'magic' numbers. (CRYPTO_DIGEST_x_SIZE)
- Modified the File database table (sqlite3 only for now):
- Renamed the 'MD5' column to 'Digest'
- Bumped the database version to 10
- Added STREAM_NONE (0) to make existing usage more explicit
- Added support for SHA-2 family of digest (SHA-256 and SHA-512):
- autoconf additions for defining HAVE_SHA2 (based on OpenSSL version availability - 0.9.8 required)
- Stream types for SHA-2 digests (STREAM_SHA256_DIGEST, STREAM_SHA512_DIGEST)
- Support for SHA-2 family of digests in crypto.c
- Expanded the 'S' fileset flag to specify which SHA derivative to use
- New functions in crypto.c:
- Added crypto_digest_stream_type(): Returns the crypto_digest_t type for a specified stream value
- Added ASN.1 definitions and the requisite OpenSSL implementation for the BaculaCrypto module:
- Require RSA keys for signing/encryption (DSA + SHA1 can not be considered secure for the potential lifetime of backups)
- Re-implement the crypto.c digest API to allow for detached message signing from digest creation
Bacula ASN.1 Syntax
BaculaCrypto { iso(1) identified-organization(3) usdod(6)
internet(1) private(4) enterprises(1) three-rings(22054)
external(500) bacula(2) published(1) bacula-encryption(1)
asn1-modules(1) bacula-crypto(1) }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
SignatureData ::= SEQUENCE {
version Version DEFAULT v0,
signerInfos SingerInfos }
SignerInfos ::= SET OF SignerInfo
Version ::= INTEGER { v0(0) }
SignerInfo ::= SEQUENCE {
version Version,
subjectKeyIdentifier SubjectKeyIdentifier,
digestAlgorithm DigestAlgorithmIdentifier,
signatureAlgorithm SignatureAlgorithmIdentifier,
signature SignatureValue }
SubjectKeyIdentifier ::= OCTET STRING
DigestAlgorithmIdentifier ::= AlgorithmIdentifier
SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
SignatureValue ::= OCTET STRING
AlgorithmIdentifier ::= OBJECT IDENTIFIER
END