mirror of
https://github.com/openssl/openssl.git
synced 2024-11-29 04:55:11 +08:00
Make the PKCS#7 S/MIME functions check for passed NULL pointers.
Fix the usage message of smime utility and sanitise the return codes. Add some documentation.
This commit is contained in:
parent
a4af39ac44
commit
e3775a33c1
28
apps/smime.c
28
apps/smime.c
@ -136,6 +136,8 @@ int MAIN(int argc, char **argv)
|
||||
flags &= ~PKCS7_DETACHED;
|
||||
else if (!strcmp (*args, "-binary"))
|
||||
flags |= PKCS7_BINARY;
|
||||
else if (!strcmp (*args, "-nosigs"))
|
||||
flags |= PKCS7_NOSIGS;
|
||||
else if (!strcmp (*args, "-to")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
@ -224,6 +226,13 @@ int MAIN(int argc, char **argv)
|
||||
BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40\n");
|
||||
BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n");
|
||||
BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n");
|
||||
BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n");
|
||||
BIO_printf (bio_err, "-nosigs don't verify message signature\n");
|
||||
BIO_printf (bio_err, "-noverify don't verify signers certificate\n");
|
||||
BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n");
|
||||
BIO_printf (bio_err, "-nodetach use opaque signing\n");
|
||||
BIO_printf (bio_err, "-noattr don't include any signed attributes\n");
|
||||
BIO_printf (bio_err, "-binary don't translate message to text\n");
|
||||
BIO_printf (bio_err, "-in file input file\n");
|
||||
BIO_printf (bio_err, "-certfile file other certificates file\n");
|
||||
BIO_printf (bio_err, "-signer file signer certificate file\n");
|
||||
@ -235,6 +244,8 @@ int MAIN(int argc, char **argv)
|
||||
BIO_printf (bio_err, "-from ad from address\n");
|
||||
BIO_printf (bio_err, "-subject s subject\n");
|
||||
BIO_printf (bio_err, "-text include or delete text MIME headers\n");
|
||||
BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
|
||||
BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
|
||||
BIO_printf (bio_err, "cert.pem recipient certificate(s)\n");
|
||||
goto end;
|
||||
}
|
||||
@ -319,6 +330,7 @@ int MAIN(int argc, char **argv)
|
||||
if(!(store = setup_verify(CAfile, CApath))) goto end;
|
||||
|
||||
ret = 3;
|
||||
|
||||
if(operation == SMIME_ENCRYPT) {
|
||||
p7 = PKCS7_encrypt(encerts, in, cipher, flags);
|
||||
} else if(operation == SMIME_SIGN) {
|
||||
@ -327,34 +339,35 @@ int MAIN(int argc, char **argv)
|
||||
} else {
|
||||
if(!(p7 = SMIME_read_PKCS7(in, &indata))) {
|
||||
BIO_printf(bio_err, "Error reading S/MIME message\n");
|
||||
ret = 4;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!p7) {
|
||||
BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 4;
|
||||
if(operation == SMIME_DECRYPT) {
|
||||
if(!PKCS7_decrypt(p7, key, recip, out, flags))
|
||||
if(!PKCS7_decrypt(p7, key, recip, out, flags)) {
|
||||
BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
|
||||
else ret = 0;
|
||||
goto end;
|
||||
}
|
||||
} else if(operation == SMIME_VERIFY) {
|
||||
STACK_OF(X509) *signers;
|
||||
signers = PKCS7_iget_signers(p7, other, flags);
|
||||
if(PKCS7_verify(p7, other, store, indata, out, flags)) {
|
||||
BIO_printf(bio_err, "Verification Successful\n");
|
||||
ret = 0;
|
||||
} else {
|
||||
BIO_printf(bio_err, "Verification Failure\n");
|
||||
ret = 5;
|
||||
goto end;
|
||||
}
|
||||
if(!save_certs(signerfile, signers)) {
|
||||
BIO_printf(bio_err, "Error writing signers to %s\n",
|
||||
signerfile);
|
||||
ret = 2;
|
||||
ret = 5;
|
||||
goto end;
|
||||
}
|
||||
sk_X509_free(signers);
|
||||
} else if(operation == SMIME_PK7OUT) {
|
||||
@ -365,6 +378,7 @@ int MAIN(int argc, char **argv)
|
||||
if(subject) BIO_printf(out, "Subject: %s\n", subject);
|
||||
SMIME_write_PKCS7(out, p7, in, flags);
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if(ret) ERR_print_errors(bio_err);
|
||||
sk_X509_pop_free(encerts, X509_free);
|
||||
|
@ -150,14 +150,19 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
BIO *p7bio;
|
||||
BIO *tmpout;
|
||||
|
||||
if(!p7) {
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!PKCS7_type_is_signed(p7)) {
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for no data and no content: no data to verify signature */
|
||||
if(PKCS7_get_detached(p7) && !indata) {
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -170,7 +175,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
|
||||
sinfos = PKCS7_get_signer_info(p7);
|
||||
|
||||
if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
|
||||
PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -264,6 +269,11 @@ STACK_OF(X509) *PKCS7_iget_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
|
||||
X509 *signer;
|
||||
int i;
|
||||
|
||||
if(!p7) {
|
||||
PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!PKCS7_type_is_signed(p7)) {
|
||||
PKCS7err(PKCS7_F_PKCS7_IGET_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
|
||||
return NULL;
|
||||
@ -376,10 +386,17 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
|
||||
BIO *tmpmem;
|
||||
int ret, i;
|
||||
char buf[4096];
|
||||
|
||||
if(!p7) {
|
||||
PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!PKCS7_type_is_enveloped(p7)) {
|
||||
PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!X509_check_private_key(cert, pkey)) {
|
||||
PKCS7err(PKCS7_F_PKCS7_DECRYPT,
|
||||
PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
|
||||
|
@ -455,6 +455,7 @@ int SMIME_text(BIO *in, BIO *out);
|
||||
#define PKCS7_R_ERROR_SETTING_CIPHER 121
|
||||
#define PKCS7_R_INTERNAL_ERROR 102
|
||||
#define PKCS7_R_INVALID_MIME_TYPE 131
|
||||
#define PKCS7_R_INVALID_NULL_POINTER 143
|
||||
#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
|
||||
#define PKCS7_R_MIME_PARSE_ERROR 133
|
||||
#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
|
||||
|
@ -105,6 +105,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
|
||||
{PKCS7_R_ERROR_SETTING_CIPHER ,"error setting cipher"},
|
||||
{PKCS7_R_INTERNAL_ERROR ,"internal error"},
|
||||
{PKCS7_R_INVALID_MIME_TYPE ,"invalid mime type"},
|
||||
{PKCS7_R_INVALID_NULL_POINTER ,"invalid null pointer"},
|
||||
{PKCS7_R_MIME_NO_CONTENT_TYPE ,"mime no content type"},
|
||||
{PKCS7_R_MIME_PARSE_ERROR ,"mime parse error"},
|
||||
{PKCS7_R_MIME_SIG_PARSE_ERROR ,"mime sig parse error"},
|
||||
|
241
doc/man/smime.pod
Normal file
241
doc/man/smime.pod
Normal file
@ -0,0 +1,241 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
smime - S/MIME utility
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<openssl> B<smime>
|
||||
[B<-encrypt>]
|
||||
[B<-decrypt>]
|
||||
[B<-sign>]
|
||||
[B<-verify>]
|
||||
[B<-pk7out>]
|
||||
[B<-des3>]
|
||||
[B<-rc2-40>]
|
||||
[B<-rc2-64>]
|
||||
[B<-rc2-128>]
|
||||
[B<-in file>]
|
||||
[B<-certfile file>]
|
||||
[B<-signer file>]
|
||||
[B<-recip file>]
|
||||
[B<-in file>]
|
||||
[B<-inkey file>]
|
||||
[B<-out file>]
|
||||
[B<-to addr>]
|
||||
[B<-from ad>]
|
||||
[B<-subject s>]
|
||||
[B<-text>]
|
||||
[cert.pem]...
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<smime> command handles S/MIME mail. It can encrypt, decrypt, sign and
|
||||
verify S/MIME messages.
|
||||
|
||||
=head1 COMMAND OPTIONS
|
||||
|
||||
There are five operation options that set the type of operation to be performed.
|
||||
The meaning of the other options varies according to the operation type.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-encrypt>
|
||||
|
||||
encrypt mail for the given recipient certificates. Input file is the message
|
||||
to be encrypted. The output file is the encrypted mail in MIME format.
|
||||
|
||||
=item B<-decrypt>
|
||||
|
||||
decrypt mail using the supplied certificate and private key. Expects an
|
||||
encrypted mail message in MIME format for the input file. The decrypted mail
|
||||
is written to the output file.
|
||||
|
||||
=item B<-sign>
|
||||
|
||||
sign mail using the supplied certificate and private key. Input file is
|
||||
the message to be signed. The signed message in MIME format is written
|
||||
to the output file.
|
||||
|
||||
=item B<-verify>
|
||||
|
||||
verify signed mail. Expects a signed mail message on input and outputs
|
||||
the signed data. Both clear text and opaque signing is supported.
|
||||
|
||||
=item B<-pk7out>
|
||||
|
||||
takes an input message and writes out a PEM encoded PKCS#7 structure.
|
||||
|
||||
=item B<-in filename>
|
||||
|
||||
the input message to be encrypted or signed or the MIME message to
|
||||
be decrypted or verified.
|
||||
|
||||
=item B<-out filename>
|
||||
|
||||
the message text that has been decrypted or verified or the output MIME
|
||||
format message that has been signed or verified.
|
||||
|
||||
=item B<-text>
|
||||
|
||||
this option adds plain text (text/plain) MIME headers to the supplied
|
||||
message if encrypting or signing. If decrypting or verifying it strips
|
||||
off text headers: if the decrypted or verified message is not of MIME
|
||||
type text/plain then an error occurs.
|
||||
|
||||
=item B<-CAfile file>
|
||||
|
||||
a file containing trusted CA certificates, only used with B<-verify>.
|
||||
|
||||
=item B<-CApath dir>
|
||||
|
||||
a directory containing trusted CA certificates, only used with
|
||||
B<-verify>. This directory must be a standard certificate directory: that
|
||||
is a hash of each subject name (using B<x509 -hash>) should be linked
|
||||
to each certificate.
|
||||
|
||||
=item B<-des3 -rc2-40 -rc2-64 -rc2-128>
|
||||
|
||||
the encryption algorithm to use. DES (56 bits), triple DES (168 bits)
|
||||
or 40, 64 or 128 bit RC2 respectively if not specified 40 bit RC2 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.
|
||||
|
||||
=item B<-noverify>
|
||||
|
||||
do not verify the signers certificate of a signed message.
|
||||
|
||||
=item B<-nochain>
|
||||
|
||||
do not do chain verification of signers certfificates: that is don't
|
||||
use the certificates in the signed message as untrusted CAs.
|
||||
|
||||
=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
|
||||
available locally (passed using the B<-certfile> option for example).
|
||||
|
||||
=item B<-noattr>
|
||||
|
||||
normally when a message is signed a set of attributes are included which
|
||||
include the signing time and supported symmetric algorithms. With this
|
||||
option they are not included.
|
||||
|
||||
=item B<-binary>
|
||||
|
||||
normally the input message is converted to "canonical" format which is
|
||||
effectively using CR and LF as end of line. When this option is present
|
||||
no translation occurs. This is useful when handling binary data which may
|
||||
not be in MIME format.
|
||||
|
||||
=item B<-nodetach>
|
||||
|
||||
when signing a message use opaque signing: this form is more resistant
|
||||
to translation by mail relays but it cannot be read by mail agents that
|
||||
do not support S/MIME. Without this option cleartext signing with
|
||||
the MIME type multipart/signed is used.
|
||||
|
||||
=item B<-certfile 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. The certificates should be in PEM format.
|
||||
|
||||
=item B<-signer file>
|
||||
|
||||
the signers certificate when signing a message. If a message is
|
||||
being verified then the signers certificates will be written to this
|
||||
file if the verification was successful.
|
||||
|
||||
=item B<-recip file>
|
||||
|
||||
the recipients certificate when decrypting a message. This certificate
|
||||
must match one of the recipients of the message or an error occurs.
|
||||
|
||||
=item B<-inkey file>
|
||||
|
||||
the private key to use when signing or decrypting. This must match the
|
||||
corresponding certificate. If this option is not specified then the
|
||||
private key must be included in the certificate file specified with
|
||||
the B<-recip> or B<-signer> file.
|
||||
|
||||
=item B<cert.pem...>
|
||||
|
||||
one or more certificates of message recipients: used when encrypting
|
||||
a message.
|
||||
|
||||
=item B<-to, -from, -subject>
|
||||
|
||||
the relevant mail headers. These are included outside the signed
|
||||
portion of a message so they may be included manually. If signing
|
||||
then many S/MIME mail clients check the signers certificate's email
|
||||
address matches that specified in the From: address.
|
||||
|
||||
=back
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The MIME message must be sent without any blank lines between the
|
||||
headers and the output. Some mail programs will automatically add
|
||||
a blank line. Piping the mail directly to sendmail is one way to
|
||||
achieve the correct format.
|
||||
|
||||
A "signed and encrypted" message is one where a signed message is
|
||||
then encrypted. This can be produced by encrypting an already signed
|
||||
message.
|
||||
|
||||
This version of the program only allows one signer per message but it
|
||||
will verify multiple signers on received messages. Some S/MIME clients
|
||||
choke if a message contains mutiple signers. It is possible to sign
|
||||
messages "in parallel" by signing an already signed message.
|
||||
|
||||
=head1 EXIT CODES
|
||||
|
||||
=over 4
|
||||
|
||||
=item 0
|
||||
|
||||
the operation was completely successful
|
||||
|
||||
=item 1
|
||||
|
||||
an error occurred parsing the command options.
|
||||
|
||||
=item 2
|
||||
|
||||
one of the input files could not be read.
|
||||
|
||||
=item 3
|
||||
|
||||
an error occurred creating the PKCS#7 file or when reading the MIME
|
||||
message.
|
||||
|
||||
=item 4
|
||||
|
||||
an error occurred decrypting or verifying the message.
|
||||
|
||||
=item 5
|
||||
|
||||
the message was verified correctly but an error occured writing out
|
||||
the signers certificates.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
to be added.
|
||||
|
||||
=cut
|
Loading…
Reference in New Issue
Block a user