diff options
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 |
