Backport of CMS code to 0.9.8-stable branch. Disabled by default.
This commit is contained in:
parent
090f931a35
commit
94b2c29f9d
14
CHANGES
14
CHANGES
@ -4,6 +4,20 @@
|
|||||||
|
|
||||||
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
|
Changes between 0.9.8g and 0.9.8h [xx XXX xxxx]
|
||||||
|
|
||||||
|
*) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
|
||||||
|
implemention in the following ways:
|
||||||
|
|
||||||
|
Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
|
||||||
|
hard coded.
|
||||||
|
|
||||||
|
Lack of BER streaming support means one pass streaming processing is
|
||||||
|
only supported if data is detached: setting the streaming flag is
|
||||||
|
ignored for embedded content.
|
||||||
|
|
||||||
|
CMS support is disabled by default and must be explicitly enabled
|
||||||
|
with the enable-cms configuration option.
|
||||||
|
[Steve Henson]
|
||||||
|
|
||||||
*) Zlib compression BIO. This is a filter BIO which compressed and
|
*) Zlib compression BIO. This is a filter BIO which compressed and
|
||||||
uncompresses any data passed through it.
|
uncompresses any data passed through it.
|
||||||
[Steve Henson]
|
[Steve Henson]
|
||||||
|
@ -613,6 +613,7 @@ my $perl;
|
|||||||
|
|
||||||
my %disabled = ( # "what" => "comment"
|
my %disabled = ( # "what" => "comment"
|
||||||
"camellia" => "default",
|
"camellia" => "default",
|
||||||
|
"cms" => "default",
|
||||||
"gmp" => "default",
|
"gmp" => "default",
|
||||||
"mdc2" => "default",
|
"mdc2" => "default",
|
||||||
"rc5" => "default",
|
"rc5" => "default",
|
||||||
|
@ -115,7 +115,7 @@ SDIRS= \
|
|||||||
bn ec rsa dsa ecdsa dh ecdh dso engine \
|
bn ec rsa dsa ecdsa dh ecdh dso engine \
|
||||||
buffer bio stack lhash rand err \
|
buffer bio stack lhash rand err \
|
||||||
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
|
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
|
||||||
store pqueue
|
store cms pqueue
|
||||||
# keep in mind that the above list is adjusted by ./Configure
|
# keep in mind that the above list is adjusted by ./Configure
|
||||||
# according to no-xxx arguments...
|
# according to no-xxx arguments...
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ EXE= $(PROGRAM)$(EXE_EXT)
|
|||||||
E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
|
E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
|
||||||
ca crl rsa rsautl dsa dsaparam ec ecparam \
|
ca crl rsa rsautl dsa dsaparam ec ecparam \
|
||||||
x509 genrsa gendsa s_server s_client speed \
|
x509 genrsa gendsa s_server s_client speed \
|
||||||
s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
|
s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
|
||||||
pkcs8 spkac smime rand engine ocsp prime
|
pkcs8 spkac smime rand engine ocsp prime
|
||||||
|
|
||||||
PROGS= $(PROGRAM).c
|
PROGS= $(PROGRAM).c
|
||||||
@ -56,7 +56,7 @@ E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o er
|
|||||||
x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
|
x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
|
||||||
s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
|
s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
|
||||||
ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o engine.o \
|
ciphers.o nseq.o pkcs12.o pkcs8.o spkac.o smime.o rand.o engine.o \
|
||||||
ocsp.o prime.o
|
ocsp.o prime.o cms.o
|
||||||
|
|
||||||
E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
|
E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
|
||||||
pkcs7.c crl2p7.c crl.c \
|
pkcs7.c crl2p7.c crl.c \
|
||||||
@ -64,7 +64,7 @@ E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.
|
|||||||
x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
|
x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
|
||||||
s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
|
s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
|
||||||
ciphers.c nseq.c pkcs12.c pkcs8.c spkac.c smime.c rand.c engine.c \
|
ciphers.c nseq.c pkcs12.c pkcs8.c spkac.c smime.c rand.c engine.c \
|
||||||
ocsp.c prime.c
|
ocsp.c prime.c cms.c
|
||||||
|
|
||||||
SRC=$(E_SRC)
|
SRC=$(E_SRC)
|
||||||
|
|
||||||
|
1325
apps/cms.c
Normal file
1325
apps/cms.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ extern int speed_main(int argc,char *argv[]);
|
|||||||
extern int s_time_main(int argc,char *argv[]);
|
extern int s_time_main(int argc,char *argv[]);
|
||||||
extern int version_main(int argc,char *argv[]);
|
extern int version_main(int argc,char *argv[]);
|
||||||
extern int pkcs7_main(int argc,char *argv[]);
|
extern int pkcs7_main(int argc,char *argv[]);
|
||||||
|
extern int cms_main(int argc,char *argv[]);
|
||||||
extern int crl2pkcs7_main(int argc,char *argv[]);
|
extern int crl2pkcs7_main(int argc,char *argv[]);
|
||||||
extern int sess_id_main(int argc,char *argv[]);
|
extern int sess_id_main(int argc,char *argv[]);
|
||||||
extern int ciphers_main(int argc,char *argv[]);
|
extern int ciphers_main(int argc,char *argv[]);
|
||||||
@ -109,6 +110,9 @@ FUNCTION functions[] = {
|
|||||||
#endif
|
#endif
|
||||||
{FUNC_TYPE_GENERAL,"version",version_main},
|
{FUNC_TYPE_GENERAL,"version",version_main},
|
||||||
{FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main},
|
{FUNC_TYPE_GENERAL,"pkcs7",pkcs7_main},
|
||||||
|
#ifndef OPENSSL_NO_CMS
|
||||||
|
{FUNC_TYPE_GENERAL,"cms",cms_main},
|
||||||
|
#endif
|
||||||
{FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main},
|
{FUNC_TYPE_GENERAL,"crl2pkcs7",crl2pkcs7_main},
|
||||||
{FUNC_TYPE_GENERAL,"sess_id",sess_id_main},
|
{FUNC_TYPE_GENERAL,"sess_id",sess_id_main},
|
||||||
#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
|
#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
|
||||||
|
@ -43,6 +43,8 @@ foreach (@ARGV)
|
|||||||
{ print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
|
{ print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
|
||||||
elsif ( ($_ =~ /^pkcs12$/))
|
elsif ( ($_ =~ /^pkcs12$/))
|
||||||
{ print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
|
{ print "#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)\n${str}#endif\n"; }
|
||||||
|
elsif ( ($_ =~ /^cms$/))
|
||||||
|
{ print "#ifndef OPENSSL_NO_CMS\n${str}#endif\n"; }
|
||||||
else
|
else
|
||||||
{ print $str; }
|
{ print $str; }
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
|
|||||||
t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
|
t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c t_bitst.c \
|
||||||
tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
|
tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
|
||||||
f_int.c f_string.c n_pkey.c \
|
f_int.c f_string.c n_pkey.c \
|
||||||
f_enum.c a_hdr.c x_pkey.c a_bool.c x_exten.c \
|
f_enum.c a_hdr.c x_pkey.c a_bool.c x_exten.c asn_mime.c \
|
||||||
asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_meth.c a_bytes.c a_strnid.c \
|
asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_meth.c a_bytes.c a_strnid.c \
|
||||||
evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
|
evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c
|
||||||
LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
|
LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
|
||||||
@ -38,7 +38,7 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
|
|||||||
t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
|
t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o t_bitst.o \
|
||||||
tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
|
tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o tasn_typ.o \
|
||||||
f_int.o f_string.o n_pkey.o \
|
f_int.o f_string.o n_pkey.o \
|
||||||
f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o \
|
f_enum.o a_hdr.o x_pkey.o a_bool.o x_exten.o asn_mime.o \
|
||||||
asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_meth.o a_bytes.o a_strnid.o \
|
asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_meth.o a_bytes.o a_strnid.o \
|
||||||
evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o
|
evp_asn1.o asn_pack.o p5_pbe.o p5_pbev2.o p8_pkey.o asn_moid.o
|
||||||
|
|
||||||
|
@ -158,6 +158,10 @@ extern "C" {
|
|||||||
#define MBSTRING_BMP (MBSTRING_FLAG|2)
|
#define MBSTRING_BMP (MBSTRING_FLAG|2)
|
||||||
#define MBSTRING_UNIV (MBSTRING_FLAG|4)
|
#define MBSTRING_UNIV (MBSTRING_FLAG|4)
|
||||||
|
|
||||||
|
#define SMIME_OLDMIME 0x400
|
||||||
|
#define SMIME_CRLFEOL 0x800
|
||||||
|
#define SMIME_STREAM 0x1000
|
||||||
|
|
||||||
struct X509_algor_st;
|
struct X509_algor_st;
|
||||||
DECLARE_STACK_OF(X509_ALGOR)
|
DECLARE_STACK_OF(X509_ALGOR)
|
||||||
|
|
||||||
@ -219,6 +223,13 @@ typedef struct asn1_object_st
|
|||||||
* be inserted in the memory buffer
|
* be inserted in the memory buffer
|
||||||
*/
|
*/
|
||||||
#define ASN1_STRING_FLAG_NDEF 0x010
|
#define ASN1_STRING_FLAG_NDEF 0x010
|
||||||
|
|
||||||
|
/* This flag is used by the CMS code to indicate that a string is not
|
||||||
|
* complete and is a place holder for content when it had all been
|
||||||
|
* accessed. The flag will be reset when content has been written to it.
|
||||||
|
*/
|
||||||
|
#define ASN1_STRING_FLAG_CONT 0x020
|
||||||
|
|
||||||
/* This is the base type that holds just about everything :-) */
|
/* This is the base type that holds just about everything :-) */
|
||||||
typedef struct asn1_string_st
|
typedef struct asn1_string_st
|
||||||
{
|
{
|
||||||
@ -1064,6 +1075,16 @@ void ASN1_add_oid_module(void);
|
|||||||
|
|
||||||
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
|
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
|
||||||
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
|
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
|
||||||
|
|
||||||
|
typedef int asn1_output_data_fn(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
|
||||||
|
const ASN1_ITEM *it);
|
||||||
|
|
||||||
|
int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
|
||||||
|
int ctype_nid, int econt_nid,
|
||||||
|
STACK_OF(X509_ALGOR) *mdalgs,
|
||||||
|
asn1_output_data_fn *data_fn,
|
||||||
|
const ASN1_ITEM *it);
|
||||||
|
ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
|
||||||
|
|
||||||
/* BEGIN ERROR CODES */
|
/* BEGIN ERROR CODES */
|
||||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||||
@ -1114,6 +1135,7 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_F_ASN1_ITEM_VERIFY 197
|
#define ASN1_F_ASN1_ITEM_VERIFY 197
|
||||||
#define ASN1_F_ASN1_MBSTRING_NCOPY 122
|
#define ASN1_F_ASN1_MBSTRING_NCOPY 122
|
||||||
#define ASN1_F_ASN1_OBJECT_NEW 123
|
#define ASN1_F_ASN1_OBJECT_NEW 123
|
||||||
|
#define ASN1_F_ASN1_OUTPUT_DATA 207
|
||||||
#define ASN1_F_ASN1_PACK_STRING 124
|
#define ASN1_F_ASN1_PACK_STRING 124
|
||||||
#define ASN1_F_ASN1_PCTX_NEW 205
|
#define ASN1_F_ASN1_PCTX_NEW 205
|
||||||
#define ASN1_F_ASN1_PKCS5_PBE_SET 125
|
#define ASN1_F_ASN1_PKCS5_PBE_SET 125
|
||||||
@ -1133,6 +1155,8 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_F_ASN1_UNPACK_STRING 136
|
#define ASN1_F_ASN1_UNPACK_STRING 136
|
||||||
#define ASN1_F_ASN1_UTCTIME_SET 187
|
#define ASN1_F_ASN1_UTCTIME_SET 187
|
||||||
#define ASN1_F_ASN1_VERIFY 137
|
#define ASN1_F_ASN1_VERIFY 137
|
||||||
|
#define ASN1_F_B64_READ_ASN1 208
|
||||||
|
#define ASN1_F_B64_WRITE_ASN1 209
|
||||||
#define ASN1_F_BITSTR_CB 180
|
#define ASN1_F_BITSTR_CB 180
|
||||||
#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
|
#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
|
||||||
#define ASN1_F_BN_TO_ASN1_INTEGER 139
|
#define ASN1_F_BN_TO_ASN1_INTEGER 139
|
||||||
@ -1173,6 +1197,8 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_F_PARSE_TAGGING 182
|
#define ASN1_F_PARSE_TAGGING 182
|
||||||
#define ASN1_F_PKCS5_PBE2_SET 167
|
#define ASN1_F_PKCS5_PBE2_SET 167
|
||||||
#define ASN1_F_PKCS5_PBE_SET 202
|
#define ASN1_F_PKCS5_PBE_SET 202
|
||||||
|
#define ASN1_F_SMIME_READ_ASN1 210
|
||||||
|
#define ASN1_F_SMIME_TEXT 211
|
||||||
#define ASN1_F_X509_CINF_NEW 168
|
#define ASN1_F_X509_CINF_NEW 168
|
||||||
#define ASN1_F_X509_CRL_ADD0_REVOKED 169
|
#define ASN1_F_X509_CRL_ADD0_REVOKED 169
|
||||||
#define ASN1_F_X509_INFO_NEW 170
|
#define ASN1_F_X509_INFO_NEW 170
|
||||||
@ -1184,6 +1210,8 @@ void ERR_load_ASN1_strings(void);
|
|||||||
|
|
||||||
/* Reason codes. */
|
/* Reason codes. */
|
||||||
#define ASN1_R_ADDING_OBJECT 171
|
#define ASN1_R_ADDING_OBJECT 171
|
||||||
|
#define ASN1_R_ASN1_PARSE_ERROR 198
|
||||||
|
#define ASN1_R_ASN1_SIG_PARSE_ERROR 199
|
||||||
#define ASN1_R_AUX_ERROR 100
|
#define ASN1_R_AUX_ERROR 100
|
||||||
#define ASN1_R_BAD_CLASS 101
|
#define ASN1_R_BAD_CLASS 101
|
||||||
#define ASN1_R_BAD_OBJECT_HEADER 102
|
#define ASN1_R_BAD_OBJECT_HEADER 102
|
||||||
@ -1230,6 +1258,7 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
|
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
|
||||||
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
|
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
|
||||||
#define ASN1_R_INVALID_DIGIT 130
|
#define ASN1_R_INVALID_DIGIT 130
|
||||||
|
#define ASN1_R_INVALID_MIME_TYPE 200
|
||||||
#define ASN1_R_INVALID_MODIFIER 186
|
#define ASN1_R_INVALID_MODIFIER 186
|
||||||
#define ASN1_R_INVALID_NUMBER 187
|
#define ASN1_R_INVALID_NUMBER 187
|
||||||
#define ASN1_R_INVALID_SEPARATOR 131
|
#define ASN1_R_INVALID_SEPARATOR 131
|
||||||
@ -1239,6 +1268,9 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_R_IV_TOO_LARGE 135
|
#define ASN1_R_IV_TOO_LARGE 135
|
||||||
#define ASN1_R_LENGTH_ERROR 136
|
#define ASN1_R_LENGTH_ERROR 136
|
||||||
#define ASN1_R_LIST_ERROR 188
|
#define ASN1_R_LIST_ERROR 188
|
||||||
|
#define ASN1_R_MIME_NO_CONTENT_TYPE 201
|
||||||
|
#define ASN1_R_MIME_PARSE_ERROR 202
|
||||||
|
#define ASN1_R_MIME_SIG_PARSE_ERROR 203
|
||||||
#define ASN1_R_MISSING_EOC 137
|
#define ASN1_R_MISSING_EOC 137
|
||||||
#define ASN1_R_MISSING_SECOND_NUMBER 138
|
#define ASN1_R_MISSING_SECOND_NUMBER 138
|
||||||
#define ASN1_R_MISSING_VALUE 189
|
#define ASN1_R_MISSING_VALUE 189
|
||||||
@ -1248,7 +1280,11 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_R_NON_HEX_CHARACTERS 141
|
#define ASN1_R_NON_HEX_CHARACTERS 141
|
||||||
#define ASN1_R_NOT_ASCII_FORMAT 190
|
#define ASN1_R_NOT_ASCII_FORMAT 190
|
||||||
#define ASN1_R_NOT_ENOUGH_DATA 142
|
#define ASN1_R_NOT_ENOUGH_DATA 142
|
||||||
|
#define ASN1_R_NO_CONTENT_TYPE 204
|
||||||
#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
|
#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
|
||||||
|
#define ASN1_R_NO_MULTIPART_BODY_FAILURE 205
|
||||||
|
#define ASN1_R_NO_MULTIPART_BOUNDARY 206
|
||||||
|
#define ASN1_R_NO_SIG_CONTENT_TYPE 207
|
||||||
#define ASN1_R_NULL_IS_WRONG_LENGTH 144
|
#define ASN1_R_NULL_IS_WRONG_LENGTH 144
|
||||||
#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
|
#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
|
||||||
#define ASN1_R_ODD_NUMBER_OF_CHARS 145
|
#define ASN1_R_ODD_NUMBER_OF_CHARS 145
|
||||||
@ -1258,6 +1294,8 @@ void ERR_load_ASN1_strings(void);
|
|||||||
#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
|
#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
|
||||||
#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192
|
#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192
|
||||||
#define ASN1_R_SHORT_LINE 150
|
#define ASN1_R_SHORT_LINE 150
|
||||||
|
#define ASN1_R_SIG_INVALID_MIME_TYPE 208
|
||||||
|
#define ASN1_R_STREAMING_NOT_SUPPORTED 209
|
||||||
#define ASN1_R_STRING_TOO_LONG 151
|
#define ASN1_R_STRING_TOO_LONG 151
|
||||||
#define ASN1_R_STRING_TOO_SHORT 152
|
#define ASN1_R_STRING_TOO_SHORT 152
|
||||||
#define ASN1_R_TAG_VALUE_TOO_HIGH 153
|
#define ASN1_R_TAG_VALUE_TOO_HIGH 153
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* crypto/asn1/asn1_err.c */
|
/* crypto/asn1/asn1_err.c */
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -110,6 +110,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
|
|||||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
|
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
|
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
|
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
|
||||||
|
{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
|
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"},
|
{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_NEW"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
|
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
|
||||||
@ -129,6 +130,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
|
|||||||
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
|
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
|
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
|
||||||
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
|
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
|
||||||
|
{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
|
||||||
|
{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
|
||||||
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
|
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
|
||||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
|
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
|
||||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
|
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
|
||||||
@ -169,6 +172,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
|
|||||||
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
|
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
|
||||||
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"},
|
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET), "PKCS5_pbe2_set"},
|
||||||
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
|
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
|
||||||
|
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
|
||||||
|
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
|
||||||
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
|
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
|
||||||
{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
|
{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
|
||||||
{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
|
{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
|
||||||
@ -183,6 +188,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
|
|||||||
static ERR_STRING_DATA ASN1_str_reasons[]=
|
static ERR_STRING_DATA ASN1_str_reasons[]=
|
||||||
{
|
{
|
||||||
{ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"},
|
{ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"},
|
||||||
|
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) ,"asn1 parse error"},
|
||||||
|
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
|
||||||
{ERR_REASON(ASN1_R_AUX_ERROR) ,"aux error"},
|
{ERR_REASON(ASN1_R_AUX_ERROR) ,"aux error"},
|
||||||
{ERR_REASON(ASN1_R_BAD_CLASS) ,"bad class"},
|
{ERR_REASON(ASN1_R_BAD_CLASS) ,"bad class"},
|
||||||
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"},
|
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"},
|
||||||
@ -229,6 +236,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
|||||||
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
|
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
|
||||||
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
|
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
|
||||||
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
|
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
|
||||||
|
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
|
||||||
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
|
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
|
||||||
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
|
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
|
||||||
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
|
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
|
||||||
@ -238,6 +246,9 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
|||||||
{ERR_REASON(ASN1_R_IV_TOO_LARGE) ,"iv too large"},
|
{ERR_REASON(ASN1_R_IV_TOO_LARGE) ,"iv too large"},
|
||||||
{ERR_REASON(ASN1_R_LENGTH_ERROR) ,"length error"},
|
{ERR_REASON(ASN1_R_LENGTH_ERROR) ,"length error"},
|
||||||
{ERR_REASON(ASN1_R_LIST_ERROR) ,"list error"},
|
{ERR_REASON(ASN1_R_LIST_ERROR) ,"list error"},
|
||||||
|
{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"},
|
||||||
|
{ERR_REASON(ASN1_R_MIME_PARSE_ERROR) ,"mime parse error"},
|
||||||
|
{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"},
|
||||||
{ERR_REASON(ASN1_R_MISSING_EOC) ,"missing eoc"},
|
{ERR_REASON(ASN1_R_MISSING_EOC) ,"missing eoc"},
|
||||||
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
|
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
|
||||||
{ERR_REASON(ASN1_R_MISSING_VALUE) ,"missing value"},
|
{ERR_REASON(ASN1_R_MISSING_VALUE) ,"missing value"},
|
||||||
@ -247,7 +258,11 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
|||||||
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"},
|
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"},
|
||||||
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"},
|
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"},
|
||||||
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"},
|
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"},
|
||||||
|
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"},
|
||||||
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
|
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
|
||||||
|
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
|
||||||
|
{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
|
||||||
|
{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
|
||||||
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
|
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
|
||||||
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
|
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
|
||||||
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) ,"odd number of chars"},
|
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) ,"odd number of chars"},
|
||||||
@ -257,6 +272,8 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
|
|||||||
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
|
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
|
||||||
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
|
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
|
||||||
{ERR_REASON(ASN1_R_SHORT_LINE) ,"short line"},
|
{ERR_REASON(ASN1_R_SHORT_LINE) ,"short line"},
|
||||||
|
{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
|
||||||
|
{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"},
|
||||||
{ERR_REASON(ASN1_R_STRING_TOO_LONG) ,"string too long"},
|
{ERR_REASON(ASN1_R_STRING_TOO_LONG) ,"string too long"},
|
||||||
{ERR_REASON(ASN1_R_STRING_TOO_SHORT) ,"string too short"},
|
{ERR_REASON(ASN1_R_STRING_TOO_SHORT) ,"string too short"},
|
||||||
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) ,"tag value too high"},
|
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) ,"tag value too high"},
|
||||||
|
887
crypto/asn1/asn_mime.c
Normal file
887
crypto/asn1/asn_mime.c
Normal file
@ -0,0 +1,887 @@
|
|||||||
|
/* asn_mime.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/asn1.h>
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
|
||||||
|
/* Generalised MIME like utilities for streaming ASN1. Although many
|
||||||
|
* have a PKCS7/CMS like flavour others are more general purpose.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* MIME format structures
|
||||||
|
* Note that all are translated to lower case apart from
|
||||||
|
* parameter values. Quotes are stripped off
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *param_name; /* Param name e.g. "micalg" */
|
||||||
|
char *param_value; /* Param value e.g. "sha1" */
|
||||||
|
} MIME_PARAM;
|
||||||
|
|
||||||
|
DECLARE_STACK_OF(MIME_PARAM)
|
||||||
|
IMPLEMENT_STACK_OF(MIME_PARAM)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name; /* Name of line e.g. "content-type" */
|
||||||
|
char *value; /* Value of line e.g. "text/plain" */
|
||||||
|
STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
|
||||||
|
} MIME_HEADER;
|
||||||
|
|
||||||
|
DECLARE_STACK_OF(MIME_HEADER)
|
||||||
|
IMPLEMENT_STACK_OF(MIME_HEADER)
|
||||||
|
|
||||||
|
static char * strip_ends(char *name);
|
||||||
|
static char * strip_start(char *name);
|
||||||
|
static char * strip_end(char *name);
|
||||||
|
static MIME_HEADER *mime_hdr_new(char *name, char *value);
|
||||||
|
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
|
||||||
|
static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
|
||||||
|
static int mime_hdr_cmp(const MIME_HEADER * const *a,
|
||||||
|
const MIME_HEADER * const *b);
|
||||||
|
static int mime_param_cmp(const MIME_PARAM * const *a,
|
||||||
|
const MIME_PARAM * const *b);
|
||||||
|
static void mime_param_free(MIME_PARAM *param);
|
||||||
|
static int mime_bound_check(char *line, int linelen, char *bound, int blen);
|
||||||
|
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
|
||||||
|
static int strip_eol(char *linebuf, int *plen);
|
||||||
|
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
|
||||||
|
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
|
||||||
|
static void mime_hdr_free(MIME_HEADER *hdr);
|
||||||
|
|
||||||
|
#define MAX_SMLEN 1024
|
||||||
|
#define mime_debug(x) /* x */
|
||||||
|
|
||||||
|
/* Base 64 read and write of ASN1 structure */
|
||||||
|
|
||||||
|
static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
|
||||||
|
const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
BIO *b64;
|
||||||
|
int r;
|
||||||
|
b64 = BIO_new(BIO_f_base64());
|
||||||
|
if(!b64)
|
||||||
|
{
|
||||||
|
ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* prepend the b64 BIO so all data is base64 encoded.
|
||||||
|
*/
|
||||||
|
out = BIO_push(b64, out);
|
||||||
|
r = ASN1_item_i2d_bio(it, out, val);
|
||||||
|
(void)BIO_flush(out);
|
||||||
|
BIO_pop(out);
|
||||||
|
BIO_free(b64);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Streaming ASN1 PEM write */
|
||||||
|
|
||||||
|
int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
|
||||||
|
const char *hdr,
|
||||||
|
const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
BIO_printf(out, "-----BEGIN %s-----\n", hdr);
|
||||||
|
r = B64_write_ASN1(out, val, in, flags, it);
|
||||||
|
BIO_printf(out, "-----END %s-----\n", hdr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
BIO *b64;
|
||||||
|
ASN1_VALUE *val;
|
||||||
|
if(!(b64 = BIO_new(BIO_f_base64()))) {
|
||||||
|
ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bio = BIO_push(b64, bio);
|
||||||
|
val = ASN1_item_d2i_bio(it, bio, NULL);
|
||||||
|
if(!val)
|
||||||
|
ASN1err(ASN1_F_B64_READ_ASN1,ASN1_R_DECODE_ERROR);
|
||||||
|
(void)BIO_flush(bio);
|
||||||
|
bio = BIO_pop(bio);
|
||||||
|
BIO_free(b64);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
|
||||||
|
|
||||||
|
static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
|
||||||
|
{
|
||||||
|
const EVP_MD *md;
|
||||||
|
int i, have_unknown = 0, write_comma, md_nid;
|
||||||
|
have_unknown = 0;
|
||||||
|
write_comma = 0;
|
||||||
|
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
|
||||||
|
{
|
||||||
|
if (write_comma)
|
||||||
|
BIO_write(out, ",", 1);
|
||||||
|
write_comma = 1;
|
||||||
|
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
|
||||||
|
md = EVP_get_digestbynid(md_nid);
|
||||||
|
switch(md_nid)
|
||||||
|
{
|
||||||
|
case NID_sha1:
|
||||||
|
BIO_puts(out, "sha1");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_md5:
|
||||||
|
BIO_puts(out, "md5");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_sha256:
|
||||||
|
BIO_puts(out, "sha-256");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_sha384:
|
||||||
|
BIO_puts(out, "sha-384");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_sha512:
|
||||||
|
BIO_puts(out, "sha-512");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (have_unknown)
|
||||||
|
write_comma = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BIO_puts(out, "unknown");
|
||||||
|
have_unknown = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SMIME sender */
|
||||||
|
|
||||||
|
int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
|
||||||
|
int ctype_nid, int econt_nid,
|
||||||
|
STACK_OF(X509_ALGOR) *mdalgs,
|
||||||
|
asn1_output_data_fn *data_fn,
|
||||||
|
const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
char bound[33], c;
|
||||||
|
int i;
|
||||||
|
const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
|
||||||
|
const char *msg_type=NULL;
|
||||||
|
if (flags & SMIME_OLDMIME)
|
||||||
|
mime_prefix = "application/x-pkcs7-";
|
||||||
|
else
|
||||||
|
mime_prefix = "application/pkcs7-";
|
||||||
|
|
||||||
|
if (flags & SMIME_CRLFEOL)
|
||||||
|
mime_eol = "\r\n";
|
||||||
|
else
|
||||||
|
mime_eol = "\n";
|
||||||
|
if((flags & SMIME_DETACHED) && data) {
|
||||||
|
/* We want multipart/signed */
|
||||||
|
/* Generate a random boundary */
|
||||||
|
RAND_pseudo_bytes((unsigned char *)bound, 32);
|
||||||
|
for(i = 0; i < 32; i++) {
|
||||||
|
c = bound[i] & 0xf;
|
||||||
|
if(c < 10) c += '0';
|
||||||
|
else c += 'A' - 10;
|
||||||
|
bound[i] = c;
|
||||||
|
}
|
||||||
|
bound[32] = 0;
|
||||||
|
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Type: multipart/signed;");
|
||||||
|
BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
|
||||||
|
BIO_puts(bio, " micalg=\"");
|
||||||
|
asn1_write_micalg(bio, mdalgs);
|
||||||
|
BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
|
||||||
|
bound, mime_eol, mime_eol);
|
||||||
|
BIO_printf(bio, "This is an S/MIME signed message%s%s",
|
||||||
|
mime_eol, mime_eol);
|
||||||
|
/* Now write out the first part */
|
||||||
|
BIO_printf(bio, "------%s%s", bound, mime_eol);
|
||||||
|
if (!data_fn(bio, data, val, flags, it))
|
||||||
|
return 0;
|
||||||
|
BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
|
||||||
|
|
||||||
|
/* Headers for signature */
|
||||||
|
|
||||||
|
BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
|
||||||
|
BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
|
||||||
|
mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Disposition: attachment;");
|
||||||
|
BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
|
||||||
|
mime_eol, mime_eol);
|
||||||
|
B64_write_ASN1(bio, val, NULL, 0, it);
|
||||||
|
BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
|
||||||
|
mime_eol, mime_eol);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine smime-type header */
|
||||||
|
|
||||||
|
if (ctype_nid == NID_pkcs7_enveloped)
|
||||||
|
msg_type = "enveloped-data";
|
||||||
|
else if (ctype_nid == NID_pkcs7_signed)
|
||||||
|
{
|
||||||
|
if (econt_nid == NID_id_smime_ct_receipt)
|
||||||
|
msg_type = "signed-receipt";
|
||||||
|
else if (sk_X509_ALGOR_num(mdalgs) >= 0)
|
||||||
|
msg_type = "signed-data";
|
||||||
|
else
|
||||||
|
msg_type = "certs-only";
|
||||||
|
}
|
||||||
|
else if (ctype_nid == NID_id_smime_ct_compressedData)
|
||||||
|
{
|
||||||
|
msg_type = "compressed-data";
|
||||||
|
cname = "smime.p7z";
|
||||||
|
}
|
||||||
|
/* MIME headers */
|
||||||
|
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Disposition: attachment;");
|
||||||
|
BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
|
||||||
|
if (msg_type)
|
||||||
|
BIO_printf(bio, " smime-type=%s;", msg_type);
|
||||||
|
BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
|
||||||
|
BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
|
||||||
|
mime_eol, mime_eol);
|
||||||
|
if (!B64_write_ASN1(bio, val, data, flags, it))
|
||||||
|
return 0;
|
||||||
|
BIO_printf(bio, "%s", mime_eol);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* Handle output of ASN1 data */
|
||||||
|
|
||||||
|
|
||||||
|
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
|
||||||
|
const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
BIO *tmpbio;
|
||||||
|
const ASN1_AUX *aux = it->funcs;
|
||||||
|
ASN1_STREAM_ARG sarg;
|
||||||
|
|
||||||
|
if (!(flags & SMIME_DETACHED))
|
||||||
|
{
|
||||||
|
SMIME_crlf_copy(data, out, flags);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aux || !aux->asn1_cb)
|
||||||
|
{
|
||||||
|
ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
|
||||||
|
ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sarg.out = out;
|
||||||
|
sarg.ndef_bio = NULL;
|
||||||
|
sarg.boundary = NULL;
|
||||||
|
|
||||||
|
/* Let ASN1 code prepend any needed BIOs */
|
||||||
|
|
||||||
|
if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Copy data across, passing through filter BIOs for processing */
|
||||||
|
SMIME_crlf_copy(data, sarg.ndef_bio, flags);
|
||||||
|
|
||||||
|
/* Finalize structure */
|
||||||
|
if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Now remove any digests prepended to the BIO */
|
||||||
|
|
||||||
|
while (sarg.ndef_bio != out)
|
||||||
|
{
|
||||||
|
tmpbio = BIO_pop(sarg.ndef_bio);
|
||||||
|
BIO_free(sarg.ndef_bio);
|
||||||
|
sarg.ndef_bio = tmpbio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SMIME reader: handle multipart/signed and opaque signing.
|
||||||
|
* in multipart case the content is placed in a memory BIO
|
||||||
|
* pointed to by "bcont". In opaque this is set to NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
BIO *asnin;
|
||||||
|
STACK_OF(MIME_HEADER) *headers = NULL;
|
||||||
|
STACK_OF(BIO) *parts = NULL;
|
||||||
|
MIME_HEADER *hdr;
|
||||||
|
MIME_PARAM *prm;
|
||||||
|
ASN1_VALUE *val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(bcont) *bcont = NULL;
|
||||||
|
|
||||||
|
if (!(headers = mime_parse_hdr(bio))) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle multipart/signed */
|
||||||
|
|
||||||
|
if(!strcmp(hdr->value, "multipart/signed")) {
|
||||||
|
/* Split into two parts */
|
||||||
|
prm = mime_param_find(hdr, "boundary");
|
||||||
|
if(!prm || !prm->param_value) {
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = multi_split(bio, prm->param_value, &parts);
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
if(!ret || (sk_BIO_num(parts) != 2) ) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
|
||||||
|
sk_BIO_pop_free(parts, BIO_vfree);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the signature piece */
|
||||||
|
asnin = sk_BIO_value(parts, 1);
|
||||||
|
|
||||||
|
if (!(headers = mime_parse_hdr(asnin))) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
|
||||||
|
sk_BIO_pop_free(parts, BIO_vfree);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get content type */
|
||||||
|
|
||||||
|
if(!(hdr = mime_hdr_find(headers, "content-type")) ||
|
||||||
|
!hdr->value) {
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
|
||||||
|
strcmp(hdr->value, "application/pkcs7-signature")) {
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
|
||||||
|
ERR_add_error_data(2, "type: ", hdr->value);
|
||||||
|
sk_BIO_pop_free(parts, BIO_vfree);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
/* Read in ASN1 */
|
||||||
|
if(!(val = b64_read_asn1(asnin, it))) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
|
||||||
|
sk_BIO_pop_free(parts, BIO_vfree);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bcont) {
|
||||||
|
*bcont = sk_BIO_value(parts, 0);
|
||||||
|
BIO_free(asnin);
|
||||||
|
sk_BIO_free(parts);
|
||||||
|
} else sk_BIO_pop_free(parts, BIO_vfree);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, if not multipart/signed try opaque signature */
|
||||||
|
|
||||||
|
if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
|
||||||
|
strcmp (hdr->value, "application/pkcs7-mime")) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_INVALID_MIME_TYPE);
|
||||||
|
ERR_add_error_data(2, "type: ", hdr->value);
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
|
||||||
|
if(!(val = b64_read_asn1(bio, it))) {
|
||||||
|
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy text from one BIO to another making the output CRLF at EOL */
|
||||||
|
int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
|
||||||
|
{
|
||||||
|
BIO *bf;
|
||||||
|
char eol;
|
||||||
|
int len;
|
||||||
|
char linebuf[MAX_SMLEN];
|
||||||
|
/* Buffer output so we don't write one line at a time. This is
|
||||||
|
* useful when streaming as we don't end up with one OCTET STRING
|
||||||
|
* per line.
|
||||||
|
*/
|
||||||
|
bf = BIO_new(BIO_f_buffer());
|
||||||
|
if (!bf)
|
||||||
|
return 0;
|
||||||
|
out = BIO_push(bf, out);
|
||||||
|
if(flags & SMIME_BINARY)
|
||||||
|
{
|
||||||
|
while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
|
||||||
|
BIO_write(out, linebuf, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(flags & SMIME_TEXT)
|
||||||
|
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
|
||||||
|
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
|
||||||
|
{
|
||||||
|
eol = strip_eol(linebuf, &len);
|
||||||
|
if (len)
|
||||||
|
BIO_write(out, linebuf, len);
|
||||||
|
if(eol) BIO_write(out, "\r\n", 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void)BIO_flush(out);
|
||||||
|
BIO_pop(out);
|
||||||
|
BIO_free(bf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip off headers if they are text/plain */
|
||||||
|
int SMIME_text(BIO *in, BIO *out)
|
||||||
|
{
|
||||||
|
char iobuf[4096];
|
||||||
|
int len;
|
||||||
|
STACK_OF(MIME_HEADER) *headers;
|
||||||
|
MIME_HEADER *hdr;
|
||||||
|
|
||||||
|
if (!(headers = mime_parse_hdr(in))) {
|
||||||
|
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
||||||
|
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (strcmp (hdr->value, "text/plain")) {
|
||||||
|
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
|
||||||
|
ERR_add_error_data(2, "type: ", hdr->value);
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
||||||
|
while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
|
||||||
|
BIO_write(out, iobuf, len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Split a multipart/XXX message body into component parts: result is
|
||||||
|
* canonical parts in a STACK of bios
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
|
||||||
|
{
|
||||||
|
char linebuf[MAX_SMLEN];
|
||||||
|
int len, blen;
|
||||||
|
int eol = 0, next_eol = 0;
|
||||||
|
BIO *bpart = NULL;
|
||||||
|
STACK_OF(BIO) *parts;
|
||||||
|
char state, part, first;
|
||||||
|
|
||||||
|
blen = strlen(bound);
|
||||||
|
part = 0;
|
||||||
|
state = 0;
|
||||||
|
first = 1;
|
||||||
|
parts = sk_BIO_new_null();
|
||||||
|
*ret = parts;
|
||||||
|
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
|
||||||
|
state = mime_bound_check(linebuf, len, bound, blen);
|
||||||
|
if(state == 1) {
|
||||||
|
first = 1;
|
||||||
|
part++;
|
||||||
|
} else if(state == 2) {
|
||||||
|
sk_BIO_push(parts, bpart);
|
||||||
|
return 1;
|
||||||
|
} else if(part) {
|
||||||
|
/* Strip CR+LF from linebuf */
|
||||||
|
next_eol = strip_eol(linebuf, &len);
|
||||||
|
if(first) {
|
||||||
|
first = 0;
|
||||||
|
if(bpart) sk_BIO_push(parts, bpart);
|
||||||
|
bpart = BIO_new(BIO_s_mem());
|
||||||
|
BIO_set_mem_eof_return(bpart, 0);
|
||||||
|
} else if (eol)
|
||||||
|
BIO_write(bpart, "\r\n", 2);
|
||||||
|
eol = next_eol;
|
||||||
|
if (len)
|
||||||
|
BIO_write(bpart, linebuf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the big one: parse MIME header lines up to message body */
|
||||||
|
|
||||||
|
#define MIME_INVALID 0
|
||||||
|
#define MIME_START 1
|
||||||
|
#define MIME_TYPE 2
|
||||||
|
#define MIME_NAME 3
|
||||||
|
#define MIME_VALUE 4
|
||||||
|
#define MIME_QUOTE 5
|
||||||
|
#define MIME_COMMENT 6
|
||||||
|
|
||||||
|
|
||||||
|
static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
|
||||||
|
{
|
||||||
|
char *p, *q, c;
|
||||||
|
char *ntmp;
|
||||||
|
char linebuf[MAX_SMLEN];
|
||||||
|
MIME_HEADER *mhdr = NULL;
|
||||||
|
STACK_OF(MIME_HEADER) *headers;
|
||||||
|
int len, state, save_state = 0;
|
||||||
|
|
||||||
|
headers = sk_MIME_HEADER_new(mime_hdr_cmp);
|
||||||
|
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
|
||||||
|
/* If whitespace at line start then continuation line */
|
||||||
|
if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
|
||||||
|
else state = MIME_START;
|
||||||
|
ntmp = NULL;
|
||||||
|
/* Go through all characters */
|
||||||
|
for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
|
||||||
|
|
||||||
|
/* State machine to handle MIME headers
|
||||||
|
* if this looks horrible that's because it *is*
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
case MIME_START:
|
||||||
|
if(c == ':') {
|
||||||
|
state = MIME_TYPE;
|
||||||
|
*p = 0;
|
||||||
|
ntmp = strip_ends(q);
|
||||||
|
q = p + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIME_TYPE:
|
||||||
|
if(c == ';') {
|
||||||
|
mime_debug("Found End Value\n");
|
||||||
|
*p = 0;
|
||||||
|
mhdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||||
|
sk_MIME_HEADER_push(headers, mhdr);
|
||||||
|
ntmp = NULL;
|
||||||
|
q = p + 1;
|
||||||
|
state = MIME_NAME;
|
||||||
|
} else if(c == '(') {
|
||||||
|
save_state = state;
|
||||||
|
state = MIME_COMMENT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIME_COMMENT:
|
||||||
|
if(c == ')') {
|
||||||
|
state = save_state;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIME_NAME:
|
||||||
|
if(c == '=') {
|
||||||
|
state = MIME_VALUE;
|
||||||
|
*p = 0;
|
||||||
|
ntmp = strip_ends(q);
|
||||||
|
q = p + 1;
|
||||||
|
}
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case MIME_VALUE:
|
||||||
|
if(c == ';') {
|
||||||
|
state = MIME_NAME;
|
||||||
|
*p = 0;
|
||||||
|
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
|
||||||
|
ntmp = NULL;
|
||||||
|
q = p + 1;
|
||||||
|
} else if (c == '"') {
|
||||||
|
mime_debug("Found Quote\n");
|
||||||
|
state = MIME_QUOTE;
|
||||||
|
} else if(c == '(') {
|
||||||
|
save_state = state;
|
||||||
|
state = MIME_COMMENT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIME_QUOTE:
|
||||||
|
if(c == '"') {
|
||||||
|
mime_debug("Found Match Quote\n");
|
||||||
|
state = MIME_VALUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state == MIME_TYPE) {
|
||||||
|
mhdr = mime_hdr_new(ntmp, strip_ends(q));
|
||||||
|
sk_MIME_HEADER_push(headers, mhdr);
|
||||||
|
} else if(state == MIME_VALUE)
|
||||||
|
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
|
||||||
|
if(p == linebuf) break; /* Blank line means end of headers */
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *strip_ends(char *name)
|
||||||
|
{
|
||||||
|
return strip_end(strip_start(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip a parameter of whitespace from start of param */
|
||||||
|
static char *strip_start(char *name)
|
||||||
|
{
|
||||||
|
char *p, c;
|
||||||
|
/* Look for first non white space or quote */
|
||||||
|
for(p = name; (c = *p) ;p++) {
|
||||||
|
if(c == '"') {
|
||||||
|
/* Next char is start of string if non null */
|
||||||
|
if(p[1]) return p + 1;
|
||||||
|
/* Else null string */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!isspace((unsigned char)c)) return p;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As above but strip from end of string : maybe should handle brackets? */
|
||||||
|
static char *strip_end(char *name)
|
||||||
|
{
|
||||||
|
char *p, c;
|
||||||
|
if(!name) return NULL;
|
||||||
|
/* Look for first non white space or quote */
|
||||||
|
for(p = name + strlen(name) - 1; p >= name ;p--) {
|
||||||
|
c = *p;
|
||||||
|
if(c == '"') {
|
||||||
|
if(p - 1 == name) return NULL;
|
||||||
|
*p = 0;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
if(isspace((unsigned char)c)) *p = 0;
|
||||||
|
else return name;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MIME_HEADER *mime_hdr_new(char *name, char *value)
|
||||||
|
{
|
||||||
|
MIME_HEADER *mhdr;
|
||||||
|
char *tmpname, *tmpval, *p;
|
||||||
|
int c;
|
||||||
|
if(name) {
|
||||||
|
if(!(tmpname = BUF_strdup(name))) return NULL;
|
||||||
|
for(p = tmpname ; *p; p++) {
|
||||||
|
c = *p;
|
||||||
|
if(isupper(c)) {
|
||||||
|
c = tolower(c);
|
||||||
|
*p = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else tmpname = NULL;
|
||||||
|
if(value) {
|
||||||
|
if(!(tmpval = BUF_strdup(value))) return NULL;
|
||||||
|
for(p = tmpval ; *p; p++) {
|
||||||
|
c = *p;
|
||||||
|
if(isupper(c)) {
|
||||||
|
c = tolower(c);
|
||||||
|
*p = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else tmpval = NULL;
|
||||||
|
mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
|
||||||
|
if(!mhdr) return NULL;
|
||||||
|
mhdr->name = tmpname;
|
||||||
|
mhdr->value = tmpval;
|
||||||
|
if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
|
||||||
|
return mhdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
|
||||||
|
{
|
||||||
|
char *tmpname, *tmpval, *p;
|
||||||
|
int c;
|
||||||
|
MIME_PARAM *mparam;
|
||||||
|
if(name) {
|
||||||
|
tmpname = BUF_strdup(name);
|
||||||
|
if(!tmpname) return 0;
|
||||||
|
for(p = tmpname ; *p; p++) {
|
||||||
|
c = *p;
|
||||||
|
if(isupper(c)) {
|
||||||
|
c = tolower(c);
|
||||||
|
*p = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else tmpname = NULL;
|
||||||
|
if(value) {
|
||||||
|
tmpval = BUF_strdup(value);
|
||||||
|
if(!tmpval) return 0;
|
||||||
|
} else tmpval = NULL;
|
||||||
|
/* Parameter values are case sensitive so leave as is */
|
||||||
|
mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
|
||||||
|
if(!mparam) return 0;
|
||||||
|
mparam->param_name = tmpname;
|
||||||
|
mparam->param_value = tmpval;
|
||||||
|
sk_MIME_PARAM_push(mhdr->params, mparam);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mime_hdr_cmp(const MIME_HEADER * const *a,
|
||||||
|
const MIME_HEADER * const *b)
|
||||||
|
{
|
||||||
|
return(strcmp((*a)->name, (*b)->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mime_param_cmp(const MIME_PARAM * const *a,
|
||||||
|
const MIME_PARAM * const *b)
|
||||||
|
{
|
||||||
|
return(strcmp((*a)->param_name, (*b)->param_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find a header with a given name (if possible) */
|
||||||
|
|
||||||
|
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
|
||||||
|
{
|
||||||
|
MIME_HEADER htmp;
|
||||||
|
int idx;
|
||||||
|
htmp.name = name;
|
||||||
|
idx = sk_MIME_HEADER_find(hdrs, &htmp);
|
||||||
|
if(idx < 0) return NULL;
|
||||||
|
return sk_MIME_HEADER_value(hdrs, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
|
||||||
|
{
|
||||||
|
MIME_PARAM param;
|
||||||
|
int idx;
|
||||||
|
param.param_name = name;
|
||||||
|
idx = sk_MIME_PARAM_find(hdr->params, ¶m);
|
||||||
|
if(idx < 0) return NULL;
|
||||||
|
return sk_MIME_PARAM_value(hdr->params, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mime_hdr_free(MIME_HEADER *hdr)
|
||||||
|
{
|
||||||
|
if(hdr->name) OPENSSL_free(hdr->name);
|
||||||
|
if(hdr->value) OPENSSL_free(hdr->value);
|
||||||
|
if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
|
||||||
|
OPENSSL_free(hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mime_param_free(MIME_PARAM *param)
|
||||||
|
{
|
||||||
|
if(param->param_name) OPENSSL_free(param->param_name);
|
||||||
|
if(param->param_value) OPENSSL_free(param->param_value);
|
||||||
|
OPENSSL_free(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for a multipart boundary. Returns:
|
||||||
|
* 0 : no boundary
|
||||||
|
* 1 : part boundary
|
||||||
|
* 2 : final boundary
|
||||||
|
*/
|
||||||
|
static int mime_bound_check(char *line, int linelen, char *bound, int blen)
|
||||||
|
{
|
||||||
|
if(linelen == -1) linelen = strlen(line);
|
||||||
|
if(blen == -1) blen = strlen(bound);
|
||||||
|
/* Quickly eliminate if line length too short */
|
||||||
|
if(blen + 2 > linelen) return 0;
|
||||||
|
/* Check for part boundary */
|
||||||
|
if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
|
||||||
|
if(!strncmp(line + blen + 2, "--", 2)) return 2;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int strip_eol(char *linebuf, int *plen)
|
||||||
|
{
|
||||||
|
int len = *plen;
|
||||||
|
char *p, c;
|
||||||
|
int is_eol = 0;
|
||||||
|
p = linebuf + len - 1;
|
||||||
|
for (p = linebuf + len - 1; len > 0; len--, p--)
|
||||||
|
{
|
||||||
|
c = *p;
|
||||||
|
if (c == '\n')
|
||||||
|
is_eol = 1;
|
||||||
|
else if (c != '\r')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*plen = len;
|
||||||
|
return is_eol;
|
||||||
|
}
|
183
crypto/cms/Makefile
Normal file
183
crypto/cms/Makefile
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#
|
||||||
|
# OpenSSL/crypto/cms/Makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
DIR= cms
|
||||||
|
TOP= ../..
|
||||||
|
CC= cc
|
||||||
|
INCLUDES= -I.. -I$(TOP) -I../../include
|
||||||
|
CFLAG=-g
|
||||||
|
MAKEFILE= Makefile
|
||||||
|
AR= ar r
|
||||||
|
|
||||||
|
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||||
|
|
||||||
|
GENERAL=Makefile
|
||||||
|
TEST=
|
||||||
|
APPS=
|
||||||
|
|
||||||
|
LIB=$(TOP)/libcrypto.a
|
||||||
|
LIBSRC= cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
|
||||||
|
cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c
|
||||||
|
LIBOBJ= cms_lib.o cms_asn1.o cms_att.o cms_io.o cms_smime.o cms_err.o \
|
||||||
|
cms_sd.o cms_dd.o cms_cd.o cms_env.o cms_enc.o cms_ess.o
|
||||||
|
|
||||||
|
SRC= $(LIBSRC)
|
||||||
|
|
||||||
|
EXHEADER= cms.h
|
||||||
|
HEADER= cms_lcl.h $(EXHEADER)
|
||||||
|
|
||||||
|
ALL= $(GENERAL) $(SRC) $(HEADER)
|
||||||
|
|
||||||
|
top:
|
||||||
|
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
|
||||||
|
|
||||||
|
test:
|
||||||
|
|
||||||
|
all: lib
|
||||||
|
|
||||||
|
lib: $(LIBOBJ)
|
||||||
|
$(AR) $(LIB) $(LIBOBJ)
|
||||||
|
$(RANLIB) $(LIB) || echo Never mind.
|
||||||
|
@touch lib
|
||||||
|
|
||||||
|
files:
|
||||||
|
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
|
||||||
|
|
||||||
|
links:
|
||||||
|
@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
|
||||||
|
@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
|
||||||
|
@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
|
||||||
|
|
||||||
|
install:
|
||||||
|
@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
|
||||||
|
@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
|
||||||
|
do \
|
||||||
|
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
|
||||||
|
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
|
||||||
|
done;
|
||||||
|
|
||||||
|
tags:
|
||||||
|
ctags $(SRC)
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
lint:
|
||||||
|
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||||
|
|
||||||
|
depend:
|
||||||
|
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
|
||||||
|
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
|
||||||
|
|
||||||
|
dclean:
|
||||||
|
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||||
|
mv -f Makefile.new $(MAKEFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||||
|
|
||||||
|
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||||
|
|
||||||
|
cms_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||||
|
cms_asn1.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||||
|
cms_asn1.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||||
|
cms_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
|
cms_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
|
cms_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||||
|
cms_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||||
|
cms_asn1.o: ../../include/openssl/opensslconf.h
|
||||||
|
cms_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||||
|
cms_asn1.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
|
||||||
|
cms_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||||
|
cms_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||||
|
cms_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||||
|
cms_asn1.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||||
|
cms_asn1.o: cms.h cms_asn1.c cms_lcl.h
|
||||||
|
cms_att.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||||
|
cms_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||||
|
cms_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||||
|
cms_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
|
cms_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
|
cms_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||||
|
cms_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||||
|
cms_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||||
|
cms_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||||
|
cms_att.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
|
||||||
|
cms_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||||
|
cms_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||||
|
cms_att.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||||
|
cms_att.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||||
|
cms_att.o: cms.h cms_att.c cms_lcl.h
|
||||||
|
cms_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||||
|
cms_err.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
|
||||||
|
cms_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||||
|
cms_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||||
|
cms_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
|
||||||
|
cms_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||||
|
cms_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||||
|
cms_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
|
||||||
|
cms_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
|
||||||
|
cms_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||||
|
cms_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||||
|
cms_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||||
|
cms_err.o: cms_err.c
|
||||||
|
cms_io.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||||
|
cms_io.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||||
|
cms_io.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||||
|
cms_io.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||||
|
cms_io.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
|
||||||
|
cms_io.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||||
|
cms_io.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||||
|
cms_io.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
|
||||||
|
cms_io.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
|
||||||
|
cms_io.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
|
||||||
|
cms_io.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||||
|
cms_io.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||||
|
cms_io.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
|
||||||
|
cms_io.o: cms_io.c cms_lcl.h
|
||||||
|
cms_lib.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||||
|
cms_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
|
||||||
|
cms_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
|
||||||
|
cms_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
||||||
|
cms_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
|
||||||
|
cms_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||||
|
cms_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||||
|
cms_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
|
||||||
|
cms_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
|
||||||
|
cms_lib.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
|
||||||
|
cms_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||||
|
cms_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||||
|
cms_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h cms.h
|
||||||
|
cms_lib.o: cms_lcl.h cms_lib.c
|
||||||
|
cms_sd.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||||
|
cms_sd.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
|
||||||
|
cms_sd.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
|
||||||
|
cms_sd.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||||
|
cms_sd.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
|
cms_sd.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
|
cms_sd.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||||
|
cms_sd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||||
|
cms_sd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
|
||||||
|
cms_sd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||||
|
cms_sd.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
|
||||||
|
cms_sd.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||||
|
cms_sd.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||||
|
cms_sd.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||||
|
cms_sd.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||||
|
cms_sd.o: ../cryptlib.h cms_lcl.h cms_sd.c
|
||||||
|
cms_smime.o: ../../e_os.h ../../include/openssl/asn1.h
|
||||||
|
cms_smime.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
|
||||||
|
cms_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
|
||||||
|
cms_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
||||||
|
cms_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
|
cms_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
|
cms_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
||||||
|
cms_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||||
|
cms_smime.o: ../../include/openssl/objects.h
|
||||||
|
cms_smime.o: ../../include/openssl/opensslconf.h
|
||||||
|
cms_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||||
|
cms_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
|
||||||
|
cms_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||||
|
cms_smime.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
|
||||||
|
cms_smime.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
||||||
|
cms_smime.o: ../cryptlib.h cms_lcl.h cms_smime.c
|
474
crypto/cms/cms.h
Normal file
474
crypto/cms/cms.h
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
/* crypto/cms/cms.h */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HEADER_CMS_H
|
||||||
|
#define HEADER_CMS_H
|
||||||
|
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_CMS
|
||||||
|
#error CMS is disabled.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct CMS_ContentInfo_st CMS_ContentInfo;
|
||||||
|
typedef struct CMS_SignerInfo_st CMS_SignerInfo;
|
||||||
|
typedef struct CMS_CertificateChoices CMS_CertificateChoices;
|
||||||
|
typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
|
||||||
|
typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
|
||||||
|
typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
|
||||||
|
typedef struct CMS_Receipt_st CMS_Receipt;
|
||||||
|
|
||||||
|
DECLARE_STACK_OF(CMS_SignerInfo)
|
||||||
|
DECLARE_STACK_OF(GENERAL_NAMES)
|
||||||
|
DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo)
|
||||||
|
DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest)
|
||||||
|
|
||||||
|
#define CMS_SIGNERINFO_ISSUER_SERIAL 0
|
||||||
|
#define CMS_SIGNERINFO_KEYIDENTIFIER 1
|
||||||
|
|
||||||
|
#define CMS_RECIPINFO_TRANS 0
|
||||||
|
#define CMS_RECIPINFO_AGREE 1
|
||||||
|
#define CMS_RECIPINFO_KEK 2
|
||||||
|
#define CMS_RECIPINFO_PASS 3
|
||||||
|
#define CMS_RECIPINFO_OTHER 4
|
||||||
|
|
||||||
|
/* S/MIME related flags */
|
||||||
|
|
||||||
|
#define CMS_TEXT 0x1
|
||||||
|
#define CMS_NOCERTS 0x2
|
||||||
|
#define CMS_NO_CONTENT_VERIFY 0x4
|
||||||
|
#define CMS_NO_ATTR_VERIFY 0x8
|
||||||
|
#define CMS_NOSIGS \
|
||||||
|
(CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
|
||||||
|
#define CMS_NOINTERN 0x10
|
||||||
|
#define CMS_NO_SIGNER_CERT_VERIFY 0x20
|
||||||
|
#define CMS_NOVERIFY 0x20
|
||||||
|
#define CMS_DETACHED 0x40
|
||||||
|
#define CMS_BINARY 0x80
|
||||||
|
#define CMS_NOATTR 0x100
|
||||||
|
#define CMS_NOSMIMECAP 0x200
|
||||||
|
#define CMS_NOOLDMIMETYPE 0x400
|
||||||
|
#define CMS_CRLFEOL 0x800
|
||||||
|
#define CMS_STREAM 0x1000
|
||||||
|
#define CMS_NOCRL 0x2000
|
||||||
|
#define CMS_PARTIAL 0x4000
|
||||||
|
#define CMS_REUSE_DIGEST 0x8000
|
||||||
|
#define CMS_USE_KEYID 0x10000
|
||||||
|
|
||||||
|
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
|
||||||
|
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
|
||||||
|
|
||||||
|
ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
|
||||||
|
int CMS_is_detached(CMS_ContentInfo *cms);
|
||||||
|
int CMS_set_detached(CMS_ContentInfo *cms, int detached);
|
||||||
|
|
||||||
|
#ifdef HEADER_PEM_H
|
||||||
|
DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
|
||||||
|
int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
|
||||||
|
int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
|
||||||
|
int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
|
||||||
|
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
|
||||||
|
int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
|
||||||
|
|
||||||
|
int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags);
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||||
|
BIO *data, unsigned int flags);
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||||
|
X509 *signcert, EVP_PKEY *pkey,
|
||||||
|
STACK_OF(X509) *certs,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
|
||||||
|
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags);
|
||||||
|
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
BIO *dcont, BIO *out, unsigned int flags);
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||||
|
const unsigned char *key, size_t keylen);
|
||||||
|
|
||||||
|
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||||
|
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||||
|
STACK_OF(X509) *certs,
|
||||||
|
X509_STORE *store, unsigned int flags);
|
||||||
|
|
||||||
|
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
|
||||||
|
const EVP_CIPHER *cipher, unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
|
||||||
|
BIO *data, BIO *dcont,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
|
||||||
|
int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
|
||||||
|
unsigned char *key, size_t keylen,
|
||||||
|
unsigned char *id, size_t idlen);
|
||||||
|
|
||||||
|
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
|
||||||
|
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
|
||||||
|
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
|
||||||
|
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||||
|
X509 *recip, unsigned int flags);
|
||||||
|
int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
|
||||||
|
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
|
||||||
|
int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
|
||||||
|
EVP_PKEY **pk, X509 **recip,
|
||||||
|
X509_ALGOR **palg);
|
||||||
|
int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
|
||||||
|
ASN1_OCTET_STRING **keyid,
|
||||||
|
X509_NAME **issuer, ASN1_INTEGER **sno);
|
||||||
|
|
||||||
|
CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
|
||||||
|
unsigned char *key, size_t keylen,
|
||||||
|
unsigned char *id, size_t idlen,
|
||||||
|
ASN1_GENERALIZEDTIME *date,
|
||||||
|
ASN1_OBJECT *otherTypeId,
|
||||||
|
ASN1_TYPE *otherType);
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
|
||||||
|
X509_ALGOR **palg,
|
||||||
|
ASN1_OCTET_STRING **pid,
|
||||||
|
ASN1_GENERALIZEDTIME **pdate,
|
||||||
|
ASN1_OBJECT **potherid,
|
||||||
|
ASN1_TYPE **pothertype);
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
|
||||||
|
unsigned char *key, size_t keylen);
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
|
||||||
|
const unsigned char *id, size_t idlen);
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
|
||||||
|
|
||||||
|
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags);
|
||||||
|
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
|
||||||
|
const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
|
||||||
|
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
|
||||||
|
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
|
||||||
|
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
|
||||||
|
int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
|
||||||
|
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
int CMS_SignedData_init(CMS_ContentInfo *cms);
|
||||||
|
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||||||
|
X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
|
||||||
|
unsigned int flags);
|
||||||
|
STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
|
||||||
|
int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
|
||||||
|
ASN1_OCTET_STRING **keyid,
|
||||||
|
X509_NAME **issuer, ASN1_INTEGER **sno);
|
||||||
|
int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
|
||||||
|
int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||||
|
unsigned int flags);
|
||||||
|
void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
|
||||||
|
X509_ALGOR **pdig, X509_ALGOR **psig);
|
||||||
|
int CMS_SignerInfo_sign(CMS_SignerInfo *si);
|
||||||
|
int CMS_SignerInfo_verify(CMS_SignerInfo *si);
|
||||||
|
int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
|
||||||
|
|
||||||
|
int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
|
||||||
|
int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
|
||||||
|
int algnid, int keysize);
|
||||||
|
int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
|
||||||
|
|
||||||
|
int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
|
||||||
|
int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
|
||||||
|
int lastpos);
|
||||||
|
int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
|
||||||
|
int lastpos);
|
||||||
|
X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
|
||||||
|
X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
|
||||||
|
int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
|
||||||
|
int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
|
||||||
|
const ASN1_OBJECT *obj, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
|
||||||
|
int nid, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
|
||||||
|
const char *attrname, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||||
|
int lastpos, int type);
|
||||||
|
|
||||||
|
int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
|
||||||
|
int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
|
||||||
|
int lastpos);
|
||||||
|
int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
|
||||||
|
int lastpos);
|
||||||
|
X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
|
||||||
|
X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
|
||||||
|
int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
|
||||||
|
int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
|
||||||
|
const ASN1_OBJECT *obj, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
|
||||||
|
int nid, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
|
||||||
|
const char *attrname, int type,
|
||||||
|
const void *bytes, int len);
|
||||||
|
void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||||
|
int lastpos, int type);
|
||||||
|
|
||||||
|
#ifdef HEADER_X509V3_H
|
||||||
|
|
||||||
|
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
|
||||||
|
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||||
|
int allorfirst,
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptList,
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptsTo);
|
||||||
|
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
|
||||||
|
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||||
|
ASN1_STRING **pcid,
|
||||||
|
int *pallorfirst,
|
||||||
|
STACK_OF(GENERAL_NAMES) **plist,
|
||||||
|
STACK_OF(GENERAL_NAMES) **prto);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BEGIN ERROR CODES */
|
||||||
|
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||||
|
* made after this point may be overwritten when the script is next run.
|
||||||
|
*/
|
||||||
|
void ERR_load_CMS_strings(void);
|
||||||
|
|
||||||
|
/* Error codes for the CMS functions. */
|
||||||
|
|
||||||
|
/* Function codes. */
|
||||||
|
#define CMS_F_CHECK_CONTENT 99
|
||||||
|
#define CMS_F_CMS_ADD0_RECIPIENT_KEY 100
|
||||||
|
#define CMS_F_CMS_ADD1_RECEIPTREQUEST 158
|
||||||
|
#define CMS_F_CMS_ADD1_RECIPIENT_CERT 101
|
||||||
|
#define CMS_F_CMS_ADD1_SIGNER 102
|
||||||
|
#define CMS_F_CMS_ADD1_SIGNINGTIME 103
|
||||||
|
#define CMS_F_CMS_COMPRESS 104
|
||||||
|
#define CMS_F_CMS_COMPRESSEDDATA_CREATE 105
|
||||||
|
#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106
|
||||||
|
#define CMS_F_CMS_COPY_CONTENT 107
|
||||||
|
#define CMS_F_CMS_COPY_MESSAGEDIGEST 108
|
||||||
|
#define CMS_F_CMS_DATA 109
|
||||||
|
#define CMS_F_CMS_DATAFINAL 110
|
||||||
|
#define CMS_F_CMS_DATAINIT 111
|
||||||
|
#define CMS_F_CMS_DECRYPT 112
|
||||||
|
#define CMS_F_CMS_DECRYPT_SET1_KEY 113
|
||||||
|
#define CMS_F_CMS_DECRYPT_SET1_PKEY 114
|
||||||
|
#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115
|
||||||
|
#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116
|
||||||
|
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117
|
||||||
|
#define CMS_F_CMS_DIGEST_VERIFY 118
|
||||||
|
#define CMS_F_CMS_ENCODE_RECEIPT 161
|
||||||
|
#define CMS_F_CMS_ENCRYPT 119
|
||||||
|
#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120
|
||||||
|
#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121
|
||||||
|
#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122
|
||||||
|
#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123
|
||||||
|
#define CMS_F_CMS_ENVELOPEDDATA_CREATE 124
|
||||||
|
#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125
|
||||||
|
#define CMS_F_CMS_ENVELOPED_DATA_INIT 126
|
||||||
|
#define CMS_F_CMS_FINAL 127
|
||||||
|
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128
|
||||||
|
#define CMS_F_CMS_GET0_CONTENT 129
|
||||||
|
#define CMS_F_CMS_GET0_ECONTENT_TYPE 130
|
||||||
|
#define CMS_F_CMS_GET0_ENVELOPED 131
|
||||||
|
#define CMS_F_CMS_GET0_REVOCATION_CHOICES 132
|
||||||
|
#define CMS_F_CMS_GET0_SIGNED 133
|
||||||
|
#define CMS_F_CMS_MSGSIGDIGEST_ADD1 162
|
||||||
|
#define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159
|
||||||
|
#define CMS_F_CMS_RECEIPT_VERIFY 160
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144
|
||||||
|
#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145
|
||||||
|
#define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146
|
||||||
|
#define CMS_F_CMS_SET_DETACHED 147
|
||||||
|
#define CMS_F_CMS_SIGN 148
|
||||||
|
#define CMS_F_CMS_SIGNED_DATA_INIT 149
|
||||||
|
#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150
|
||||||
|
#define CMS_F_CMS_SIGNERINFO_SIGN 151
|
||||||
|
#define CMS_F_CMS_SIGNERINFO_VERIFY 152
|
||||||
|
#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153
|
||||||
|
#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154
|
||||||
|
#define CMS_F_CMS_SIGN_RECEIPT 163
|
||||||
|
#define CMS_F_CMS_STREAM 155
|
||||||
|
#define CMS_F_CMS_UNCOMPRESS 156
|
||||||
|
#define CMS_F_CMS_VERIFY 157
|
||||||
|
|
||||||
|
/* Reason codes. */
|
||||||
|
#define CMS_R_ADD_SIGNER_ERROR 99
|
||||||
|
#define CMS_R_CERTIFICATE_HAS_NO_KEYID 160
|
||||||
|
#define CMS_R_CERTIFICATE_VERIFY_ERROR 100
|
||||||
|
#define CMS_R_CIPHER_INITIALISATION_ERROR 101
|
||||||
|
#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102
|
||||||
|
#define CMS_R_CMS_DATAFINAL_ERROR 103
|
||||||
|
#define CMS_R_CMS_LIB 104
|
||||||
|
#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170
|
||||||
|
#define CMS_R_CONTENT_NOT_FOUND 105
|
||||||
|
#define CMS_R_CONTENT_TYPE_MISMATCH 171
|
||||||
|
#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106
|
||||||
|
#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107
|
||||||
|
#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108
|
||||||
|
#define CMS_R_CONTENT_VERIFY_ERROR 109
|
||||||
|
#define CMS_R_CTRL_ERROR 110
|
||||||
|
#define CMS_R_CTRL_FAILURE 111
|
||||||
|
#define CMS_R_DECRYPT_ERROR 112
|
||||||
|
#define CMS_R_DIGEST_ERROR 161
|
||||||
|
#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113
|
||||||
|
#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114
|
||||||
|
#define CMS_R_ERROR_SETTING_KEY 115
|
||||||
|
#define CMS_R_ERROR_SETTING_RECIPIENTINFO 116
|
||||||
|
#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117
|
||||||
|
#define CMS_R_INVALID_KEY_LENGTH 118
|
||||||
|
#define CMS_R_MD_BIO_INIT_ERROR 119
|
||||||
|
#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120
|
||||||
|
#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121
|
||||||
|
#define CMS_R_MSGSIGDIGEST_ERROR 172
|
||||||
|
#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162
|
||||||
|
#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163
|
||||||
|
#define CMS_R_NEED_ONE_SIGNER 164
|
||||||
|
#define CMS_R_NOT_A_SIGNED_RECEIPT 165
|
||||||
|
#define CMS_R_NOT_ENCRYPTED_DATA 122
|
||||||
|
#define CMS_R_NOT_KEK 123
|
||||||
|
#define CMS_R_NOT_KEY_TRANSPORT 124
|
||||||
|
#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125
|
||||||
|
#define CMS_R_NO_CIPHER 126
|
||||||
|
#define CMS_R_NO_CONTENT 127
|
||||||
|
#define CMS_R_NO_CONTENT_TYPE 173
|
||||||
|
#define CMS_R_NO_DEFAULT_DIGEST 128
|
||||||
|
#define CMS_R_NO_DIGEST_SET 129
|
||||||
|
#define CMS_R_NO_KEY 130
|
||||||
|
#define CMS_R_NO_KEY_OR_CERT 174
|
||||||
|
#define CMS_R_NO_MATCHING_DIGEST 131
|
||||||
|
#define CMS_R_NO_MATCHING_RECIPIENT 132
|
||||||
|
#define CMS_R_NO_MATCHING_SIGNATURE 166
|
||||||
|
#define CMS_R_NO_MSGSIGDIGEST 167
|
||||||
|
#define CMS_R_NO_PRIVATE_KEY 133
|
||||||
|
#define CMS_R_NO_PUBLIC_KEY 134
|
||||||
|
#define CMS_R_NO_RECEIPT_REQUEST 168
|
||||||
|
#define CMS_R_NO_SIGNERS 135
|
||||||
|
#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136
|
||||||
|
#define CMS_R_RECEIPT_DECODE_ERROR 169
|
||||||
|
#define CMS_R_RECIPIENT_ERROR 137
|
||||||
|
#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138
|
||||||
|
#define CMS_R_SIGNFINAL_ERROR 139
|
||||||
|
#define CMS_R_SMIME_TEXT_ERROR 140
|
||||||
|
#define CMS_R_STORE_INIT_ERROR 141
|
||||||
|
#define CMS_R_TYPE_NOT_COMPRESSED_DATA 142
|
||||||
|
#define CMS_R_TYPE_NOT_DATA 143
|
||||||
|
#define CMS_R_TYPE_NOT_DIGESTED_DATA 144
|
||||||
|
#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145
|
||||||
|
#define CMS_R_TYPE_NOT_ENVELOPED_DATA 146
|
||||||
|
#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147
|
||||||
|
#define CMS_R_UNKNOWN_CIPHER 148
|
||||||
|
#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149
|
||||||
|
#define CMS_R_UNKNOWN_ID 150
|
||||||
|
#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151
|
||||||
|
#define CMS_R_UNSUPPORTED_CONTENT_TYPE 152
|
||||||
|
#define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153
|
||||||
|
#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154
|
||||||
|
#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155
|
||||||
|
#define CMS_R_UNSUPPORTED_TYPE 156
|
||||||
|
#define CMS_R_UNWRAP_ERROR 157
|
||||||
|
#define CMS_R_VERIFICATION_FAILURE 158
|
||||||
|
#define CMS_R_WRAP_ERROR 159
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
346
crypto/cms/cms_asn1.c
Normal file
346
crypto/cms/cms_asn1.c
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
/* crypto/cms/cms_asn1.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include "cms.h"
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
|
||||||
|
ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
|
||||||
|
ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
|
||||||
|
ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
|
||||||
|
ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_CertificateChoices) = {
|
||||||
|
ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
|
||||||
|
ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
|
||||||
|
ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
|
||||||
|
ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
|
||||||
|
ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
|
||||||
|
} ASN1_CHOICE_END(CMS_CertificateChoices)
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_SignerIdentifier) = {
|
||||||
|
ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
|
||||||
|
ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
|
||||||
|
} ASN1_CHOICE_END(CMS_SignerIdentifier)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
|
||||||
|
ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
|
||||||
|
|
||||||
|
/* Minor tweak to operation: free up signer key, cert */
|
||||||
|
static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
if(operation == ASN1_OP_FREE_POST)
|
||||||
|
{
|
||||||
|
CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
|
||||||
|
if (si->pkey)
|
||||||
|
EVP_PKEY_free(si->pkey);
|
||||||
|
if (si->signer)
|
||||||
|
X509_free(si->signer);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
|
||||||
|
ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
|
||||||
|
ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
|
||||||
|
ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
|
||||||
|
} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
|
||||||
|
ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
|
||||||
|
ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_RevocationInfoChoice) = {
|
||||||
|
ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
|
||||||
|
ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
|
||||||
|
} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_SignedData, version, LONG),
|
||||||
|
ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
|
||||||
|
ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OriginatorInfo) = {
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
|
||||||
|
ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
|
||||||
|
ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
|
||||||
|
ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
|
||||||
|
ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
|
||||||
|
ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
|
||||||
|
ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
|
||||||
|
ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
|
||||||
|
ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
|
||||||
|
ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
|
||||||
|
} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = {
|
||||||
|
ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
|
||||||
|
ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
|
||||||
|
ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
|
||||||
|
ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
|
||||||
|
ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
|
||||||
|
ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
|
||||||
|
} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
|
||||||
|
ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
|
||||||
|
ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
|
||||||
|
ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_KEKIdentifier) = {
|
||||||
|
ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
|
||||||
|
ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
|
||||||
|
ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_KEKIdentifier)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
|
||||||
|
ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
|
||||||
|
ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
|
||||||
|
ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
|
||||||
|
ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
|
||||||
|
|
||||||
|
/* Free up RecipientInfo additional data */
|
||||||
|
static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
if(operation == ASN1_OP_FREE_PRE)
|
||||||
|
{
|
||||||
|
CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
|
||||||
|
if (ri->type == CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
|
||||||
|
if (ktri->pkey)
|
||||||
|
EVP_PKEY_free(ktri->pkey);
|
||||||
|
if (ktri->recip)
|
||||||
|
X509_free(ktri->recip);
|
||||||
|
}
|
||||||
|
else if (ri->type == CMS_RECIPINFO_KEK)
|
||||||
|
{
|
||||||
|
CMS_KEKRecipientInfo *kekri = ri->d.kekri;
|
||||||
|
if (kekri->key)
|
||||||
|
{
|
||||||
|
OPENSSL_cleanse(kekri->key, kekri->keylen);
|
||||||
|
OPENSSL_free(kekri->key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
|
||||||
|
ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
|
||||||
|
ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
|
||||||
|
ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
|
||||||
|
ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
|
||||||
|
ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
|
||||||
|
} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
|
||||||
|
ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
|
||||||
|
ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
|
||||||
|
ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_DigestedData, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
|
||||||
|
ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
|
||||||
|
ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
|
||||||
|
ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
|
||||||
|
ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
|
||||||
|
ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
|
||||||
|
ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
|
||||||
|
ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
|
||||||
|
ASN1_SIMPLE(CMS_CompressedData, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
|
||||||
|
ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
|
||||||
|
|
||||||
|
/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
|
||||||
|
|
||||||
|
ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
|
||||||
|
|
||||||
|
ASN1_ADB(CMS_ContentInfo) = {
|
||||||
|
ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
|
||||||
|
ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
|
||||||
|
ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
|
||||||
|
ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
|
||||||
|
ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
|
||||||
|
ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
|
||||||
|
ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
|
||||||
|
} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
|
||||||
|
|
||||||
|
ASN1_NDEF_SEQUENCE(CMS_ContentInfo) = {
|
||||||
|
ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
|
||||||
|
ASN1_ADB_OBJECT(CMS_ContentInfo)
|
||||||
|
} ASN1_NDEF_SEQUENCE_END(CMS_ContentInfo)
|
||||||
|
|
||||||
|
/* Specials for signed attributes */
|
||||||
|
|
||||||
|
/* When signing attributes we want to reorder them to match the sorted
|
||||||
|
* encoding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
|
||||||
|
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
|
||||||
|
ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
|
||||||
|
|
||||||
|
/* When verifying attributes we need to use the received order. So
|
||||||
|
* we use SEQUENCE OF and tag it to SET OF
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) =
|
||||||
|
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
|
||||||
|
V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
|
||||||
|
ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ASN1_CHOICE(CMS_ReceiptsFrom) = {
|
||||||
|
ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
|
||||||
|
ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
|
||||||
|
} ASN1_CHOICE_END(CMS_ReceiptsFrom)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_ReceiptRequest) = {
|
||||||
|
ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
|
||||||
|
ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
|
||||||
|
ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
|
||||||
|
|
||||||
|
ASN1_SEQUENCE(CMS_Receipt) = {
|
||||||
|
ASN1_SIMPLE(CMS_Receipt, version, LONG),
|
||||||
|
ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
|
||||||
|
ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
|
||||||
|
ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
|
||||||
|
} ASN1_SEQUENCE_END(CMS_Receipt)
|
||||||
|
|
195
crypto/cms/cms_att.c
Normal file
195
crypto/cms/cms_att.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* crypto/cms/cms_att.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include "cms.h"
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
/* CMS SignedData Attribute utilities */
|
||||||
|
|
||||||
|
int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_count(si->signedAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
|
||||||
|
int lastpos)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
|
||||||
|
int lastpos)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
|
||||||
|
{
|
||||||
|
return X509at_get_attr(si->signedAttrs, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
|
||||||
|
{
|
||||||
|
return X509at_delete_attr(si->signedAttrs, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr(&si->signedAttrs, attr)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
|
||||||
|
const ASN1_OBJECT *obj, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
|
||||||
|
int nid, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_NID(&si->signedAttrs, nid,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
|
||||||
|
const char *attrname, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||||
|
int lastpos, int type)
|
||||||
|
{
|
||||||
|
return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_count(si->unsignedAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
|
||||||
|
int lastpos)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
|
||||||
|
int lastpos)
|
||||||
|
{
|
||||||
|
return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
|
||||||
|
{
|
||||||
|
return X509at_get_attr(si->unsignedAttrs, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
|
||||||
|
{
|
||||||
|
return X509at_delete_attr(si->unsignedAttrs, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
|
||||||
|
const ASN1_OBJECT *obj, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
|
||||||
|
int nid, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
|
||||||
|
const char *attrname, int type,
|
||||||
|
const void *bytes, int len)
|
||||||
|
{
|
||||||
|
if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
|
||||||
|
type, bytes, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||||
|
int lastpos, int type)
|
||||||
|
{
|
||||||
|
return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific attribute cases */
|
134
crypto/cms/cms_cd.c
Normal file
134
crypto/cms/cms_cd.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* crypto/cms/cms_cd.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/comp.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_CompressedData)
|
||||||
|
|
||||||
|
#ifdef ZLIB
|
||||||
|
|
||||||
|
/* CMS CompressedData Utilities */
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
CMS_CompressedData *cd;
|
||||||
|
/* Will need something cleverer if there is ever more than one
|
||||||
|
* compression algorithm or parameters have some meaning...
|
||||||
|
*/
|
||||||
|
if (comp_nid != NID_zlib_compression)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
|
||||||
|
CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cd = M_ASN1_new_of(CMS_CompressedData);
|
||||||
|
|
||||||
|
if (!cd)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
|
||||||
|
cms->d.compressedData = cd;
|
||||||
|
|
||||||
|
cd->version = 0;
|
||||||
|
|
||||||
|
X509_ALGOR_set0(cd->compressionAlgorithm,
|
||||||
|
OBJ_nid2obj(NID_zlib_compression),
|
||||||
|
V_ASN1_UNDEF, NULL);
|
||||||
|
|
||||||
|
cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||||
|
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
if (cms)
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
CMS_CompressedData *cd;
|
||||||
|
ASN1_OBJECT *compoid;
|
||||||
|
if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
|
||||||
|
CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cd = cms->d.compressedData;
|
||||||
|
X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
|
||||||
|
if (OBJ_obj2nid(compoid) != NID_zlib_compression)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
|
||||||
|
CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return BIO_new(BIO_f_zlib());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
148
crypto/cms/cms_dd.c
Normal file
148
crypto/cms/cms_dd.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* crypto/cms/cms_dd.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_DigestedData)
|
||||||
|
|
||||||
|
/* CMS DigestedData Utilities */
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
CMS_DigestedData *dd;
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dd = M_ASN1_new_of(CMS_DigestedData);
|
||||||
|
|
||||||
|
if (!dd)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
|
||||||
|
cms->d.digestedData = dd;
|
||||||
|
|
||||||
|
dd->version = 0;
|
||||||
|
dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||||
|
|
||||||
|
cms_DigestAlgorithm_set(dd->digestAlgorithm, md);
|
||||||
|
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
if (cms)
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
CMS_DigestedData *dd;
|
||||||
|
dd = cms->d.digestedData;
|
||||||
|
return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX mctx;
|
||||||
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int mdlen;
|
||||||
|
int r = 0;
|
||||||
|
CMS_DigestedData *dd;
|
||||||
|
EVP_MD_CTX_init(&mctx);
|
||||||
|
|
||||||
|
dd = cms->d.digestedData;
|
||||||
|
|
||||||
|
if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (verify)
|
||||||
|
{
|
||||||
|
if (mdlen != (unsigned int)dd->digest->length)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
|
||||||
|
CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(md, dd->digest->data, mdlen))
|
||||||
|
CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
|
||||||
|
CMS_R_VERIFICATION_FAILURE);
|
||||||
|
else
|
||||||
|
r = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ASN1_STRING_set(dd->digest, md, mdlen))
|
||||||
|
goto err;
|
||||||
|
r = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
EVP_MD_CTX_cleanup(&mctx);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
262
crypto/cms/cms_enc.c
Normal file
262
crypto/cms/cms_enc.c
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/* crypto/cms/cms_enc.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
/* CMS EncryptedData Utilities */
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_EncryptedData)
|
||||||
|
|
||||||
|
/* Return BIO based on EncryptedContentInfo and key */
|
||||||
|
|
||||||
|
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
|
||||||
|
{
|
||||||
|
BIO *b;
|
||||||
|
EVP_CIPHER_CTX *ctx;
|
||||||
|
const EVP_CIPHER *ciph;
|
||||||
|
X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
|
||||||
|
unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
|
||||||
|
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
int enc, keep_key = 0;
|
||||||
|
|
||||||
|
enc = ec->cipher ? 1 : 0;
|
||||||
|
|
||||||
|
b = BIO_new(BIO_f_cipher());
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_get_cipher_ctx(b, &ctx);
|
||||||
|
|
||||||
|
if (enc)
|
||||||
|
{
|
||||||
|
ciph = ec->cipher;
|
||||||
|
/* If not keeping key set cipher to NULL so subsequent calls
|
||||||
|
* decrypt.
|
||||||
|
*/
|
||||||
|
if (ec->key)
|
||||||
|
ec->cipher = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ciph = EVP_get_cipherbyobj(calg->algorithm);
|
||||||
|
|
||||||
|
if (!ciph)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_UNKNOWN_CIPHER);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_CIPHER_INITIALISATION_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enc)
|
||||||
|
{
|
||||||
|
int ivlen;
|
||||||
|
calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
|
||||||
|
/* Generate a random IV if we need one */
|
||||||
|
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
|
||||||
|
if (ivlen > 0)
|
||||||
|
{
|
||||||
|
if (RAND_pseudo_bytes(iv, ivlen) <= 0)
|
||||||
|
goto err;
|
||||||
|
piv = iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (enc && !ec->key)
|
||||||
|
{
|
||||||
|
/* Generate random key */
|
||||||
|
if (!ec->keylen)
|
||||||
|
ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
|
||||||
|
ec->key = OPENSSL_malloc(ec->keylen);
|
||||||
|
if (!ec->key)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0)
|
||||||
|
goto err;
|
||||||
|
keep_key = 1;
|
||||||
|
}
|
||||||
|
else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx))
|
||||||
|
{
|
||||||
|
/* If necessary set key length */
|
||||||
|
if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_INVALID_KEY_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_CIPHER_INITIALISATION_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (piv)
|
||||||
|
{
|
||||||
|
calg->parameter = ASN1_TYPE_new();
|
||||||
|
if (!calg->parameter)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
|
||||||
|
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (ec->key && !keep_key)
|
||||||
|
{
|
||||||
|
OPENSSL_cleanse(ec->key, ec->keylen);
|
||||||
|
OPENSSL_free(ec->key);
|
||||||
|
ec->key = NULL;
|
||||||
|
}
|
||||||
|
if (ok)
|
||||||
|
return b;
|
||||||
|
BIO_free(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||||
|
const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
ec->cipher = cipher;
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
ec->key = OPENSSL_malloc(keylen);
|
||||||
|
if (!ec->key)
|
||||||
|
return 0;
|
||||||
|
memcpy(ec->key, key, keylen);
|
||||||
|
}
|
||||||
|
ec->keylen = keylen;
|
||||||
|
if (cipher)
|
||||||
|
ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
|
||||||
|
const unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
if (!key || !keylen)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ciph)
|
||||||
|
{
|
||||||
|
cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
|
||||||
|
if (!cms->d.encryptedData)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
|
||||||
|
cms->d.encryptedData->version = 0;
|
||||||
|
}
|
||||||
|
else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
|
||||||
|
CMS_R_NOT_ENCRYPTED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ec = cms->d.encryptedData->encryptedContentInfo;
|
||||||
|
return cms_EncryptedContent_init(ec, ciph, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
CMS_EncryptedData *enc = cms->d.encryptedData;
|
||||||
|
if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
|
||||||
|
enc->version = 2;
|
||||||
|
return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
|
||||||
|
}
|
825
crypto/cms/cms_env.c
Normal file
825
crypto/cms/cms_env.c
Normal file
@ -0,0 +1,825 @@
|
|||||||
|
/* crypto/cms/cms_env.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
/* CMS EnvelopedData Utilities */
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_EnvelopedData)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_RecipientInfo)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
|
||||||
|
|
||||||
|
DECLARE_STACK_OF(CMS_RecipientInfo)
|
||||||
|
|
||||||
|
static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_GET0_ENVELOPED,
|
||||||
|
CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return cms->d.envelopedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
if (cms->d.other == NULL)
|
||||||
|
{
|
||||||
|
cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
|
||||||
|
if (!cms->d.envelopedData)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cms->d.envelopedData->version = 0;
|
||||||
|
cms->d.envelopedData->encryptedContentInfo->contentType =
|
||||||
|
OBJ_nid2obj(NID_pkcs7_data);
|
||||||
|
ASN1_OBJECT_free(cms->contentType);
|
||||||
|
cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
|
||||||
|
return cms->d.envelopedData;
|
||||||
|
}
|
||||||
|
return cms_get0_enveloped(cms);
|
||||||
|
}
|
||||||
|
|
||||||
|
STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
CMS_EnvelopedData *env;
|
||||||
|
env = cms_get0_enveloped(cms);
|
||||||
|
if (!env)
|
||||||
|
return NULL;
|
||||||
|
return env->recipientInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
return ri->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
CMS_EnvelopedData *env;
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (!cms)
|
||||||
|
goto merr;
|
||||||
|
env = cms_enveloped_data_init(cms);
|
||||||
|
if (!env)
|
||||||
|
goto merr;
|
||||||
|
if (!cms_EncryptedContent_init(env->encryptedContentInfo,
|
||||||
|
cipher, NULL, 0))
|
||||||
|
goto merr;
|
||||||
|
return cms;
|
||||||
|
merr:
|
||||||
|
if (cms)
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Key Transport Recipient Info (KTRI) routines */
|
||||||
|
|
||||||
|
/* Add a recipient certificate. For now only handle key transport.
|
||||||
|
* If we ever handle key agreement will need updating.
|
||||||
|
*/
|
||||||
|
|
||||||
|
CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
|
||||||
|
X509 *recip, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_RecipientInfo *ri = NULL;
|
||||||
|
CMS_KeyTransRecipientInfo *ktri;
|
||||||
|
CMS_EnvelopedData *env;
|
||||||
|
EVP_PKEY *pk = NULL;
|
||||||
|
int type;
|
||||||
|
env = cms_get0_enveloped(cms);
|
||||||
|
if (!env)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Initialize recipient info */
|
||||||
|
ri = M_ASN1_new_of(CMS_RecipientInfo);
|
||||||
|
if (!ri)
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
/* Initialize and add key transport recipient info */
|
||||||
|
|
||||||
|
ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
|
||||||
|
if (!ri->d.ktri)
|
||||||
|
goto merr;
|
||||||
|
ri->type = CMS_RECIPINFO_TRANS;
|
||||||
|
|
||||||
|
ktri = ri->d.ktri;
|
||||||
|
|
||||||
|
X509_check_purpose(recip, -1, -1);
|
||||||
|
pk = X509_get_pubkey(recip);
|
||||||
|
if (!pk)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
|
||||||
|
CMS_R_ERROR_GETTING_PUBLIC_KEY);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
|
||||||
|
ktri->pkey = pk;
|
||||||
|
ktri->recip = recip;
|
||||||
|
|
||||||
|
if (flags & CMS_USE_KEYID)
|
||||||
|
{
|
||||||
|
ktri->version = 2;
|
||||||
|
type = CMS_RECIPINFO_KEYIDENTIFIER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ktri->version = 0;
|
||||||
|
type = CMS_RECIPINFO_ISSUER_SERIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not a typo: RecipientIdentifier and SignerIdentifier are the
|
||||||
|
* same structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8,
|
||||||
|
* hard code algorithm parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (pk->type == EVP_PKEY_RSA)
|
||||||
|
{
|
||||||
|
X509_ALGOR_set0(ktri->keyEncryptionAlgorithm,
|
||||||
|
OBJ_nid2obj(NID_rsaEncryption),
|
||||||
|
V_ASN1_NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
|
||||||
|
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
return ri;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
|
||||||
|
err:
|
||||||
|
if (ri)
|
||||||
|
M_ASN1_free_of(ri, CMS_RecipientInfo);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
|
||||||
|
EVP_PKEY **pk, X509 **recip,
|
||||||
|
X509_ALGOR **palg)
|
||||||
|
{
|
||||||
|
CMS_KeyTransRecipientInfo *ktri;
|
||||||
|
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
|
||||||
|
CMS_R_NOT_KEY_TRANSPORT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ktri = ri->d.ktri;
|
||||||
|
|
||||||
|
if (pk)
|
||||||
|
*pk = ktri->pkey;
|
||||||
|
if (recip)
|
||||||
|
*recip = ktri->recip;
|
||||||
|
if (palg)
|
||||||
|
*palg = ktri->keyEncryptionAlgorithm;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
|
||||||
|
ASN1_OCTET_STRING **keyid,
|
||||||
|
X509_NAME **issuer, ASN1_INTEGER **sno)
|
||||||
|
{
|
||||||
|
CMS_KeyTransRecipientInfo *ktri;
|
||||||
|
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
|
||||||
|
CMS_R_NOT_KEY_TRANSPORT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ktri = ri->d.ktri;
|
||||||
|
|
||||||
|
return cms_SignerIdentifier_get0_signer_id(ktri->rid,
|
||||||
|
keyid, issuer, sno);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
|
||||||
|
{
|
||||||
|
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
|
||||||
|
CMS_R_NOT_KEY_TRANSPORT);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
|
||||||
|
{
|
||||||
|
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
|
||||||
|
CMS_R_NOT_KEY_TRANSPORT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ri->d.ktri->pkey = pkey;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encrypt content key in key transport recipient info */
|
||||||
|
|
||||||
|
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
|
||||||
|
CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
CMS_KeyTransRecipientInfo *ktri;
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
unsigned char *ek = NULL;
|
||||||
|
int eklen;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ri->type != CMS_RECIPINFO_TRANS)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
|
||||||
|
CMS_R_NOT_KEY_TRANSPORT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ktri = ri->d.ktri;
|
||||||
|
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||||
|
|
||||||
|
eklen = EVP_PKEY_size(ktri->pkey);
|
||||||
|
|
||||||
|
ek = OPENSSL_malloc(eklen);
|
||||||
|
|
||||||
|
if (ek == NULL)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey);
|
||||||
|
|
||||||
|
if (eklen <= 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
|
||||||
|
ek = NULL;
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (ek)
|
||||||
|
OPENSSL_free(ek);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrypt content key from KTRI */
|
||||||
|
|
||||||
|
static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
|
||||||
|
CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
|
||||||
|
unsigned char *ek = NULL;
|
||||||
|
int eklen;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ktri->pkey == NULL)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
|
||||||
|
CMS_R_NO_PRIVATE_KEY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
eklen = EVP_PKEY_size(ktri->pkey);
|
||||||
|
|
||||||
|
ek = OPENSSL_malloc(eklen);
|
||||||
|
|
||||||
|
if (ek == NULL)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
eklen = EVP_PKEY_decrypt(ek,
|
||||||
|
ktri->encryptedKey->data,
|
||||||
|
ktri->encryptedKey->length, ktri->pkey);
|
||||||
|
if (eklen <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
cms->d.envelopedData->encryptedContentInfo->key = ek;
|
||||||
|
cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (!ret && ek)
|
||||||
|
OPENSSL_free(ek);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Key Encrypted Key (KEK) RecipientInfo routines */
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
|
||||||
|
const unsigned char *id, size_t idlen)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING tmp_os;
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
if (ri->type != CMS_RECIPINFO_KEK)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
kekri = ri->d.kekri;
|
||||||
|
tmp_os.type = V_ASN1_OCTET_STRING;
|
||||||
|
tmp_os.flags = 0;
|
||||||
|
tmp_os.data = (unsigned char *)id;
|
||||||
|
tmp_os.length = (int)idlen;
|
||||||
|
return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For now hard code AES key wrap info */
|
||||||
|
|
||||||
|
static size_t aes_wrap_keylen(int nid)
|
||||||
|
{
|
||||||
|
switch (nid)
|
||||||
|
{
|
||||||
|
case NID_id_aes128_wrap:
|
||||||
|
return 16;
|
||||||
|
|
||||||
|
case NID_id_aes192_wrap:
|
||||||
|
return 24;
|
||||||
|
|
||||||
|
case NID_id_aes256_wrap:
|
||||||
|
return 32;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
|
||||||
|
unsigned char *key, size_t keylen,
|
||||||
|
unsigned char *id, size_t idlen,
|
||||||
|
ASN1_GENERALIZEDTIME *date,
|
||||||
|
ASN1_OBJECT *otherTypeId,
|
||||||
|
ASN1_TYPE *otherType)
|
||||||
|
{
|
||||||
|
CMS_RecipientInfo *ri = NULL;
|
||||||
|
CMS_EnvelopedData *env;
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
env = cms_get0_enveloped(cms);
|
||||||
|
if (!env)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (nid == NID_undef)
|
||||||
|
{
|
||||||
|
switch (keylen)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
nid = NID_id_aes128_wrap;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
nid = NID_id_aes192_wrap;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
nid = NID_id_aes256_wrap;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
|
||||||
|
CMS_R_INVALID_KEY_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t exp_keylen = aes_wrap_keylen(nid);
|
||||||
|
|
||||||
|
if (!exp_keylen)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
|
||||||
|
CMS_R_UNSUPPORTED_KEK_ALGORITHM);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keylen != exp_keylen)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
|
||||||
|
CMS_R_INVALID_KEY_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize recipient info */
|
||||||
|
ri = M_ASN1_new_of(CMS_RecipientInfo);
|
||||||
|
if (!ri)
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
|
||||||
|
if (!ri->d.kekri)
|
||||||
|
goto merr;
|
||||||
|
ri->type = CMS_RECIPINFO_KEK;
|
||||||
|
|
||||||
|
kekri = ri->d.kekri;
|
||||||
|
|
||||||
|
if (otherTypeId)
|
||||||
|
{
|
||||||
|
kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
|
||||||
|
if (kekri->kekid->other == NULL)
|
||||||
|
goto merr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
|
||||||
|
/* After this point no calls can fail */
|
||||||
|
|
||||||
|
kekri->version = 4;
|
||||||
|
|
||||||
|
kekri->key = key;
|
||||||
|
kekri->keylen = keylen;
|
||||||
|
|
||||||
|
ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
|
||||||
|
|
||||||
|
kekri->kekid->date = date;
|
||||||
|
|
||||||
|
if (kekri->kekid->other)
|
||||||
|
{
|
||||||
|
kekri->kekid->other->keyAttrId = otherTypeId;
|
||||||
|
kekri->kekid->other->keyAttr = otherType;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
|
||||||
|
OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
|
||||||
|
|
||||||
|
return ri;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
|
||||||
|
err:
|
||||||
|
if (ri)
|
||||||
|
M_ASN1_free_of(ri, CMS_RecipientInfo);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
|
||||||
|
X509_ALGOR **palg,
|
||||||
|
ASN1_OCTET_STRING **pid,
|
||||||
|
ASN1_GENERALIZEDTIME **pdate,
|
||||||
|
ASN1_OBJECT **potherid,
|
||||||
|
ASN1_TYPE **pothertype)
|
||||||
|
{
|
||||||
|
CMS_KEKIdentifier *rkid;
|
||||||
|
if (ri->type != CMS_RECIPINFO_KEK)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rkid = ri->d.kekri->kekid;
|
||||||
|
if (palg)
|
||||||
|
*palg = ri->d.kekri->keyEncryptionAlgorithm;
|
||||||
|
if (pid)
|
||||||
|
*pid = rkid->keyIdentifier;
|
||||||
|
if (pdate)
|
||||||
|
*pdate = rkid->date;
|
||||||
|
if (potherid)
|
||||||
|
{
|
||||||
|
if (rkid->other)
|
||||||
|
*potherid = rkid->other->keyAttrId;
|
||||||
|
else
|
||||||
|
*potherid = NULL;
|
||||||
|
}
|
||||||
|
if (pothertype)
|
||||||
|
{
|
||||||
|
if (rkid->other)
|
||||||
|
*pothertype = rkid->other->keyAttr;
|
||||||
|
else
|
||||||
|
*pothertype = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
|
||||||
|
unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
if (ri->type != CMS_RECIPINFO_KEK)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kekri = ri->d.kekri;
|
||||||
|
kekri->key = key;
|
||||||
|
kekri->keylen = keylen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Encrypt content key in KEK recipient info */
|
||||||
|
|
||||||
|
static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
|
||||||
|
CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
AES_KEY actx;
|
||||||
|
unsigned char *wkey = NULL;
|
||||||
|
int wkeylen;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||||
|
|
||||||
|
kekri = ri->d.kekri;
|
||||||
|
|
||||||
|
if (!kekri->key)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
|
||||||
|
CMS_R_ERROR_SETTING_KEY);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
wkey = OPENSSL_malloc(ec->keylen + 8);
|
||||||
|
|
||||||
|
if (!wkey)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
|
||||||
|
|
||||||
|
if (wkeylen <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
if (!r && wkey)
|
||||||
|
OPENSSL_free(wkey);
|
||||||
|
OPENSSL_cleanse(&actx, sizeof(actx));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrypt content key in KEK recipient info */
|
||||||
|
|
||||||
|
static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
|
||||||
|
CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
AES_KEY actx;
|
||||||
|
unsigned char *ukey = NULL;
|
||||||
|
int ukeylen;
|
||||||
|
int r = 0, wrap_nid;
|
||||||
|
|
||||||
|
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||||
|
|
||||||
|
kekri = ri->d.kekri;
|
||||||
|
|
||||||
|
if (!kekri->key)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
|
||||||
|
if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
|
||||||
|
CMS_R_INVALID_KEY_LENGTH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If encrypted key length is invalid don't bother */
|
||||||
|
|
||||||
|
if (kekri->encryptedKey->length < 16)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
|
||||||
|
CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
|
||||||
|
CMS_R_ERROR_SETTING_KEY);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
|
||||||
|
|
||||||
|
if (!ukey)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
|
||||||
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ukeylen = AES_unwrap_key(&actx, NULL, ukey,
|
||||||
|
kekri->encryptedKey->data,
|
||||||
|
kekri->encryptedKey->length);
|
||||||
|
|
||||||
|
if (ukeylen <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
|
||||||
|
CMS_R_UNWRAP_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ec->key = ukey;
|
||||||
|
ec->keylen = ukeylen;
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
if (!r && ukey)
|
||||||
|
OPENSSL_free(ukey);
|
||||||
|
OPENSSL_cleanse(&actx, sizeof(actx));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
|
||||||
|
{
|
||||||
|
switch(ri->type)
|
||||||
|
{
|
||||||
|
case CMS_RECIPINFO_TRANS:
|
||||||
|
return cms_RecipientInfo_ktri_decrypt(cms, ri);
|
||||||
|
|
||||||
|
case CMS_RECIPINFO_KEK:
|
||||||
|
return cms_RecipientInfo_kekri_decrypt(cms, ri);
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
|
||||||
|
CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
STACK_OF(CMS_RecipientInfo) *rinfos;
|
||||||
|
CMS_RecipientInfo *ri;
|
||||||
|
int i, r, ok = 0;
|
||||||
|
BIO *ret;
|
||||||
|
|
||||||
|
/* Get BIO first to set up key */
|
||||||
|
|
||||||
|
ec = cms->d.envelopedData->encryptedContentInfo;
|
||||||
|
ret = cms_EncryptedContent_init_bio(ec);
|
||||||
|
|
||||||
|
/* If error or no cipher end of processing */
|
||||||
|
|
||||||
|
if (!ret || !ec->cipher)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Now encrypt content key according to each RecipientInfo type */
|
||||||
|
|
||||||
|
rinfos = cms->d.envelopedData->recipientInfos;
|
||||||
|
|
||||||
|
for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
|
||||||
|
{
|
||||||
|
ri = sk_CMS_RecipientInfo_value(rinfos, i);
|
||||||
|
|
||||||
|
switch (ri->type)
|
||||||
|
{
|
||||||
|
case CMS_RECIPINFO_TRANS:
|
||||||
|
r = cms_RecipientInfo_ktri_encrypt(cms, ri);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMS_RECIPINFO_KEK:
|
||||||
|
r = cms_RecipientInfo_kekri_encrypt(cms, ri);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
|
||||||
|
CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
|
||||||
|
CMS_R_ERROR_SETTING_RECIPIENTINFO);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ec->cipher = NULL;
|
||||||
|
if (ec->key)
|
||||||
|
{
|
||||||
|
OPENSSL_cleanse(ec->key, ec->keylen);
|
||||||
|
OPENSSL_free(ec->key);
|
||||||
|
ec->key = NULL;
|
||||||
|
ec->keylen = 0;
|
||||||
|
}
|
||||||
|
if (ok)
|
||||||
|
return ret;
|
||||||
|
BIO_free(ret);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
234
crypto/cms/cms_err.c
Normal file
234
crypto/cms/cms_err.c
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/* crypto/cms/cms_err.c */
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* openssl-core@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This product includes cryptographic software written by Eric Young
|
||||||
|
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||||
|
* Hudson (tjh@cryptsoft.com).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||||
|
* made to it will be overwritten when the script next updates this file,
|
||||||
|
* only reason strings will be preserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
|
||||||
|
/* BEGIN ERROR CODES */
|
||||||
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
|
||||||
|
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
|
||||||
|
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
|
||||||
|
|
||||||
|
static ERR_STRING_DATA CMS_str_functs[]=
|
||||||
|
{
|
||||||
|
{ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "CMS_COMPRESSEDDATA_CREATE"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), "CMS_COMPRESSEDDATA_INIT_BIO"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), "CMS_DIGESTALGORITHM_FIND_CTX"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), "CMS_DIGESTALGORITHM_INIT_BIO"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "CMS_ENCODE_RECEIPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), "CMS_ENCRYPTEDCONTENT_INIT_BIO"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), "CMS_EncryptedData_set1_key"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), "CMS_ENVELOPEDDATA_INIT_BIO"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "CMS_GET0_ENVELOPED"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), "CMS_GET0_REVOCATION_CHOICES"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "CMS_MSGSIGDIGEST_ADD1"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0), "CMS_ReceiptRequest_create0"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "CMS_RECEIPT_VERIFY"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), "CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), "CMS_RecipientInfo_kekri_get0_id"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), "CMS_RecipientInfo_kekri_id_cmp"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), "CMS_RECIPIENTINFO_KTRI_DECRYPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), "CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), "CMS_RecipientInfo_ktri_get0_algs"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), "CMS_RecipientInfo_ktri_get0_signer_id"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), "CMS_RecipientInfo_set0_key"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), "CMS_RecipientInfo_set0_pkey"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "CMS_SET1_SIGNERIDENTIFIER"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN), "CMS_SIGNERINFO_CONTENT_SIGN"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_SIGN_RECEIPT"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"},
|
||||||
|
{0,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static ERR_STRING_DATA CMS_str_reasons[]=
|
||||||
|
{
|
||||||
|
{ERR_REASON(CMS_R_ADD_SIGNER_ERROR) ,"add signer error"},
|
||||||
|
{ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"},
|
||||||
|
{ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
|
||||||
|
{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
|
||||||
|
{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
|
||||||
|
{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"},
|
||||||
|
{ERR_REASON(CMS_R_CMS_LIB) ,"cms lib"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_NOT_FOUND) ,"content not found"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
|
||||||
|
{ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR) ,"content verify error"},
|
||||||
|
{ERR_REASON(CMS_R_CTRL_ERROR) ,"ctrl error"},
|
||||||
|
{ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"},
|
||||||
|
{ERR_REASON(CMS_R_DECRYPT_ERROR) ,"decrypt error"},
|
||||||
|
{ERR_REASON(CMS_R_DIGEST_ERROR) ,"digest error"},
|
||||||
|
{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
|
||||||
|
{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
|
||||||
|
{ERR_REASON(CMS_R_ERROR_SETTING_KEY) ,"error setting key"},
|
||||||
|
{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
|
||||||
|
{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
|
||||||
|
{ERR_REASON(CMS_R_INVALID_KEY_LENGTH) ,"invalid key length"},
|
||||||
|
{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR) ,"md bio init error"},
|
||||||
|
{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
|
||||||
|
{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
|
||||||
|
{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR) ,"msgsigdigest error"},
|
||||||
|
{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
|
||||||
|
{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
|
||||||
|
{ERR_REASON(CMS_R_NEED_ONE_SIGNER) ,"need one signer"},
|
||||||
|
{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT) ,"not a signed receipt"},
|
||||||
|
{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA) ,"not encrypted data"},
|
||||||
|
{ERR_REASON(CMS_R_NOT_KEK) ,"not kek"},
|
||||||
|
{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT) ,"not key transport"},
|
||||||
|
{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
|
||||||
|
{ERR_REASON(CMS_R_NO_CIPHER) ,"no cipher"},
|
||||||
|
{ERR_REASON(CMS_R_NO_CONTENT) ,"no content"},
|
||||||
|
{ERR_REASON(CMS_R_NO_CONTENT_TYPE) ,"no content type"},
|
||||||
|
{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST) ,"no default digest"},
|
||||||
|
{ERR_REASON(CMS_R_NO_DIGEST_SET) ,"no digest set"},
|
||||||
|
{ERR_REASON(CMS_R_NO_KEY) ,"no key"},
|
||||||
|
{ERR_REASON(CMS_R_NO_KEY_OR_CERT) ,"no key or cert"},
|
||||||
|
{ERR_REASON(CMS_R_NO_MATCHING_DIGEST) ,"no matching digest"},
|
||||||
|
{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
|
||||||
|
{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
|
||||||
|
{ERR_REASON(CMS_R_NO_MSGSIGDIGEST) ,"no msgsigdigest"},
|
||||||
|
{ERR_REASON(CMS_R_NO_PRIVATE_KEY) ,"no private key"},
|
||||||
|
{ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"},
|
||||||
|
{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST) ,"no receipt request"},
|
||||||
|
{ERR_REASON(CMS_R_NO_SIGNERS) ,"no signers"},
|
||||||
|
{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
|
||||||
|
{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR) ,"receipt decode error"},
|
||||||
|
{ERR_REASON(CMS_R_RECIPIENT_ERROR) ,"recipient error"},
|
||||||
|
{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
||||||
|
{ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"},
|
||||||
|
{ERR_REASON(CMS_R_SMIME_TEXT_ERROR) ,"smime text error"},
|
||||||
|
{ERR_REASON(CMS_R_STORE_INIT_ERROR) ,"store init error"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
|
||||||
|
{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
|
||||||
|
{ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"},
|
||||||
|
{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
|
||||||
|
{ERR_REASON(CMS_R_UNKNOWN_ID) ,"unknown id"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
|
||||||
|
{ERR_REASON(CMS_R_UNSUPPORTED_TYPE) ,"unsupported type"},
|
||||||
|
{ERR_REASON(CMS_R_UNWRAP_ERROR) ,"unwrap error"},
|
||||||
|
{ERR_REASON(CMS_R_VERIFICATION_FAILURE) ,"verification failure"},
|
||||||
|
{ERR_REASON(CMS_R_WRAP_ERROR) ,"wrap error"},
|
||||||
|
{0,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ERR_load_CMS_strings(void)
|
||||||
|
{
|
||||||
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
|
||||||
|
if (ERR_func_error_string(CMS_str_functs[0].error) == NULL)
|
||||||
|
{
|
||||||
|
ERR_load_strings(0,CMS_str_functs);
|
||||||
|
ERR_load_strings(0,CMS_str_reasons);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
420
crypto/cms/cms_ess.c
Normal file
420
crypto/cms/cms_ess.c
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
/* crypto/cms/cms_ess.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_Receipt)
|
||||||
|
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest)
|
||||||
|
|
||||||
|
/* ESS services: for now just Signed Receipt related */
|
||||||
|
|
||||||
|
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
|
||||||
|
{
|
||||||
|
ASN1_STRING *str;
|
||||||
|
CMS_ReceiptRequest *rr = NULL;
|
||||||
|
if (prr)
|
||||||
|
*prr = NULL;
|
||||||
|
str = CMS_signed_get0_data_by_OBJ(si,
|
||||||
|
OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
|
||||||
|
-3, V_ASN1_SEQUENCE);
|
||||||
|
if (!str)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
|
||||||
|
if (!rr)
|
||||||
|
return -1;
|
||||||
|
if (prr)
|
||||||
|
*prr = rr;
|
||||||
|
else
|
||||||
|
CMS_ReceiptRequest_free(rr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||||
|
int allorfirst,
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptList,
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptsTo)
|
||||||
|
{
|
||||||
|
CMS_ReceiptRequest *rr = NULL;
|
||||||
|
|
||||||
|
rr = CMS_ReceiptRequest_new();
|
||||||
|
if (!rr)
|
||||||
|
goto merr;
|
||||||
|
if (id)
|
||||||
|
ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
|
||||||
|
goto merr;
|
||||||
|
if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32)
|
||||||
|
<= 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
|
||||||
|
rr->receiptsTo = receiptsTo;
|
||||||
|
|
||||||
|
if (receiptList)
|
||||||
|
{
|
||||||
|
rr->receiptsFrom->type = 1;
|
||||||
|
rr->receiptsFrom->d.receiptList = receiptList;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rr->receiptsFrom->type = 0;
|
||||||
|
rr->receiptsFrom->d.allOrFirstTier = allorfirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rr;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (rr)
|
||||||
|
CMS_ReceiptRequest_free(rr);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
|
||||||
|
{
|
||||||
|
unsigned char *rrder = NULL;
|
||||||
|
int rrderlen, r = 0;
|
||||||
|
|
||||||
|
rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
|
||||||
|
if (rrderlen < 0)
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
|
||||||
|
V_ASN1_SEQUENCE, rrder, rrderlen))
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
if (!r)
|
||||||
|
CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
|
||||||
|
|
||||||
|
if (rrder)
|
||||||
|
OPENSSL_free(rrder);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||||
|
ASN1_STRING **pcid,
|
||||||
|
int *pallorfirst,
|
||||||
|
STACK_OF(GENERAL_NAMES) **plist,
|
||||||
|
STACK_OF(GENERAL_NAMES) **prto)
|
||||||
|
{
|
||||||
|
if (pcid)
|
||||||
|
*pcid = rr->signedContentIdentifier;
|
||||||
|
if (rr->receiptsFrom->type == 0)
|
||||||
|
{
|
||||||
|
if (pallorfirst)
|
||||||
|
*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
|
||||||
|
if (plist)
|
||||||
|
*plist = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pallorfirst)
|
||||||
|
*pallorfirst = -1;
|
||||||
|
if (plist)
|
||||||
|
*plist = rr->receiptsFrom->d.receiptList;
|
||||||
|
}
|
||||||
|
if (prto)
|
||||||
|
*prto = rr->receiptsTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digest a SignerInfo structure for msgSigDigest attribute processing */
|
||||||
|
|
||||||
|
static int cms_msgSigDigest(CMS_SignerInfo *si,
|
||||||
|
unsigned char *dig, unsigned int *diglen)
|
||||||
|
{
|
||||||
|
const EVP_MD *md;
|
||||||
|
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
|
||||||
|
if (md == NULL)
|
||||||
|
return 0;
|
||||||
|
if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
|
||||||
|
si->signedAttrs, dig, diglen))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a msgSigDigest attribute to a SignerInfo */
|
||||||
|
|
||||||
|
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
|
||||||
|
{
|
||||||
|
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int diglen;
|
||||||
|
if (!cms_msgSigDigest(src, dig, &diglen))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
|
||||||
|
V_ASN1_OCTET_STRING, dig, diglen))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify signed receipt after it has already passed normal CMS verify */
|
||||||
|
|
||||||
|
int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
|
||||||
|
{
|
||||||
|
int r = 0, i;
|
||||||
|
CMS_ReceiptRequest *rr = NULL;
|
||||||
|
CMS_Receipt *rct = NULL;
|
||||||
|
STACK_OF(CMS_SignerInfo) *sis, *osis;
|
||||||
|
CMS_SignerInfo *si, *osi = NULL;
|
||||||
|
ASN1_OCTET_STRING *msig, **pcont;
|
||||||
|
ASN1_OBJECT *octype;
|
||||||
|
unsigned char dig[EVP_MAX_MD_SIZE];
|
||||||
|
unsigned int diglen;
|
||||||
|
|
||||||
|
/* Get SignerInfos, also checks SignedData content type */
|
||||||
|
osis = CMS_get0_SignerInfos(req_cms);
|
||||||
|
sis = CMS_get0_SignerInfos(cms);
|
||||||
|
if (!osis || !sis)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (sk_CMS_SignerInfo_num(sis) != 1)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check receipt content type */
|
||||||
|
if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract and decode receipt content */
|
||||||
|
pcont = CMS_get0_content(cms);
|
||||||
|
if (!pcont || !*pcont)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
|
||||||
|
|
||||||
|
if (!rct)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate original request */
|
||||||
|
|
||||||
|
for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
|
||||||
|
{
|
||||||
|
osi = sk_CMS_SignerInfo_value(osis, i);
|
||||||
|
if (!ASN1_STRING_cmp(osi->signature,
|
||||||
|
rct->originatorSignatureValue))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == sk_CMS_SignerInfo_num(osis))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
si = sk_CMS_SignerInfo_value(sis, 0);
|
||||||
|
|
||||||
|
/* Get msgSigDigest value and compare */
|
||||||
|
|
||||||
|
msig = CMS_signed_get0_data_by_OBJ(si,
|
||||||
|
OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
|
||||||
|
-3, V_ASN1_OCTET_STRING);
|
||||||
|
|
||||||
|
if (!msig)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cms_msgSigDigest(osi, dig, &diglen))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diglen != (unsigned int)msig->length)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||||
|
CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(dig, msig->data, diglen))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||||
|
CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare content types */
|
||||||
|
|
||||||
|
octype = CMS_signed_get0_data_by_OBJ(osi,
|
||||||
|
OBJ_nid2obj(NID_pkcs9_contentType),
|
||||||
|
-3, V_ASN1_OBJECT);
|
||||||
|
if (!octype)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare details in receipt request */
|
||||||
|
|
||||||
|
if (OBJ_cmp(octype, rct->contentType))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get original receipt request details */
|
||||||
|
|
||||||
|
if (!CMS_get1_ReceiptRequest(osi, &rr))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ASN1_STRING_cmp(rr->signedContentIdentifier,
|
||||||
|
rct->signedContentIdentifier))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
|
||||||
|
CMS_R_CONTENTIDENTIFIER_MISMATCH);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (rr)
|
||||||
|
CMS_ReceiptRequest_free(rr);
|
||||||
|
if (rct)
|
||||||
|
M_ASN1_free_of(rct, CMS_Receipt);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode a Receipt into an OCTET STRING read for including into content of
|
||||||
|
* a SignedData ContentInfo.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
|
||||||
|
{
|
||||||
|
CMS_Receipt rct;
|
||||||
|
CMS_ReceiptRequest *rr = NULL;
|
||||||
|
ASN1_OBJECT *ctype;
|
||||||
|
ASN1_OCTET_STRING *os = NULL;
|
||||||
|
|
||||||
|
/* Get original receipt request */
|
||||||
|
|
||||||
|
/* Get original receipt request details */
|
||||||
|
|
||||||
|
if (!CMS_get1_ReceiptRequest(si, &rr))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get original content type */
|
||||||
|
|
||||||
|
ctype = CMS_signed_get0_data_by_OBJ(si,
|
||||||
|
OBJ_nid2obj(NID_pkcs9_contentType),
|
||||||
|
-3, V_ASN1_OBJECT);
|
||||||
|
if (!ctype)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
rct.version = 1;
|
||||||
|
rct.contentType = ctype;
|
||||||
|
rct.signedContentIdentifier = rr->signedContentIdentifier;
|
||||||
|
rct.originatorSignatureValue = si->signature;
|
||||||
|
|
||||||
|
os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (rr)
|
||||||
|
CMS_ReceiptRequest_free(rr);
|
||||||
|
|
||||||
|
return os;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
140
crypto/cms/cms_io.c
Normal file
140
crypto/cms/cms_io.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* crypto/cms/cms_io.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include "cms.h"
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
|
||||||
|
{
|
||||||
|
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
|
||||||
|
|
||||||
|
/* Callback for int_smime_write_ASN1 */
|
||||||
|
|
||||||
|
static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
|
||||||
|
const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms = (CMS_ContentInfo *)val;
|
||||||
|
BIO *tmpbio, *cmsbio;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if (!(flags & SMIME_DETACHED))
|
||||||
|
{
|
||||||
|
SMIME_crlf_copy(data, out, flags);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let CMS code prepend any needed BIOs */
|
||||||
|
|
||||||
|
cmsbio = CMS_dataInit(cms, out);
|
||||||
|
|
||||||
|
if (!cmsbio)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Copy data across, passing through filter BIOs for processing */
|
||||||
|
SMIME_crlf_copy(data, cmsbio, flags);
|
||||||
|
|
||||||
|
/* Finalize structure */
|
||||||
|
if (CMS_dataFinal(cms, cmsbio) <= 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
/* Now remove any digests prepended to the BIO */
|
||||||
|
|
||||||
|
while (cmsbio != out)
|
||||||
|
{
|
||||||
|
tmpbio = BIO_pop(cmsbio);
|
||||||
|
BIO_free(cmsbio);
|
||||||
|
cmsbio = tmpbio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
|
||||||
|
{
|
||||||
|
STACK_OF(X509_ALGOR) *mdalgs;
|
||||||
|
int ctype_nid = OBJ_obj2nid(cms->contentType);
|
||||||
|
int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
|
||||||
|
if (ctype_nid == NID_pkcs7_signed)
|
||||||
|
mdalgs = cms->d.signedData->digestAlgorithms;
|
||||||
|
else
|
||||||
|
mdalgs = NULL;
|
||||||
|
|
||||||
|
return int_smime_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
|
||||||
|
ctype_nid, econt_nid, mdalgs,
|
||||||
|
cms_output_data,
|
||||||
|
ASN1_ITEM_rptr(CMS_ContentInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
|
||||||
|
{
|
||||||
|
return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
|
||||||
|
ASN1_ITEM_rptr(CMS_ContentInfo));
|
||||||
|
}
|
460
crypto/cms/cms_lcl.h
Normal file
460
crypto/cms/cms_lcl.h
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/* crypto/cms/cms_lcl.h */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_CMS_LCL_H
|
||||||
|
#define HEADER_CMS_LCL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
|
/* Cryptographic message syntax (CMS) structures: taken
|
||||||
|
* from RFC3852
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Forward references */
|
||||||
|
|
||||||
|
typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
|
||||||
|
typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
|
||||||
|
typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
|
||||||
|
typedef struct CMS_SignedData_st CMS_SignedData;
|
||||||
|
typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
|
||||||
|
typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
|
||||||
|
typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
|
||||||
|
typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
|
||||||
|
typedef struct CMS_DigestedData_st CMS_DigestedData;
|
||||||
|
typedef struct CMS_EncryptedData_st CMS_EncryptedData;
|
||||||
|
typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
|
||||||
|
typedef struct CMS_CompressedData_st CMS_CompressedData;
|
||||||
|
typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
|
||||||
|
typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
|
||||||
|
typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
|
||||||
|
typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
|
||||||
|
typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
|
||||||
|
typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
|
||||||
|
typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
|
||||||
|
typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
|
||||||
|
typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
|
||||||
|
typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
|
||||||
|
typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
|
||||||
|
typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
|
||||||
|
typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
|
||||||
|
typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
|
||||||
|
|
||||||
|
struct CMS_ContentInfo_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *contentType;
|
||||||
|
union {
|
||||||
|
ASN1_OCTET_STRING *data;
|
||||||
|
CMS_SignedData *signedData;
|
||||||
|
CMS_EnvelopedData *envelopedData;
|
||||||
|
CMS_DigestedData *digestedData;
|
||||||
|
CMS_EncryptedData *encryptedData;
|
||||||
|
CMS_AuthenticatedData *authenticatedData;
|
||||||
|
CMS_CompressedData *compressedData;
|
||||||
|
ASN1_TYPE *other;
|
||||||
|
/* Other types ... */
|
||||||
|
void *otherData;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_SignedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
STACK_OF(X509_ALGOR) *digestAlgorithms;
|
||||||
|
CMS_EncapsulatedContentInfo *encapContentInfo;
|
||||||
|
STACK_OF(CMS_CertificateChoices) *certificates;
|
||||||
|
STACK_OF(CMS_RevocationInfoChoice) *crls;
|
||||||
|
STACK_OF(CMS_SignerInfo) *signerInfos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_EncapsulatedContentInfo_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *eContentType;
|
||||||
|
ASN1_OCTET_STRING *eContent;
|
||||||
|
/* Set to 1 if incomplete structure only part set up */
|
||||||
|
int partial;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_SignerInfo_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_SignerIdentifier *sid;
|
||||||
|
X509_ALGOR *digestAlgorithm;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *signedAttrs;
|
||||||
|
X509_ALGOR *signatureAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *signature;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
|
||||||
|
/* Signing certificate and key */
|
||||||
|
X509 *signer;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_SignerIdentifier_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
|
||||||
|
ASN1_OCTET_STRING *subjectKeyIdentifier;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_EnvelopedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_OriginatorInfo *originatorInfo;
|
||||||
|
STACK_OF(CMS_RecipientInfo) *recipientInfos;
|
||||||
|
CMS_EncryptedContentInfo *encryptedContentInfo;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_OriginatorInfo_st
|
||||||
|
{
|
||||||
|
STACK_OF(CMS_CertificateChoices) *certificates;
|
||||||
|
STACK_OF(CMS_RevocationInfoChoice) *crls;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_EncryptedContentInfo_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *contentType;
|
||||||
|
X509_ALGOR *contentEncryptionAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *encryptedContent;
|
||||||
|
/* Content encryption algorithm and key */
|
||||||
|
const EVP_CIPHER *cipher;
|
||||||
|
unsigned char *key;
|
||||||
|
size_t keylen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_RecipientInfo_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
CMS_KeyTransRecipientInfo *ktri;
|
||||||
|
CMS_KeyAgreeRecipientInfo *kari;
|
||||||
|
CMS_KEKRecipientInfo *kekri;
|
||||||
|
CMS_PasswordRecipientInfo *pwri;
|
||||||
|
CMS_OtherRecipientInfo *ori;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
|
||||||
|
|
||||||
|
struct CMS_KeyTransRecipientInfo_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_RecipientIdentifier *rid;
|
||||||
|
X509_ALGOR *keyEncryptionAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *encryptedKey;
|
||||||
|
/* Recipient Key and cert */
|
||||||
|
X509 *recip;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_KeyAgreeRecipientInfo_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_OriginatorIdentifierOrKey *originator;
|
||||||
|
ASN1_OCTET_STRING *ukm;
|
||||||
|
X509_ALGOR *keyEncryptionAlgorithm;
|
||||||
|
STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_OriginatorIdentifierOrKey_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
|
||||||
|
ASN1_OCTET_STRING *subjectKeyIdentifier;
|
||||||
|
CMS_OriginatorPublicKey *originatorKey;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_OriginatorPublicKey_st
|
||||||
|
{
|
||||||
|
X509_ALGOR *algorithm;
|
||||||
|
ASN1_BIT_STRING *publicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_RecipientEncryptedKey_st
|
||||||
|
{
|
||||||
|
CMS_KeyAgreeRecipientIdentifier *rid;
|
||||||
|
ASN1_OCTET_STRING *encryptedKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_KeyAgreeRecipientIdentifier_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
|
||||||
|
CMS_RecipientKeyIdentifier *rKeyId;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_RecipientKeyIdentifier_st
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING *subjectKeyIdentifier;
|
||||||
|
ASN1_GENERALIZEDTIME *date;
|
||||||
|
CMS_OtherKeyAttribute *other;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_KEKRecipientInfo_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_KEKIdentifier *kekid;
|
||||||
|
X509_ALGOR *keyEncryptionAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *encryptedKey;
|
||||||
|
/* Extra info: symmetric key to use */
|
||||||
|
unsigned char *key;
|
||||||
|
size_t keylen;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_KEKIdentifier_st
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING *keyIdentifier;
|
||||||
|
ASN1_GENERALIZEDTIME *date;
|
||||||
|
CMS_OtherKeyAttribute *other;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_PasswordRecipientInfo_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
X509_ALGOR *keyDerivationAlgorithm;
|
||||||
|
X509_ALGOR *keyEncryptionAlgorithm;
|
||||||
|
ASN1_OCTET_STRING *encryptedKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_OtherRecipientInfo_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *oriType;
|
||||||
|
ASN1_TYPE *oriValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_DigestedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
X509_ALGOR *digestAlgorithm;
|
||||||
|
CMS_EncapsulatedContentInfo *encapContentInfo;
|
||||||
|
ASN1_OCTET_STRING *digest;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_EncryptedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_EncryptedContentInfo *encryptedContentInfo;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_AuthenticatedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
CMS_OriginatorInfo *originatorInfo;
|
||||||
|
STACK_OF(CMS_RecipientInfo) *recipientInfos;
|
||||||
|
X509_ALGOR *macAlgorithm;
|
||||||
|
X509_ALGOR *digestAlgorithm;
|
||||||
|
CMS_EncapsulatedContentInfo *encapContentInfo;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *authAttrs;
|
||||||
|
ASN1_OCTET_STRING *mac;
|
||||||
|
STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_CompressedData_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
X509_ALGOR *compressionAlgorithm;
|
||||||
|
STACK_OF(CMS_RecipientInfo) *recipientInfos;
|
||||||
|
CMS_EncapsulatedContentInfo *encapContentInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_RevocationInfoChoice_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
X509_CRL *crl;
|
||||||
|
CMS_OtherRevocationInfoFormat *other;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CMS_REVCHOICE_CRL 0
|
||||||
|
#define CMS_REVCHOICE_OTHER 1
|
||||||
|
|
||||||
|
struct CMS_OtherRevocationInfoFormat_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *otherRevInfoFormat;
|
||||||
|
ASN1_TYPE *otherRevInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_CertificateChoices
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
X509 *certificate;
|
||||||
|
ASN1_STRING *extendedCertificate; /* Obsolete */
|
||||||
|
ASN1_STRING *v1AttrCert; /* Left encoded for now */
|
||||||
|
ASN1_STRING *v2AttrCert; /* Left encoded for now */
|
||||||
|
CMS_OtherCertificateFormat *other;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CMS_CERTCHOICE_CERT 0
|
||||||
|
#define CMS_CERTCHOICE_EXCERT 1
|
||||||
|
#define CMS_CERTCHOICE_V1ACERT 2
|
||||||
|
#define CMS_CERTCHOICE_V2ACERT 3
|
||||||
|
#define CMS_CERTCHOICE_OTHER 4
|
||||||
|
|
||||||
|
struct CMS_OtherCertificateFormat_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *otherCertFormat;
|
||||||
|
ASN1_TYPE *otherCert;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is also defined in pkcs7.h but we duplicate it
|
||||||
|
* to allow the CMS code to be independent of PKCS#7
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct CMS_IssuerAndSerialNumber_st
|
||||||
|
{
|
||||||
|
X509_NAME *issuer;
|
||||||
|
ASN1_INTEGER *serialNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CMS_OtherKeyAttribute_st
|
||||||
|
{
|
||||||
|
ASN1_OBJECT *keyAttrId;
|
||||||
|
ASN1_TYPE *keyAttr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ESS structures */
|
||||||
|
|
||||||
|
#ifdef HEADER_X509V3_H
|
||||||
|
|
||||||
|
struct CMS_ReceiptRequest_st
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING *signedContentIdentifier;
|
||||||
|
CMS_ReceiptsFrom *receiptsFrom;
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptsTo;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CMS_ReceiptsFrom_st
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
long allOrFirstTier;
|
||||||
|
STACK_OF(GENERAL_NAMES) *receiptList;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct CMS_Receipt_st
|
||||||
|
{
|
||||||
|
long version;
|
||||||
|
ASN1_OBJECT *contentType;
|
||||||
|
ASN1_OCTET_STRING *signedContentIdentifier;
|
||||||
|
ASN1_OCTET_STRING *originatorSignatureValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_SignerInfo)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
|
||||||
|
DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
|
||||||
|
|
||||||
|
#define CMS_SIGNERINFO_ISSUER_SERIAL 0
|
||||||
|
#define CMS_SIGNERINFO_KEYIDENTIFIER 1
|
||||||
|
|
||||||
|
#define CMS_RECIPINFO_ISSUER_SERIAL 0
|
||||||
|
#define CMS_RECIPINFO_KEYIDENTIFIER 1
|
||||||
|
|
||||||
|
BIO *cms_content_bio(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_Data_create(void);
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
|
||||||
|
BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
|
||||||
|
|
||||||
|
BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
|
||||||
|
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
|
||||||
|
int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
|
||||||
|
ASN1_OCTET_STRING **keyid,
|
||||||
|
X509_NAME **issuer, ASN1_INTEGER **sno);
|
||||||
|
int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
|
||||||
|
BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
|
||||||
|
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
|
||||||
|
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
||||||
|
X509_ALGOR *mdalg);
|
||||||
|
|
||||||
|
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
|
||||||
|
BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
|
||||||
|
const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, size_t keylen);
|
||||||
|
|
||||||
|
int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
|
||||||
|
int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
|
||||||
|
ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
|
||||||
|
|
||||||
|
BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
620
crypto/cms/cms_lib.c
Normal file
620
crypto/cms/cms_lib.c
Normal file
@ -0,0 +1,620 @@
|
|||||||
|
/* crypto/cms/cms_lib.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/asn1.h>
|
||||||
|
#include "cms.h"
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo)
|
||||||
|
|
||||||
|
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
|
||||||
|
DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
|
||||||
|
DECLARE_STACK_OF(CMS_CertificateChoices)
|
||||||
|
DECLARE_STACK_OF(CMS_RevocationInfoChoice)
|
||||||
|
|
||||||
|
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
return cms->contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *cms_Data_create(void)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (cms)
|
||||||
|
{
|
||||||
|
cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
|
||||||
|
/* Never detached */
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
return cms;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *cms_content_bio(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
||||||
|
if (!pos)
|
||||||
|
return NULL;
|
||||||
|
/* If content detached data goes nowhere: create NULL BIO */
|
||||||
|
if (!*pos)
|
||||||
|
return BIO_new(BIO_s_null());
|
||||||
|
/* If content not detached and created return memory BIO
|
||||||
|
*/
|
||||||
|
if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
|
||||||
|
return BIO_new(BIO_s_mem());
|
||||||
|
/* Else content was read in: return read only BIO for it */
|
||||||
|
return BIO_new_mem_buf((*pos)->data, (*pos)->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
|
||||||
|
{
|
||||||
|
BIO *cmsbio, *cont;
|
||||||
|
if (icont)
|
||||||
|
cont = icont;
|
||||||
|
else
|
||||||
|
cont = cms_content_bio(cms);
|
||||||
|
if (!cont)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_data:
|
||||||
|
return cont;
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
cmsbio = cms_SignedData_init_bio(cms);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_pkcs7_digest:
|
||||||
|
cmsbio = cms_DigestedData_init_bio(cms);
|
||||||
|
break;
|
||||||
|
#ifdef ZLIB
|
||||||
|
case NID_id_smime_ct_compressedData:
|
||||||
|
cmsbio = cms_CompressedData_init_bio(cms);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case NID_pkcs7_encrypted:
|
||||||
|
cmsbio = cms_EncryptedData_init_bio(cms);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
cmsbio = cms_EnvelopedData_init_bio(cms);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmsbio)
|
||||||
|
return BIO_push(cmsbio, cont);
|
||||||
|
|
||||||
|
if (!icont)
|
||||||
|
BIO_free(cont);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
||||||
|
if (!pos)
|
||||||
|
return 0;
|
||||||
|
/* If ebmedded content find memory BIO and set content */
|
||||||
|
if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
|
||||||
|
{
|
||||||
|
BIO *mbio;
|
||||||
|
unsigned char *cont;
|
||||||
|
long contlen;
|
||||||
|
mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
|
||||||
|
if (!mbio)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
contlen = BIO_get_mem_data(mbio, &cont);
|
||||||
|
/* Set bio as read only so its content can't be clobbered */
|
||||||
|
BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
|
||||||
|
BIO_set_mem_eof_return(mbio, 0);
|
||||||
|
ASN1_STRING_set0(*pos, cont, contlen);
|
||||||
|
(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_data:
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
case NID_pkcs7_encrypted:
|
||||||
|
case NID_id_smime_ct_compressedData:
|
||||||
|
/* Nothing to do */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
return cms_SignedData_final(cms, cmsbio);
|
||||||
|
|
||||||
|
case NID_pkcs7_digest:
|
||||||
|
return cms_DigestedData_do_final(cms, cmsbio, 0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return an OCTET STRING pointer to content. This allows it to
|
||||||
|
* be accessed or set later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_data:
|
||||||
|
return &cms->d.data;
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
return &cms->d.signedData->encapContentInfo->eContent;
|
||||||
|
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
|
||||||
|
|
||||||
|
case NID_pkcs7_digest:
|
||||||
|
return &cms->d.digestedData->encapContentInfo->eContent;
|
||||||
|
|
||||||
|
case NID_pkcs7_encrypted:
|
||||||
|
return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
|
||||||
|
|
||||||
|
case NID_id_smime_ct_authData:
|
||||||
|
return &cms->d.authenticatedData->encapContentInfo->eContent;
|
||||||
|
|
||||||
|
case NID_id_smime_ct_compressedData:
|
||||||
|
return &cms->d.compressedData->encapContentInfo->eContent;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (cms->d.other->type == V_ASN1_OCTET_STRING)
|
||||||
|
return &cms->d.other->value.octet_string;
|
||||||
|
CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return an ASN1_OBJECT pointer to content type. This allows it to
|
||||||
|
* be accessed or set later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
return &cms->d.signedData->encapContentInfo->eContentType;
|
||||||
|
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
return &cms->d.envelopedData->encryptedContentInfo->contentType;
|
||||||
|
|
||||||
|
case NID_pkcs7_digest:
|
||||||
|
return &cms->d.digestedData->encapContentInfo->eContentType;
|
||||||
|
|
||||||
|
case NID_pkcs7_encrypted:
|
||||||
|
return &cms->d.encryptedData->encryptedContentInfo->contentType;
|
||||||
|
|
||||||
|
case NID_id_smime_ct_authData:
|
||||||
|
return &cms->d.authenticatedData->encapContentInfo->eContentType;
|
||||||
|
|
||||||
|
case NID_id_smime_ct_compressedData:
|
||||||
|
return &cms->d.compressedData->encapContentInfo->eContentType;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
|
||||||
|
CMS_R_UNSUPPORTED_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
ASN1_OBJECT **petype;
|
||||||
|
petype = cms_get0_econtent_type(cms);
|
||||||
|
if (petype)
|
||||||
|
return *petype;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
|
||||||
|
{
|
||||||
|
ASN1_OBJECT **petype, *etype;
|
||||||
|
petype = cms_get0_econtent_type(cms);
|
||||||
|
if (!petype)
|
||||||
|
return 0;
|
||||||
|
if (!oid)
|
||||||
|
return 1;
|
||||||
|
etype = OBJ_dup(oid);
|
||||||
|
if (!etype)
|
||||||
|
return 0;
|
||||||
|
ASN1_OBJECT_free(*petype);
|
||||||
|
*petype = etype;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_is_detached(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos;
|
||||||
|
pos = CMS_get0_content(cms);
|
||||||
|
if (!pos)
|
||||||
|
return -1;
|
||||||
|
if (*pos)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_set_detached(CMS_ContentInfo *cms, int detached)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos;
|
||||||
|
pos = CMS_get0_content(cms);
|
||||||
|
if (!pos)
|
||||||
|
return 0;
|
||||||
|
if (detached)
|
||||||
|
{
|
||||||
|
if (*pos)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING_free(*pos);
|
||||||
|
*pos = NULL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!*pos)
|
||||||
|
*pos = ASN1_OCTET_STRING_new();
|
||||||
|
if (*pos)
|
||||||
|
{
|
||||||
|
/* NB: special flag to show content is created and not
|
||||||
|
* read in.
|
||||||
|
*/
|
||||||
|
(*pos)->flags |= ASN1_STRING_FLAG_CONT;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
|
||||||
|
|
||||||
|
void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
|
||||||
|
{
|
||||||
|
int param_type;
|
||||||
|
|
||||||
|
switch (EVP_MD_type(md))
|
||||||
|
{
|
||||||
|
case NID_sha1:
|
||||||
|
case NID_sha224:
|
||||||
|
case NID_sha256:
|
||||||
|
case NID_sha384:
|
||||||
|
case NID_sha512:
|
||||||
|
param_type = V_ASN1_UNDEF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
param_type = V_ASN1_NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a digest BIO from an X509_ALGOR structure */
|
||||||
|
|
||||||
|
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
|
||||||
|
{
|
||||||
|
BIO *mdbio = NULL;
|
||||||
|
ASN1_OBJECT *digestoid;
|
||||||
|
const EVP_MD *digest;
|
||||||
|
X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
|
||||||
|
digest = EVP_get_digestbyobj(digestoid);
|
||||||
|
if (!digest)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
|
||||||
|
CMS_R_UNKNOWN_DIGEST_ALGORIHM);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
mdbio = BIO_new(BIO_f_md());
|
||||||
|
if (!mdbio || !BIO_set_md(mdbio, digest))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
|
||||||
|
CMS_R_MD_BIO_INIT_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return mdbio;
|
||||||
|
err:
|
||||||
|
if (mdbio)
|
||||||
|
BIO_free(mdbio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate a message digest content from a BIO chain based on SignerInfo */
|
||||||
|
|
||||||
|
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
||||||
|
X509_ALGOR *mdalg)
|
||||||
|
{
|
||||||
|
int nid;
|
||||||
|
ASN1_OBJECT *mdoid;
|
||||||
|
X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
|
||||||
|
nid = OBJ_obj2nid(mdoid);
|
||||||
|
/* Look for digest type to match signature */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX *mtmp;
|
||||||
|
chain = BIO_find_type(chain, BIO_TYPE_MD);
|
||||||
|
if (chain == NULL)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
|
||||||
|
CMS_R_NO_MATCHING_DIGEST);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
BIO_get_md_ctx(chain, &mtmp);
|
||||||
|
if (EVP_MD_CTX_type(mtmp) == nid)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX_copy_ex(mctx, mtmp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
chain = BIO_next(chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
return &cms->d.signedData->certificates;
|
||||||
|
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
return &cms->d.envelopedData->originatorInfo->certificates;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
|
||||||
|
CMS_R_UNSUPPORTED_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
STACK_OF(CMS_CertificateChoices) **pcerts;
|
||||||
|
CMS_CertificateChoices *cch;
|
||||||
|
pcerts = cms_get0_certificate_choices(cms);
|
||||||
|
if (!pcerts)
|
||||||
|
return NULL;
|
||||||
|
if (!*pcerts)
|
||||||
|
*pcerts = sk_CMS_CertificateChoices_new_null();
|
||||||
|
if (!*pcerts)
|
||||||
|
return NULL;
|
||||||
|
cch = M_ASN1_new_of(CMS_CertificateChoices);
|
||||||
|
if (!cch)
|
||||||
|
return NULL;
|
||||||
|
if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
|
||||||
|
{
|
||||||
|
M_ASN1_free_of(cch, CMS_CertificateChoices);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return cch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
|
||||||
|
{
|
||||||
|
CMS_CertificateChoices *cch;
|
||||||
|
STACK_OF(CMS_CertificateChoices) **pcerts;
|
||||||
|
int i;
|
||||||
|
pcerts = cms_get0_certificate_choices(cms);
|
||||||
|
if (!pcerts)
|
||||||
|
return 0;
|
||||||
|
if (!pcerts)
|
||||||
|
return 0;
|
||||||
|
for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
|
||||||
|
{
|
||||||
|
cch = sk_CMS_CertificateChoices_value(*pcerts, i);
|
||||||
|
if (cch->type == CMS_CERTCHOICE_CERT)
|
||||||
|
{
|
||||||
|
if (!X509_cmp(cch->d.certificate, cert))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cch = CMS_add0_CertificateChoices(cms);
|
||||||
|
if (!cch)
|
||||||
|
return 0;
|
||||||
|
cch->type = CMS_CERTCHOICE_CERT;
|
||||||
|
cch->d.certificate = cert;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = CMS_add0_cert(cms, cert);
|
||||||
|
if (r > 0)
|
||||||
|
CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
switch (OBJ_obj2nid(cms->contentType))
|
||||||
|
{
|
||||||
|
|
||||||
|
case NID_pkcs7_signed:
|
||||||
|
return &cms->d.signedData->crls;
|
||||||
|
|
||||||
|
case NID_pkcs7_enveloped:
|
||||||
|
return &cms->d.envelopedData->originatorInfo->crls;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
|
||||||
|
CMS_R_UNSUPPORTED_CONTENT_TYPE);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
STACK_OF(CMS_RevocationInfoChoice) **pcrls;
|
||||||
|
CMS_RevocationInfoChoice *rch;
|
||||||
|
pcrls = cms_get0_revocation_choices(cms);
|
||||||
|
if (!pcrls)
|
||||||
|
return NULL;
|
||||||
|
if (!*pcrls)
|
||||||
|
*pcrls = sk_CMS_RevocationInfoChoice_new_null();
|
||||||
|
if (!*pcrls)
|
||||||
|
return NULL;
|
||||||
|
rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
|
||||||
|
if (!rch)
|
||||||
|
return NULL;
|
||||||
|
if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
|
||||||
|
{
|
||||||
|
M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
|
||||||
|
{
|
||||||
|
CMS_RevocationInfoChoice *rch;
|
||||||
|
rch = CMS_add0_RevocationInfoChoice(cms);
|
||||||
|
if (!rch)
|
||||||
|
return 0;
|
||||||
|
rch->type = CMS_REVCHOICE_CRL;
|
||||||
|
rch->d.crl = crl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
STACK_OF(X509) *certs = NULL;
|
||||||
|
CMS_CertificateChoices *cch;
|
||||||
|
STACK_OF(CMS_CertificateChoices) **pcerts;
|
||||||
|
int i;
|
||||||
|
pcerts = cms_get0_certificate_choices(cms);
|
||||||
|
if (!pcerts)
|
||||||
|
return NULL;
|
||||||
|
for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
|
||||||
|
{
|
||||||
|
cch = sk_CMS_CertificateChoices_value(*pcerts, i);
|
||||||
|
if (cch->type == 0)
|
||||||
|
{
|
||||||
|
if (!certs)
|
||||||
|
{
|
||||||
|
certs = sk_X509_new_null();
|
||||||
|
if (!certs)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!sk_X509_push(certs, cch->d.certificate))
|
||||||
|
{
|
||||||
|
sk_X509_pop_free(certs, X509_free);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
CRYPTO_add(&cch->d.certificate->references,
|
||||||
|
1, CRYPTO_LOCK_X509);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return certs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
STACK_OF(X509_CRL) *crls = NULL;
|
||||||
|
STACK_OF(CMS_RevocationInfoChoice) **pcrls;
|
||||||
|
CMS_RevocationInfoChoice *rch;
|
||||||
|
int i;
|
||||||
|
pcrls = cms_get0_revocation_choices(cms);
|
||||||
|
if (!pcrls)
|
||||||
|
return NULL;
|
||||||
|
for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
|
||||||
|
{
|
||||||
|
rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
|
||||||
|
if (rch->type == 0)
|
||||||
|
{
|
||||||
|
if (!crls)
|
||||||
|
{
|
||||||
|
crls = sk_X509_CRL_new_null();
|
||||||
|
if (!crls)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!sk_X509_CRL_push(crls, rch->d.crl))
|
||||||
|
{
|
||||||
|
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
CRYPTO_add(&rch->d.crl->references,
|
||||||
|
1, CRYPTO_LOCK_X509_CRL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crls;
|
||||||
|
}
|
1006
crypto/cms/cms_sd.c
Normal file
1006
crypto/cms/cms_sd.c
Normal file
File diff suppressed because it is too large
Load Diff
784
crypto/cms/cms_smime.c
Normal file
784
crypto/cms/cms_smime.c
Normal file
@ -0,0 +1,784 @@
|
|||||||
|
/* crypto/cms/cms_smime.c */
|
||||||
|
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
* project.
|
||||||
|
*/
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. All advertising materials mentioning features or use of this
|
||||||
|
* software must display the following acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please contact
|
||||||
|
* licensing@OpenSSL.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
* nor may "OpenSSL" appear in their names without prior written
|
||||||
|
* permission of the OpenSSL Project.
|
||||||
|
*
|
||||||
|
* 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
* acknowledgment:
|
||||||
|
* "This product includes software developed by the OpenSSL Project
|
||||||
|
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryptlib.h"
|
||||||
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#include "cms_lcl.h"
|
||||||
|
|
||||||
|
static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
|
||||||
|
{
|
||||||
|
unsigned char buf[4096];
|
||||||
|
int r = 0, i;
|
||||||
|
BIO *tmpout = NULL;
|
||||||
|
|
||||||
|
if (out == NULL)
|
||||||
|
tmpout = BIO_new(BIO_s_null());
|
||||||
|
else if (flags & CMS_TEXT)
|
||||||
|
tmpout = BIO_new(BIO_s_mem());
|
||||||
|
else
|
||||||
|
tmpout = out;
|
||||||
|
|
||||||
|
if(!tmpout)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read all content through chain to process digest, decrypt etc */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
i=BIO_read(in,buf,sizeof(buf));
|
||||||
|
if (i <= 0)
|
||||||
|
{
|
||||||
|
if (BIO_method_type(in) == BIO_TYPE_CIPHER)
|
||||||
|
{
|
||||||
|
if (!BIO_get_cipher_status(in))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpout)
|
||||||
|
BIO_write(tmpout, buf, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags & CMS_TEXT)
|
||||||
|
{
|
||||||
|
if(!SMIME_text(tmpout, out))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (tmpout && (tmpout != out))
|
||||||
|
BIO_free(tmpout);
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_content(CMS_ContentInfo *cms)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
||||||
|
if (!pos || !*pos)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
|
||||||
|
{
|
||||||
|
BIO *cont;
|
||||||
|
int r;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cont = CMS_dataInit(cms, NULL);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
cms = cms_Data_create();
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (CMS_final(cms, in, flags))
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
BIO *cont;
|
||||||
|
int r;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dcont && !check_content(cms))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cont = CMS_dataInit(cms, dcont);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
if (r)
|
||||||
|
r = cms_DigestedData_do_final(cms, cont, 1);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
if (!md)
|
||||||
|
md = EVP_sha1();
|
||||||
|
cms = cms_DigestedData_create(md);
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!(flags & CMS_DETACHED))
|
||||||
|
{
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & CMS_STREAM) || CMS_final(cms, in, flags))
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
BIO *dcont, BIO *out, unsigned int flags)
|
||||||
|
{
|
||||||
|
BIO *cont;
|
||||||
|
int r;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
|
||||||
|
CMS_R_TYPE_NOT_ENCRYPTED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dcont && !check_content(cms))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
|
||||||
|
return 0;
|
||||||
|
cont = CMS_dataInit(cms, dcont);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
if (!cipher)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!(flags & CMS_DETACHED))
|
||||||
|
{
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, in, flags))
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||||
|
X509_STORE *store,
|
||||||
|
STACK_OF(X509) *certs,
|
||||||
|
STACK_OF(X509_CRL) *crls,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
X509_STORE_CTX ctx;
|
||||||
|
X509 *signer;
|
||||||
|
int i, j, r = 0;
|
||||||
|
CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
|
||||||
|
if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
|
||||||
|
CMS_R_STORE_INIT_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_SMIME_SIGN);
|
||||||
|
if (crls)
|
||||||
|
X509_STORE_CTX_set0_crls(&ctx, crls);
|
||||||
|
|
||||||
|
i = X509_verify_cert(&ctx);
|
||||||
|
if (i <= 0)
|
||||||
|
{
|
||||||
|
j = X509_STORE_CTX_get_error(&ctx);
|
||||||
|
CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
|
||||||
|
CMS_R_CERTIFICATE_VERIFY_ERROR);
|
||||||
|
ERR_add_error_data(2, "Verify error:",
|
||||||
|
X509_verify_cert_error_string(j));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
r = 1;
|
||||||
|
err:
|
||||||
|
X509_STORE_CTX_cleanup(&ctx);
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||||
|
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_SignerInfo *si;
|
||||||
|
STACK_OF(CMS_SignerInfo) *sinfos;
|
||||||
|
STACK_OF(X509) *cms_certs = NULL;
|
||||||
|
STACK_OF(X509_CRL) *crls = NULL;
|
||||||
|
X509 *signer;
|
||||||
|
int i, scount = 0, ret = 0;
|
||||||
|
BIO *cmsbio = NULL, *tmpin = NULL;
|
||||||
|
|
||||||
|
if (!dcont && !check_content(cms))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Attempt to find all signer certificates */
|
||||||
|
|
||||||
|
sinfos = CMS_get0_SignerInfos(cms);
|
||||||
|
|
||||||
|
if (sk_CMS_SignerInfo_num(sinfos) <= 0)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
|
||||||
|
{
|
||||||
|
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||||
|
CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
|
||||||
|
if (signer)
|
||||||
|
scount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scount != sk_CMS_SignerInfo_num(sinfos))
|
||||||
|
scount += CMS_set1_signers_certs(cms, certs, flags);
|
||||||
|
|
||||||
|
if (scount != sk_CMS_SignerInfo_num(sinfos))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to verify all signers certs */
|
||||||
|
|
||||||
|
if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
|
||||||
|
{
|
||||||
|
cms_certs = CMS_get1_certs(cms);
|
||||||
|
crls = CMS_get1_crls(cms);
|
||||||
|
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
|
||||||
|
{
|
||||||
|
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||||
|
if (!cms_signerinfo_verify_cert(si, store,
|
||||||
|
cms_certs, crls, flags))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to verify all SignerInfo signed attribute signatures */
|
||||||
|
|
||||||
|
if (!(flags & CMS_NO_ATTR_VERIFY))
|
||||||
|
{
|
||||||
|
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
|
||||||
|
{
|
||||||
|
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||||
|
if (CMS_signed_get_attr_count(si) < 0)
|
||||||
|
continue;
|
||||||
|
if (CMS_SignerInfo_verify(si) <= 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Performance optimization: if the content is a memory BIO then
|
||||||
|
* store its contents in a temporary read only memory BIO. This
|
||||||
|
* avoids potentially large numbers of slow copies of data which will
|
||||||
|
* occur when reading from a read write memory BIO when signatures
|
||||||
|
* are calculated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
long len;
|
||||||
|
len = BIO_get_mem_data(dcont, &ptr);
|
||||||
|
tmpin = BIO_new_mem_buf(ptr, len);
|
||||||
|
if (tmpin == NULL)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmpin = dcont;
|
||||||
|
|
||||||
|
|
||||||
|
cmsbio=CMS_dataInit(cms, tmpin);
|
||||||
|
if (!cmsbio)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!cms_copy_content(out, cmsbio, flags))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!(flags & CMS_NO_CONTENT_VERIFY))
|
||||||
|
{
|
||||||
|
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
|
||||||
|
{
|
||||||
|
si = sk_CMS_SignerInfo_value(sinfos, i);
|
||||||
|
if (!CMS_SignerInfo_verify_content(si, cmsbio))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_VERIFY,
|
||||||
|
CMS_R_CONTENT_VERIFY_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
|
||||||
|
if (dcont && (tmpin == dcont))
|
||||||
|
BIO_pop(cmsbio);
|
||||||
|
BIO_free_all(cmsbio);
|
||||||
|
|
||||||
|
if (cms_certs)
|
||||||
|
sk_X509_pop_free(cms_certs, X509_free);
|
||||||
|
if (crls)
|
||||||
|
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
|
||||||
|
STACK_OF(X509) *certs,
|
||||||
|
X509_STORE *store, unsigned int flags)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
return cms_Receipt_verify(rcms, ocms);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
|
||||||
|
BIO *data, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
int i;
|
||||||
|
cms = CMS_ContentInfo_new();
|
||||||
|
if (!cms)
|
||||||
|
goto merr;
|
||||||
|
if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
for (i = 0; i < sk_X509_num(certs); i++)
|
||||||
|
{
|
||||||
|
X509 *x = sk_X509_value(certs, i);
|
||||||
|
if (!CMS_add1_cert(cms, x))
|
||||||
|
goto merr;
|
||||||
|
}
|
||||||
|
/* If no signer or certs initialize signedData */
|
||||||
|
if (!pkey && !i && !CMS_SignedData_init(cms))
|
||||||
|
goto merr;
|
||||||
|
|
||||||
|
if(!(flags & CMS_DETACHED))
|
||||||
|
{
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, flags))
|
||||||
|
return cms;
|
||||||
|
else
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (cms)
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
|
||||||
|
X509 *signcert, EVP_PKEY *pkey,
|
||||||
|
STACK_OF(X509) *certs,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_SignerInfo *rct_si;
|
||||||
|
CMS_ContentInfo *cms = NULL;
|
||||||
|
ASN1_OCTET_STRING **pos, *os;
|
||||||
|
BIO *rct_cont = NULL;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
/* Not really detached but avoids content being allocated */
|
||||||
|
flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
|
||||||
|
if (!pkey || !signcert)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize signed data */
|
||||||
|
|
||||||
|
cms = CMS_sign(NULL, NULL, certs, NULL, flags);
|
||||||
|
if (!cms)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Set inner content type to signed receipt */
|
||||||
|
if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
|
||||||
|
if (!rct_si)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
os = cms_encode_Receipt(si);
|
||||||
|
|
||||||
|
if (!os)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Set content to digest */
|
||||||
|
rct_cont = BIO_new_mem_buf(os->data, os->length);
|
||||||
|
if (!rct_cont)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Add msgSigDigest attribute */
|
||||||
|
|
||||||
|
if (!cms_msgSigDigest_add1(rct_si, si))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Finalize structure */
|
||||||
|
if (!CMS_final(cms, rct_cont, flags))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Set embedded content */
|
||||||
|
pos = CMS_get0_content(cms);
|
||||||
|
*pos = os;
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (rct_cont)
|
||||||
|
BIO_free(rct_cont);
|
||||||
|
if (r)
|
||||||
|
return cms;
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
|
||||||
|
const EVP_CIPHER *cipher, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
int i;
|
||||||
|
X509 *recip;
|
||||||
|
cms = CMS_EnvelopedData_create(cipher);
|
||||||
|
if (!cms)
|
||||||
|
goto merr;
|
||||||
|
for (i = 0; i < sk_X509_num(certs); i++)
|
||||||
|
{
|
||||||
|
recip = sk_X509_value(certs, i);
|
||||||
|
if (!CMS_add1_recipient_cert(cms, recip, flags))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(flags & CMS_DETACHED))
|
||||||
|
{
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & (CMS_STREAM|CMS_PARTIAL)) || CMS_final(cms, data, flags))
|
||||||
|
return cms;
|
||||||
|
else
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
merr:
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
||||||
|
err:
|
||||||
|
if (cms)
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
|
||||||
|
{
|
||||||
|
STACK_OF(CMS_RecipientInfo) *ris;
|
||||||
|
CMS_RecipientInfo *ri;
|
||||||
|
int i, r;
|
||||||
|
ris = CMS_get0_RecipientInfos(cms);
|
||||||
|
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
|
||||||
|
{
|
||||||
|
ri = sk_CMS_RecipientInfo_value(ris, i);
|
||||||
|
if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
|
||||||
|
continue;
|
||||||
|
/* If we have a cert try matching RecipientInfo
|
||||||
|
* otherwise try them all.
|
||||||
|
*/
|
||||||
|
if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
|
||||||
|
{
|
||||||
|
CMS_RecipientInfo_set0_pkey(ri, pk);
|
||||||
|
r = CMS_RecipientInfo_decrypt(cms, ri);
|
||||||
|
CMS_RecipientInfo_set0_pkey(ri, NULL);
|
||||||
|
if (r > 0)
|
||||||
|
return 1;
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
|
||||||
|
CMS_R_DECRYPT_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
|
||||||
|
unsigned char *key, size_t keylen,
|
||||||
|
unsigned char *id, size_t idlen)
|
||||||
|
{
|
||||||
|
STACK_OF(CMS_RecipientInfo) *ris;
|
||||||
|
CMS_RecipientInfo *ri;
|
||||||
|
int i, r;
|
||||||
|
ris = CMS_get0_RecipientInfos(cms);
|
||||||
|
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
|
||||||
|
{
|
||||||
|
ri = sk_CMS_RecipientInfo_value(ris, i);
|
||||||
|
if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If we have an id try matching RecipientInfo
|
||||||
|
* otherwise try them all.
|
||||||
|
*/
|
||||||
|
if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
|
||||||
|
{
|
||||||
|
CMS_RecipientInfo_set0_key(ri, key, keylen);
|
||||||
|
r = CMS_RecipientInfo_decrypt(cms, ri);
|
||||||
|
CMS_RecipientInfo_set0_key(ri, NULL, 0);
|
||||||
|
if (r > 0)
|
||||||
|
return 1;
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
|
||||||
|
CMS_R_DECRYPT_ERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
|
||||||
|
BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
BIO *cont;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!dcont && !check_content(cms))
|
||||||
|
return 0;
|
||||||
|
if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cont = CMS_dataInit(cms, dcont);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags)
|
||||||
|
{
|
||||||
|
BIO *cmsbio;
|
||||||
|
int ret = 0;
|
||||||
|
if (!(cmsbio = CMS_dataInit(cms, NULL)))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMIME_crlf_copy(data, cmsbio, flags);
|
||||||
|
|
||||||
|
(void)BIO_flush(cmsbio);
|
||||||
|
|
||||||
|
|
||||||
|
if (!CMS_dataFinal(cms, cmsbio))
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
err:
|
||||||
|
BIO_free_all(cmsbio);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ZLIB
|
||||||
|
|
||||||
|
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
BIO *cont;
|
||||||
|
int r;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_UNCOMPRESS,
|
||||||
|
CMS_R_TYPE_NOT_COMPRESSED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dcont && !check_content(cms))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cont = CMS_dataInit(cms, dcont);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMS_ContentInfo *cms;
|
||||||
|
if (comp_nid <= 0)
|
||||||
|
comp_nid = NID_zlib_compression;
|
||||||
|
cms = cms_CompressedData_create(comp_nid);
|
||||||
|
if (!cms)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!(flags & CMS_DETACHED))
|
||||||
|
{
|
||||||
|
flags &= ~CMS_STREAM;
|
||||||
|
CMS_set_detached(cms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CMS_final(cms, in, flags))
|
||||||
|
return cms;
|
||||||
|
|
||||||
|
CMS_ContentInfo_free(cms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -83,23 +83,23 @@ err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
|||||||
err.o: ../cryptlib.h err.c
|
err.o: ../cryptlib.h err.c
|
||||||
err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
err_all.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
|
||||||
err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
err_all.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
|
||||||
err_all.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
|
err_all.o: ../../include/openssl/cms.h ../../include/openssl/conf.h
|
||||||
err_all.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
|
err_all.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
|
||||||
err_all.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
|
err_all.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
|
||||||
err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
|
err_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
|
err_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
|
err_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
|
||||||
err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
err_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
|
||||||
err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
|
err_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
|
||||||
err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
|
err_all.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
|
||||||
err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
|
err_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
|
||||||
err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
|
err_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
|
||||||
err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
|
err_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
|
||||||
err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
|
||||||
err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
|
||||||
err_all.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
|
err_all.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
|
||||||
err_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
|
err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||||
err_all.o: err_all.c
|
err_all.o: ../../include/openssl/x509v3.h err_all.c
|
||||||
err_prn.o: ../../e_os.h ../../include/openssl/bio.h
|
err_prn.o: ../../e_os.h ../../include/openssl/bio.h
|
||||||
err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||||
err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
|
||||||
|
@ -149,6 +149,7 @@ static ERR_STRING_DATA ERR_str_libraries[]=
|
|||||||
{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
|
{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
|
||||||
{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
|
{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
|
||||||
{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
|
{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
|
||||||
|
{ERR_PACK(ERR_LIB_CMS,0,0) ,"CMS routines"},
|
||||||
{0,NULL},
|
{0,NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ typedef struct err_state_st
|
|||||||
#define ERR_LIB_ECDSA 42
|
#define ERR_LIB_ECDSA 42
|
||||||
#define ERR_LIB_ECDH 43
|
#define ERR_LIB_ECDH 43
|
||||||
#define ERR_LIB_STORE 44
|
#define ERR_LIB_STORE 44
|
||||||
|
#define ERR_LIB_CMS 45
|
||||||
|
|
||||||
#define ERR_LIB_USER 128
|
#define ERR_LIB_USER 128
|
||||||
|
|
||||||
@ -171,6 +172,7 @@ typedef struct err_state_st
|
|||||||
#define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
|
#define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
|
||||||
#define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
|
#define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
|
||||||
#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
|
#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
|
||||||
|
#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
|
||||||
|
|
||||||
/* Borland C seems too stupid to be able to shift and do longs in
|
/* Borland C seems too stupid to be able to shift and do longs in
|
||||||
* the pre-processor :-( */
|
* the pre-processor :-( */
|
||||||
|
@ -94,6 +94,9 @@
|
|||||||
#include <openssl/ui.h>
|
#include <openssl/ui.h>
|
||||||
#include <openssl/ocsp.h>
|
#include <openssl/ocsp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#ifndef OPENSSL_NO_CMS
|
||||||
|
#include <openssl/cms.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void ERR_load_crypto_strings(void)
|
void ERR_load_crypto_strings(void)
|
||||||
{
|
{
|
||||||
@ -138,5 +141,8 @@ void ERR_load_crypto_strings(void)
|
|||||||
#endif
|
#endif
|
||||||
ERR_load_OCSP_strings();
|
ERR_load_OCSP_strings();
|
||||||
ERR_load_UI_strings();
|
ERR_load_UI_strings();
|
||||||
|
#ifndef OPENSSL_NO_CMS
|
||||||
|
ERR_load_CMS_strings();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ extern "C" {
|
|||||||
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
|
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
|
||||||
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
|
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
|
||||||
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
|
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
|
||||||
|
#define PEM_STRING_CMS "CMS"
|
||||||
|
|
||||||
/* Note that this structure is initialised by PEM_SealInit and cleaned up
|
/* Note that this structure is initialised by PEM_SealInit and cleaned up
|
||||||
by PEM_SealFinal (at least for now) */
|
by PEM_SealFinal (at least for now) */
|
||||||
|
@ -377,57 +377,6 @@ PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy text from one BIO to another making the output CRLF at EOL */
|
|
||||||
int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
|
|
||||||
{
|
|
||||||
char eol;
|
|
||||||
int len;
|
|
||||||
char linebuf[MAX_SMLEN];
|
|
||||||
if(flags & PKCS7_BINARY) {
|
|
||||||
while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
|
|
||||||
BIO_write(out, linebuf, len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(flags & PKCS7_TEXT)
|
|
||||||
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
|
|
||||||
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
|
|
||||||
eol = strip_eol(linebuf, &len);
|
|
||||||
if (len)
|
|
||||||
BIO_write(out, linebuf, len);
|
|
||||||
if(eol) BIO_write(out, "\r\n", 2);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strip off headers if they are text/plain */
|
|
||||||
int SMIME_text(BIO *in, BIO *out)
|
|
||||||
{
|
|
||||||
char iobuf[4096];
|
|
||||||
int len;
|
|
||||||
STACK_OF(MIME_HEADER) *headers;
|
|
||||||
MIME_HEADER *hdr;
|
|
||||||
|
|
||||||
if (!(headers = mime_parse_hdr(in))) {
|
|
||||||
PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
|
|
||||||
PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE);
|
|
||||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (strcmp (hdr->value, "text/plain")) {
|
|
||||||
PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE);
|
|
||||||
ERR_add_error_data(2, "type: ", hdr->value);
|
|
||||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
|
|
||||||
while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
|
|
||||||
BIO_write(out, iobuf, len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Split a multipart/XXX message body into component parts: result is
|
/* Split a multipart/XXX message body into component parts: result is
|
||||||
* canonical parts in a STACK of bios
|
* canonical parts in a STACK of bios
|
||||||
*/
|
*/
|
||||||
|
@ -414,6 +414,94 @@ STACK_OF(type) \
|
|||||||
#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
|
#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
|
||||||
#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
|
#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
|
||||||
|
|
||||||
|
#define sk_CMS_CertificateChoices_new(st) SKM_sk_new(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
|
||||||
|
#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
|
||||||
|
#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
|
||||||
|
#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
|
||||||
|
#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
|
||||||
|
#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
|
||||||
|
#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
|
||||||
|
#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
|
||||||
|
#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
|
||||||
|
#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
|
||||||
|
#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
|
||||||
|
#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
|
||||||
|
#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
|
||||||
|
#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
|
||||||
|
#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
|
||||||
|
|
||||||
|
#define sk_CMS_RecipientInfo_new(st) SKM_sk_new(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
|
||||||
|
#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
|
||||||
|
#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
|
||||||
|
#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
|
||||||
|
#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
|
||||||
|
#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
|
||||||
|
#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
|
||||||
|
#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
|
||||||
|
#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
|
||||||
|
#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
|
||||||
|
#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
|
||||||
|
#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
|
||||||
|
#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
|
||||||
|
#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
|
||||||
|
#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
|
||||||
|
|
||||||
|
#define sk_CMS_RevocationInfoChoice_new(st) SKM_sk_new(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
|
||||||
|
#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
|
||||||
|
#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
|
||||||
|
#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
|
||||||
|
|
||||||
|
#define sk_CMS_SignerInfo_new(st) SKM_sk_new(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
|
||||||
|
#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
|
||||||
|
#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
|
||||||
|
#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
|
||||||
|
#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
|
||||||
|
#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
|
||||||
|
#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
|
||||||
|
#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
|
||||||
|
#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
|
||||||
|
#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
|
||||||
|
#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
|
||||||
|
#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
|
||||||
|
#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
|
||||||
|
#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
|
||||||
|
#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
|
||||||
|
|
||||||
#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
|
#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
|
||||||
#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
|
#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
|
||||||
#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
|
#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
|
||||||
@ -612,6 +700,28 @@ STACK_OF(type) \
|
|||||||
#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
|
#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
|
||||||
#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
|
#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
|
||||||
|
|
||||||
|
#define sk_GENERAL_NAMES_new(st) SKM_sk_new(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
|
||||||
|
#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
|
||||||
|
#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
|
||||||
|
#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
|
||||||
|
#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
|
||||||
|
#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
|
||||||
|
#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
|
||||||
|
#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
|
||||||
|
#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
|
||||||
|
#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
|
||||||
|
#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
|
||||||
|
#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
|
||||||
|
#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
|
||||||
|
#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
|
||||||
|
#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
|
||||||
|
|
||||||
#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
|
#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
|
||||||
#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
|
#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
|
||||||
#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
|
#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
|
||||||
|
389
test/cms-examples.pl
Normal file
389
test/cms-examples.pl
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
# test/cms-examples.pl
|
||||||
|
# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
# project.
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
# Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
#
|
||||||
|
# 3. All advertising materials mentioning features or use of this
|
||||||
|
# software must display the following acknowledgment:
|
||||||
|
# "This product includes software developed by the OpenSSL Project
|
||||||
|
# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
#
|
||||||
|
# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# prior written permission. For written permission, please contact
|
||||||
|
# licensing@OpenSSL.org.
|
||||||
|
#
|
||||||
|
# 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
# nor may "OpenSSL" appear in their names without prior written
|
||||||
|
# permission of the OpenSSL Project.
|
||||||
|
#
|
||||||
|
# 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
# acknowledgment:
|
||||||
|
# "This product includes software developed by the OpenSSL Project
|
||||||
|
# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
# ====================================================================
|
||||||
|
|
||||||
|
# Perl script to run tests against S/MIME examples in RFC4134
|
||||||
|
# Assumes RFC is in current directory and called "rfc4134.txt"
|
||||||
|
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
|
my $badttest = 0;
|
||||||
|
my $verbose = 1;
|
||||||
|
|
||||||
|
my $cmscmd;
|
||||||
|
my $exdir = "./";
|
||||||
|
my $exfile = "./rfc4134.txt";
|
||||||
|
|
||||||
|
if (-f "../apps/openssl")
|
||||||
|
{
|
||||||
|
$cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
|
||||||
|
}
|
||||||
|
elsif (-f "..\\out32dll\\openssl.exe")
|
||||||
|
{
|
||||||
|
$cmscmd = "..\\out32dll\\openssl.exe cms";
|
||||||
|
}
|
||||||
|
elsif (-f "..\\out32\\openssl.exe")
|
||||||
|
{
|
||||||
|
$cmscmd = "..\\out32\\openssl.exe cms";
|
||||||
|
}
|
||||||
|
|
||||||
|
my @test_list = (
|
||||||
|
[ "3.1.bin" => "dataout" ],
|
||||||
|
[ "3.2.bin" => "encode, dataout" ],
|
||||||
|
[ "4.1.bin" => "encode, verifyder, content, dss" ],
|
||||||
|
[ "4.2.bin" => "encode, verifyder, cont, rsa" ],
|
||||||
|
[ "4.3.bin" => "encode, verifyder, cont_extern, dss" ],
|
||||||
|
[ "4.4.bin" => "encode, verifyder, cont, dss" ],
|
||||||
|
[ "4.5.bin" => "verifyder, content, rsa" ],
|
||||||
|
[ "4.6.bin" => "encode, verifyder, cont, dss" ],
|
||||||
|
[ "4.7.bin" => "encode, verifyder, cont, dss" ],
|
||||||
|
[ "4.8.eml" => "verifymime, dss" ],
|
||||||
|
[ "4.9.eml" => "verifymime, dss" ],
|
||||||
|
[ "4.10.bin" => "encode, verifyder, cont, dss" ],
|
||||||
|
[ "4.11.bin" => "encode" ],
|
||||||
|
[ "5.1.bin" => "encode, envelopeder, cont" ],
|
||||||
|
[ "5.2.bin" => "encode, envelopeder, cont" ],
|
||||||
|
[ "5.3.eml" => "envelopemime, cont" ],
|
||||||
|
[ "6.0.bin" => "encode, digest, cont" ],
|
||||||
|
[ "7.1.bin" => "encode, encrypted, cont" ],
|
||||||
|
[ "7.2.bin" => "encode, encrypted, cont" ]
|
||||||
|
);
|
||||||
|
|
||||||
|
# Extract examples from RFC4134 text.
|
||||||
|
# Base64 decode all examples, certificates and
|
||||||
|
# private keys are converted to PEM format.
|
||||||
|
|
||||||
|
my ( $filename, $data );
|
||||||
|
|
||||||
|
my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
|
||||||
|
|
||||||
|
$data = "";
|
||||||
|
|
||||||
|
open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
|
||||||
|
|
||||||
|
while (<IN>) {
|
||||||
|
next unless (/^\|/);
|
||||||
|
s/^\|//;
|
||||||
|
next if (/^\*/);
|
||||||
|
if (/^>(.*)$/) {
|
||||||
|
$filename = $1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if (/^</) {
|
||||||
|
$filename = "$exdir/$filename";
|
||||||
|
if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
|
||||||
|
$data = decode_base64($data);
|
||||||
|
open OUT, ">$filename";
|
||||||
|
binmode OUT;
|
||||||
|
print OUT $data;
|
||||||
|
close OUT;
|
||||||
|
push @cleanup, $filename;
|
||||||
|
}
|
||||||
|
elsif ( $filename =~ /\.cer$/ ) {
|
||||||
|
write_pem( $filename, "CERTIFICATE", $data );
|
||||||
|
}
|
||||||
|
elsif ( $filename =~ /\.pri$/ ) {
|
||||||
|
write_pem( $filename, "PRIVATE KEY", $data );
|
||||||
|
}
|
||||||
|
$data = "";
|
||||||
|
$filename = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data .= $_;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
my $secretkey =
|
||||||
|
"73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
|
||||||
|
|
||||||
|
foreach (@test_list) {
|
||||||
|
my ( $file, $tlist ) = @$_;
|
||||||
|
print "Example file $file:\n";
|
||||||
|
if ( $tlist =~ /encode/ ) {
|
||||||
|
run_reencode_test( $exdir, $file );
|
||||||
|
}
|
||||||
|
if ( $tlist =~ /dataout/ ) {
|
||||||
|
run_dataout_test( $exdir, $file );
|
||||||
|
}
|
||||||
|
if ( $tlist =~ /verify/ ) {
|
||||||
|
run_verify_test( $exdir, $tlist, $file );
|
||||||
|
}
|
||||||
|
if ( $tlist =~ /digest/ ) {
|
||||||
|
run_digest_test( $exdir, $tlist, $file );
|
||||||
|
}
|
||||||
|
if ( $tlist =~ /encrypted/ ) {
|
||||||
|
run_encrypted_test( $exdir, $tlist, $file, $secretkey );
|
||||||
|
}
|
||||||
|
if ( $tlist =~ /envelope/ ) {
|
||||||
|
run_envelope_test( $exdir, $tlist, $file );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (@cleanup) {
|
||||||
|
unlink $_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($badtest) {
|
||||||
|
print "\n$badtest TESTS FAILED!!\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\n***All tests successful***\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub write_pem {
|
||||||
|
my ( $filename, $str, $data ) = @_;
|
||||||
|
|
||||||
|
$filename =~ s/\.[^.]*$/.pem/;
|
||||||
|
|
||||||
|
push @cleanup, $filename;
|
||||||
|
|
||||||
|
open OUT, ">$filename";
|
||||||
|
|
||||||
|
print OUT "-----BEGIN $str-----\n";
|
||||||
|
print OUT $data;
|
||||||
|
print OUT "-----END $str-----\n";
|
||||||
|
|
||||||
|
close OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_reencode_test {
|
||||||
|
my ( $cmsdir, $tfile ) = @_;
|
||||||
|
unlink "tmp.der";
|
||||||
|
|
||||||
|
system( "$cmscmd -cmsout -inform DER -outform DER"
|
||||||
|
. " -in $cmsdir/$tfile -out tmp.der" );
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tReencode command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
|
||||||
|
print "\tReencode FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tReencode passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_dataout_test {
|
||||||
|
my ( $cmsdir, $tfile ) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
system(
|
||||||
|
"$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tDataout command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
|
||||||
|
print "\tDataout compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tDataout passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_verify_test {
|
||||||
|
my ( $cmsdir, $tlist, $tfile ) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
$form = "DER" if $tlist =~ /verifyder/;
|
||||||
|
$form = "SMIME" if $tlist =~ /verifymime/;
|
||||||
|
$cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
|
||||||
|
$cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
|
||||||
|
|
||||||
|
$cmd =
|
||||||
|
"$cmscmd -verify -inform $form"
|
||||||
|
. " -CAfile $cafile"
|
||||||
|
. " -in $cmsdir/$tfile -out tmp.txt";
|
||||||
|
|
||||||
|
$cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
|
||||||
|
|
||||||
|
system("$cmd 2>cms.err 1>cms.out");
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tVerify command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( $tlist =~ /cont/
|
||||||
|
&& !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
|
||||||
|
{
|
||||||
|
print "\tVerify content compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tVerify passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_envelope_test {
|
||||||
|
my ( $cmsdir, $tlist, $tfile ) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
$form = "DER" if $tlist =~ /envelopeder/;
|
||||||
|
$form = "SMIME" if $tlist =~ /envelopemime/;
|
||||||
|
|
||||||
|
$cmd =
|
||||||
|
"$cmscmd -decrypt -inform $form"
|
||||||
|
. " -recip $cmsdir/BobRSASignByCarl.pem"
|
||||||
|
. " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
|
||||||
|
. " -in $cmsdir/$tfile -out tmp.txt";
|
||||||
|
|
||||||
|
system("$cmd 2>cms.err 1>cms.out");
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tDecrypt command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( $tlist =~ /cont/
|
||||||
|
&& !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
|
||||||
|
{
|
||||||
|
print "\tDecrypt content compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tDecrypt passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_digest_test {
|
||||||
|
my ( $cmsdir, $tlist, $tfile ) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
my $cmd =
|
||||||
|
"$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
|
||||||
|
|
||||||
|
system("$cmd 2>cms.err 1>cms.out");
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tDigest verify command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( $tlist =~ /cont/
|
||||||
|
&& !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
|
||||||
|
{
|
||||||
|
print "\tDigest verify content compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tDigest verify passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub run_encrypted_test {
|
||||||
|
my ( $cmsdir, $tlist, $tfile, $key ) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
system( "$cmscmd -EncryptedData_decrypt -inform DER"
|
||||||
|
. " -secretkey $key"
|
||||||
|
. " -in $cmsdir/$tfile -out tmp.txt" );
|
||||||
|
|
||||||
|
if ($?) {
|
||||||
|
print "\tEncrypted Data command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ( $tlist =~ /cont/
|
||||||
|
&& !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
|
||||||
|
{
|
||||||
|
print "\tEncrypted Data content compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "\tEncryptedData verify passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cmp_files {
|
||||||
|
my ( $f1, $f2 ) = @_;
|
||||||
|
my ( $fp1, $fp2 );
|
||||||
|
|
||||||
|
my ( $rd1, $rd2 );
|
||||||
|
|
||||||
|
if ( !open( $fp1, "<$f1" ) ) {
|
||||||
|
print STDERR "Can't Open file $f1\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !open( $fp2, "<$f2" ) ) {
|
||||||
|
print STDERR "Can't Open file $f2\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
binmode $fp1;
|
||||||
|
binmode $fp2;
|
||||||
|
|
||||||
|
my $ret = 0;
|
||||||
|
|
||||||
|
for ( ; ; ) {
|
||||||
|
$n1 = sysread $fp1, $rd1, 4096;
|
||||||
|
$n2 = sysread $fp2, $rd2, 4096;
|
||||||
|
last if ( $n1 != $n2 );
|
||||||
|
last if ( $rd1 ne $rd2 );
|
||||||
|
|
||||||
|
if ( $n1 == 0 ) {
|
||||||
|
$ret = 1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close $fp1;
|
||||||
|
close $fp2;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
452
test/cms-test.pl
Normal file
452
test/cms-test.pl
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
# test/cms-test.pl
|
||||||
|
# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||||
|
# project.
|
||||||
|
#
|
||||||
|
# ====================================================================
|
||||||
|
# Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
#
|
||||||
|
# 3. All advertising materials mentioning features or use of this
|
||||||
|
# software must display the following acknowledgment:
|
||||||
|
# "This product includes software developed by the OpenSSL Project
|
||||||
|
# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||||
|
#
|
||||||
|
# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||||
|
# endorse or promote products derived from this software without
|
||||||
|
# prior written permission. For written permission, please contact
|
||||||
|
# licensing@OpenSSL.org.
|
||||||
|
#
|
||||||
|
# 5. Products derived from this software may not be called "OpenSSL"
|
||||||
|
# nor may "OpenSSL" appear in their names without prior written
|
||||||
|
# permission of the OpenSSL Project.
|
||||||
|
#
|
||||||
|
# 6. Redistributions of any form whatsoever must retain the following
|
||||||
|
# acknowledgment:
|
||||||
|
# "This product includes software developed by the OpenSSL Project
|
||||||
|
# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||||
|
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||||
|
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
# ====================================================================
|
||||||
|
|
||||||
|
# CMS, PKCS7 consistency test script. Run extensive tests on
|
||||||
|
# OpenSSL PKCS#7 and CMS implementations.
|
||||||
|
|
||||||
|
my $ossl_path;
|
||||||
|
|
||||||
|
if ( -f "../apps/openssl" ) {
|
||||||
|
$ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
|
||||||
|
}
|
||||||
|
elsif ( -f "..\\out32dll\\openssl.exe" ) {
|
||||||
|
$ossl_path = "..\\out32dll\\openssl.exe";
|
||||||
|
}
|
||||||
|
elsif ( -f "..\\out32\\openssl.exe" ) {
|
||||||
|
$ossl_path = "..\\out32\\openssl.exe";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die "Can't find OpenSSL executable";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $pk7cmd = "$ossl_path smime ";
|
||||||
|
my $cmscmd = "$ossl_path cms ";
|
||||||
|
my $smdir = "smime-certs";
|
||||||
|
my $halt_err = 1;
|
||||||
|
|
||||||
|
my $badcmd = 0;
|
||||||
|
my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
|
||||||
|
|
||||||
|
my @smime_pkcs7_tests = (
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content DER format, RSA key",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach"
|
||||||
|
. " -signer $smdir/smrsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed detached content DER format, RSA key",
|
||||||
|
"-sign -in smcont.txt -outform DER"
|
||||||
|
. " -signer $smdir/smrsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming BER format, RSA",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach"
|
||||||
|
. " -stream -signer $smdir/smrsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content DER format, DSA key",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach"
|
||||||
|
. " -signer $smdir/smdsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed detached content DER format, DSA key",
|
||||||
|
"-sign -in smcont.txt -outform DER"
|
||||||
|
. " -signer $smdir/smdsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed detached content DER format, add RSA signer",
|
||||||
|
"-resign -inform DER -in test.cms -outform DER"
|
||||||
|
. " -signer $smdir/smrsa1.pem -out test2.cms",
|
||||||
|
"-verify -in test2.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming BER format, DSA key",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach"
|
||||||
|
. " -stream -signer $smdir/smdsa1.pem -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming BER format, 2 DSA and 2 RSA keys",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
|
||||||
|
"-sign -in smcont.txt -outform DER -noattr -nodetach"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
|
||||||
|
"-sign -in smcont.txt -nodetach"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
|
||||||
|
"-sign -in smcont.txt"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming S/MIME format, 3 recipients",
|
||||||
|
"-encrypt -in smcont.txt"
|
||||||
|
. " -stream -out test.cms"
|
||||||
|
. " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
|
||||||
|
"-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming S/MIME format, 3 recipients, 3rd used",
|
||||||
|
"-encrypt -in smcont.txt"
|
||||||
|
. " -stream -out test.cms"
|
||||||
|
. " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
|
||||||
|
"-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming S/MIME format, 3 recipients, key only used",
|
||||||
|
"-encrypt -in smcont.txt"
|
||||||
|
. " -stream -out test.cms"
|
||||||
|
. " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
|
||||||
|
"-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
|
||||||
|
"-encrypt -in smcont.txt"
|
||||||
|
. " -aes256 -stream -out test.cms"
|
||||||
|
. " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
|
||||||
|
"-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
my @smime_cms_tests = (
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
|
||||||
|
"-sign -in smcont.txt -outform DER -nodetach -keyid"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms -inform DER "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content test streaming PEM format, 2 DSA and 2 RSA keys",
|
||||||
|
"-sign -in smcont.txt -outform PEM -nodetach"
|
||||||
|
. " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
|
||||||
|
. " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-verify -in test.cms -inform PEM "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed content MIME format, RSA key, signed receipt request",
|
||||||
|
"-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
|
||||||
|
. " -receipt_request_to test@openssl.org -receipt_request_all"
|
||||||
|
. " -out test.cms",
|
||||||
|
"-verify -in test.cms "
|
||||||
|
. " -CAfile $smdir/smroot.pem -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"signed receipt MIME format, RSA key",
|
||||||
|
"-sign_receipt -in test.cms"
|
||||||
|
. " -signer $smdir/smrsa2.pem"
|
||||||
|
. " -out test2.cms",
|
||||||
|
"-verify_receipt test2.cms -in test.cms"
|
||||||
|
. " -CAfile $smdir/smroot.pem"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming S/MIME format, 3 recipients, keyid",
|
||||||
|
"-encrypt -in smcont.txt"
|
||||||
|
. " -stream -out test.cms -keyid"
|
||||||
|
. " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
|
||||||
|
"-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming PEM format, KEK",
|
||||||
|
"-encrypt -in smcont.txt -outform PEM -aes128"
|
||||||
|
. " -stream -out test.cms "
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F "
|
||||||
|
. " -secretkeyid C0FEE0",
|
||||||
|
"-decrypt -in test.cms -out smtst.txt -inform PEM"
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F "
|
||||||
|
. " -secretkeyid C0FEE0"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"enveloped content test streaming PEM format, KEK, key only",
|
||||||
|
"-encrypt -in smcont.txt -outform PEM -aes128"
|
||||||
|
. " -stream -out test.cms "
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F "
|
||||||
|
. " -secretkeyid C0FEE0",
|
||||||
|
"-decrypt -in test.cms -out smtst.txt -inform PEM"
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F "
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"data content test streaming PEM format",
|
||||||
|
"-data_create -in smcont.txt -outform PEM -nodetach"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-data_out -in test.cms -inform PEM -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"encrypted content test streaming PEM format, 128 bit RC2 key",
|
||||||
|
"-EncryptedData_encrypt -in smcont.txt -outform PEM"
|
||||||
|
. " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-EncryptedData_decrypt -in test.cms -inform PEM "
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"encrypted content test streaming PEM format, 40 bit RC2 key",
|
||||||
|
"-EncryptedData_encrypt -in smcont.txt -outform PEM"
|
||||||
|
. " -rc2 -secretkey 0001020304"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-EncryptedData_decrypt -in test.cms -inform PEM "
|
||||||
|
. " -secretkey 0001020304 -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"encrypted content test streaming PEM format, triple DES key",
|
||||||
|
"-EncryptedData_encrypt -in smcont.txt -outform PEM"
|
||||||
|
. " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-EncryptedData_decrypt -in test.cms -inform PEM "
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
|
||||||
|
. " -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"encrypted content test streaming PEM format, 128 bit AES key",
|
||||||
|
"-EncryptedData_encrypt -in smcont.txt -outform PEM"
|
||||||
|
. " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-EncryptedData_decrypt -in test.cms -inform PEM "
|
||||||
|
. " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
|
||||||
|
],
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
my @smime_cms_comp_tests = (
|
||||||
|
|
||||||
|
[
|
||||||
|
"compressed content test streaming PEM format",
|
||||||
|
"-compress -in smcont.txt -outform PEM -nodetach"
|
||||||
|
. " -stream -out test.cms",
|
||||||
|
"-uncompress -in test.cms -inform PEM -out smtst.txt"
|
||||||
|
]
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
print "PKCS#7 <=> PKCS#7 consistency tests\n";
|
||||||
|
|
||||||
|
run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd );
|
||||||
|
|
||||||
|
print "CMS => PKCS#7 compatibility tests\n";
|
||||||
|
|
||||||
|
run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
|
||||||
|
|
||||||
|
print "CMS <= PKCS#7 compatibility tests\n";
|
||||||
|
|
||||||
|
run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
|
||||||
|
|
||||||
|
print "CMS <=> CMS consistency tests\n";
|
||||||
|
|
||||||
|
run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
|
||||||
|
run_smime_tests( \$badcmd, \@smime_cms_tests, $cmscmd, $cmscmd );
|
||||||
|
|
||||||
|
if ( `$ossl_path version -f` =~ /ZLIB/ ) {
|
||||||
|
run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Zlib not supported: compression tests skipped\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
|
||||||
|
|
||||||
|
if ($badcmd) {
|
||||||
|
print "$badcmd TESTS FAILED!!\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "ALL TESTS SUCCESSFUL.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink "test.cms";
|
||||||
|
unlink "test2.cms";
|
||||||
|
unlink "smtst.txt";
|
||||||
|
unlink "cms.out";
|
||||||
|
unlink "cms.err";
|
||||||
|
|
||||||
|
sub run_smime_tests {
|
||||||
|
my ( $rv, $aref, $scmd, $vcmd ) = @_;
|
||||||
|
|
||||||
|
foreach $smtst (@$aref) {
|
||||||
|
my ( $tnam, $rscmd, $rvcmd ) = @$smtst;
|
||||||
|
if ($ossl8)
|
||||||
|
{
|
||||||
|
# Skip smime resign: 0.9.8 smime doesn't support -resign
|
||||||
|
next if ($scmd =~ /smime/ && $rscmd =~ /-resign/);
|
||||||
|
# Disable streaming: option not supported in 0.9.8
|
||||||
|
$tnam =~ s/streaming//;
|
||||||
|
$rscmd =~ s/-stream//;
|
||||||
|
$rvcmd =~ s/-stream//;
|
||||||
|
}
|
||||||
|
system("$scmd$rscmd 2>cms.err 1>cms.out");
|
||||||
|
if ($?) {
|
||||||
|
print "$tnam: generation error\n";
|
||||||
|
$$rv++;
|
||||||
|
exit 1 if $halt_err;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
system("$vcmd$rvcmd 2>cms.err 1>cms.out");
|
||||||
|
if ($?) {
|
||||||
|
print "$tnam: verify error\n";
|
||||||
|
$$rv++;
|
||||||
|
exit 1 if $halt_err;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if (!cmp_files("smtst.txt", "smcont.txt")) {
|
||||||
|
print "$tnam: content verify error\n";
|
||||||
|
$$rv++;
|
||||||
|
exit 1 if $halt_err;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
print "$tnam: OK\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub cmp_files {
|
||||||
|
my ( $f1, $f2 ) = @_;
|
||||||
|
my ( $fp1, $fp2 );
|
||||||
|
|
||||||
|
my ( $rd1, $rd2 );
|
||||||
|
|
||||||
|
if ( !open( $fp1, "<$f1" ) ) {
|
||||||
|
print STDERR "Can't Open file $f1\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !open( $fp2, "<$f2" ) ) {
|
||||||
|
print STDERR "Can't Open file $f2\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
binmode $fp1;
|
||||||
|
binmode $fp2;
|
||||||
|
|
||||||
|
my $ret = 0;
|
||||||
|
|
||||||
|
for ( ; ; ) {
|
||||||
|
$n1 = sysread $fp1, $rd1, 4096;
|
||||||
|
$n2 = sysread $fp2, $rd2, 4096;
|
||||||
|
last if ( $n1 != $n2 );
|
||||||
|
last if ( $rd1 ne $rd2 );
|
||||||
|
|
||||||
|
if ( $n1 == 0 ) {
|
||||||
|
$ret = 1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close $fp1;
|
||||||
|
close $fp2;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
1
test/smcont.txt
Normal file
1
test/smcont.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Some test content for OpenSSL CMS
|
Loading…
x
Reference in New Issue
Block a user