Files
David Benjamin 34a1d37575 Implement functions to generate CMS external signatures
This implements just the small subset of OpenSSL's CMS API to support
the Linux kernel's sign-file.c tool. It is nowhere close to a full CMS
implementation and is not intended to become one. In particular, it does
not implement enough of CMS to support S/MIME. That requires much, much
more infrastructure than was implemented here.

CMS is, like PKCS#7, an over-engineered and cryptographically unsound
set of nestable combinators to support just about any configuration of
cryptographic operations. Profiling CMS down to a usable subset is, as a
result, more complicated, more risky, and less efficient than just
designing a bespoke structure for your use case. It is derived from
PKCS#7, and largely overlaps. However, both PKCS#7 and CMS use the v1
version number, but CMS made incompatible changes in some corner cases
that, so far, do not matter to us. (It is incompatible if you try to
layer SignedData atop another combinator, where the lack of proper
domain separation in this badly designed format is of extra risk.)

In the case of the kernel, sign-file.c wants an "external signature",
which is when the data to be signed lives elsewhere. This is, as a
result, a very, very inefficient way to concatenate an enum with a byte
string. But this is what the kernel chose, so here we are.

Because PKCS#7 and CMS are broadly the same structure, I've generalized
the internal PKCS#7 function rather than duplicating all this code. If
we ever hit the cases where PKCS#7 and CMS v1 are incompatible, plumbing
an extra boolean will be the least of our worries.

Test data was generated by compiling the actual sign-file.c against
OpenSSL and saving the output.

Change-Id: Idb0874d2b5294bfad564f3a00458c3fd044d9da5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78452
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2025-04-14 13:44:28 -07:00

79 lines
2.4 KiB
C

// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This header is provided in order to make compiling against code that expects
// OpenSSL easier.
#ifndef OPENSSL_HEADER_OPENSSLCONF_H
#define OPENSSL_HEADER_OPENSSLCONF_H
// Keep in sync with the list in rust/bssl-sys/build.rs.
#define OPENSSL_NO_ASYNC
#define OPENSSL_NO_BF
#define OPENSSL_NO_BLAKE2
#define OPENSSL_NO_BUF_FREELISTS
#define OPENSSL_NO_CAMELLIA
#define OPENSSL_NO_CAPIENG
#define OPENSSL_NO_CAST
#define OPENSSL_NO_COMP
#define OPENSSL_NO_CT
#define OPENSSL_NO_DANE
#define OPENSSL_NO_DEPRECATED
#define OPENSSL_NO_DGRAM
#define OPENSSL_NO_DYNAMIC_ENGINE
#define OPENSSL_NO_EC_NISTP_64_GCC_128
#define OPENSSL_NO_EC2M
#define OPENSSL_NO_EGD
#define OPENSSL_NO_ENGINE
#define OPENSSL_NO_GMP
#define OPENSSL_NO_GOST
#define OPENSSL_NO_HEARTBEATS
#define OPENSSL_NO_HW
#define OPENSSL_NO_IDEA
#define OPENSSL_NO_JPAKE
#define OPENSSL_NO_KRB5
#define OPENSSL_NO_MD2
#define OPENSSL_NO_MDC2
#define OPENSSL_NO_OCB
#define OPENSSL_NO_OCSP
#define OPENSSL_NO_RC2
#define OPENSSL_NO_RC5
#define OPENSSL_NO_RFC3779
#define OPENSSL_NO_RIPEMD
#define OPENSSL_NO_RMD160
#define OPENSSL_NO_SCTP
#define OPENSSL_NO_SEED
#define OPENSSL_NO_SM2
#define OPENSSL_NO_SM3
#define OPENSSL_NO_SM4
#define OPENSSL_NO_SRP
#define OPENSSL_NO_SSL_TRACE
#define OPENSSL_NO_SSL2
#define OPENSSL_NO_SSL3
#define OPENSSL_NO_SSL3_METHOD
#define OPENSSL_NO_STATIC_ENGINE
#define OPENSSL_NO_STORE
#define OPENSSL_NO_WHIRLPOOL
// We do not implement OpenSSL's CMS API, except for a tiny subset. Projects
// targeting the tiny subset can define BORINGSSL_NO_NO_CMS to suppress
// OPENSSL_NO_CMS, to make it easier to compile code that expects OpenSSL. This
// option does not change what APIs are exposed by BoringSSL, only this macro.
#if !defined(BORINGSSL_NO_NO_CMS)
#define OPENSSL_NO_CMS
#endif
#endif // OPENSSL_HEADER_OPENSSLCONF_H