diff options
author | beck <> | 2000-03-19 11:13:58 +0000 |
---|---|---|
committer | beck <> | 2000-03-19 11:13:58 +0000 |
commit | 796d609550df3a33fc11468741c5d2f6d3df4c11 (patch) | |
tree | 6c6d539061caa20372dad0ac4ddb1dfae2fbe7fe /src/lib/libcrypto/pkcs7 | |
parent | 5be3114c1fd7e0dfea1e38d3abb4cbba75244419 (diff) | |
download | openbsd-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.ssl | 85 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/bio_ber.c | 18 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/dec.c | 12 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/enc.c | 15 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/example.c | 15 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_attr.c | 85 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_doit.c | 121 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_lib.c | 54 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_mime.c | 673 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_smime.c | 427 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pkcs7.h | 85 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/pkcs7err.c | 39 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/sign.c | 13 | ||||
-rw-r--r-- | src/lib/libcrypto/pkcs7/verify.c | 11 |
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 | ||
5 | DIR= pkcs7 | 5 | DIR= pkcs7 |
@@ -15,6 +15,9 @@ MAKEDEPEND= $(TOP)/util/domd $(TOP) | |||
15 | MAKEFILE= Makefile.ssl | 15 | MAKEFILE= Makefile.ssl |
16 | AR= ar r | 16 | AR= ar r |
17 | 17 | ||
18 | PEX_LIBS= | ||
19 | EX_LIBS= | ||
20 | |||
18 | CFLAGS= $(INCLUDES) $(CFLAG) | 21 | CFLAGS= $(INCLUDES) $(CFLAG) |
19 | 22 | ||
20 | GENERAL=Makefile README | 23 | GENERAL=Makefile README |
@@ -22,8 +25,8 @@ TEST= | |||
22 | APPS= | 25 | APPS= |
23 | 26 | ||
24 | LIB=$(TOP)/libcrypto.a | 27 | LIB=$(TOP)/libcrypto.a |
25 | LIBSRC= pk7_lib.c pkcs7err.c pk7_doit.c | 28 | LIBSRC= pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c pk7_mime.c |
26 | LIBOBJ= pk7_lib.o pkcs7err.o pk7_doit.o | 29 | LIBOBJ= pk7_lib.o pkcs7err.o pk7_doit.o pk7_smime.o pk7_attr.o pk7_mime.o |
27 | 30 | ||
28 | SRC= $(LIBSRC) | 31 | SRC= $(LIBSRC) |
29 | 32 | ||
@@ -42,16 +45,16 @@ all: lib | |||
42 | testapps: enc dec sign verify | 45 | testapps: enc dec sign verify |
43 | 46 | ||
44 | enc: enc.o lib | 47 | enc: 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 | ||
47 | dec: dec.o lib | 50 | dec: 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 | ||
50 | sign: sign.o lib | 53 | sign: 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 | ||
53 | verify: verify.o example.o lib | 56 | verify: 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 | ||
56 | lib: $(LIBOBJ) | 59 | lib: $(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 | ||
92 | clean: | 95 | clean: |
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 | ||
100 | pk7_attr.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
101 | pk7_attr.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
102 | pk7_attr.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h | ||
103 | pk7_attr.o: ../../include/openssl/des.h ../../include/openssl/dh.h | ||
104 | pk7_attr.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h | ||
105 | pk7_attr.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
106 | pk7_attr.o: ../../include/openssl/idea.h ../../include/openssl/md2.h | ||
107 | pk7_attr.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
108 | pk7_attr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h | ||
109 | pk7_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h | ||
110 | pk7_attr.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h | ||
111 | pk7_attr.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
112 | pk7_attr.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
113 | pk7_attr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
114 | pk7_attr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
115 | pk7_attr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h | ||
97 | pk7_doit.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | 116 | pk7_doit.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h |
98 | pk7_doit.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | 117 | pk7_doit.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h |
99 | pk7_doit.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | 118 | pk7_doit.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h |
100 | pk7_doit.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | 119 | pk7_doit.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h |
101 | pk7_doit.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | 120 | pk7_doit.o: ../../include/openssl/des.h ../../include/openssl/dh.h |
102 | pk7_doit.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h | 121 | pk7_doit.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h |
103 | pk7_doit.o: ../../include/openssl/err.h ../../include/openssl/evp.h | 122 | pk7_doit.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h |
104 | pk7_doit.o: ../../include/openssl/idea.h ../../include/openssl/md2.h | 123 | pk7_doit.o: ../../include/openssl/evp.h ../../include/openssl/idea.h |
124 | pk7_doit.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h | ||
105 | pk7_doit.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | 125 | pk7_doit.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h |
106 | pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h | 126 | pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h |
107 | pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h | 127 | pk7_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 | |||
110 | pk7_doit.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h | 130 | pk7_doit.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h |
111 | pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h | 131 | pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h |
112 | pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/x509.h | 132 | pk7_doit.o: ../../include/openssl/stack.h ../../include/openssl/x509.h |
113 | pk7_doit.o: ../../include/openssl/x509_vfy.h ../cryptlib.h | 133 | pk7_doit.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h |
134 | pk7_doit.o: ../cryptlib.h | ||
114 | pk7_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | 135 | pk7_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h |
115 | pk7_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | 136 | pk7_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h |
116 | pk7_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | 137 | pk7_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 | |||
128 | pk7_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | 149 | pk7_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h |
129 | pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h | 150 | pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h |
130 | pk7_lib.o: ../cryptlib.h | 151 | pk7_lib.o: ../cryptlib.h |
152 | pk7_mime.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
153 | pk7_mime.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
154 | pk7_mime.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
155 | pk7_mime.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
156 | pk7_mime.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
157 | pk7_mime.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h | ||
158 | pk7_mime.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
159 | pk7_mime.o: ../../include/openssl/idea.h ../../include/openssl/md2.h | ||
160 | pk7_mime.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
161 | pk7_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h | ||
162 | pk7_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h | ||
163 | pk7_mime.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h | ||
164 | pk7_mime.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h | ||
165 | pk7_mime.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h | ||
166 | pk7_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h | ||
167 | pk7_mime.o: ../../include/openssl/stack.h ../../include/openssl/x509.h | ||
168 | pk7_mime.o: ../../include/openssl/x509_vfy.h ../cryptlib.h | ||
169 | pk7_smime.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
170 | pk7_smime.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
171 | pk7_smime.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
172 | pk7_smime.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h | ||
173 | pk7_smime.o: ../../include/openssl/des.h ../../include/openssl/dh.h | ||
174 | pk7_smime.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h | ||
175 | pk7_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h | ||
176 | pk7_smime.o: ../../include/openssl/evp.h ../../include/openssl/idea.h | ||
177 | pk7_smime.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h | ||
178 | pk7_smime.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
179 | pk7_smime.o: ../../include/openssl/objects.h | ||
180 | pk7_smime.o: ../../include/openssl/opensslconf.h | ||
181 | pk7_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h | ||
182 | pk7_smime.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
183 | pk7_smime.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
184 | pk7_smime.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
185 | pk7_smime.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
186 | pk7_smime.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h | ||
187 | pk7_smime.o: ../../include/openssl/x509v3.h ../cryptlib.h | ||
131 | pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | 188 | pkcs7err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h |
132 | pkcs7err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | 189 | pkcs7err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h |
133 | pkcs7err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h | 190 | pkcs7err.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); | |||
69 | static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2); | 69 | static long ber_ctrl(BIO *h,int cmd,long arg1,char *arg2); |
70 | static int ber_new(BIO *h); | 70 | static int ber_new(BIO *h); |
71 | static int ber_free(BIO *data); | 71 | static int ber_free(BIO *data); |
72 | static 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 | ||
120 | BIO_METHOD *BIO_f_ber(void) | 122 | BIO_METHOD *BIO_f_ber(void) |
@@ -409,6 +411,20 @@ again: | |||
409 | return(ret); | 411 | return(ret); |
410 | } | 412 | } |
411 | 413 | ||
414 | static 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 | /* |
413 | void BIO_set_cipher_ctx(b,c) | 429 | void BIO_set_cipher_ctx(b,c) |
414 | BIO *b; | 430 | BIO *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 | ||
71 | static signed_seq2string_nid= -1; | 72 | static int signed_seq2string_nid= -1; |
72 | /* ########################################### */ | 73 | /* ########################################### */ |
73 | int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2) | 74 | int 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 | |||
17 | int 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 | |||
44 | STACK *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 */ | ||
57 | int 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 | ||
65 | static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | 66 | static 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) | |||
289 | int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, | 297 | int 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); |
328 | err: | 341 | err: |
@@ -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) | |||
425 | int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) | 438 | int 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 | |||
72 | typedef struct { | ||
73 | char *name; /* Name of line e.g. "content-type" */ | ||
74 | char *value; /* Value of line e.g. "text/plain" */ | ||
75 | STACK /* MIME_PARAM */ *params; /* Zero or more parameters */ | ||
76 | } MIME_HEADER; | ||
77 | |||
78 | typedef struct { | ||
79 | char *param_name; /* Param name e.g. "micalg" */ | ||
80 | char *param_value; /* Param value e.g. "sha1" */ | ||
81 | } MIME_PARAM; | ||
82 | |||
83 | |||
84 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7); | ||
85 | static PKCS7 *B64_read_PKCS7(BIO *bio); | ||
86 | static char * strip_ends(char *name); | ||
87 | static char * strip_start(char *name); | ||
88 | static char * strip_end(char *name); | ||
89 | static MIME_HEADER *mime_hdr_new(char *name, char *value); | ||
90 | static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); | ||
91 | static STACK *mime_parse_hdr(BIO *bio); | ||
92 | static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b); | ||
93 | static int mime_param_cmp(MIME_PARAM **a, MIME_PARAM **b); | ||
94 | static void mime_param_free(MIME_PARAM *param); | ||
95 | static int mime_bound_check(char *line, int linelen, char *bound, int blen); | ||
96 | static int multi_split(BIO *bio, char *bound, STACK **ret); | ||
97 | static int iscrlf(char c); | ||
98 | static MIME_HEADER *mime_hdr_find(STACK *hdrs, char *name); | ||
99 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); | ||
100 | static void mime_hdr_free(MIME_HEADER *hdr); | ||
101 | |||
102 | #define MAX_SMLEN 1024 | ||
103 | #define mime_debug(x) /* x */ | ||
104 | |||
105 | |||
106 | typedef void (*stkfree)(); | ||
107 | |||
108 | /* Base 64 read and write of PKCS#7 structure */ | ||
109 | |||
110 | static 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 | |||
125 | static 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 | |||
144 | int 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 | |||
196 | PKCS7 *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 */ | ||
300 | int 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 */ | ||
324 | int 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 | |||
355 | static 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 | |||
391 | static 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 | |||
408 | static 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 | |||
502 | return headers; | ||
503 | |||
504 | } | ||
505 | |||
506 | static 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 */ | ||
512 | static 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? */ | ||
529 | static 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 | |||
547 | static 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 | |||
580 | static 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 | |||
609 | static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b) | ||
610 | { | ||
611 | return(strcmp((*a)->name, (*b)->name)); | ||
612 | } | ||
613 | |||
614 | static 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 | |||
621 | static 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 | |||
631 | static 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 *)¶m); | ||
637 | if(idx < 0) return NULL; | ||
638 | return (MIME_PARAM *)sk_value(hdr->params, idx); | ||
639 | } | ||
640 | |||
641 | static 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 | |||
649 | static 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 | */ | ||
661 | static 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 | |||
66 | PKCS7 *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 | |||
144 | int 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 | |||
267 | STACK_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 | |||
325 | PKCS7 *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 | |||
377 | int 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 | ||
240 | PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void ); | 265 | PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void ); |
241 | void PKCS7_ISSUER_AND_SERIAL_free( | 266 | void 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 |
250 | int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,EVP_MD *type, | 275 | int 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 |
253 | PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7); | 278 | PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7); |
@@ -368,6 +393,23 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, | |||
368 | int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk); | 393 | int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk); |
369 | 394 | ||
370 | 395 | ||
396 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | ||
397 | BIO *data, int flags); | ||
398 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | ||
399 | BIO *indata, BIO *out, int flags); | ||
400 | STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); | ||
401 | PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher, | ||
402 | int flags); | ||
403 | int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); | ||
404 | |||
405 | int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap); | ||
406 | STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); | ||
407 | int PKCS7_simple_smimecap(STACK *sk, int nid, int arg); | ||
408 | |||
409 | int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); | ||
410 | PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); | ||
411 | int SMIME_crlf_copy(BIO *in, BIO *out, int flags); | ||
412 | int 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 |
66 | static ERR_STRING_DATA PKCS7_str_functs[]= | 66 | static 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 | ||
84 | static ERR_STRING_DATA PKCS7_str_reasons[]= | 95 | static 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()); |
84 | again: | 93 | again: |
@@ -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 |