Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work in progress: Clam 2677 2678 codesigning #1417

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

micahsnyder
Copy link
Contributor

This is a work in progress near completion. It bears similarities to #1344, adding external code signing signature files (.cvd.sign) to accompany existing .cvd databases.

The .sign take a form similar to other clamav signatures where comment lines start with a # and all other lines are signatures. Each signature line takes the form:

min_flevel : max_flevel (optional) : sig_format : public_key_fingerprint : signature_text

min_flevel:  the minimum flevel required to support the signature format.
max_flevel:  the maximum flevel supporting the signature format. This is optional, and may be empty. 
signature_format:  for the initial implementation, it must be: "pkcs7-pem".
signature_text:  must be printable ascii with no new lines. If "sig_format" is "pkcs7-pem" it is the base64 encoded part of the a PEM signature (aka header and footer removed) with all new-lines removed. if additional formats are added, this field would be used to store things like the hash of the file, the algorithm, plus any other required signing details. 

I've added commands to sigtool for signing:

  Commands creating and verifying .sign detached digital signatures:

    --sign FILE                            Sign a file.
                                           The resulting .sign file name will
                                           be in the form: dbname-version.cvd.sign
                                           or FILE.sign for non-CVD targets.
                                           It will be created next to the target file.
                                           If a .sign file already exists, then the
                                           new signature will be appended to file.
    --key /path/to/private.key             Specify a signing key.
    --cert /path/to/private.key            Specify a signing cert.
                                           May be used more than once to add
                                           intermediate and root certificates.

    --verify FILE                          Find and verify a detached digital
                                           signature for the given file.
                                           The digital signature file name must
                                           be in the form: dbname-version.cvd.sign
                                           or FILE.sign for non-CVD targets.
                                           It must be found next to the target file.
    --cvdcertsdir DIRECTORY                Specify a directory containing the root
                                           CA cert needed to verify the signature.
                                           If not provided, then sigtool will look in:
                                           /usr/local/etc/certs/

I have not included scripts needed for openssl to generate signing keys and certs.

I am still working on adding changes to freshclam and then cvdupdate to download .cvd.sign files.

@mark-carey-sap @aghassemlouei

Fixes: #564

Replaces: #1344

CMakeOptions.cmake Outdated Show resolved Hide resolved
libclamav/cvd.c Outdated Show resolved Hide resolved
libclamav/cvd.c Outdated Show resolved Hide resolved
}

/* For actual .cvd files, verify the digital signature. */
if (dbtype == CVD_TYPE_CVD) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to also check this for CUD? Probably. This would be a case where database is not signed with old MD5-RSA, and only signed with external PKCS7 sig.

if (!cvd_verify(
cvd,
engine->certs_directory,
false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider if we want to make a config or commandline option to disable the older md5-based RSA checks, or simply let it fail if FIPS is enabled and the cert-based method doesn't work/isn't available.

I think it's okay either way.

@@ -26,6 +26,13 @@ inflate = "0.4"
bzip2-rs = "0.1"
byteorder = "1.5"
delharc = "0.6"
clam-sigutil = { path = "../../clamav-signature-util" }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporarily pointing a copy of the rust clam-sigutil project in my workspace. Will change it to a github URL soon.

Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.

Add a Rust implementation for parsing, verifying, and unpacking CVD
files.

Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
  `-D CVD_CERTS_DIRECTORY=PATH`

New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
  `--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
  `CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
  `CVDCertsDirectory PATH`

Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.

Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.

libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
  Resolves: Cisco-Talos#1304
- Add two new API's to the public clamav.h header:
  ```c
  extern cl_error_t cl_cvdverify_ex(const char *file,
                                    const char *certs_directory);

  extern cl_error_t cl_cvdunpack_ex(const char *file,
                                    const char *dir,
                                    bool dont_verify,
                                    const char *certs_directory);
  ```
  The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
  You may set this option with `cl_engine_set_str` and get it
  with `cl_engine_get_str`, to override the compiled in default
  CVD certs directory.

libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
@micahsnyder micahsnyder force-pushed the CLAM-2677-2678-codesigning branch from fa87545 to c84ae11 Compare December 16, 2024 18:55
@micahsnyder
Copy link
Contributor Author

sigtool --sign: After debug-logging the certs for the cert stack, should info-print:

  • cert Serial
  • CommonName
  • the issuer commonName (if an issuer exists)

@micahsnyder
Copy link
Contributor Author

micahsnyder commented Dec 17, 2024

For verifying,

  1. Load all ca certs from the ca certs directory into the x509 store and put the x509 store into the Verifier.

  2. The Verifier should be stored in the cl_engine.

Edit: done.

Create a sign-verifier once and pass it around.

Sign verifier can now load multiple certs from a single file.
Additionallly, it may load multiple certs and verify once.
No need to try each individually or check serial numbers.

Signer can also now load multiple certs from a bundle.

Fixed bug with sign --append option when file didn't exist yet.
Also (re)signed the test CVD's and CDIFF's with the test certs.
Fixed some issues that had the unit tests depending on the installed
certs rather than the test certs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ClamAV is unusable on FIPS-enabled Linux systems due to MD5 use
1 participant