#cms #apple #codesign #rfc5652

cryptographic-message-syntax

A pure Rust implementation of Crypographic Message Syntax (RFC 5652)

17 breaking releases

Uses new Rust 2021

0.18.0 Sep 17, 2022
0.16.0 Apr 25, 2022
0.13.0 Mar 28, 2022
0.6.0 Dec 13, 2021
0.3.0 May 6, 2021

#186 in Cryptography

Download history 275/week @ 2022-06-07 186/week @ 2022-06-14 312/week @ 2022-06-21 221/week @ 2022-06-28 265/week @ 2022-07-05 211/week @ 2022-07-12 340/week @ 2022-07-19 532/week @ 2022-07-26 477/week @ 2022-08-02 577/week @ 2022-08-09 413/week @ 2022-08-16 803/week @ 2022-08-23 679/week @ 2022-08-30 622/week @ 2022-09-06 1049/week @ 2022-09-13 1086/week @ 2022-09-20

3,611 downloads per month
Used in 9 crates (4 directly)

MPL-2.0 license

340KB
6.5K SLoC

cryptographic-message-syntax

cryptographic-message-syntax is a pure Rust implementation of Cryptographic Message Syntax (CMS) as defined by RFC 5652. Also included is Time-Stamp Protocol (TSP) (RFC 3161) client support.

From a high level CMS defines a way to digitally sign and authenticate arbitrary content.

CMS is used to power the digital signatures embedded within Mach-O binaries on Apple platforms such as macOS and iOS. The primitives in this crate could be used to sign and authenticate Mach-O binaries. (See the sister apple-codesign crate in the Git repository for code that does just this.)

This crate is developed as part of the PyOxidizer project and is developed in that repository. While this crate is developed as part of a larger product, it is authored such that it can be used standalone and modifications to supports its use outside of its original use case are very much welcome!


lib.rs:

Cryptographic Message Syntax (RFC 5652) in Pure Rust

This crate attempts to implement parts of RFC 5652 in pure, safe Rust.

Functionality includes:

  • Partial (de)serialization support for ASN.1 data structures. The Rust structs are all defined. But not everything has (de)serialization code implemented.
  • High-level Rust API for extracting useful attributes from a parsed SignedData structure and performing common operations, such as verifying signature integrity.

RFC 5652 is quite old. If you are looking to digitally sign content, you may want to look at something newer, such as RPKI (RFC 6488). (RPKI appears to be the spiritual success to this specification.)

IMPORTANT SECURITY LIMITATIONS

The verification functionality in this crate is purposefully limited and isn't sufficient for trusting signed data. You need to include additional trust verification if you are using this crate for verifying signed data.

This crate exposes functionality to verify signatures and content integrity of signed data. Specifically it can verify that an embedded cryptographic signature over some arbitrary/embedded content was issued by a known signing certificate. This answers the question did certificate X sign content Y. This is an important question to answer, but it fails to answer other important questions such as:

  • Is the signature cryptographically strong or weak? Do I trust the signature?
  • Do I trust the signer?

Answering do I trust the signer is an extremely difficult and nuanced problem. It entails things like:

  • Ensuring the signing certificate is using secure cryptography.
  • Validating that the signing certificate is one you think it was or was issued by a trusted party.
  • Validating the certificate isn't expired or hasn't been revoked.
  • Validating that the certificate contains attributes/extensions desired (e.g. a certificate can be earmarked as used for signing code).

If you are using this crate as part of verifying signed content, you need to have answers to these hard questions. This will require writing code beyond what is available in this crate. You ideally want to use existing libraries for this, as getting this correct is difficult. Ideally you would consult a security/cryptography domain expert for help.

Technical Notes

RFC 5652 is based off PKCS #7 version 1.5 (RFC 2315). So common tools/libraries for interacting with PKCS #7 may have success parsing this format. For example, you can use OpenSSL to read the data structures:

$ openssl pkcs7 -inform DER -in -print $ openssl pkcs7 -inform PEM -in -print $ openssl asn1parse -inform DER -in

RFC 5652 uses BER (not DER) for serialization. There were attempts to use other, more popular BER/DER/ASN.1 serialization crates. However, we could only get bcder working. In a similar vein, there are other crates implementing support for common ASN.1 functionality, such as serializing X.509 certificates. Again, many of these depend on serializers that don't seem to be compatible with BER. So we've recursively defined ASN.1 data structures referenced by RFC5652 and taught them to serialize using bcder.

Dependencies

~9–18MB
~429K SLoC