summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
authorbeck <>2000-03-19 11:13:58 +0000
committerbeck <>2000-03-19 11:13:58 +0000
commit796d609550df3a33fc11468741c5d2f6d3df4c11 (patch)
tree6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/pkcs7
parent5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff)
downloadopenbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.gz
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.tar.bz2
openbsd-796d609550df3a33fc11468741c5d2f6d3df4c11.zip
OpenSSL 0.9.5 merge
*warning* this bumps shared lib minors for libssl and libcrypto from 2.1 to 2.2 if you are using the ssl26 packages for ssh and other things to work you will need to get new ones (see ~beck/libsslsnap/<arch>) on cvs or ~beck/src-patent.tar.gz on cvs
Diffstat (limited to 'src/lib/libcrypto/pkcs7')
-rw-r--r--src/lib/libcrypto/pkcs7/Makefile.ssl85
-rw-r--r--src/lib/libcrypto/pkcs7/bio_ber.c18
-rw-r--r--src/lib/libcrypto/pkcs7/dec.c12
-rw-r--r--src/lib/libcrypto/pkcs7/enc.c15
-rw-r--r--src/lib/libcrypto/pkcs7/example.c15
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_attr.c85
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c121
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c54
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c673
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c427
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h85
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c39
-rw-r--r--src/lib/libcrypto/pkcs7/sign.c13
-rw-r--r--src/lib/libcrypto/pkcs7/verify.c11
14 files changed, 1559 insertions, 94 deletions
diff --git a/src/lib/libcrypto/pkcs7/Makefile.ssl b/src/lib/libcrypto/pkcs7/Makefile.ssl
index 6c4644b2f2..0e508386e8 100644
--- a/src/lib/libcrypto/pkcs7/Makefile.ssl
+++ b/src/lib/libcrypto/pkcs7/Makefile.ssl
@@ -1,5 +1,5 @@
1# 1#
2# SSLeay/crypto/asn1/Makefile 2# SSLeay/crypto/pkcs7/Makefile
3# 3#
4 4
5DIR= pkcs7 5DIR= pkcs7
@@ -15,6 +15,9 @@ MAKEDEPEND= $(TOP)/util/domd $(TOP)
15MAKEFILE= Makefile.ssl 15MAKEFILE= Makefile.ssl
16AR= ar r 16AR= ar r
17 17
18PEX_LIBS=
19EX_LIBS=
20
18CFLAGS= $(INCLUDES) $(CFLAG) 21CFLAGS= $(INCLUDES) $(CFLAG)
19 22
20GENERAL=Makefile README 23GENERAL=Makefile README
@@ -22,8 +25,8 @@ TEST=
22APPS= 25APPS=
23 26
24LIB=$(TOP)/libcrypto.a 27LIB=$(TOP)/libcrypto.a
25LIBSRC= pk7_lib.c pkcs7err.c pk7_doit.c 28LIBSRC= pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c pk7_mime.c
26LIBOBJ= pk7_lib.o pkcs7err.o pk7_doit.o 29LIBOBJ= pk7_lib.o pkcs7err.o pk7_doit.o pk7_smime.o pk7_attr.o pk7_mime.o
27 30
28SRC= $(LIBSRC) 31SRC= $(LIBSRC)
29 32
@@ -42,16 +45,16 @@ all: lib
42testapps: enc dec sign verify 45testapps: enc dec sign verify
43 46
44enc: enc.o lib 47enc: enc.o lib
45 $(CC) $(CFLAGS) -o enc enc.o $(LIB) 48 $(CC) $(CFLAGS) -o enc enc.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
46 49
47dec: dec.o lib 50dec: dec.o lib
48 $(CC) $(CFLAGS) -o dec dec.o $(LIB) 51 $(CC) $(CFLAGS) -o dec dec.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
49 52
50sign: sign.o lib 53sign: sign.o lib
51 $(CC) $(CFLAGS) -o sign sign.o $(LIB) 54 $(CC) $(CFLAGS) -o sign sign.o $(PEX_LIBS) $(LIB) $(EX_LIBS)
52 55
53verify: verify.o example.o lib 56verify: verify.o example.o lib
54 $(CC) $(CFLAGS) -o verify verify.o example.o $(LIB) 57 $(CC) $(CFLAGS) -o verify verify.o $(PEX_LIBS) example.o $(LIB) $(EX_LIBS)
55 58
56lib: $(LIBOBJ) 59lib: $(LIBOBJ)
57 $(AR) $(LIB) $(LIBOBJ) 60 $(AR) $(LIB) $(LIBOBJ)
@@ -90,18 +93,35 @@ dclean:
90 mv -f Makefile.new $(MAKEFILE) 93 mv -f Makefile.new $(MAKEFILE)
91 94
92clean: 95clean:
93 rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff 96 rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff enc dec sign verify
94 97
95# DO NOT DELETE THIS LINE -- make depend depends on it. 98# DO NOT DELETE THIS LINE -- make depend depends on it.
96 99
100pk7_attr.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
101pk7_attr.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
102pk7_attr.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
103pk7_attr.o: ../../include/openssl/des.h ../../include/openssl/dh.h
104pk7_attr.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
105pk7_attr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
106pk7_attr.o: ../../include/openssl/idea.h ../../include/openssl/md2.h
107pk7_attr.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
108pk7_attr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
109pk7_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h
110pk7_attr.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
111pk7_attr.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
112pk7_attr.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
113pk7_attr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
114pk7_attr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
115pk7_attr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
97pk7_doit.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 116pk7_doit.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
98pk7_doit.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 117pk7_doit.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
99pk7_doit.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 118pk7_doit.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
100pk7_doit.o: ../../include/openssl/crypto.h ../../include/openssl/des.h 119pk7_doit.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
101pk7_doit.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h 120pk7_doit.o: ../../include/openssl/des.h ../../include/openssl/dh.h
102pk7_doit.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h 121pk7_doit.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
103pk7_doit.o: ../../include/openssl/err.h ../../include/openssl/evp.h 122pk7_doit.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
104pk7_doit.o: ../../include/openssl/idea.h ../../include/openssl/md2.h 123pk7_doit.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
124pk7_doit.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
105pk7_doit.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h 125pk7_doit.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
106pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h 126pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
107pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h 127pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
@@ -110,7 +130,8 @@ pk7_doit.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
110pk7_doit.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h 130pk7_doit.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
111pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h 131pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
112pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/x509.h 132pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
113pk7_doit.o: ../../include/openssl/x509_vfy.h ../cryptlib.h 133pk7_doit.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
134pk7_doit.o: ../cryptlib.h
114pk7_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 135pk7_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
115pk7_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 136pk7_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
116pk7_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h 137pk7_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
@@ -128,6 +149,42 @@ pk7_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
128pk7_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 149pk7_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
129pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h 150pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
130pk7_lib.o: ../cryptlib.h 151pk7_lib.o: ../cryptlib.h
152pk7_mime.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
153pk7_mime.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
154pk7_mime.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
155pk7_mime.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
156pk7_mime.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
157pk7_mime.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
158pk7_mime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
159pk7_mime.o: ../../include/openssl/idea.h ../../include/openssl/md2.h
160pk7_mime.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
161pk7_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
162pk7_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
163pk7_mime.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
164pk7_mime.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
165pk7_mime.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
166pk7_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
167pk7_mime.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
168pk7_mime.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
169pk7_smime.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
170pk7_smime.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
171pk7_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
172pk7_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
173pk7_smime.o: ../../include/openssl/des.h ../../include/openssl/dh.h
174pk7_smime.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
175pk7_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
176pk7_smime.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
177pk7_smime.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
178pk7_smime.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
179pk7_smime.o: ../../include/openssl/objects.h
180pk7_smime.o: ../../include/openssl/opensslconf.h
181pk7_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
182pk7_smime.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
183pk7_smime.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
184pk7_smime.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
185pk7_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
186pk7_smime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
187pk7_smime.o: ../../include/openssl/x509v3.h ../cryptlib.h
131pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h 188pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
132pkcs7err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h 189pkcs7err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
133pkcs7err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h 190pkcs7err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
diff --git a/src/lib/libcrypto/pkcs7/bio_ber.c b/src/lib/libcrypto/pkcs7/bio_ber.c
index 2f17723e98..4803966fd2 100644
--- a/src/lib/libcrypto/pkcs7/bio_ber.c
+++ b/src/lib/libcrypto/pkcs7/bio_ber.c
@@ -69,6 +69,7 @@ static int ber_read(BIO *h,char *buf,int size);
69static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2); 69static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2);
70static int ber_new(BIO *h); 70static int ber_new(BIO *h);
71static int ber_free(BIO *data); 71static int ber_free(BIO *data);
72static long ber_callback_ctrl(BIO *h,int cmd,void *(*fp)());
72#define BER_BUF_SIZE (32) 73#define BER_BUF_SIZE (32)
73 74
74/* This is used to hold the state of the BER objects being read. */ 75/* This is used to hold the state of the BER objects being read. */
@@ -92,7 +93,7 @@ typedef struct bio_ber_struct
92 /* most of the following are used when doing non-blocking IO */ 93 /* most of the following are used when doing non-blocking IO */
93 /* reading */ 94 /* reading */
94 long num_left; /* number of bytes still to read/write in block */ 95 long num_left; /* number of bytes still to read/write in block */
95 int depth; /* used with idefinite encoding. */ 96 int depth; /* used with indefinite encoding. */
96 int finished; /* No more read data */ 97 int finished; /* No more read data */
97 98
98 /* writting */ 99 /* writting */
@@ -115,6 +116,7 @@ static BIO_METHOD methods_ber=
115 ber_ctrl, 116 ber_ctrl,
116 ber_new, 117 ber_new,
117 ber_free, 118 ber_free,
119 ber_callback_ctrl,
118 }; 120 };
119 121
120BIO_METHOD *BIO_f_ber(void) 122BIO_METHOD *BIO_f_ber(void)
@@ -409,6 +411,20 @@ again:
409 return(ret); 411 return(ret);
410 } 412 }
411 413
414static long ber_callback_ctrl(BIO *b, int cmd, void *(*fp)())
415 {
416 long ret=1;
417
418 if (b->next_bio == NULL) return(0);
419 switch (cmd)
420 {
421 default:
422 ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
423 break;
424 }
425 return(ret);
426 }
427
412/* 428/*
413void BIO_set_cipher_ctx(b,c) 429void BIO_set_cipher_ctx(b,c)
414BIO *b; 430BIO *b;
diff --git a/src/lib/libcrypto/pkcs7/dec.c b/src/lib/libcrypto/pkcs7/dec.c
index b3661f28d3..6752ec568a 100644
--- a/src/lib/libcrypto/pkcs7/dec.c
+++ b/src/lib/libcrypto/pkcs7/dec.c
@@ -57,6 +57,7 @@
57 */ 57 */
58#include <stdio.h> 58#include <stdio.h>
59#include <stdlib.h> 59#include <stdlib.h>
60#include <string.h>
60#include <openssl/bio.h> 61#include <openssl/bio.h>
61#include <openssl/x509.h> 62#include <openssl/x509.h>
62#include <openssl/pem.h> 63#include <openssl/pem.h>
@@ -85,7 +86,7 @@ char *argv[];
85 int i,printit=0; 86 int i,printit=0;
86 STACK_OF(PKCS7_SIGNER_INFO) *sk; 87 STACK_OF(PKCS7_SIGNER_INFO) *sk;
87 88
88 SSLeay_add_all_algorithms(); 89 OpenSSL_add_all_algorithms();
89 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 90 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
90 91
91 data=BIO_new(BIO_s_file()); 92 data=BIO_new(BIO_s_file());
@@ -121,9 +122,10 @@ char *argv[];
121 } 122 }
122 123
123 if ((in=BIO_new_file(keyfile,"r")) == NULL) goto err; 124 if ((in=BIO_new_file(keyfile,"r")) == NULL) goto err;
124 if ((x509=PEM_read_bio_X509(in,NULL,NULL)) == NULL) goto err; 125 if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
125 BIO_reset(in); 126 BIO_reset(in);
126 if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err; 127 if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL)
128 goto err;
127 BIO_free(in); 129 BIO_free(in);
128 130
129 if (pp == NULL) 131 if (pp == NULL)
@@ -131,7 +133,7 @@ char *argv[];
131 133
132 134
133 /* Load the PKCS7 object from a file */ 135 /* Load the PKCS7 object from a file */
134 if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL)) == NULL) goto err; 136 if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
135 137
136 138
137 139
@@ -148,7 +150,7 @@ char *argv[];
148 /* We need to process the data */ 150 /* We need to process the data */
149 /* We cannot support detached encryption */ 151 /* We cannot support detached encryption */
150 p7bio=PKCS7_dataDecode(p7,pkey,detached,x509); 152 p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
151 153
152 if (p7bio == NULL) 154 if (p7bio == NULL)
153 { 155 {
154 printf("problems decoding\n"); 156 printf("problems decoding\n");
diff --git a/src/lib/libcrypto/pkcs7/enc.c b/src/lib/libcrypto/pkcs7/enc.c
index 43bfd10a23..2b56c2eff3 100644
--- a/src/lib/libcrypto/pkcs7/enc.c
+++ b/src/lib/libcrypto/pkcs7/enc.c
@@ -56,6 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58#include <stdio.h> 58#include <stdio.h>
59#include <string.h>
59#include <openssl/bio.h> 60#include <openssl/bio.h>
60#include <openssl/x509.h> 61#include <openssl/x509.h>
61#include <openssl/pem.h> 62#include <openssl/pem.h>
@@ -76,7 +77,7 @@ char *argv[];
76 const EVP_CIPHER *cipher=NULL; 77 const EVP_CIPHER *cipher=NULL;
77 STACK_OF(X509) *recips=NULL; 78 STACK_OF(X509) *recips=NULL;
78 79
79 SSLeay_add_all_algorithms(); 80 OpenSSL_add_all_algorithms();
80 81
81 data=BIO_new(BIO_s_file()); 82 data=BIO_new(BIO_s_file());
82 while(argc > 1) 83 while(argc > 1)
@@ -98,7 +99,8 @@ char *argv[];
98 argc-=2; 99 argc-=2;
99 argv+=2; 100 argv+=2;
100 if (!(in=BIO_new_file(keyfile,"r"))) goto err; 101 if (!(in=BIO_new_file(keyfile,"r"))) goto err;
101 if (!(x509=PEM_read_bio_X509(in,NULL,NULL))) goto err; 102 if (!(x509=PEM_read_bio_X509(in,NULL,NULL,NULL)))
103 goto err;
102 if(!recips) recips = sk_X509_new_null(); 104 if(!recips) recips = sk_X509_new_null();
103 sk_X509_push(recips, x509); 105 sk_X509_push(recips, x509);
104 BIO_free(in); 106 BIO_free(in);
@@ -125,7 +127,14 @@ char *argv[];
125#else 127#else
126 PKCS7_set_type(p7,NID_pkcs7_enveloped); 128 PKCS7_set_type(p7,NID_pkcs7_enveloped);
127#endif 129#endif
128 if(!cipher) cipher = EVP_des_ede3_cbc(); 130 if(!cipher) {
131#ifndef NO_DES
132 cipher = EVP_des_ede3_cbc();
133#else
134 fprintf(stderr, "No cipher selected\n");
135 goto err;
136#endif
137 }
129 138
130 if (!PKCS7_set_cipher(p7,cipher)) goto err; 139 if (!PKCS7_set_cipher(p7,cipher)) goto err;
131 for(i = 0; i < sk_X509_num(recips); i++) { 140 for(i = 0; i < sk_X509_num(recips); i++) {
diff --git a/src/lib/libcrypto/pkcs7/example.c b/src/lib/libcrypto/pkcs7/example.c
index 7354890084..f6656be28e 100644
--- a/src/lib/libcrypto/pkcs7/example.c
+++ b/src/lib/libcrypto/pkcs7/example.c
@@ -1,5 +1,6 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stdlib.h> 2#include <stdlib.h>
3#include <string.h>
3#include <openssl/pkcs7.h> 4#include <openssl/pkcs7.h>
4#include <openssl/asn1_mac.h> 5#include <openssl/asn1_mac.h>
5 6
@@ -36,7 +37,7 @@ void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
36 signed_string_nid= 37 signed_string_nid=
37 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); 38 OBJ_create("1.2.3.4.5","OID_example","Our example OID");
38 os=ASN1_OCTET_STRING_new(); 39 os=ASN1_OCTET_STRING_new();
39 ASN1_OCTET_STRING_set(os,str,strlen(str)); 40 ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
40 /* When we add, we do not free */ 41 /* When we add, we do not free */
41 PKCS7_add_signed_attribute(si,signed_string_nid, 42 PKCS7_add_signed_attribute(si,signed_string_nid,
42 V_ASN1_OCTET_STRING,(char *)os); 43 V_ASN1_OCTET_STRING,(char *)os);
@@ -68,7 +69,7 @@ int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
68 return(0); 69 return(0);
69 } 70 }
70 71
71static signed_seq2string_nid= -1; 72static int signed_seq2string_nid= -1;
72/* ########################################### */ 73/* ########################################### */
73int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2) 74int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
74 { 75 {
@@ -86,8 +87,8 @@ int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
86 87
87 os1=ASN1_OCTET_STRING_new(); 88 os1=ASN1_OCTET_STRING_new();
88 os2=ASN1_OCTET_STRING_new(); 89 os2=ASN1_OCTET_STRING_new();
89 ASN1_OCTET_STRING_set(os1,str1,strlen(str1)); 90 ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
90 ASN1_OCTET_STRING_set(os2,str1,strlen(str1)); 91 ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
91 i =i2d_ASN1_OCTET_STRING(os1,NULL); 92 i =i2d_ASN1_OCTET_STRING(os1,NULL);
92 i+=i2d_ASN1_OCTET_STRING(os2,NULL); 93 i+=i2d_ASN1_OCTET_STRING(os2,NULL);
93 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE); 94 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
@@ -197,7 +198,7 @@ X509_ATTRIBUTE *create_string(char *str)
197 signed_string_nid= 198 signed_string_nid=
198 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); 199 OBJ_create("1.2.3.4.5","OID_example","Our example OID");
199 os=ASN1_OCTET_STRING_new(); 200 os=ASN1_OCTET_STRING_new();
200 ASN1_OCTET_STRING_set(os,str,strlen(str)); 201 ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
201 /* When we add, we do not free */ 202 /* When we add, we do not free */
202 ret=X509_ATTRIBUTE_create(signed_string_nid, 203 ret=X509_ATTRIBUTE_create(signed_string_nid,
203 V_ASN1_OCTET_STRING,(char *)os); 204 V_ASN1_OCTET_STRING,(char *)os);
@@ -250,8 +251,8 @@ X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
250 251
251 os1=ASN1_OCTET_STRING_new(); 252 os1=ASN1_OCTET_STRING_new();
252 os2=ASN1_OCTET_STRING_new(); 253 os2=ASN1_OCTET_STRING_new();
253 ASN1_OCTET_STRING_set(os1,str1,strlen(str1)); 254 ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
254 ASN1_OCTET_STRING_set(os2,str1,strlen(str1)); 255 ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
255 i =i2d_ASN1_OCTET_STRING(os1,NULL); 256 i =i2d_ASN1_OCTET_STRING(os1,NULL);
256 i+=i2d_ASN1_OCTET_STRING(os2,NULL); 257 i+=i2d_ASN1_OCTET_STRING(os2,NULL);
257 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE); 258 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c
new file mode 100644
index 0000000000..3b9c0fe3f2
--- /dev/null
+++ b/src/lib/libcrypto/pkcs7/pk7_attr.c
@@ -0,0 +1,85 @@
1/* pk7_attr.c */
2/* S/MIME code.
3 * Copyright (C) 1997-8 Dr S N Henson (shenson@bigfoot.com)
4 * All Rights Reserved.
5 * Redistribution of this code without the authors permission is expressly
6 * prohibited.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <openssl/bio.h>
12#include <openssl/asn1.h>
13#include <openssl/pem.h>
14#include <openssl/pkcs7.h>
15#include <openssl/err.h>
16
17int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap)
18{
19 ASN1_STRING *seq;
20 unsigned char *p, *pp;
21 int len;
22 len=i2d_ASN1_SET(cap,NULL,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
23 V_ASN1_UNIVERSAL, IS_SEQUENCE);
24 if(!(pp=(unsigned char *)Malloc(len))) {
25 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
26 return 0;
27 }
28 p=pp;
29 i2d_ASN1_SET(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
30 V_ASN1_UNIVERSAL, IS_SEQUENCE);
31 if(!(seq = ASN1_STRING_new())) {
32 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
33 return 0;
34 }
35 if(!ASN1_STRING_set (seq, pp, len)) {
36 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
37 return 0;
38 }
39 Free (pp);
40 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
41 V_ASN1_SEQUENCE, seq);
42}
43
44STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
45{
46 ASN1_TYPE *cap;
47 unsigned char *p;
48 cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
49 if (!cap) return NULL;
50 p = cap->value.sequence->data;
51 return d2i_ASN1_SET (NULL, &p, cap->value.sequence->length,
52 (char *(*)())d2i_X509_ALGOR, X509_ALGOR_free, V_ASN1_SEQUENCE,
53 V_ASN1_UNIVERSAL);
54}
55
56/* Basic smime-capabilities OID and optional integer arg */
57int PKCS7_simple_smimecap(STACK *sk, int nid, int arg)
58{
59 X509_ALGOR *alg;
60 if(!(alg = X509_ALGOR_new())) {
61 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
62 return 0;
63 }
64 ASN1_OBJECT_free(alg->algorithm);
65 alg->algorithm = OBJ_nid2obj (nid);
66 if (arg > 0) {
67 ASN1_INTEGER *nbit;
68 if(!(alg->parameter = ASN1_TYPE_new())) {
69 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
70 return 0;
71 }
72 if(!(nbit = ASN1_INTEGER_new())) {
73 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
74 return 0;
75 }
76 if(!ASN1_INTEGER_set (nbit, arg)) {
77 PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);
78 return 0;
79 }
80 alg->parameter->value.integer = nbit;
81 alg->parameter->type = V_ASN1_INTEGER;
82 }
83 sk_push (sk, (char *)alg);
84 return 1;
85}
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
index dee81b547a..80ac5e34b4 100644
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/src/lib/libcrypto/pkcs7/pk7_doit.c
@@ -61,6 +61,7 @@
61#include <openssl/rand.h> 61#include <openssl/rand.h>
62#include <openssl/objects.h> 62#include <openssl/objects.h>
63#include <openssl/x509.h> 63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
64 65
65static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, 66static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
66 void *value); 67 void *value);
@@ -160,9 +161,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
160 BIO_get_cipher_ctx(btmp, &ctx); 161 BIO_get_cipher_ctx(btmp, &ctx);
161 keylen=EVP_CIPHER_key_length(evp_cipher); 162 keylen=EVP_CIPHER_key_length(evp_cipher);
162 ivlen=EVP_CIPHER_iv_length(evp_cipher); 163 ivlen=EVP_CIPHER_iv_length(evp_cipher);
163 RAND_bytes(key,keylen); 164 if (RAND_bytes(key,keylen) <= 0)
165 goto err;
164 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); 166 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
165 if (ivlen > 0) RAND_bytes(iv,ivlen); 167 if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
166 EVP_CipherInit(ctx, evp_cipher, key, iv, 1); 168 EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
167 169
168 if (ivlen > 0) { 170 if (ivlen > 0) {
@@ -204,7 +206,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
204 Free(tmp); 206 Free(tmp);
205 goto err; 207 goto err;
206 } 208 }
207 ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); 209 M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
208 } 210 }
209 Free(tmp); 211 Free(tmp);
210 memset(key, 0, keylen); 212 memset(key, 0, keylen);
@@ -216,30 +218,23 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
216 btmp=NULL; 218 btmp=NULL;
217 } 219 }
218 220
219 if (bio == NULL) /* ??????????? */ 221 if (bio == NULL) {
220 {
221 if (p7->detached) 222 if (p7->detached)
222 bio=BIO_new(BIO_s_null()); 223 bio=BIO_new(BIO_s_null());
223 else 224 else {
224 {
225 bio=BIO_new(BIO_s_mem());
226 /* We need to set this so that when we have read all
227 * the data, the encrypt BIO, if present, will read
228 * EOF and encode the last few bytes */
229 BIO_set_mem_eof_return(bio,0);
230
231 if (PKCS7_type_is_signed(p7) && 225 if (PKCS7_type_is_signed(p7) &&
232 PKCS7_type_is_data(p7->d.sign->contents)) 226 PKCS7_type_is_data(p7->d.sign->contents)) {
233 {
234 ASN1_OCTET_STRING *os; 227 ASN1_OCTET_STRING *os;
235
236 os=p7->d.sign->contents->d.data; 228 os=p7->d.sign->contents->d.data;
237 if (os->length > 0) 229 if (os->length > 0) bio =
238 BIO_write(bio,(char *)os->data, 230 BIO_new_mem_buf(os->data, os->length);
239 os->length); 231 }
240 } 232 if(bio == NULL) {
233 bio=BIO_new(BIO_s_mem());
234 BIO_set_mem_eof_return(bio,0);
241 } 235 }
242 } 236 }
237 }
243 BIO_push(out,bio); 238 BIO_push(out,bio);
244 bio=NULL; 239 bio=NULL;
245 if (0) 240 if (0)
@@ -259,7 +254,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
259 { 254 {
260 int i,j; 255 int i,j;
261 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 256 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
262 char *tmp=NULL; 257 unsigned char *tmp=NULL;
263 X509_ALGOR *xa; 258 X509_ALGOR *xa;
264 ASN1_OCTET_STRING *data_body=NULL; 259 ASN1_OCTET_STRING *data_body=NULL;
265 const EVP_MD *evp_md; 260 const EVP_MD *evp_md;
@@ -270,6 +265,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
270 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 265 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
271 X509_ALGOR *xalg=NULL; 266 X509_ALGOR *xalg=NULL;
272 PKCS7_RECIP_INFO *ri=NULL; 267 PKCS7_RECIP_INFO *ri=NULL;
268#ifndef NO_RC2
269 char is_rc2 = 0;
270#endif
273/* EVP_PKEY *pkey; */ 271/* EVP_PKEY *pkey; */
274#if 0 272#if 0
275 X509_STORE_CTX s_ctx; 273 X509_STORE_CTX s_ctx;
@@ -314,6 +312,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
314 goto err; 312 goto err;
315 } 313 }
316 314
315 if(EVP_CIPHER_nid(evp_cipher) == NID_rc2_cbc)
316 {
317#ifndef NO_RC2
318 is_rc2 = 1;
319#else
320 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
321 goto err;
322#endif
323 }
324
317 /* We will be checking the signature */ 325 /* We will be checking the signature */
318 if (md_sk != NULL) 326 if (md_sk != NULL)
319 { 327 {
@@ -372,7 +380,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
372 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 380 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
373 if(!X509_NAME_cmp(ri->issuer_and_serial->issuer, 381 if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
374 pcert->cert_info->issuer) && 382 pcert->cert_info->issuer) &&
375 !ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, 383 !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
376 ri->issuer_and_serial->serial)) break; 384 ri->issuer_and_serial->serial)) break;
377 ri=NULL; 385 ri=NULL;
378 } 386 }
@@ -383,17 +391,15 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
383 } 391 }
384 392
385 jj=EVP_PKEY_size(pkey); 393 jj=EVP_PKEY_size(pkey);
386 tmp=Malloc(jj+10); 394 tmp=(unsigned char *)Malloc(jj+10);
387 if (tmp == NULL) 395 if (tmp == NULL)
388 { 396 {
389 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); 397 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
390 goto err; 398 goto err;
391 } 399 }
392 400
393 jj=EVP_PKEY_decrypt((unsigned char *)tmp, 401 jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
394 ASN1_STRING_data(ri->enc_key), 402 M_ASN1_STRING_length(ri->enc_key), pkey);
395 ASN1_STRING_length(ri->enc_key),
396 pkey);
397 if (jj <= 0) 403 if (jj <= 0)
398 { 404 {
399 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); 405 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
@@ -406,13 +412,25 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
406 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 412 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
407 return(NULL); 413 return(NULL);
408 414
409 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) 415 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
410 { 416 /* HACK: some S/MIME clients don't use the same key
411 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 417 * and effective key length. The key length is
418 * determined by the size of the decrypted RSA key.
419 * So we hack things to manually set the RC2 key
420 * because we currently can't do this with the EVP
421 * interface.
422 */
423#ifndef NO_RC2
424 if(is_rc2) RC2_set_key(&(evp_ctx->c.rc2_ks),jj, tmp,
425 EVP_CIPHER_CTX_key_length(evp_ctx)*8);
426 else
427#endif
428 {
429 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
412 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); 430 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
413 goto err; 431 goto err;
414 } 432 }
415 EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0); 433 } else EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
416 434
417 memset(tmp,0,jj); 435 memset(tmp,0,jj);
418 436
@@ -430,6 +448,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
430 } 448 }
431 else 449 else
432 { 450 {
451#if 0
433 bio=BIO_new(BIO_s_mem()); 452 bio=BIO_new(BIO_s_mem());
434 /* We need to set this so that when we have read all 453 /* We need to set this so that when we have read all
435 * the data, the encrypt BIO, if present, will read 454 * the data, the encrypt BIO, if present, will read
@@ -438,6 +457,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
438 457
439 if (data_body->length > 0) 458 if (data_body->length > 0)
440 BIO_write(bio,(char *)data_body->data,data_body->length); 459 BIO_write(bio,(char *)data_body->data,data_body->length);
460#else
461 if (data_body->length > 0)
462 bio = BIO_new_mem_buf(data_body->data,data_body->length);
463 else {
464 bio=BIO_new(BIO_s_mem());
465 BIO_set_mem_eof_return(bio,0);
466 }
467#endif
441 } 468 }
442 BIO_push(out,bio); 469 BIO_push(out,bio);
443 bio=NULL; 470 bio=NULL;
@@ -479,12 +506,12 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
479 case NID_pkcs7_signedAndEnveloped: 506 case NID_pkcs7_signedAndEnveloped:
480 /* XXXXXXXXXXXXXXXX */ 507 /* XXXXXXXXXXXXXXXX */
481 si_sk=p7->d.signed_and_enveloped->signer_info; 508 si_sk=p7->d.signed_and_enveloped->signer_info;
482 os=ASN1_OCTET_STRING_new(); 509 os=M_ASN1_OCTET_STRING_new();
483 p7->d.signed_and_enveloped->enc_data->enc_data=os; 510 p7->d.signed_and_enveloped->enc_data->enc_data=os;
484 break; 511 break;
485 case NID_pkcs7_enveloped: 512 case NID_pkcs7_enveloped:
486 /* XXXXXXXXXXXXXXXX */ 513 /* XXXXXXXXXXXXXXXX */
487 os=ASN1_OCTET_STRING_new(); 514 os=M_ASN1_OCTET_STRING_new();
488 p7->d.enveloped->enc_data->enc_data=os; 515 p7->d.enveloped->enc_data->enc_data=os;
489 break; 516 break;
490 case NID_pkcs7_signed: 517 case NID_pkcs7_signed:
@@ -492,7 +519,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
492 os=p7->d.sign->contents->d.data; 519 os=p7->d.sign->contents->d.data;
493 /* If detached data then the content is excluded */ 520 /* If detached data then the content is excluded */
494 if(p7->detached) { 521 if(p7->detached) {
495 ASN1_OCTET_STRING_free(os); 522 M_ASN1_OCTET_STRING_free(os);
496 p7->d.sign->contents->d.data = NULL; 523 p7->d.sign->contents->d.data = NULL;
497 } 524 }
498 break; 525 break;
@@ -527,7 +554,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
527 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR); 554 PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
528 goto err; 555 goto err;
529 } 556 }
530 if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == j) 557 if (EVP_MD_CTX_type(mdc) == j)
531 break; 558 break;
532 else 559 else
533 btmp=btmp->next_bio; 560 btmp=btmp->next_bio;
@@ -561,10 +588,10 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
561 V_ASN1_UTCTIME,sign_time); 588 V_ASN1_UTCTIME,sign_time);
562 589
563 /* Add digest */ 590 /* Add digest */
564 md_tmp=EVP_MD_CTX_type(&ctx_tmp); 591 md_tmp=EVP_MD_CTX_md(&ctx_tmp);
565 EVP_DigestFinal(&ctx_tmp,md_data,&md_len); 592 EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
566 digest=ASN1_OCTET_STRING_new(); 593 digest=M_ASN1_OCTET_STRING_new();
567 ASN1_OCTET_STRING_set(digest,md_data,md_len); 594 M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
568 PKCS7_add_signed_attribute(si, 595 PKCS7_add_signed_attribute(si,
569 NID_pkcs9_messageDigest, 596 NID_pkcs9_messageDigest,
570 V_ASN1_OCTET_STRING,digest); 597 V_ASN1_OCTET_STRING,digest);
@@ -611,8 +638,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
611 goto err; 638 goto err;
612 } 639 }
613 BIO_get_mem_ptr(btmp,&buf_mem); 640 BIO_get_mem_ptr(btmp,&buf_mem);
614 ASN1_OCTET_STRING_set(os, 641 /* Mark the BIO read only then we can use its copy of the data
642 * instead of making an extra copy.
643 */
644 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
645 BIO_set_mem_eof_return(btmp, 0);
646 os->data = (unsigned char *)buf_mem->data;
647 os->length = buf_mem->length;
648#if 0
649 M_ASN1_OCTET_STRING_set(os,
615 (unsigned char *)buf_mem->data,buf_mem->length); 650 (unsigned char *)buf_mem->data,buf_mem->length);
651#endif
616 } 652 }
617 if (pp != NULL) Free(pp); 653 if (pp != NULL) Free(pp);
618 pp=NULL; 654 pp=NULL;
@@ -658,6 +694,7 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
658 694
659 /* Lets verify */ 695 /* Lets verify */
660 X509_STORE_CTX_init(ctx,cert_store,x509,cert); 696 X509_STORE_CTX_init(ctx,cert_store,x509,cert);
697 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
661 i=X509_verify_cert(ctx); 698 i=X509_verify_cert(ctx);
662 if (i <= 0) 699 if (i <= 0)
663 { 700 {
@@ -709,7 +746,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
709 PKCS7_R_INTERNAL_ERROR); 746 PKCS7_R_INTERNAL_ERROR);
710 goto err; 747 goto err;
711 } 748 }
712 if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type) 749 if (EVP_MD_CTX_type(mdc) == md_type)
713 break; 750 break;
714 btmp=btmp->next_bio; 751 btmp=btmp->next_bio;
715 } 752 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
index 8b863d0558..45973fe850 100644
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/src/lib/libcrypto/pkcs7/pk7_lib.c
@@ -123,7 +123,7 @@ int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
123 { 123 {
124 case NID_pkcs7_signed: 124 case NID_pkcs7_signed:
125 if (p7->d.sign->contents != NULL) 125 if (p7->d.sign->contents != NULL)
126 PKCS7_content_free(p7->d.sign->contents); 126 PKCS7_free(p7->d.sign->contents);
127 p7->d.sign->contents=p7_data; 127 p7->d.sign->contents=p7_data;
128 break; 128 break;
129 case NID_pkcs7_digest: 129 case NID_pkcs7_digest:
@@ -157,7 +157,7 @@ int PKCS7_set_type(PKCS7 *p7, int type)
157 break; 157 break;
158 case NID_pkcs7_data: 158 case NID_pkcs7_data:
159 p7->type=obj; 159 p7->type=obj;
160 if ((p7->d.data=ASN1_OCTET_STRING_new()) == NULL) 160 if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
161 goto err; 161 goto err;
162 break; 162 break;
163 case NID_pkcs7_signedAndEnveloped: 163 case NID_pkcs7_signedAndEnveloped:
@@ -165,9 +165,6 @@ int PKCS7_set_type(PKCS7 *p7, int type)
165 if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new()) 165 if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
166 == NULL) goto err; 166 == NULL) goto err;
167 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1); 167 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
168/* p7->d.signed_and_enveloped->enc_data->content_type=
169 OBJ_nid2obj(NID_pkcs7_encrypted);*/
170
171 break; 168 break;
172 case NID_pkcs7_enveloped: 169 case NID_pkcs7_enveloped:
173 p7->type=obj; 170 p7->type=obj;
@@ -175,8 +172,14 @@ int PKCS7_set_type(PKCS7 *p7, int type)
175 == NULL) goto err; 172 == NULL) goto err;
176 ASN1_INTEGER_set(p7->d.enveloped->version,0); 173 ASN1_INTEGER_set(p7->d.enveloped->version,0);
177 break; 174 break;
178 case NID_pkcs7_digest:
179 case NID_pkcs7_encrypted: 175 case NID_pkcs7_encrypted:
176 p7->type=obj;
177 if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
178 == NULL) goto err;
179 ASN1_INTEGER_set(p7->d.encrypted->version,0);
180 break;
181
182 case NID_pkcs7_digest:
180 default: 183 default:
181 PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 184 PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
182 goto err; 185 goto err;
@@ -224,8 +227,13 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
224 } 227 }
225 if (!j) /* we need to add another algorithm */ 228 if (!j) /* we need to add another algorithm */
226 { 229 {
227 alg=X509_ALGOR_new(); 230 if(!(alg=X509_ALGOR_new())
231 || !(alg->parameter = ASN1_TYPE_new())) {
232 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE);
233 return(0);
234 }
228 alg->algorithm=OBJ_nid2obj(nid); 235 alg->algorithm=OBJ_nid2obj(nid);
236 alg->parameter->type = V_ASN1_NULL;
229 sk_X509_ALGOR_push(md_sk,alg); 237 sk_X509_ALGOR_push(md_sk,alg);
230 } 238 }
231 239
@@ -289,6 +297,9 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
289int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 297int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
290 EVP_MD *dgst) 298 EVP_MD *dgst)
291 { 299 {
300 char is_dsa;
301 if (pkey->type == EVP_PKEY_DSA) is_dsa = 1;
302 else is_dsa = 0;
292 /* We now need to add another PKCS7_SIGNER_INFO entry */ 303 /* We now need to add another PKCS7_SIGNER_INFO entry */
293 ASN1_INTEGER_set(p7i->version,1); 304 ASN1_INTEGER_set(p7i->version,1);
294 X509_NAME_set(&p7i->issuer_and_serial->issuer, 305 X509_NAME_set(&p7i->issuer_and_serial->issuer,
@@ -296,17 +307,16 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
296 307
297 /* because ASN1_INTEGER_set is used to set a 'long' we will do 308 /* because ASN1_INTEGER_set is used to set a 'long' we will do
298 * things the ugly way. */ 309 * things the ugly way. */
299 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 310 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
300 p7i->issuer_and_serial->serial= 311 p7i->issuer_and_serial->serial=
301 ASN1_INTEGER_dup(X509_get_serialNumber(x509)); 312 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));
302 313
303 /* lets keep the pkey around for a while */ 314 /* lets keep the pkey around for a while */
304 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); 315 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
305 p7i->pkey=pkey; 316 p7i->pkey=pkey;
306 317
307 /* Set the algorithms */ 318 /* Set the algorithms */
308 if (pkey->type == EVP_PKEY_DSA) 319 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
309 p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
310 else 320 else
311 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); 321 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
312 322
@@ -320,9 +330,12 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
320 330
321 if (p7i->digest_enc_alg->parameter != NULL) 331 if (p7i->digest_enc_alg->parameter != NULL)
322 ASN1_TYPE_free(p7i->digest_enc_alg->parameter); 332 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
323 if ((p7i->digest_enc_alg->parameter=ASN1_TYPE_new()) == NULL) 333 if(is_dsa) p7i->digest_enc_alg->parameter = NULL;
324 goto err; 334 else {
325 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; 335 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
336 goto err;
337 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
338 }
326 339
327 return(1); 340 return(1);
328err: 341err:
@@ -397,9 +410,9 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
397 X509_NAME_set(&p7i->issuer_and_serial->issuer, 410 X509_NAME_set(&p7i->issuer_and_serial->issuer,
398 X509_get_issuer_name(x509)); 411 X509_get_issuer_name(x509));
399 412
400 ASN1_INTEGER_free(p7i->issuer_and_serial->serial); 413 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
401 p7i->issuer_and_serial->serial= 414 p7i->issuer_and_serial->serial=
402 ASN1_INTEGER_dup(X509_get_serialNumber(x509)); 415 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));
403 416
404 X509_ALGOR_free(p7i->key_enc_algor); 417 X509_ALGOR_free(p7i->key_enc_algor);
405 p7i->key_enc_algor=(X509_ALGOR *)ASN1_dup(i2d_X509_ALGOR, 418 p7i->key_enc_algor=(X509_ALGOR *)ASN1_dup(i2d_X509_ALGOR,
@@ -425,6 +438,7 @@ X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
425int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) 438int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
426 { 439 {
427 int i; 440 int i;
441 ASN1_OBJECT *objtmp;
428 PKCS7_ENC_CONTENT *ec; 442 PKCS7_ENC_CONTENT *ec;
429 443
430 i=OBJ_obj2nid(p7->type); 444 i=OBJ_obj2nid(p7->type);
@@ -441,7 +455,13 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
441 return(0); 455 return(0);
442 } 456 }
443 457
444 /* Setup cipher OID */ 458 /* Check cipher OID exists and has data in it*/
459 i = EVP_CIPHER_type(cipher);
460 if(i == NID_undef) {
461 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
462 return(0);
463 }
464 objtmp = OBJ_nid2obj(i);
445 465
446 ec->cipher = cipher; 466 ec->cipher = cipher;
447 return 1; 467 return 1;
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
new file mode 100644
index 0000000000..734643be28
--- /dev/null
+++ b/src/lib/libcrypto/pkcs7/pk7_mime.c
@@ -0,0 +1,673 @@
1/* pk7_mime.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <ctype.h>
61#include "cryptlib.h"
62#include <openssl/rand.h>
63#include <openssl/x509.h>
64
65/* MIME and related routines */
66
67/* MIME format structures
68 * Note that all are translated to lower case apart from
69 * parameter values. Quotes are stripped off
70 */
71
72typedef struct {
73char *name; /* Name of line e.g. "content-type" */
74char *value; /* Value of line e.g. "text/plain" */
75STACK /* MIME_PARAM */ *params; /* Zero or more parameters */
76} MIME_HEADER;
77
78typedef struct {
79char *param_name; /* Param name e.g. "micalg" */
80char *param_value; /* Param value e.g. "sha1" */
81} MIME_PARAM;
82
83
84static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
85static PKCS7 *B64_read_PKCS7(BIO *bio);
86static char * strip_ends(char *name);
87static char * strip_start(char *name);
88static char * strip_end(char *name);
89static MIME_HEADER *mime_hdr_new(char *name, char *value);
90static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
91static STACK *mime_parse_hdr(BIO *bio);
92static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b);
93static int mime_param_cmp(MIME_PARAM **a, MIME_PARAM **b);
94static void mime_param_free(MIME_PARAM *param);
95static int mime_bound_check(char *line, int linelen, char *bound, int blen);
96static int multi_split(BIO *bio, char *bound, STACK **ret);
97static int iscrlf(char c);
98static MIME_HEADER *mime_hdr_find(STACK *hdrs, char *name);
99static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
100static void mime_hdr_free(MIME_HEADER *hdr);
101
102#define MAX_SMLEN 1024
103#define mime_debug(x) /* x */
104
105
106typedef void (*stkfree)();
107
108/* Base 64 read and write of PKCS#7 structure */
109
110static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
111{
112 BIO *b64;
113 if(!(b64 = BIO_new(BIO_f_base64()))) {
114 PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE);
115 return 0;
116 }
117 bio = BIO_push(b64, bio);
118 i2d_PKCS7_bio(bio, p7);
119 BIO_flush(bio);
120 bio = BIO_pop(bio);
121 BIO_free(b64);
122 return 1;
123}
124
125static PKCS7 *B64_read_PKCS7(BIO *bio)
126{
127 BIO *b64;
128 PKCS7 *p7;
129 if(!(b64 = BIO_new(BIO_f_base64()))) {
130 PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE);
131 return 0;
132 }
133 bio = BIO_push(b64, bio);
134 if(!(p7 = d2i_PKCS7_bio(bio, NULL)))
135 PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
136 BIO_flush(bio);
137 bio = BIO_pop(bio);
138 BIO_free(b64);
139 return p7;
140}
141
142/* SMIME sender */
143
144int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
145{
146 char linebuf[MAX_SMLEN];
147 char bound[33], c;
148 int i;
149 if((flags & PKCS7_DETACHED) && data) {
150 /* We want multipart/signed */
151 /* Generate a random boundary */
152 RAND_pseudo_bytes((unsigned char *)bound, 32);
153 for(i = 0; i < 32; i++) {
154 c = bound[i] & 0xf;
155 if(c < 10) c += '0';
156 else c += 'A' - 10;
157 bound[i] = c;
158 }
159 bound[32] = 0;
160 BIO_printf(bio, "MIME-Version: 1.0\n");
161 BIO_printf(bio, "Content-Type: multipart/signed ; ");
162 BIO_printf(bio, "protocol=\"application/x-pkcs7-signature\" ; ");
163 BIO_printf(bio, "micalg=sha1 ; boundary=\"----%s\"\n\n", bound);
164 BIO_printf(bio, "This is an S/MIME signed message\n\n");
165 /* Now write out the first part */
166 BIO_printf(bio, "------%s\r\n", bound);
167 if(flags & PKCS7_TEXT) BIO_printf(bio, "Content-Type: text/plain\n\n");
168 while((i = BIO_read(data, linebuf, MAX_SMLEN)) > 0)
169 BIO_write(bio, linebuf, i);
170 BIO_printf(bio, "\n------%s\n", bound);
171
172 /* Headers for signature */
173
174 BIO_printf(bio, "Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\n");
175 BIO_printf(bio, "Content-Transfer-Encoding: base64\n");
176 BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7s\"\n\n");
177 B64_write_PKCS7(bio, p7);
178 BIO_printf(bio,"\n------%s--\n\n", bound);
179 return 1;
180 }
181 /* MIME headers */
182 BIO_printf(bio, "MIME-Version: 1.0\n");
183 BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7m\"\n");
184 BIO_printf(bio, "Content-Type: application/x-pkcs7-mime; name=\"smime.p7m\"\n");
185 BIO_printf(bio, "Content-Transfer-Encoding: base64\n\n");
186 B64_write_PKCS7(bio, p7);
187 BIO_printf(bio, "\n");
188 return 1;
189}
190
191/* SMIME reader: handle multipart/signed and opaque signing.
192 * in multipart case the content is placed in a memory BIO
193 * pointed to by "bcont". In opaque this is set to NULL
194 */
195
196PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
197{
198 BIO *p7in;
199 STACK *headers = NULL;
200 STACK *parts = NULL;
201 MIME_HEADER *hdr;
202 MIME_PARAM *prm;
203 PKCS7 *p7;
204 int ret;
205
206 if(bcont) *bcont = NULL;
207
208 if (!(headers = mime_parse_hdr(bio))) {
209 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
210 return NULL;
211 }
212
213 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
214 sk_pop_free(headers, mime_hdr_free);
215 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
216 return NULL;
217 }
218
219 /* Handle multipart/signed */
220
221 if(!strcmp(hdr->value, "multipart/signed")) {
222 /* Split into two parts */
223 prm = mime_param_find(hdr, "boundary");
224 if(!prm || !prm->param_value) {
225 sk_pop_free(headers, mime_hdr_free);
226 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
227 return NULL;
228 }
229 ret = multi_split(bio, prm->param_value, &parts);
230 sk_pop_free(headers, mime_hdr_free);
231 if(!ret || (sk_num(parts) != 2) ) {
232 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
233 sk_pop_free(parts, (stkfree)BIO_free);
234 return NULL;
235 }
236
237 /* Parse the signature piece */
238 p7in = (BIO *)sk_value(parts, 1);
239
240 if (!(headers = mime_parse_hdr(p7in))) {
241 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
242 sk_pop_free(parts, (stkfree)BIO_free);
243 return NULL;
244 }
245
246 /* Get content type */
247
248 if(!(hdr = mime_hdr_find(headers, "content-type")) ||
249 !hdr->value) {
250 sk_pop_free(headers, mime_hdr_free);
251 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
252 return NULL;
253 }
254
255 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
256 strcmp(hdr->value, "application/pkcs7-signature")) {
257 sk_pop_free(headers, mime_hdr_free);
258 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
259 ERR_add_error_data(2, "type: ", hdr->value);
260 sk_pop_free(parts, (stkfree)BIO_free);
261 return NULL;
262 }
263 sk_pop_free(headers, mime_hdr_free);
264 /* Read in PKCS#7 */
265 if(!(p7 = B64_read_PKCS7(p7in))) {
266 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
267 sk_pop_free(parts, (stkfree)BIO_free);
268 return NULL;
269 }
270
271 if(bcont) {
272 *bcont = (BIO *)sk_value(parts, 0);
273 BIO_free(p7in);
274 sk_free(parts);
275 } else sk_pop_free(parts, (stkfree)BIO_free);
276 return p7;
277 }
278
279 /* OK, if not multipart/signed try opaque signature */
280
281 if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
282 strcmp (hdr->value, "application/pkcs7-mime")) {
283 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
284 ERR_add_error_data(2, "type: ", hdr->value);
285 sk_pop_free(headers, mime_hdr_free);
286 return NULL;
287 }
288
289 sk_pop_free(headers, mime_hdr_free);
290
291 if(!(p7 = B64_read_PKCS7(bio))) {
292 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
293 return NULL;
294 }
295 return p7;
296
297}
298
299/* Copy text from one BIO to another making the output CRLF at EOL */
300int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
301{
302 char eol;
303 int len;
304 char linebuf[MAX_SMLEN];
305 if(flags & PKCS7_BINARY) {
306 while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
307 BIO_write(out, linebuf, len);
308 return 1;
309 }
310 if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
311 while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
312 eol = 0;
313 while(iscrlf(linebuf[len - 1])) {
314 len--;
315 eol = 1;
316 }
317 BIO_write(out, linebuf, len);
318 if(eol) BIO_write(out, "\r\n", 2);
319 }
320 return 1;
321}
322
323/* Strip off headers if they are text/plain */
324int SMIME_text(BIO *in, BIO *out)
325{
326 char iobuf[4096];
327 int len;
328 STACK *headers;
329 MIME_HEADER *hdr;
330 if (!(headers = mime_parse_hdr(in))) {
331 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR);
332 return 0;
333 }
334 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
335 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE);
336 sk_pop_free(headers, mime_hdr_free);
337 return 0;
338 }
339 if (strcmp (hdr->value, "text/plain")) {
340 PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE);
341 ERR_add_error_data(2, "type: ", hdr->value);
342 sk_pop_free(headers, mime_hdr_free);
343 return 0;
344 }
345 sk_pop_free(headers, mime_hdr_free);
346 while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
347 BIO_write(out, iobuf, len);
348 return 1;
349}
350
351/* Split a multipart/XXX message body into component parts: result is
352 * canonical parts in a STACK of bios
353 */
354
355static int multi_split(BIO *bio, char *bound, STACK **ret)
356{
357 char linebuf[MAX_SMLEN];
358 int len, blen;
359 BIO *bpart = NULL;
360 STACK *parts;
361 char state, part, first;
362 blen = strlen(bound);
363 part = 0;
364 state = 0;
365 first = 1;
366 parts = sk_new(NULL);
367 *ret = parts;
368 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
369 state = mime_bound_check(linebuf, len, bound, blen);
370 if(state == 1) {
371 first = 1;
372 part++;
373 } else if(state == 2) {
374 sk_push(parts, (char *)bpart);
375 return 1;
376 } else if(part) {
377 if(first) {
378 first = 0;
379 if(bpart) sk_push(parts, (char *)bpart);
380 bpart = BIO_new(BIO_s_mem());
381
382 } else BIO_write(bpart, "\r\n", 2);
383 /* Strip CR+LF from linebuf */
384 while(iscrlf(linebuf[len - 1])) len--;
385 BIO_write(bpart, linebuf, len);
386 }
387 }
388 return 0;
389}
390
391static int iscrlf(char c)
392{
393 if(c == '\r' || c == '\n') return 1;
394 return 0;
395}
396
397/* This is the big one: parse MIME header lines up to message body */
398
399#define MIME_INVALID 0
400#define MIME_START 1
401#define MIME_TYPE 2
402#define MIME_NAME 3
403#define MIME_VALUE 4
404#define MIME_QUOTE 5
405#define MIME_COMMENT 6
406
407
408static STACK *mime_parse_hdr(BIO *bio)
409{
410 char *p, *q, c;
411 char *ntmp;
412 char linebuf[MAX_SMLEN];
413 MIME_HEADER *mhdr = NULL;
414 STACK *headers;
415 int len, state, save_state = 0;
416 headers = sk_new(mime_hdr_cmp);
417 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
418 /* If whitespace at line start then continuation line */
419 if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
420 else state = MIME_START;
421 ntmp = NULL;
422 /* Go through all characters */
423 for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
424
425 /* State machine to handle MIME headers
426 * if this looks horrible that's because it *is*
427 */
428
429 switch(state) {
430 case MIME_START:
431 if(c == ':') {
432 state = MIME_TYPE;
433 *p = 0;
434 ntmp = strip_ends(q);
435 q = p + 1;
436 }
437 break;
438
439 case MIME_TYPE:
440 if(c == ';') {
441 mime_debug("Found End Value\n");
442 *p = 0;
443 mhdr = mime_hdr_new(ntmp, strip_ends(q));
444 sk_push(headers, (char *)mhdr);
445 ntmp = NULL;
446 q = p + 1;
447 state = MIME_NAME;
448 } else if(c == '(') {
449 save_state = state;
450 state = MIME_COMMENT;
451 }
452 break;
453
454 case MIME_COMMENT:
455 if(c == ')') {
456 state = save_state;
457 }
458 break;
459
460 case MIME_NAME:
461 if(c == '=') {
462 state = MIME_VALUE;
463 *p = 0;
464 ntmp = strip_ends(q);
465 q = p + 1;
466 }
467 break ;
468
469 case MIME_VALUE:
470 if(c == ';') {
471 state = MIME_NAME;
472 *p = 0;
473 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
474 ntmp = NULL;
475 q = p + 1;
476 } else if (c == '"') {
477 mime_debug("Found Quote\n");
478 state = MIME_QUOTE;
479 } else if(c == '(') {
480 save_state = state;
481 state = MIME_COMMENT;
482 }
483 break;
484
485 case MIME_QUOTE:
486 if(c == '"') {
487 mime_debug("Found Match Quote\n");
488 state = MIME_VALUE;
489 }
490 break;
491 }
492 }
493
494 if(state == MIME_TYPE) {
495 mhdr = mime_hdr_new(ntmp, strip_ends(q));
496 sk_push(headers, (char *)mhdr);
497 } else if(state == MIME_VALUE)
498 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
499 if(p == linebuf) break; /* Blank line means end of headers */
500}
501
502return headers;
503
504}
505
506static char *strip_ends(char *name)
507{
508 return strip_end(strip_start(name));
509}
510
511/* Strip a parameter of whitespace from start of param */
512static char *strip_start(char *name)
513{
514 char *p, c;
515 /* Look for first non white space or quote */
516 for(p = name; (c = *p) ;p++) {
517 if(c == '"') {
518 /* Next char is start of string if non null */
519 if(p[1]) return p + 1;
520 /* Else null string */
521 return NULL;
522 }
523 if(!isspace((unsigned char)c)) return p;
524 }
525 return NULL;
526}
527
528/* As above but strip from end of string : maybe should handle brackets? */
529static char *strip_end(char *name)
530{
531 char *p, c;
532 if(!name) return NULL;
533 /* Look for first non white space or quote */
534 for(p = name + strlen(name) - 1; p >= name ;p--) {
535 c = *p;
536 if(c == '"') {
537 if(p - 1 == name) return NULL;
538 *p = 0;
539 return name;
540 }
541 if(isspace((unsigned char)c)) *p = 0;
542 else return name;
543 }
544 return NULL;
545}
546
547static MIME_HEADER *mime_hdr_new(char *name, char *value)
548{
549 MIME_HEADER *mhdr;
550 char *tmpname, *tmpval, *p;
551 int c;
552 if(name) {
553 if(!(tmpname = BUF_strdup(name))) return NULL;
554 for(p = tmpname ; *p; p++) {
555 c = *p;
556 if(isupper(c)) {
557 c = tolower(c);
558 *p = c;
559 }
560 }
561 } else tmpname = NULL;
562 if(value) {
563 if(!(tmpval = BUF_strdup(value))) return NULL;
564 for(p = tmpval ; *p; p++) {
565 c = *p;
566 if(isupper(c)) {
567 c = tolower(c);
568 *p = c;
569 }
570 }
571 } else tmpval = NULL;
572 mhdr = (MIME_HEADER *) Malloc(sizeof(MIME_HEADER));
573 if(!mhdr) return NULL;
574 mhdr->name = tmpname;
575 mhdr->value = tmpval;
576 if(!(mhdr->params = sk_new(mime_param_cmp))) return NULL;
577 return mhdr;
578}
579
580static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
581{
582 char *tmpname, *tmpval, *p;
583 int c;
584 MIME_PARAM *mparam;
585 if(name) {
586 tmpname = BUF_strdup(name);
587 if(!tmpname) return 0;
588 for(p = tmpname ; *p; p++) {
589 c = *p;
590 if(isupper(c)) {
591 c = tolower(c);
592 *p = c;
593 }
594 }
595 } else tmpname = NULL;
596 if(value) {
597 tmpval = BUF_strdup(value);
598 if(!tmpval) return 0;
599 } else tmpval = NULL;
600 /* Parameter values are case sensitive so leave as is */
601 mparam = (MIME_PARAM *) Malloc(sizeof(MIME_PARAM));
602 if(!mparam) return 0;
603 mparam->param_name = tmpname;
604 mparam->param_value = tmpval;
605 sk_push(mhdr->params, (char *)mparam);
606 return 1;
607}
608
609static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b)
610{
611 return(strcmp((*a)->name, (*b)->name));
612}
613
614static int mime_param_cmp(MIME_PARAM **a, MIME_PARAM **b)
615{
616 return(strcmp((*a)->param_name, (*b)->param_name));
617}
618
619/* Find a header with a given name (if possible) */
620
621static MIME_HEADER *mime_hdr_find(STACK *hdrs, char *name)
622{
623 MIME_HEADER htmp;
624 int idx;
625 htmp.name = name;
626 idx = sk_find(hdrs, (char *)&htmp);
627 if(idx < 0) return NULL;
628 return (MIME_HEADER *)sk_value(hdrs, idx);
629}
630
631static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
632{
633 MIME_PARAM param;
634 int idx;
635 param.param_name = name;
636 idx = sk_find(hdr->params, (char *)&param);
637 if(idx < 0) return NULL;
638 return (MIME_PARAM *)sk_value(hdr->params, idx);
639}
640
641static void mime_hdr_free(MIME_HEADER *hdr)
642{
643 if(hdr->name) Free(hdr->name);
644 if(hdr->value) Free(hdr->value);
645 if(hdr->params) sk_pop_free(hdr->params, mime_param_free);
646 Free(hdr);
647}
648
649static void mime_param_free(MIME_PARAM *param)
650{
651 if(param->param_name) Free(param->param_name);
652 if(param->param_value) Free(param->param_value);
653 Free(param);
654}
655
656/* Check for a multipart boundary. Returns:
657 * 0 : no boundary
658 * 1 : part boundary
659 * 2 : final boundary
660 */
661static int mime_bound_check(char *line, int linelen, char *bound, int blen)
662{
663 if(linelen == -1) linelen = strlen(line);
664 if(blen == -1) blen = strlen(bound);
665 /* Quickly eliminate if line length too short */
666 if(blen + 2 > linelen) return 0;
667 /* Check for part boundary */
668 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
669 if(!strncmp(line + blen + 2, "--", 2)) return 2;
670 else return 1;
671 }
672 return 0;
673}
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
new file mode 100644
index 0000000000..b41f42ed04
--- /dev/null
+++ b/src/lib/libcrypto/pkcs7/pk7_smime.c
@@ -0,0 +1,427 @@
1/* pk7_smime.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* Simple PKCS#7 processing functions */
60
61#include <stdio.h>
62#include "cryptlib.h"
63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
65
66PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67 BIO *data, int flags)
68{
69 PKCS7 *p7;
70 PKCS7_SIGNER_INFO *si;
71 BIO *p7bio;
72 STACK *smcap;
73 int i;
74
75 if(!X509_check_private_key(signcert, pkey)) {
76 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
77 return NULL;
78 }
79
80 if(!(p7 = PKCS7_new())) {
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
82 return NULL;
83 }
84
85 PKCS7_set_type(p7, NID_pkcs7_signed);
86
87 PKCS7_content_new(p7, NID_pkcs7_data);
88
89 if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {
90 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
91 return NULL;
92 }
93
94 if(!(flags & PKCS7_NOCERTS)) {
95 PKCS7_add_certificate(p7, signcert);
96 if(certs) for(i = 0; i < sk_X509_num(certs); i++)
97 PKCS7_add_certificate(p7, sk_X509_value(certs, i));
98 }
99
100 if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
101 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
102 return NULL;
103 }
104
105
106 SMIME_crlf_copy(data, p7bio, flags);
107
108 if(!(flags & PKCS7_NOATTR)) {
109 PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
110 V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
111 /* Add SMIMECapabilities */
112 if(!(smcap = sk_new(NULL))) {
113 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
114 return NULL;
115 }
116#ifndef NO_DES
117 PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1);
118#endif
119#ifndef NO_RC2
120 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128);
121 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64);
122#endif
123#ifndef NO_DES
124 PKCS7_simple_smimecap (smcap, NID_des_cbc, -1);
125#endif
126#ifndef NO_RC2
127 PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40);
128#endif
129 PKCS7_add_attrib_smimecap (si, smcap);
130 sk_pop_free(smcap, X509_ALGOR_free);
131 }
132
133 if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);
134
135 if (!PKCS7_dataFinal(p7,p7bio)) {
136 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
137 return NULL;
138 }
139
140 BIO_free_all(p7bio);
141 return p7;
142}
143
144int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
145 BIO *indata, BIO *out, int flags)
146{
147 STACK_OF(X509) *signers;
148 X509 *signer;
149 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
150 PKCS7_SIGNER_INFO *si;
151 X509_STORE_CTX cert_ctx;
152 char buf[4096];
153 int i, j=0;
154 BIO *p7bio;
155 BIO *tmpout;
156
157 if(!p7) {
158 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER);
159 return 0;
160 }
161
162 if(!PKCS7_type_is_signed(p7)) {
163 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE);
164 return 0;
165 }
166
167 /* Check for no data and no content: no data to verify signature */
168 if(PKCS7_get_detached(p7) && !indata) {
169 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT);
170 return 0;
171 }
172
173 /* Check for data and content: two sets of data */
174 if(!PKCS7_get_detached(p7) && indata) {
175 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT);
176 return 0;
177 }
178
179 sinfos = PKCS7_get_signer_info(p7);
180
181 if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
182 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA);
183 return 0;
184 }
185
186
187 signers = PKCS7_get0_signers(p7, certs, flags);
188
189 if(!signers) return 0;
190
191 /* Now verify the certificates */
192
193 if (!(flags & PKCS7_NOVERIFY)) for (i = 0; i < sk_X509_num(signers); i++) {
194 signer = sk_X509_value (signers, i);
195 if (!(flags & PKCS7_NOCHAIN)) {
196 X509_STORE_CTX_init(&cert_ctx, store, signer,
197 p7->d.sign->cert);
198 X509_STORE_CTX_set_purpose(&cert_ctx,
199 X509_PURPOSE_SMIME_SIGN);
200 } else X509_STORE_CTX_init (&cert_ctx, store, signer, NULL);
201 i = X509_verify_cert(&cert_ctx);
202 if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx);
203 X509_STORE_CTX_cleanup(&cert_ctx);
204 if (i <= 0) {
205 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR);
206 ERR_add_error_data(2, "Verify error:",
207 X509_verify_cert_error_string(j));
208 sk_X509_free(signers);
209 return 0;
210 }
211 /* Check for revocation status here */
212 }
213
214 p7bio=PKCS7_dataInit(p7,indata);
215
216 if(flags & PKCS7_TEXT) {
217 if(!(tmpout = BIO_new(BIO_s_mem()))) {
218 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
219 goto err;
220 }
221 } else tmpout = out;
222
223 /* We now have to 'read' from p7bio to calculate digests etc. */
224 for (;;)
225 {
226 i=BIO_read(p7bio,buf,sizeof(buf));
227 if (i <= 0) break;
228 if (tmpout) BIO_write(tmpout, buf, i);
229 }
230
231 if(flags & PKCS7_TEXT) {
232 if(!SMIME_text(tmpout, out)) {
233 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR);
234 BIO_free(tmpout);
235 goto err;
236 }
237 BIO_free(tmpout);
238 }
239
240 /* Now Verify All Signatures */
241 if (!(flags & PKCS7_NOSIGS))
242 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
243 {
244 si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
245 signer = sk_X509_value (signers, i);
246 j=PKCS7_signatureVerify(p7bio,p7,si, signer);
247 if (j <= 0) {
248 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE);
249 goto err;
250 }
251 }
252
253 sk_X509_free(signers);
254 if(indata) BIO_pop(p7bio);
255 BIO_free_all(p7bio);
256
257 return 1;
258
259 err:
260
261 sk_X509_free(signers);
262 BIO_free(p7bio);
263
264 return 0;
265}
266
267STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
268{
269 STACK_OF(X509) *signers;
270 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
271 PKCS7_SIGNER_INFO *si;
272 PKCS7_ISSUER_AND_SERIAL *ias;
273 X509 *signer;
274 int i;
275
276 if(!p7) {
277 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER);
278 return NULL;
279 }
280
281 if(!PKCS7_type_is_signed(p7)) {
282 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
283 return NULL;
284 }
285 if(!(signers = sk_X509_new(NULL))) {
286 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
287 return NULL;
288 }
289
290 /* Collect all the signers together */
291
292 sinfos = PKCS7_get_signer_info(p7);
293
294 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
295 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
296 return 0;
297 }
298
299 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
300 {
301 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
302 ias = si->issuer_and_serial;
303 signer = NULL;
304 /* If any certificates passed they take priority */
305 if (certs) signer = X509_find_by_issuer_and_serial (certs,
306 ias->issuer, ias->serial);
307 if (!signer && !(flags & PKCS7_NOINTERN)
308 && p7->d.sign->cert) signer =
309 X509_find_by_issuer_and_serial (p7->d.sign->cert,
310 ias->issuer, ias->serial);
311 if (!signer) {
312 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
313 sk_X509_free(signers);
314 return 0;
315 }
316
317 sk_X509_push(signers, signer);
318 }
319 return signers;
320}
321
322
323/* Build a complete PKCS#7 enveloped data */
324
325PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
326 int flags)
327{
328 PKCS7 *p7;
329 BIO *p7bio = NULL;
330 int i;
331 X509 *x509;
332 if(!(p7 = PKCS7_new())) {
333 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
334 return NULL;
335 }
336
337 PKCS7_set_type(p7, NID_pkcs7_enveloped);
338 if(!PKCS7_set_cipher(p7, cipher)) {
339 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
340 goto err;
341 }
342
343 for(i = 0; i < sk_X509_num(certs); i++) {
344 x509 = sk_X509_value(certs, i);
345 if(!PKCS7_add_recipient(p7, x509)) {
346 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
347 PKCS7_R_ERROR_ADDING_RECIPIENT);
348 goto err;
349 }
350 }
351
352 if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
353 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
354 goto err;
355 }
356
357 SMIME_crlf_copy(in, p7bio, flags);
358
359 BIO_flush(p7bio);
360
361 if (!PKCS7_dataFinal(p7,p7bio)) {
362 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
363 goto err;
364 }
365 BIO_free_all(p7bio);
366
367 return p7;
368
369 err:
370
371 BIO_free(p7bio);
372 PKCS7_free(p7);
373 return NULL;
374
375}
376
377int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
378{
379 BIO *tmpmem;
380 int ret, i;
381 char buf[4096];
382
383 if(!p7) {
384 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER);
385 return 0;
386 }
387
388 if(!PKCS7_type_is_enveloped(p7)) {
389 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE);
390 return 0;
391 }
392
393 if(!X509_check_private_key(cert, pkey)) {
394 PKCS7err(PKCS7_F_PKCS7_DECRYPT,
395 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
396 return 0;
397 }
398
399 if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
400 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
401 return 0;
402 }
403
404 if (flags & PKCS7_TEXT) {
405 BIO *tmpbuf, *bread;
406 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
407 if(!(tmpbuf = BIO_new(BIO_f_buffer()))) {
408 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
409 return 0;
410 }
411 if(!(bread = BIO_push(tmpbuf, tmpmem))) {
412 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
413 return 0;
414 }
415 ret = SMIME_text(bread, data);
416 BIO_free_all(bread);
417 return ret;
418 } else {
419 for(;;) {
420 i = BIO_read(tmpmem, buf, sizeof(buf));
421 if(i <= 0) break;
422 BIO_write(data, buf, i);
423 }
424 BIO_free_all(tmpmem);
425 return 1;
426 }
427}
diff --git a/src/lib/libcrypto/pkcs7/pkcs7.h b/src/lib/libcrypto/pkcs7/pkcs7.h
index c42bd6d391..3ec725d226 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7.h
+++ b/src/lib/libcrypto/pkcs7/pkcs7.h
@@ -71,8 +71,9 @@ extern "C" {
71#endif 71#endif
72 72
73#ifdef WIN32 73#ifdef WIN32
74/* Under Win32 this is defined in wincrypt.h */ 74/* Under Win32 thes are defined in wincrypt.h */
75#undef PKCS7_ISSUER_AND_SERIAL 75#undef PKCS7_ISSUER_AND_SERIAL
76#undef PKCS7_SIGNER_INFO
76#endif 77#endif
77 78
78/* 79/*
@@ -219,6 +220,7 @@ typedef struct pkcs7_st
219#define PKCS7_get_attributes(si) ((si)->unauth_attr) 220#define PKCS7_get_attributes(si) ((si)->unauth_attr)
220 221
221#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) 222#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
223#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
222#define PKCS7_type_is_signedAndEnveloped(a) \ 224#define PKCS7_type_is_signedAndEnveloped(a) \
223 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) 225 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
224#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) 226#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
@@ -236,6 +238,29 @@ typedef struct pkcs7_st
236#endif 238#endif
237#endif 239#endif
238 240
241/* S/MIME related flags */
242
243#define PKCS7_TEXT 0x1
244#define PKCS7_NOCERTS 0x2
245#define PKCS7_NOSIGS 0x4
246#define PKCS7_NOCHAIN 0x8
247#define PKCS7_NOINTERN 0x10
248#define PKCS7_NOVERIFY 0x20
249#define PKCS7_DETACHED 0x40
250#define PKCS7_BINARY 0x80
251#define PKCS7_NOATTR 0x100
252
253/* Flags: for compatibility with older code */
254
255#define SMIME_TEXT PKCS7_TEXT
256#define SMIME_NOCERTS PKCS7_NOCERTS
257#define SMIME_NOSIGS PKCS7_NOSIGS
258#define SMIME_NOCHAIN PKCS7_NOCHAIN
259#define SMIME_NOINTERN PKCS7_NOINTERN
260#define SMIME_NOVERIFY PKCS7_NOVERIFY
261#define SMIME_DETACHED PKCS7_DETACHED
262#define SMIME_BINARY PKCS7_BINARY
263#define SMIME_NOATTR PKCS7_NOATTR
239 264
240PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void ); 265PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void );
241void PKCS7_ISSUER_AND_SERIAL_free( 266void PKCS7_ISSUER_AND_SERIAL_free(
@@ -247,7 +272,7 @@ PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL(
247 unsigned char **pp, long length); 272 unsigned char **pp, long length);
248 273
249#ifndef SSLEAY_MACROS 274#ifndef SSLEAY_MACROS
250int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,EVP_MD *type, 275int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
251 unsigned char *md,unsigned int *len); 276 unsigned char *md,unsigned int *len);
252#ifndef NO_FP_API 277#ifndef NO_FP_API
253PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7); 278PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
@@ -368,6 +393,23 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
368int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk); 393int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
369 394
370 395
396PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
397 BIO *data, int flags);
398int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
399 BIO *indata, BIO *out, int flags);
400STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
401PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher,
402 int flags);
403int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
404
405int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap);
406STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
407int PKCS7_simple_smimecap(STACK *sk, int nid, int arg);
408
409int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
410PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
411int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
412int SMIME_text(BIO *in, BIO *out);
371 413
372/* BEGIN ERROR CODES */ 414/* BEGIN ERROR CODES */
373/* The following lines are auto generated by the script mkerr.pl. Any changes 415/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -377,6 +419,9 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
377/* Error codes for the PKCS7 functions. */ 419/* Error codes for the PKCS7 functions. */
378 420
379/* Function codes. */ 421/* Function codes. */
422#define PKCS7_F_B64_READ_PKCS7 120
423#define PKCS7_F_B64_WRITE_PKCS7 121
424#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
380#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 425#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
381#define PKCS7_F_PKCS7_ADD_CRL 101 426#define PKCS7_F_PKCS7_ADD_CRL 101
382#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 427#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
@@ -386,20 +431,56 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
386#define PKCS7_F_PKCS7_DATAINIT 105 431#define PKCS7_F_PKCS7_DATAINIT 105
387#define PKCS7_F_PKCS7_DATASIGN 106 432#define PKCS7_F_PKCS7_DATASIGN 106
388#define PKCS7_F_PKCS7_DATAVERIFY 107 433#define PKCS7_F_PKCS7_DATAVERIFY 107
434#define PKCS7_F_PKCS7_DECRYPT 114
435#define PKCS7_F_PKCS7_ENCRYPT 115
436#define PKCS7_F_PKCS7_GET0_SIGNERS 124
389#define PKCS7_F_PKCS7_SET_CIPHER 108 437#define PKCS7_F_PKCS7_SET_CIPHER 108
390#define PKCS7_F_PKCS7_SET_CONTENT 109 438#define PKCS7_F_PKCS7_SET_CONTENT 109
391#define PKCS7_F_PKCS7_SET_TYPE 110 439#define PKCS7_F_PKCS7_SET_TYPE 110
440#define PKCS7_F_PKCS7_SIGN 116
392#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 441#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
442#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
443#define PKCS7_F_PKCS7_VERIFY 117
444#define PKCS7_F_SMIME_READ_PKCS7 122
445#define PKCS7_F_SMIME_TEXT 123
393 446
394/* Reason codes. */ 447/* Reason codes. */
448#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117
449#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
395#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 450#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
451#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
452#define PKCS7_R_DECODE_ERROR 130
396#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 453#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
454#define PKCS7_R_DECRYPT_ERROR 119
397#define PKCS7_R_DIGEST_FAILURE 101 455#define PKCS7_R_DIGEST_FAILURE 101
456#define PKCS7_R_ERROR_ADDING_RECIPIENT 120
457#define PKCS7_R_ERROR_SETTING_CIPHER 121
398#define PKCS7_R_INTERNAL_ERROR 102 458#define PKCS7_R_INTERNAL_ERROR 102
459#define PKCS7_R_INVALID_MIME_TYPE 131
460#define PKCS7_R_INVALID_NULL_POINTER 143
461#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
462#define PKCS7_R_MIME_PARSE_ERROR 133
463#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
399#define PKCS7_R_MISSING_CERIPEND_INFO 103 464#define PKCS7_R_MISSING_CERIPEND_INFO 103
465#define PKCS7_R_NO_CONTENT 122
466#define PKCS7_R_NO_CONTENT_TYPE 135
467#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
468#define PKCS7_R_NO_MULTIPART_BOUNDARY 137
400#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 469#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
470#define PKCS7_R_NO_SIGNATURES_ON_DATA 123
471#define PKCS7_R_NO_SIGNERS 142
472#define PKCS7_R_NO_SIG_CONTENT_TYPE 138
401#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 473#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
474#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
475#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
476#define PKCS7_R_PKCS7_DATASIGN 126
477#define PKCS7_R_PKCS7_PARSE_ERROR 139
478#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140
479#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
402#define PKCS7_R_SIGNATURE_FAILURE 105 480#define PKCS7_R_SIGNATURE_FAILURE 105
481#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
482#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
483#define PKCS7_R_SMIME_TEXT_ERROR 129
403#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 484#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
404#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 485#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107
405#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 486#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108
diff --git a/src/lib/libcrypto/pkcs7/pkcs7err.c b/src/lib/libcrypto/pkcs7/pkcs7err.c
index 82be3c2ca1..813a8af9ed 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ b/src/lib/libcrypto/pkcs7/pkcs7err.c
@@ -65,6 +65,9 @@
65#ifndef NO_ERR 65#ifndef NO_ERR
66static ERR_STRING_DATA PKCS7_str_functs[]= 66static ERR_STRING_DATA PKCS7_str_functs[]=
67 { 67 {
68{ERR_PACK(0,PKCS7_F_B64_READ_PKCS7,0), "B64_READ_PKCS7"},
69{ERR_PACK(0,PKCS7_F_B64_WRITE_PKCS7,0), "B64_WRITE_PKCS7"},
70{ERR_PACK(0,PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,0), "PKCS7_add_attrib_smimecap"},
68{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CERTIFICATE,0), "PKCS7_add_certificate"}, 71{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CERTIFICATE,0), "PKCS7_add_certificate"},
69{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CRL,0), "PKCS7_add_crl"}, 72{ERR_PACK(0,PKCS7_F_PKCS7_ADD_CRL,0), "PKCS7_add_crl"},
70{ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0), "PKCS7_add_recipient_info"}, 73{ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0), "PKCS7_add_recipient_info"},
@@ -74,23 +77,59 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
74{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"}, 77{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
75{ERR_PACK(0,PKCS7_F_PKCS7_DATASIGN,0), "PKCS7_DATASIGN"}, 78{ERR_PACK(0,PKCS7_F_PKCS7_DATASIGN,0), "PKCS7_DATASIGN"},
76{ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"}, 79{ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"},
80{ERR_PACK(0,PKCS7_F_PKCS7_DECRYPT,0), "PKCS7_decrypt"},
81{ERR_PACK(0,PKCS7_F_PKCS7_ENCRYPT,0), "PKCS7_encrypt"},
82{ERR_PACK(0,PKCS7_F_PKCS7_GET0_SIGNERS,0), "PKCS7_get0_signers"},
77{ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"}, 83{ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"},
78{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"}, 84{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
79{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"}, 85{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
86{ERR_PACK(0,PKCS7_F_PKCS7_SIGN,0), "PKCS7_sign"},
80{ERR_PACK(0,PKCS7_F_PKCS7_SIGNATUREVERIFY,0), "PKCS7_signatureVerify"}, 87{ERR_PACK(0,PKCS7_F_PKCS7_SIGNATUREVERIFY,0), "PKCS7_signatureVerify"},
88{ERR_PACK(0,PKCS7_F_PKCS7_SIMPLE_SMIMECAP,0), "PKCS7_simple_smimecap"},
89{ERR_PACK(0,PKCS7_F_PKCS7_VERIFY,0), "PKCS7_verify"},
90{ERR_PACK(0,PKCS7_F_SMIME_READ_PKCS7,0), "SMIME_read_PKCS7"},
91{ERR_PACK(0,PKCS7_F_SMIME_TEXT,0), "SMIME_text"},
81{0,NULL} 92{0,NULL}
82 }; 93 };
83 94
84static ERR_STRING_DATA PKCS7_str_reasons[]= 95static ERR_STRING_DATA PKCS7_str_reasons[]=
85 { 96 {
97{PKCS7_R_CERTIFICATE_VERIFY_ERROR ,"certificate verify error"},
98{PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER ,"cipher has no object identifier"},
86{PKCS7_R_CIPHER_NOT_INITIALIZED ,"cipher not initialized"}, 99{PKCS7_R_CIPHER_NOT_INITIALIZED ,"cipher not initialized"},
100{PKCS7_R_CONTENT_AND_DATA_PRESENT ,"content and data present"},
101{PKCS7_R_DECODE_ERROR ,"decode error"},
87{PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH ,"decrypted key is wrong length"}, 102{PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH ,"decrypted key is wrong length"},
103{PKCS7_R_DECRYPT_ERROR ,"decrypt error"},
88{PKCS7_R_DIGEST_FAILURE ,"digest failure"}, 104{PKCS7_R_DIGEST_FAILURE ,"digest failure"},
105{PKCS7_R_ERROR_ADDING_RECIPIENT ,"error adding recipient"},
106{PKCS7_R_ERROR_SETTING_CIPHER ,"error setting cipher"},
89{PKCS7_R_INTERNAL_ERROR ,"internal error"}, 107{PKCS7_R_INTERNAL_ERROR ,"internal error"},
108{PKCS7_R_INVALID_MIME_TYPE ,"invalid mime type"},
109{PKCS7_R_INVALID_NULL_POINTER ,"invalid null pointer"},
110{PKCS7_R_MIME_NO_CONTENT_TYPE ,"mime no content type"},
111{PKCS7_R_MIME_PARSE_ERROR ,"mime parse error"},
112{PKCS7_R_MIME_SIG_PARSE_ERROR ,"mime sig parse error"},
90{PKCS7_R_MISSING_CERIPEND_INFO ,"missing ceripend info"}, 113{PKCS7_R_MISSING_CERIPEND_INFO ,"missing ceripend info"},
114{PKCS7_R_NO_CONTENT ,"no content"},
115{PKCS7_R_NO_CONTENT_TYPE ,"no content type"},
116{PKCS7_R_NO_MULTIPART_BODY_FAILURE ,"no multipart body failure"},
117{PKCS7_R_NO_MULTIPART_BOUNDARY ,"no multipart boundary"},
91{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"}, 118{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
119{PKCS7_R_NO_SIGNATURES_ON_DATA ,"no signatures on data"},
120{PKCS7_R_NO_SIGNERS ,"no signers"},
121{PKCS7_R_NO_SIG_CONTENT_TYPE ,"no sig content type"},
92{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"}, 122{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"},
123{PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR ,"pkcs7 add signature error"},
124{PKCS7_R_PKCS7_DATAFINAL_ERROR ,"pkcs7 datafinal error"},
125{PKCS7_R_PKCS7_DATASIGN ,"pkcs7 datasign"},
126{PKCS7_R_PKCS7_PARSE_ERROR ,"pkcs7 parse error"},
127{PKCS7_R_PKCS7_SIG_PARSE_ERROR ,"pkcs7 sig parse error"},
128{PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE,"private key does not match certificate"},
93{PKCS7_R_SIGNATURE_FAILURE ,"signature failure"}, 129{PKCS7_R_SIGNATURE_FAILURE ,"signature failure"},
130{PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND ,"signer certificate not found"},
131{PKCS7_R_SIG_INVALID_MIME_TYPE ,"sig invalid mime type"},
132{PKCS7_R_SMIME_TEXT_ERROR ,"smime text error"},
94{PKCS7_R_UNABLE_TO_FIND_CERTIFICATE ,"unable to find certificate"}, 133{PKCS7_R_UNABLE_TO_FIND_CERTIFICATE ,"unable to find certificate"},
95{PKCS7_R_UNABLE_TO_FIND_MEM_BIO ,"unable to find mem bio"}, 134{PKCS7_R_UNABLE_TO_FIND_MEM_BIO ,"unable to find mem bio"},
96{PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST ,"unable to find message digest"}, 135{PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST ,"unable to find message digest"},
diff --git a/src/lib/libcrypto/pkcs7/sign.c b/src/lib/libcrypto/pkcs7/sign.c
index d5f1154006..22290e192c 100644
--- a/src/lib/libcrypto/pkcs7/sign.c
+++ b/src/lib/libcrypto/pkcs7/sign.c
@@ -56,6 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58#include <stdio.h> 58#include <stdio.h>
59#include <string.h>
59#include <openssl/bio.h> 60#include <openssl/bio.h>
60#include <openssl/x509.h> 61#include <openssl/x509.h>
61#include <openssl/pem.h> 62#include <openssl/pem.h>
@@ -75,10 +76,18 @@ char *argv[];
75 int i; 76 int i;
76 int nodetach=0; 77 int nodetach=0;
77 78
79#ifndef NO_MD2
78 EVP_add_digest(EVP_md2()); 80 EVP_add_digest(EVP_md2());
81#endif
82#ifndef NO_MD5
79 EVP_add_digest(EVP_md5()); 83 EVP_add_digest(EVP_md5());
84#endif
85#ifndef NO_SHA1
80 EVP_add_digest(EVP_sha1()); 86 EVP_add_digest(EVP_sha1());
87#endif
88#ifndef NO_MDC2
81 EVP_add_digest(EVP_mdc2()); 89 EVP_add_digest(EVP_mdc2());
90#endif
82 91
83 data=BIO_new(BIO_s_file()); 92 data=BIO_new(BIO_s_file());
84again: 93again:
@@ -97,9 +106,9 @@ again:
97 BIO_set_fp(data,stdin,BIO_NOCLOSE); 106 BIO_set_fp(data,stdin,BIO_NOCLOSE);
98 107
99 if ((in=BIO_new_file("server.pem","r")) == NULL) goto err; 108 if ((in=BIO_new_file("server.pem","r")) == NULL) goto err;
100 if ((x509=PEM_read_bio_X509(in,NULL,NULL)) == NULL) goto err; 109 if ((x509=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) goto err;
101 BIO_reset(in); 110 BIO_reset(in);
102 if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err; 111 if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL) goto err;
103 BIO_free(in); 112 BIO_free(in);
104 113
105 p7=PKCS7_new(); 114 p7=PKCS7_new();
diff --git a/src/lib/libcrypto/pkcs7/verify.c b/src/lib/libcrypto/pkcs7/verify.c
index 32d9783e45..49fc8d8bed 100644
--- a/src/lib/libcrypto/pkcs7/verify.c
+++ b/src/lib/libcrypto/pkcs7/verify.c
@@ -56,6 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58#include <stdio.h> 58#include <stdio.h>
59#include <string.h>
59#include <openssl/bio.h> 60#include <openssl/bio.h>
60#include <openssl/asn1.h> 61#include <openssl/asn1.h>
61#include <openssl/x509.h> 62#include <openssl/x509.h>
@@ -84,10 +85,18 @@ char *argv[];
84 85
85 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 86 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
86 bio_out=BIO_new_fp(stdout,BIO_NOCLOSE); 87 bio_out=BIO_new_fp(stdout,BIO_NOCLOSE);
88#ifndef NO_MD2
87 EVP_add_digest(EVP_md2()); 89 EVP_add_digest(EVP_md2());
90#endif
91#ifndef NO_MD5
88 EVP_add_digest(EVP_md5()); 92 EVP_add_digest(EVP_md5());
93#endif
94#ifndef NO_SHA1
89 EVP_add_digest(EVP_sha1()); 95 EVP_add_digest(EVP_sha1());
96#endif
97#ifndef NO_MDC2
90 EVP_add_digest(EVP_mdc2()); 98 EVP_add_digest(EVP_mdc2());
99#endif
91 100
92 data=BIO_new(BIO_s_file()); 101 data=BIO_new(BIO_s_file());
93 102
@@ -121,7 +130,7 @@ char *argv[];
121 130
122 131
123 /* Load the PKCS7 object from a file */ 132 /* Load the PKCS7 object from a file */
124 if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL)) == NULL) goto err; 133 if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL,NULL)) == NULL) goto err;
125 134
126 /* This stuff is being setup for certificate verification. 135 /* This stuff is being setup for certificate verification.
127 * When using SSL, it could be replaced with a 136 * When using SSL, it could be replaced with a