Skip to content

Commit

Permalink
PKCS7 and SMIME: improve documentation w.r.t. untrusted and signer ce…
Browse files Browse the repository at this point in the history
…rtificates
  • Loading branch information
DDvO committed Oct 4, 2023
1 parent 234ddea commit 38f4c9e
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 73 deletions.
7 changes: 5 additions & 2 deletions apps/cms.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ const OPTIONS cms_options[] = {
OPT_SECTION("Signing"),
{"md", OPT_MD, 's', "Digest algorithm to use"},
{"signer", OPT_SIGNER, 's', "Signer certificate input file"},
{"certfile", OPT_CERTFILE, '<', "Other certificates file"},
{"certfile", OPT_CERTFILE, '<',
"Other certificates to include when signing or to use when verifying;"},
{OPT_MORE_STR, 0, 0,
"may be used for chain building and as signer cerificates"},
{"cades", OPT_CADES, '-',
"Include signingCertificate attribute (CAdES-BES)"},
{"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
Expand Down Expand Up @@ -843,7 +846,7 @@ int cms_main(int argc, char **argv)
}

if (certfile != NULL) {
if (!load_certs(certfile, 0, &other, NULL, "certificate file")) {
if (!load_certs(certfile, 0, &other, NULL, "other certificates")) {
ERR_print_errors(bio_err);
goto end;
}
Expand Down
9 changes: 6 additions & 3 deletions apps/smime.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ const OPTIONS smime_options[] = {
{"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
{"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"},

{"certfile", OPT_CERTFILE, '<', "Other certificates file"},
{"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"},

OPT_SECTION("Email"),
Expand All @@ -107,6 +106,10 @@ const OPTIONS smime_options[] = {
{"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},

OPT_SECTION("Certificate chain"),
{"certfile", OPT_CERTFILE, '<',
"Other certificates to include when signing or to use when verifying;"},
{OPT_MORE_STR, 0, 0,
"may be used for chain building and as signer cerificates"},
{"CApath", OPT_CAPATH, '/', "Trusted certificates directory"},
{"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
{"CAstore", OPT_CASTORE, ':', "Trusted certificates store URI"},
Expand All @@ -117,7 +120,7 @@ const OPTIONS smime_options[] = {
{"no-CAstore", OPT_NOCASTORE, '-',
"Do not load certificates from the default certificates store"},
{"nochain", OPT_NOCHAIN, '-',
"set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" },
"Do not use certs contained in the message as untrusted CAs for chain building" },
{"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"},

OPT_R_OPTIONS,
Expand Down Expand Up @@ -491,7 +494,7 @@ int smime_main(int argc, char **argv)
}

if (certfile != NULL) {
if (!load_certs(certfile, 0, &other, NULL, "certificates")) {
if (!load_certs(certfile, 0, &other, NULL, "other certificates")) {
ERR_print_errors(bio_err);
goto end;
}
Expand Down
1 change: 1 addition & 0 deletions crypto/cms/cms_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct CMS_SignedData_st {
int32_t version;
STACK_OF(X509_ALGOR) *digestAlgorithms;
CMS_EncapsulatedContentInfo *encapContentInfo;
/* untrusted certificates for chain building, may include signer certs: */
STACK_OF(CMS_CertificateChoices) *certificates;
STACK_OF(CMS_RevocationInfoChoice) *crls;
STACK_OF(CMS_SignerInfo) *signerInfos;
Expand Down
2 changes: 1 addition & 1 deletion crypto/cms/cms_sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,6 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
}

if (!(flags & CMS_NOCERTS)) {
/* NB ignore -1 return for duplicate cert */
if (!CMS_add1_cert(cms, signer)) {
ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
goto err;
Expand Down Expand Up @@ -653,6 +652,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
if (si->signer != NULL)
continue;

/* If any certificates passed they take priority */
for (j = 0; j < sk_X509_num(scerts); j++) {
x = sk_X509_value(scerts, j);
if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
Expand Down
23 changes: 13 additions & 10 deletions doc/man1/openssl-cms.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,11 @@ used multiple times if more than one signer is required.

=item B<-certfile> I<file>

Allows additional certificates to be specified. When signing these will
be included with the message. When verifying these will be searched for
the signers certificates.
Provide additional certificates.
When signing, these will be included
in the message to help chain building and to provide extra signer certificates.
When verifying, these will be searched first for signer certificates.

The input can be in PEM, DER, or PKCS#12 format.

=item B<-cades>
Expand All @@ -473,9 +475,9 @@ the MIME type multipart/signed is used.

=item B<-nocerts>

When signing a message the signer's certificate is normally included
with this option it is excluded. This will reduce the size of the
signed message but the verifier must have a copy of the signers certificate
When signing a message, the signer's certificate it normally
included, but this option disables its inclusion. This will reduce the size of
the signed message but the verifier must have a copy of the signers certificate
available locally (passed using the B<-certfile> option for example).

=item B<-noattr>
Expand Down Expand Up @@ -542,10 +544,11 @@ Do not verify the signers certificate of a signed message.

=item B<-nointern>

When verifying a message normally certificates (if any) included in
the message are searched for the signing certificate. With this option
only the certificates specified in the B<-certfile> option are used.
The supplied certificates can still be used as untrusted CAs however.
When verifying a message, normally certificates (if any) included in
the message are searched for the signing certificate. With this option,
only the certificates given with the B<-certfile> option are used.
However, the certificates included in
the message are still used for chain building as certificates of untrusted CAs.

=item B<-cades>

Expand Down
32 changes: 16 additions & 16 deletions doc/man1/openssl-smime.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -177,29 +177,31 @@ If not specified triple DES is used. Only used with B<-encrypt>.

=item B<-nointern>

When verifying a message normally certificates (if any) included in
the message are searched for the signing certificate. With this option
only the certificates specified in the B<-certfile> option are used.
The supplied certificates can still be used as untrusted CAs however.
When verifying a message, normally certificates (if any) included in
the message are searched for the signing certificate. With this option,
only the certificates given with the B<-certfile> option are used.
However, unless the B<-nochain> option is given, the certificates included in
the message are still used for chain building as certificates of untrusted CAs.

=item B<-noverify>

Do not verify the signers certificate of a signed message.

=item B<-nochain>

Do not do chain verification of signers certificates; that is, do not
use the certificates in the signed message as untrusted CAs.
During chain verification of signer certificates, do not use the certificates
in the signed message as untrusted CA certificates for chain building.

=item B<-nosigs>

Don't try to verify the signatures on the message.

=item B<-nocerts>

When signing a message the signer's certificate is normally included
with this option it is excluded. This will reduce the size of the
signed message but the verifier must have a copy of the signers certificate
When signing a message, the signer's certificate and chain certificates are
normally included, but this option disables their inclusion.
This will reduce the size of
the signed message but the verifier must have a copy of those certificates
available locally (passed using the B<-certfile> option for example).

=item B<-noattr>
Expand Down Expand Up @@ -233,9 +235,11 @@ option is present B<CRLF> is used instead.

=item B<-certfile> I<file>

Allows additional certificates to be specified. When signing these will
be included with the message. When verifying these will be searched for
the signers certificates.
Provide additional certificates.
When signing, these will be included (unless the B<-nocerts> option is given)
in the message to help chain building and to provide extra signer certificates.
When verifying, these will be searched first for signer certificates.

The input can be in PEM, DER, or PKCS#12 format.

=item B<-signer> I<file>
Expand All @@ -245,10 +249,6 @@ used multiple times if more than one signer is required. If a message is being
verified then the signers certificates will be written to this file if the
verification was successful.

=item B<-nocerts>

Don't include signers certificate when signing.

=item B<-noattr>

Don't include any signed attributes when signing.
Expand Down
12 changes: 5 additions & 7 deletions doc/man3/CMS_add0_cert.pod
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,20 @@ CMS_add0_crl, CMS_add1_crl, CMS_get1_crls

CMS_add0_cert() and CMS_add1_cert() add certificate I<cert> to I<cms>
unless it is already present.
This is used by L<CMS_sign_ex(3)> and L<CMS_sign(3)> and may be used before
calling L<CMS_verify(3)> to help chain building in certificate validation.
This can be used with L<CMS_sign_ex(3)> and L<CMS_sign(3)>
to include a chain certificate or an extra signer certificate
and may be used with L<CMS_verify(3)> to set a
fallback signer certificate or to help chain building in certificate validation.
As the 0 implies, CMS_add0_cert() adds I<cert> internally to I<cms>
and on success it must not be freed up by the caller.
In contrast, the caller of CMS_add1_cert() must free I<cert>.
I<cms> must be of type signed data or (authenticated) enveloped data.
For signed data, such a certificate can be used when signing or verifying
to fill in the signer certificate or to provide an extra CA certificate
that may be needed for chain building in certificate validation.

CMS_get1_certs() returns all certificates in I<cms>.

CMS_add0_crl() and CMS_add1_crl() add CRL I<crl> to I<cms>.
I<cms> must be of type signed data or (authenticated) enveloped data.
For signed data, such a CRL may be used in certificate validation
with L<CMS_verify(3)>.
Such a CRL may be used in certificate validation, e.g., with L<CMS_verify(3)>.
It may be given both for inclusion when signing a CMS message
and when verifying a signed CMS message.

Expand Down
6 changes: 3 additions & 3 deletions doc/man3/CMS_verify.pod
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ CMS_get0_signers - verify a CMS SignedData structure
CMS_verify() is very similar to L<PKCS7_verify(3)>. It verifies a
B<CMS SignedData> structure contained in a structure of type B<CMS_ContentInfo>.
I<cms> points to the B<CMS_ContentInfo> structure to verify.
The optional I<certs> parameter refers to a set of certificates
in which to search for signing certificates.
The optional I<certs> parameter can provide a list of certificates,
which is searched first for the signer's certificate.
I<cms> may contain extra untrusted CA certificates that may be used for
chain building as well as CRLs that may be used for certificate validation.
I<store> may be NULL or point to
Expand Down Expand Up @@ -59,7 +59,7 @@ be SignedData. There must be at least one signature on the data and if
the content is detached I<detached_data> cannot be NULL.

An attempt is made to locate all the signing certificate(s), first looking in
the I<certs> parameter (if it is not NULL) and then looking in any
the I<certs> parameter (if it is not NULL). Then they are looked up in any
certificates contained in the I<cms> structure unless B<CMS_NOINTERN> is set.
If any signing certificate cannot be located the operation fails.

Expand Down
21 changes: 11 additions & 10 deletions doc/man3/PKCS7_sign.pod
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ PKCS7_sign_ex, PKCS7_sign

PKCS7_sign_ex() creates and returns a PKCS#7 signedData structure.
I<signcert> is the certificate to sign with, I<pkey> is the corresponding
private key. I<certs> is an optional set of extra certificates to include
in the PKCS#7 structure (for example any intermediate CAs in the chain).
private key. I<certs> is an optional additional set of certificates to include,
unless B<PKCS7_NOCERTS> is set, in the B<PKCS7> structure. They may be used as
untrusted CA certificates for chain building or as extra signer cerificates.
The library context I<libctx> and property query I<propq> are used when
retrieving algorithms from providers.

Expand All @@ -35,14 +36,14 @@ Many S/MIME clients expect the signed content to include valid MIME headers. If
the B<PKCS7_TEXT> flag is set MIME headers for type C<text/plain> are prepended
to the data.

If B<PKCS7_NOCERTS> is set the signer's certificate and the extra I<certs>
will not be included in the PKCS7 structure.
The signer's certificate must still be supplied in the I<signcert> parameter
though. This can reduce the size of the signatures if the signer's certificates
If B<PKCS7_NOCERTS> is set, the signer's certificate and extra certificates
given in the I<certs> parameter will not be included in the B<PKCS7> structure.
The signer's certificate must still be supplied in the B<signcert> parameter
though. This can reduce the size of the signatures if the signer certificates
can be obtained by other means: for example a previously signed message.

The data being signed is included in the PKCS7 structure, unless
B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS7
The data being signed is included in the B<PKCS7> structure, unless
B<PKCS7_DETACHED> is set in which case it is omitted. This is used for PKCS#7
detached signatures which are used in S/MIME plaintext signed messages for
example.

Expand Down Expand Up @@ -89,7 +90,7 @@ called to finalize the structure if streaming is not enabled. Alternative
signing digests can also be specified using this method.

If I<signcert> and I<pkey> are NULL then a certificates only
PKCS#7 structure is output.
B<PKCS7> structure is output.

In versions of OpenSSL before 1.0.0 the I<signcert> and I<pkey> parameters must
not be NULL.
Expand All @@ -104,7 +105,7 @@ Some advanced attributes such as counter signatures are not supported.

=head1 RETURN VALUES

PKCS7_sign_ex() and PKCS7_sign() return either a valid PKCS7 structure
PKCS7_sign_ex() and PKCS7_sign() return either a valid B<PKCS7> structure
or NULL if an error occurred. The error can be obtained from ERR_get_error(3).

=head1 SEE ALSO
Expand Down
40 changes: 23 additions & 17 deletions doc/man3/PKCS7_sign_add_signer.pod
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,31 @@ Unless the B<PKCS7_REUSE_DIGEST> flag is set the returned B<PKCS7> structure
is not complete and must be finalized either by streaming (if applicable) or
a call to PKCS7_final().

PKCS7_add_certificate() adds to the B<PKCS7> structure I<p7> the certificate
I<cert>, which may be an end-entity (signer) certificate
or a CA certificate useful for chain building.
This is done internally by L<PKCS7_sign_ex(3)> and similar signing functions
but can also be called directly to add a further such certificate.
It may be used before calling L<PKCS7_verify(3)>
to provide any missing certificate(s) needed for chain building
or to provide a fallback signer certificate.

PKCS7_add_crl() adds the CRL I<crl> to the B<PKCS7> structure I<p7>.
This may be called to provide certificate status information
to be included when signing or to use when verifying the B<PKCS7> structure.

=head1 NOTES

The main purpose of this function is to provide finer control over a PKCS#7
The main purpose of these functions is to provide finer control over a PKCS#7
signed data structure where the simpler PKCS7_sign() function defaults are
not appropriate. For example if multiple signers or non default digest
algorithms are needed.

The PKCS7 structure I<p7> argument must be of type signed data or
signed-and-enveloped data or an error will be returned.

Any of the following flags (ored together) can be passed in the I<flags>
parameter.
parameter of PKCS7_sign_add_signer().

If B<PKCS7_REUSE_DIGEST> is set then an attempt is made to copy the content
digest value from the B<PKCS7> structure: to add a signer to an existing structure.
Expand Down Expand Up @@ -67,25 +82,16 @@ If present the SMIMECapabilities attribute indicates support for the following
algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of
these algorithms is disabled then it will not be included.

PKCS7_sign_add_signers() returns an internal pointer to the B<PKCS7_SIGNER_INFO>
structure just added, which can be used to set additional attributes
before it is finalized.

PKCS7_add_certificate() adds to the B<PKCS7> structure I<p7> the certificate
I<cert>, which may be an end-entity (signer) certificate
or a CA certificate useful for chain building.
This is done internally by L<PKCS7_sign_ex(3)> and similar signing functions.
It may have to be used before calling L<PKCS7_verify(3)>
in order to provide any missing certificate(s) needed for verification.

PKCS7_add_crl() adds the CRL I<crl> to the B<PKCS7> structure I<p7>.
This may be called to provide certificate status information
to be included when signing or to use when verifying the B<PKCS7> structure.
Certificates and CRLs are added to the I<cert> or
I<crl> fields of PKCS7_SIGNED structure.
A certificate or CRL may be added to the same PKCS7 structure
more than once, although this does not make sense.

=head1 RETURN VALUES

PKCS7_sign_add_signers() returns an internal pointer to the B<PKCS7_SIGNER_INFO>
structure just added or NULL if an error occurs.
structure just added, which can be used to set additional attributes
before it is finalized, or NULL if an error occurs.

PKCS7_add_certificate() and PKCS7_add_crl() return 1 on success, 0 on error.

Expand Down
7 changes: 3 additions & 4 deletions doc/man3/PKCS7_verify.pod
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ PKCS7_verify, PKCS7_get0_signers - verify a PKCS#7 signedData structure

PKCS7_verify() is very similar to L<CMS_verify(3)>.
It verifies a PKCS#7 signedData structure given in I<p7>.
The optional I<certs> parameter refers to a set of certificates
in which to search for signer's certificates.
The optional I<certs> parameter can provide a list of certificates,
which is searched first for the signer's certificate.
I<p7> may contain extra untrusted CA certificates that may be used for
chain building as well as CRLs that may be used for certificate validation.
I<store> may be NULL or point to
Expand Down Expand Up @@ -83,8 +83,7 @@ returned.
If B<PKCS7_NOVERIFY> is set the signer's certificates are not chain verified.

If B<PKCS7_NOCHAIN> is set then the certificates contained in the message are
not used as untrusted CAs. This means that the whole verify chain (apart from
the signer's certificates) must be contained in the trusted store.
not used as untrusted CA certificates for chain building.

If B<PKCS7_NOSIGS> is set then the signatures on the data are not checked.

Expand Down
2 changes: 2 additions & 0 deletions include/openssl/pkcs7.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ typedef struct pkcs7_recip_info_st {
typedef struct pkcs7_signed_st {
ASN1_INTEGER *version; /* version 1 */
STACK_OF(X509_ALGOR) *md_algs; /* md used */
/* untrusted certificates for chain building, may include signer certs: */
STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */
STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
Expand Down Expand Up @@ -114,6 +115,7 @@ typedef struct pkcs7_enveloped_st {
typedef struct pkcs7_signedandenveloped_st {
ASN1_INTEGER *version; /* version 1 */
STACK_OF(X509_ALGOR) *md_algs; /* md used */
/* untrusted certificates for chain building, may include signer certs: */
STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */
STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
Expand Down

0 comments on commit 38f4c9e

Please sign in to comment.