summaryrefslogtreecommitdiffstats
path: root/crypto/pkcs7
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/pkcs7')
-rw-r--r--crypto/pkcs7/Makefile.ssl86
-rw-r--r--crypto/pkcs7/README5
-rw-r--r--crypto/pkcs7/doc24
-rw-r--r--crypto/pkcs7/mf.p718
-rw-r--r--crypto/pkcs7/p7.tst33
-rw-r--r--crypto/pkcs7/pk7_dgst.c66
-rw-r--r--crypto/pkcs7/pk7_doit.c327
-rw-r--r--crypto/pkcs7/pk7_enc.c76
-rw-r--r--crypto/pkcs7/pk7_lib.c343
-rw-r--r--crypto/pkcs7/pkcs7.err21
-rw-r--r--crypto/pkcs7/pkcs7.h416
-rw-r--r--crypto/pkcs7/pkcs7err.c99
-rw-r--r--crypto/pkcs7/server.pem24
-rw-r--r--crypto/pkcs7/sign.c83
-rw-r--r--crypto/pkcs7/verify.c181
15 files changed, 1802 insertions, 0 deletions
diff --git a/crypto/pkcs7/Makefile.ssl b/crypto/pkcs7/Makefile.ssl
new file mode 100644
index 0000000000..64a005a186
--- /dev/null
+++ b/crypto/pkcs7/Makefile.ssl
@@ -0,0 +1,86 @@
+#
+# SSLeay/crypto/asn1/Makefile
+#
+
+DIR= pkcs7
+TOP= ../..
+CC= cc
+INCLUDES= -I.. -I../../include
+CFLAG=-g
+INSTALLTOP=/usr/local/ssl
+MAKE= make -f Makefile.ssl
+MAKEDEPEND= makedepend -f Makefile.ssl
+MAKEFILE= Makefile.ssl
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+ERR=pkcs7
+ERRC=pkcs7err
+GENERAL=Makefile README
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= pk7_lib.c pkcs7err.c pk7_doit.c
+LIBOBJ= pk7_lib.o pkcs7err.o pk7_doit.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= pkcs7.h
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+test:
+
+all: lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ sh $(TOP)/util/ranlib.sh $(LIB)
+ @touch lib
+
+files:
+ perl $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
+
+links:
+ /bin/rm -f Makefile
+ $(TOP)/util/point.sh Makefile.ssl Makefile ;
+ $(TOP)/util/mklink.sh ../../include $(EXHEADER)
+ $(TOP)/util/mklink.sh ../../test $(TEST)
+ $(TOP)/util/mklink.sh ../../apps $(APPS)
+
+install:
+ @for i in $(EXHEADER) ; \
+ do \
+ (cp $$i $(INSTALLTOP)/include/$$i; \
+ chmod 644 $(INSTALLTOP)/include/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) $(INCLUDES) $(PROGS) $(LIBSRC)
+
+dclean:
+ perl -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ /bin/rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+errors:
+ perl $(TOP)/util/err-ins.pl $(ERR).err $(ERR).h
+ perl ../err/err_genc.pl $(ERR).h $(ERRC).c
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/crypto/pkcs7/README b/crypto/pkcs7/README
new file mode 100644
index 0000000000..27001c6970
--- /dev/null
+++ b/crypto/pkcs7/README
@@ -0,0 +1,5 @@
+WARNING
+
+Everything in this directory is experimental and is subject to change.
+
+Do not rely on the stuff in here not changing in the next release
diff --git a/crypto/pkcs7/doc b/crypto/pkcs7/doc
new file mode 100644
index 0000000000..d2e8b7b2a3
--- /dev/null
+++ b/crypto/pkcs7/doc
@@ -0,0 +1,24 @@
+int PKCS7_set_content_type(PKCS7 *p7, int type);
+Call to set the type of PKCS7 object we are working on
+
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+ EVP_MD *dgst);
+Use this to setup a signer info
+There will also be functions to add signed and unsigned attributes.
+
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+Add a signer info to the content.
+
+int PKCS7_add_certificae(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+
+----
+
+p7=PKCS7_new();
+PKCS7_set_content_type(p7,NID_pkcs7_signed);
+
+signer=PKCS7_SINGNER_INFO_new();
+PKCS7_SIGNER_INFO_set(signer,x509,pkey,EVP_md5());
+PKCS7_add_signer(py,signer);
+
+we are now setup.
diff --git a/crypto/pkcs7/mf.p7 b/crypto/pkcs7/mf.p7
new file mode 100644
index 0000000000..524335b4b3
--- /dev/null
+++ b/crypto/pkcs7/mf.p7
@@ -0,0 +1,18 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHAqCAMIIC2QIBATEMMAoGCCqGSIb3DQIFMIAGCSqGSIb3DQEH
+AQAAoIIB7TCCAekwggFSAgEAMA0GCSqGSIb3DQEBBAUAMFsxCzAJBgNVBAYTAkFV
+MRMwEQYDVQQIEwpRdWVlbnNsYW5kMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0
+ZDEbMBkGA1UEAxMSVGVzdCBDQSAoMTAyNCBiaXQpMB4XDTk3MDYwOTEzNTc0NloX
+DTk4MDYwOTEzNTc0NlowYzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xh
+bmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYDVQQDExpTZXJ2ZXIg
+dGVzdCBjZXJ0ICg1MTIgYml0KTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCfs8OE
+J5X/EjFSDxXvRhHErYDmNlsP3YDXYY3g/HJFCTT+VWZFQ0xol2r+qKCl3194/+7X
+ZLg/BMtv/yr+/rntAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAeEzEdgr2nChPcALL
+vY8gl/GIlpoAjPmKD+pLeGZI9s+SEX5u1q8nCrJ6ZzkfrRnqgI5Anmev9+qPZfdU
+bz5zdVSf4sUL9nX9ChXjK9NCJA3UzQHSFqhZErGUwGNkAHYHp2+zAdY6Ho6rmMzt
+g0CDu/sKR4qzm6REsQGS8kgpjz4xgcUwgcICAQEwYDBbMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
+GzAZBgNVBAMTElRlc3QgQ0EgKDEwMjQgYml0KQIBADAKBggqhkiG9w0CBTANBgkq
+hkiG9w0BAQQFAARALnrxJiOX9XZf2D+3vL8SKMQmMq55LltomwOLGUru/q1uVXzi
+ARg7FSCegOpA1nunsTURMUGgrPXKK4XmL4IseQAAAAA=
+-----END PKCS7-----
diff --git a/crypto/pkcs7/p7.tst b/crypto/pkcs7/p7.tst
new file mode 100644
index 0000000000..6d14dce163
--- /dev/null
+++ b/crypto/pkcs7/p7.tst
@@ -0,0 +1,33 @@
+-----BEGIN PKCS7-----
+MIAGCSqGSIb3DQEHAqCAMIIFsQIBATELMAkGBSsOAwIaBQAwgAYJKoZIhvcNAQcB
+AACgggQdMIICJTCCAc+gAwIBAgIBIjANBgkqhkiG9w0BAQQFADCBgjELMAkGA1UE
+BhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxETAPBgNVBAcTCEJyaXNiYW5lMRow
+GAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEUMBIGA1UECxMLZGV2ZWxvcG1lbnQx
+GTAXBgNVBAMTEENyeXB0U29mdCBEZXYgQ0EwHhcNOTcwNjEzMTgxMDE3WhcNOTgw
+NjEzMTgxMDE3WjCBiDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx
+ETAPBgNVBAcTCEJyaXNiYW5lMRowGAYDVQQKExFDcnlwdFNvZnQgUHR5IEx0ZDEU
+MBIGA1UECxMLSUlTIHRlc3RpbmcxDjAMBgNVBAMTBXRlc3QxMQ8wDQYJKoZIhvcN
+AQkBFgAwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAxtWiv59VH42+rotrmFAyDxTc
+J2osFt5uy/zEllx3vvjtwewqQxGUOwf6cjqFOTrnpEdVvwywpEhIQ5364bJqIwID
+AQABoygwJjAkBglghkgBhvhCAQ0EFxYVR2VuZXJhdGVkIHdpdGggU1NMZWF5MA0G
+CSqGSIb3DQEBBAUAA0EAMnYkNV2AdpeHPy/qlcdZx6MDGIJgrLhklhcn6Or6KiAP
+t9+nv9XdOGHyMyQr9ufsweuQfAgJ9yjKPZR2/adTjTCCAfAwggGaAgEAMA0GCSqG
+SIb3DQEBBAUAMIGCMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDER
+MA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRQw
+EgYDVQQLEwtkZXZlbG9wbWVudDEZMBcGA1UEAxMQQ3J5cHRTb2Z0IERldiBDQTAe
+Fw05NzAzMjIxMzM0MDRaFw05ODAzMjIxMzM0MDRaMIGCMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKUXVlZW5zbGFuZDERMA8GA1UEBxMIQnJpc2JhbmUxGjAYBgNVBAoT
+EUNyeXB0U29mdCBQdHkgTHRkMRQwEgYDVQQLEwtkZXZlbG9wbWVudDEZMBcGA1UE
+AxMQQ3J5cHRTb2Z0IERldiBDQTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDgDgKq
+IBuUMAJi4c8juAqEZ8f8FcuDWT+HcScvNztRJy9K8DnbGpiSrzzix4El6N4A7vbl
+crwn/0CZmQJguZpfAgMBAAEwDQYJKoZIhvcNAQEEBQADQQA0UUvxlXXe6wKkVukn
+ZoCyXbjlNsqt2rwbvfZEam6fQP3S7uq+o1Pnj+KDgE33WxWbQAA9h8fY1LWN7X3a
+yTm/MYIBbTCCAWkCAQEwgYgwgYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVl
+bnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0
+eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQg
+RGV2IENBAgEiMAkGBSsOAwIaBQCgfTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB
+MCMGCSqGSIb3DQEJBDEWBBSUVhbGkNE+KGqpOK13+FkfOkaoizAcBgkqhkiG9w0B
+CQUxDxcNOTcwNzAxMDE0MzM0WjAeBgkqhkiG9w0BCQ8xETAPMA0GCCqGSIb3DQMC
+AgEoMA0GCSqGSIb3DQEBAQUABECa9Jpo4w/fZOc3Vy78wZFAVF8kvpn7il99Ldsr
+AQ4JiBmcfiSwEBBY6WuKT+/SYtFwZl1oXkTwB5AVCFIC/IFNAAAAAA==
+-----END PKCS7-----
diff --git a/crypto/pkcs7/pk7_dgst.c b/crypto/pkcs7/pk7_dgst.c
new file mode 100644
index 0000000000..fa562a4816
--- /dev/null
+++ b/crypto/pkcs7/pk7_dgst.c
@@ -0,0 +1,66 @@
+/* crypto/pkcs7/pk7_dgst.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "evp.h"
+#include "rand.h"
+#include "objects.h"
+#include "x509.h"
+#include "pkcs7.h"
+
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
new file mode 100644
index 0000000000..32a2a45226
--- /dev/null
+++ b/crypto/pkcs7/pk7_doit.c
@@ -0,0 +1,327 @@
+/* crypto/pkcs7/pk7_doit.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "objects.h"
+#include "x509.h"
+
+BIO *PKCS7_dataInit(p7,bio)
+PKCS7 *p7;
+BIO *bio;
+ {
+ int i,j;
+ BIO *out=NULL,*btmp;
+ X509_ALGOR *xa;
+ EVP_MD *evp_md;
+
+ i=OBJ_obj2nid(p7->type);
+ p7->state=PKCS7_S_HEADER;
+
+ switch (i)
+ {
+ case NID_pkcs7_signed:
+ for (i=0; i<sk_num(p7->d.sign->md_algs); i++)
+ {
+ xa=(X509_ALGOR *)sk_value(p7->d.sign->md_algs,i);
+ if ((btmp=BIO_new(BIO_f_md())) == NULL) goto err;
+
+ j=OBJ_obj2nid(xa->algorithm);
+ evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
+ if (evp_md == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
+ goto err;
+ }
+
+ BIO_set_md(btmp,evp_md);
+ if (out == NULL)
+ out=btmp;
+ else
+ BIO_push(out,btmp);
+ }
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+ if (bio == NULL)
+ {
+ if (p7->detached)
+ bio=BIO_new(BIO_s_null());
+ else
+ {
+ bio=BIO_new(BIO_s_mem());
+ if (PKCS7_type_is_signed(p7) &&
+ PKCS7_type_is_data(p7->d.sign->contents))
+ {
+ ASN1_OCTET_STRING *os;
+
+ os=p7->d.sign->contents->d.data;
+ if (os->length > 0)
+ BIO_write(bio,os->data,os->length);
+ }
+ }
+ }
+ BIO_push(out,bio);
+ return(out);
+err:
+ return(NULL);
+ }
+
+int PKCS7_dataSign(p7,bio)
+PKCS7 *p7;
+BIO *bio;
+ {
+ int ret=0;
+ int i,j;
+ BIO *btmp;
+ BUF_MEM *buf_mem=NULL;
+ BUF_MEM *buf=NULL;
+ PKCS7_SIGNER_INFO *si;
+ EVP_MD_CTX *mdc,ctx_tmp;
+ STACK *sk;
+ unsigned char *p,*pp=NULL;
+ int x;
+
+ i=OBJ_obj2nid(p7->type);
+ p7->state=PKCS7_S_HEADER;
+
+ switch (i)
+ {
+ case NID_pkcs7_signed:
+
+ if ((buf=BUF_MEM_new()) == NULL) goto err;
+ for (i=0; i<sk_num(p7->d.sign->signer_info); i++)
+ {
+ si=(PKCS7_SIGNER_INFO *)
+ sk_value(p7->d.sign->signer_info,i);
+ if (si->pkey == NULL)
+ continue;
+ j=OBJ_obj2nid(si->digest_enc_alg->algorithm);
+
+ btmp=bio;
+ for (;;)
+ {
+ if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD))
+ == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+ goto err;
+ }
+ BIO_get_md_ctx(btmp,&mdc);
+ if (mdc == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (EVP_MD_pkey_type(EVP_MD_CTX_type(mdc)) == j)
+ break;
+ else
+ btmp=btmp->next_bio;
+ }
+
+ /* We now have the EVP_MD_CTX, lets do the
+ * signing. */
+ memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp));
+ if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
+ goto err;
+
+ sk=si->auth_attr;
+ if ((sk != NULL) && (sk_num(sk) != 0))
+ {
+ x=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE,
+ V_ASN1_SET,V_ASN1_UNIVERSAL);
+ pp=(unsigned char *)Malloc(i);
+ p=pp;
+ i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
+ V_ASN1_SET,V_ASN1_UNIVERSAL);
+ EVP_SignUpdate(&ctx_tmp,pp,x);
+ Free(pp);
+ }
+
+ if (!EVP_SignFinal(&ctx_tmp,buf->data,
+ (unsigned int *)&buf->length,si->pkey))
+ goto err;
+ if (!ASN1_STRING_set(si->enc_digest,
+ (unsigned char *)buf->data,buf->length))
+ goto err;
+
+ }
+ if (p7->detached)
+ PKCS7_content_free(p7->d.sign->contents);
+ else
+ {
+ btmp=BIO_find_type(bio,BIO_TYPE_MEM);
+ if (btmp == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+ goto err;
+ }
+ BIO_get_mem_ptr(btmp,&buf_mem);
+ ASN1_OCTET_STRING_set(p7->d.sign->contents->d.data,
+ (unsigned char *)buf_mem->data,buf_mem->length);
+ }
+ if (pp != NULL) Free(pp);
+ pp=NULL;
+ break;
+ default:
+ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+
+ if (p7->detached)
+ {
+
+ }
+ ret=1;
+err:
+ if (buf != NULL) BUF_MEM_free(buf);
+ return(ret);
+ }
+
+int PKCS7_dataVerify(cert_store,ctx,bio,p7,si)
+X509_STORE *cert_store;
+X509_STORE_CTX *ctx;
+BIO *bio;
+PKCS7 *p7;
+PKCS7_SIGNER_INFO *si;
+ {
+ PKCS7_SIGNED *s;
+ ASN1_OCTET_STRING *os;
+ EVP_MD_CTX mdc_tmp,*mdc;
+ unsigned char *pp,*p;
+ PKCS7_ISSUER_AND_SERIAL *ias;
+ int ret=0,md_type,i;
+ STACK *sk;
+ BIO *btmp;
+ X509 *x509;
+
+ if (!PKCS7_type_is_signed(p7)) abort();
+ ias=si->issuer_and_serial;
+ s=p7->d.sign;
+
+ x509=X509_find_by_issuer_and_serial(s->cert,ias->issuer,ias->serial);
+
+ /* were we able to find the cert in passed to us */
+ if (x509 == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
+ goto err;
+ }
+
+ /* Lets verify */
+ X509_STORE_CTX_init(ctx,cert_store,x509,s->cert);
+ i=X509_verify_cert(ctx);
+ if (i <= 0) goto err;
+ X509_STORE_CTX_cleanup(ctx);
+
+ /* So we like 'x509', lets check the signature. */
+ md_type=OBJ_obj2nid(si->digest_alg->algorithm);
+
+ btmp=bio;
+ for (;;)
+ {
+ if ((btmp == NULL) ||
+ ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+ goto err;
+ }
+ BIO_get_md_ctx(btmp,&mdc);
+ if (mdc == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type)
+ break;
+ btmp=btmp->next_bio;
+ }
+
+ /* mdc is the digest ctx that we want */
+ memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp));
+
+ sk=si->auth_attr;
+ if ((sk != NULL) && (sk_num(sk) != 0))
+ {
+ i=i2d_ASN1_SET(sk,NULL,i2d_X509_ATTRIBUTE,
+ V_ASN1_SET,V_ASN1_UNIVERSAL);
+ pp=(unsigned char *)malloc(i);
+ p=pp;
+ i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,
+ V_ASN1_SET,V_ASN1_UNIVERSAL);
+ EVP_VerifyUpdate(&mdc_tmp,pp,i);
+ free(pp);
+ }
+
+ os=si->enc_digest;
+ i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length,
+ X509_get_pubkey(x509));
+ if (i <= 0)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);
+ ret= -1;
+ goto err;
+ }
+ else
+ ret=1;
+err:
+ return(ret);
+ }
+
diff --git a/crypto/pkcs7/pk7_enc.c b/crypto/pkcs7/pk7_enc.c
new file mode 100644
index 0000000000..96a6dd94a8
--- /dev/null
+++ b/crypto/pkcs7/pk7_enc.c
@@ -0,0 +1,76 @@
+/* crypto/pkcs7/pk7_enc.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "evp.h"
+#include "rand.h"
+#include "objects.h"
+#include "x509.h"
+#include "pkcs7.h"
+
+PKCS7_in_bio(PKCS7 *p7,BIO *in);
+PKCS7_out_bio(PKCS7 *p7,BIO *out);
+
+PKCS7_add_signer(PKCS7 *p7,X509 *cert,EVP_PKEY *key);
+PKCS7_cipher(PKCS7 *p7,EVP_CIPHER *cipher);
+
+PKCS7_Init(PKCS7 *p7);
+PKCS7_Update(PKCS7 *p7);
+PKCS7_Finish(PKCS7 *p7);
+
diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c
new file mode 100644
index 0000000000..aac133e639
--- /dev/null
+++ b/crypto/pkcs7/pk7_lib.c
@@ -0,0 +1,343 @@
+/* crypto/pkcs7/pk7_lib.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "objects.h"
+#include "x509.h"
+
+long PKCS7_ctrl(p7,cmd,larg,parg)
+PKCS7 *p7;
+int cmd;
+long larg;
+char *parg;
+ {
+ int nid;
+ long ret;
+
+ nid=OBJ_obj2nid(p7->type);
+
+ switch (cmd)
+ {
+ case PKCS7_OP_SET_DETACHED_SIGNATURE:
+ if (nid == NID_pkcs7_signed)
+ {
+ ret=p7->detached=(int)larg;
+ }
+ else
+ {
+ PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+ ret=0;
+ }
+ break;
+ case PKCS7_OP_GET_DETACHED_SIGNATURE:
+ if (nid == NID_pkcs7_signed)
+ {
+ ret=p7->detached;
+ }
+ else
+ {
+ PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+ ret=0;
+ }
+
+ break;
+ default:
+ abort();
+ }
+ return(ret);
+ }
+
+int PKCS7_content_new(p7,type)
+PKCS7 *p7;
+int type;
+ {
+ PKCS7 *ret=NULL;
+
+ if ((ret=PKCS7_new()) == NULL) goto err;
+ if (!PKCS7_set_type(ret,type)) goto err;
+ if (!PKCS7_set_content(p7,ret)) goto err;
+
+ return(1);
+err:
+ if (ret != NULL) PKCS7_free(ret);
+ return(0);
+ }
+
+int PKCS7_set_content(p7,p7_data)
+PKCS7 *p7;
+PKCS7 *p7_data;
+ {
+ int i;
+
+ i=OBJ_obj2nid(p7->type);
+ switch (i)
+ {
+ case NID_pkcs7_signed:
+ if (p7->d.sign->contents != NULL)
+ PKCS7_content_free(p7->d.sign->contents);
+ p7->d.sign->contents=p7_data;
+ break;
+ case NID_pkcs7_digest:
+ case NID_pkcs7_data:
+ case NID_pkcs7_enveloped:
+ case NID_pkcs7_signedAndEnveloped:
+ case NID_pkcs7_encrypted:
+ default:
+ PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+ return(1);
+err:
+ return(0);
+ }
+
+int PKCS7_set_type(p7,type)
+PKCS7 *p7;
+int type;
+ {
+ ASN1_OBJECT *obj;
+
+ PKCS7_content_free(p7);
+ obj=OBJ_nid2obj(type); /* will not fail */
+
+ switch (type)
+ {
+ case NID_pkcs7_signed:
+ p7->type=obj;
+ if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
+ goto err;
+ ASN1_INTEGER_set(p7->d.sign->version,1);
+ break;
+ case NID_pkcs7_data:
+ p7->type=obj;
+ if ((p7->d.data=ASN1_OCTET_STRING_new()) == NULL)
+ goto err;
+ break;
+ case NID_pkcs7_digest:
+ case NID_pkcs7_enveloped:
+ case NID_pkcs7_signedAndEnveloped:
+ case NID_pkcs7_encrypted:
+ default:
+ PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ goto err;
+ }
+ return(1);
+err:
+ return(0);
+ }
+
+int PKCS7_add_signer(p7,psi)
+PKCS7 *p7;
+PKCS7_SIGNER_INFO *psi;
+ {
+ int i,j,nid;
+ X509_ALGOR *alg;
+ PKCS7_SIGNED *p7s;
+
+ i=OBJ_obj2nid(p7->type);
+ if (i != NID_pkcs7_signed)
+ {
+ PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
+ return(0);
+ }
+
+ p7s=p7->d.sign;
+
+ nid=OBJ_obj2nid(psi->digest_alg->algorithm);
+
+ /* If the digest is not currently listed, add it */
+ j=0;
+ for (i=0; i<sk_num(p7s->md_algs); i++)
+ {
+ alg=(X509_ALGOR *)sk_value(p7s->md_algs,i);
+ if (OBJ_obj2nid(alg->algorithm) == nid)
+ {
+ j=1;
+ break;
+ }
+ }
+ if (!j) /* we need to add another algorithm */
+ {
+ alg=X509_ALGOR_new();
+ alg->algorithm=OBJ_nid2obj(nid);
+ sk_push(p7s->md_algs,(char *)alg);
+ }
+
+ sk_push(p7s->signer_info,(char *)psi);
+ return(1);
+ }
+
+int PKCS7_add_certificate(p7,x509)
+PKCS7 *p7;
+X509 *x509;
+ {
+ int i;
+
+ i=OBJ_obj2nid(p7->type);
+ if (i != NID_pkcs7_signed)
+ {
+ PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
+ return(0);
+ }
+
+ if (p7->d.sign->cert == NULL)
+ p7->d.sign->cert=sk_new_null();
+ CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
+ sk_push(p7->d.sign->cert,(char *)x509);
+ return(1);
+ }
+
+int PKCS7_add_crl(p7,crl)
+PKCS7 *p7;
+X509_CRL *crl;
+ {
+ int i;
+ i=OBJ_obj2nid(p7->type);
+ if (i != NID_pkcs7_signed)
+ {
+ PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE);
+ return(0);
+ }
+
+ if (p7->d.sign->crl == NULL)
+ p7->d.sign->crl=sk_new_null();
+
+ CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL);
+ sk_push(p7->d.sign->crl,(char *)crl);
+ return(1);
+ }
+
+int PKCS7_SIGNER_INFO_set(p7i,x509,pkey,dgst)
+PKCS7_SIGNER_INFO *p7i;
+X509 *x509;
+EVP_PKEY *pkey;
+EVP_MD *dgst;
+ {
+ /* We now need to add another PKCS7_SIGNER_INFO entry */
+ ASN1_INTEGER_set(p7i->version,1);
+ X509_NAME_set(&p7i->issuer_and_serial->issuer,
+ X509_get_issuer_name(x509));
+
+ /* because ASN1_INTEGER_set is used to set a 'long' we will do
+ * things the ugly way. */
+ ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+ p7i->issuer_and_serial->serial=
+ ASN1_INTEGER_dup(X509_get_serialNumber(x509));
+
+ /* lets keep the pkey around for a while */
+ CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+ p7i->pkey=pkey;
+
+ /* Set the algorithms */
+ p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
+ p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_MD_pkey_type(dgst));
+
+#if 1
+ if (p7i->digest_enc_alg->parameter != NULL)
+ ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
+ if ((p7i->digest_enc_alg->parameter=ASN1_TYPE_new()) == NULL)
+ goto err;
+ p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
+#endif
+
+
+ return(1);
+err:
+ return(0);
+ }
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(p7,x509,pkey,dgst)
+PKCS7 *p7;
+X509 *x509;
+EVP_PKEY *pkey;
+EVP_MD *dgst;
+ {
+ PKCS7_SIGNER_INFO *si;
+
+ if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
+ if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
+ if (!PKCS7_add_signer(p7,si)) goto err;
+ return(si);
+err:
+ return(NULL);
+ }
+
+STACK *PKCS7_get_signer_info(p7)
+PKCS7 *p7;
+ {
+ if (PKCS7_type_is_signed(p7))
+ {
+ return(p7->d.sign->signer_info);
+ }
+ else
+ return(NULL);
+ }
+
+X509 *PKCS7_cert_from_signer_info(p7,si)
+PKCS7 *p7;
+PKCS7_SIGNER_INFO *si;
+ {
+ if (PKCS7_type_is_signed(p7))
+ return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
+ si->issuer_and_serial->issuer,
+ si->issuer_and_serial->serial));
+ else
+ return(NULL);
+ }
+
diff --git a/crypto/pkcs7/pkcs7.err b/crypto/pkcs7/pkcs7.err
new file mode 100644
index 0000000000..500f9b3de4
--- /dev/null
+++ b/crypto/pkcs7/pkcs7.err
@@ -0,0 +1,21 @@
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_PKCS7_ADD_SIGNER 100
+#define PKCS7_F_PKCS7_CTRL 101
+#define PKCS7_F_PKCS7_DATAFINAL 102
+#define PKCS7_F_PKCS7_DATAINIT 103
+#define PKCS7_F_PKCS7_DATAVERIFY 104
+#define PKCS7_F_PKCS7_SET_CONTENT 105
+#define PKCS7_F_PKCS7_SET_TYPE 106
+
+/* Reason codes. */
+#define PKCS7_R_INTERNAL_ERROR 100
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 101
+#define PKCS7_R_SIGNATURE_FAILURE 102
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 103
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 104
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 105
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE 106
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 107
+#define PKCS7_R_WRONG_CONTENT_TYPE 108
diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
new file mode 100644
index 0000000000..061f1f0709
--- /dev/null
+++ b/crypto/pkcs7/pkcs7.h
@@ -0,0 +1,416 @@
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+#define HEADER_PKCS7_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bio.h"
+#include "x509.h"
+
+/*
+Encryption_ID DES-CBC
+Digest_ID MD5
+Digest_Encryption_ID rsaEncryption
+Key_Encryption_ID rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st
+ {
+ X509_NAME *issuer;
+ ASN1_INTEGER *serial;
+ } PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st
+ {
+ ASN1_INTEGER *version; /* version 1 */
+ PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+ X509_ALGOR *digest_alg;
+ STACK /* X509_ATTRIBUTE */ *auth_attr; /* [ 0 ] */
+ X509_ALGOR *digest_enc_alg;
+ ASN1_OCTET_STRING *enc_digest;
+ STACK /* X509_ATTRIBUTE */ *unauth_attr; /* [ 1 ] */
+
+ /* The private key to sign with */
+ EVP_PKEY *pkey;
+ } PKCS7_SIGNER_INFO;
+
+typedef struct pkcs7_recip_info_st
+ {
+ ASN1_INTEGER *version; /* version 0 */
+ PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+ X509_ALGOR *key_enc_algor;
+ ASN1_OCTET_STRING *enc_key;
+ } PKCS7_RECIP_INFO;
+
+typedef struct pkcs7_signed_st
+ {
+ ASN1_INTEGER *version; /* version 1 */
+ STACK /* X509_ALGOR's */ *md_algs; /* md used */
+ struct pkcs7_st *contents;
+ STACK /* X509 */ *cert; /* [ 0 ] */
+ STACK /* X509_CRL */ *crl; /* [ 1 ] */
+ STACK /* PKCS7_SIGNER_INFO */ *signer_info;
+ } PKCS7_SIGNED;
+/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
+ * How about merging the two */
+
+typedef struct pkcs7_enc_content_st
+ {
+ ASN1_OBJECT *content_type;
+ X509_ALGOR *algorithm;
+ ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
+ } PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st
+ {
+ ASN1_INTEGER *version; /* version 0 */
+ STACK /* PKCS7_RECIP_INFO */ *recipientinfo;
+ PKCS7_ENC_CONTENT *enc_data;
+ } PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st
+ {
+ ASN1_INTEGER *version; /* version 1 */
+ STACK /* PKCS7_RECIP_INFO */ *recipientinfo;
+ STACK /* X509_ALGOR's */ *md_algs; /* md used */
+ PKCS7_ENC_CONTENT *enc_data;
+ STACK /* X509 */ *cert; /* [ 0 ] */
+ STACK /* X509_CRL */ *crl; /* [ 1 ] */
+ STACK /* PKCS7_SIGNER_INFO */ *signer_info;
+ } PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st
+ {
+ ASN1_INTEGER *version; /* version 0 */
+ X509_ALGOR *md; /* md used */
+ struct pkcs7_st *contents;
+ ASN1_OCTET_STRING *digest;
+ } PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st
+ {
+ ASN1_INTEGER *version; /* version 0 */
+ PKCS7_ENC_CONTENT *enc_data;
+ } PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st
+ {
+ /* The following is non NULL if it contains ASN1 encoding of
+ * this structure */
+ unsigned char *asn1;
+ long length;
+
+#define PKCS7_S_HEADER 0
+#define PKCS7_S_BODY 1
+#define PKCS7_S_TAIL 2
+ int state; /* used during processing */
+
+ int detached;
+
+ ASN1_OBJECT *type;
+ /* content as defined by the type */
+ /* all encryption/message digests are applied to the 'contents',
+ * leaving out the 'type' field. */
+ union {
+ char *ptr;
+
+ /* NID_pkcs7_data */
+ ASN1_OCTET_STRING *data;
+
+ /* NID_pkcs7_signed */
+ PKCS7_SIGNED *sign;
+
+ /* NID_pkcs7_enveloped */
+ PKCS7_ENVELOPE *enveloped;
+
+ /* NID_pkcs7_signedAndEnveloped */
+ PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+
+ /* NID_pkcs7_digest */
+ PKCS7_DIGEST *digest;
+
+ /* NID_pkcs7_encrypted */
+ PKCS7_ENCRYPT *encrypted;
+ } d;
+ } PKCS7;
+
+#define PKCS7_OP_SET_DETACHED_SIGNATURE 1
+#define PKCS7_OP_GET_DETACHED_SIGNATURE 2
+
+#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+
+#define PKCS7_set_detached(p,v) \
+ PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+#define PKCS7_get_detached(p) \
+ PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+#ifndef NOPROTO
+PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void );
+void PKCS7_ISSUER_AND_SERIAL_free(
+ PKCS7_ISSUER_AND_SERIAL *a);
+int i2d_PKCS7_ISSUER_AND_SERIAL(
+ PKCS7_ISSUER_AND_SERIAL *a,unsigned char **pp);
+PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL(
+ PKCS7_ISSUER_AND_SERIAL **a,
+ unsigned char **pp, long length);
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,EVP_MD *type,
+ unsigned char *md,unsigned int *len);
+
+PKCS7_SIGNER_INFO *PKCS7_SIGNER_INFO_new(void);
+void PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a);
+int i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a,
+ unsigned char **pp);
+PKCS7_SIGNER_INFO *d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a,
+ unsigned char **pp,long length);
+
+PKCS7_RECIP_INFO *PKCS7_RECIP_INFO_new(void);
+void PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a);
+int i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a,
+ unsigned char **pp);
+PKCS7_RECIP_INFO *d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a,
+ unsigned char **pp,long length);
+
+PKCS7_SIGNED *PKCS7_SIGNED_new(void);
+void PKCS7_SIGNED_free(PKCS7_SIGNED *a);
+int i2d_PKCS7_SIGNED(PKCS7_SIGNED *a,
+ unsigned char **pp);
+PKCS7_SIGNED *d2i_PKCS7_SIGNED(PKCS7_SIGNED **a,
+ unsigned char **pp,long length);
+
+PKCS7_ENC_CONTENT *PKCS7_ENC_CONTENT_new(void);
+void PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a);
+int i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a,
+ unsigned char **pp);
+PKCS7_ENC_CONTENT *d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a,
+ unsigned char **pp,long length);
+
+PKCS7_ENVELOPE *PKCS7_ENVELOPE_new(void);
+void PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a);
+int i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a,
+ unsigned char **pp);
+PKCS7_ENVELOPE *d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a,
+ unsigned char **pp,long length);
+
+PKCS7_SIGN_ENVELOPE *PKCS7_SIGN_ENVELOPE_new(void);
+void PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a);
+int i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a,
+ unsigned char **pp);
+PKCS7_SIGN_ENVELOPE *d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a,
+ unsigned char **pp,long length);
+
+PKCS7_DIGEST *PKCS7_DIGEST_new(void);
+void PKCS7_DIGEST_free(PKCS7_DIGEST *a);
+int i2d_PKCS7_DIGEST(PKCS7_DIGEST *a,
+ unsigned char **pp);
+PKCS7_DIGEST *d2i_PKCS7_DIGEST(PKCS7_DIGEST **a,
+ unsigned char **pp,long length);
+
+PKCS7_ENCRYPT *PKCS7_ENCRYPT_new(void);
+void PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a);
+int i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a,
+ unsigned char **pp);
+PKCS7_ENCRYPT *d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a,
+ unsigned char **pp,long length);
+
+PKCS7 *PKCS7_new(void);
+void PKCS7_free(PKCS7 *a);
+void PKCS7_content_free(PKCS7 *a);
+int i2d_PKCS7(PKCS7 *a,
+ unsigned char **pp);
+PKCS7 *d2i_PKCS7(PKCS7 **a,
+ unsigned char **pp,long length);
+
+void ERR_load_PKCS7_strings(void);
+
+#ifndef WIN16
+PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 *p7);
+int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
+#endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 *p7);
+int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+ EVP_MD *dgst);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataSign(PKCS7 *p7, BIO *bio);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+ BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+/*int PKCS7_DataFinal(PKCS7 *p7, BIO *bio); */
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+ EVP_PKEY *pkey, EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+STACK *PKCS7_get_signer_info(PKCS7 *p7);
+
+#else
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new();
+void PKCS7_ISSUER_AND_SERIAL_free();
+int i2d_PKCS7_ISSUER_AND_SERIAL();
+PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL();
+
+int PKCS7_ISSUER_AND_SERIAL_digest();
+
+PKCS7_SIGNER_INFO *PKCS7_SIGNER_INFO_new();
+void PKCS7_SIGNER_INFO_free();
+int i2d_PKCS7_SIGNER_INFO();
+PKCS7_SIGNER_INFO *d2i_PKCS7_SIGNER_INFO();
+PKCS7_RECIP_INFO *PKCS7_RECIP_INFO_new();
+void PKCS7_RECIP_INFO_free();
+int i2d_PKCS7_RECIP_INFO();
+PKCS7_RECIP_INFO *d2i_PKCS7_RECIP_INFO();
+PKCS7_SIGNED *PKCS7_SIGNED_new();
+void PKCS7_SIGNED_free();
+int i2d_PKCS7_SIGNED();
+PKCS7_SIGNED *d2i_PKCS7_SIGNED();
+PKCS7_ENC_CONTENT *PKCS7_ENC_CONTENT_new();
+void PKCS7_ENC_CONTENT_free();
+int i2d_PKCS7_ENC_CONTENT();
+PKCS7_ENC_CONTENT *d2i_PKCS7_ENC_CONTENT();
+PKCS7_ENVELOPE *PKCS7_ENVELOPE_new();
+void PKCS7_ENVELOPE_free();
+int i2d_PKCS7_ENVELOPE();
+PKCS7_ENVELOPE *d2i_PKCS7_ENVELOPE();
+PKCS7_SIGN_ENVELOPE *PKCS7_SIGN_ENVELOPE_new();
+void PKCS7_SIGN_ENVELOPE_free();
+int i2d_PKCS7_SIGN_ENVELOPE();
+PKCS7_SIGN_ENVELOPE *d2i_PKCS7_SIGN_ENVELOPE();
+PKCS7_DIGEST *PKCS7_DIGEST_new();
+void PKCS7_DIGEST_free();
+int i2d_PKCS7_DIGEST();
+PKCS7_DIGEST *d2i_PKCS7_DIGEST();
+PKCS7_ENCRYPT *PKCS7_ENCRYPT_new();
+void PKCS7_ENCRYPT_free();
+int i2d_PKCS7_ENCRYPT();
+PKCS7_ENCRYPT *d2i_PKCS7_ENCRYPT();
+PKCS7 *PKCS7_new();
+void PKCS7_free();
+void PKCS7_content_free();
+int i2d_PKCS7();
+PKCS7 *d2i_PKCS7();
+
+void ERR_load_PKCS7_strings();
+
+#ifndef WIN16
+PKCS7 *d2i_PKCS7_fp();
+int i2d_PKCS7_fp();
+#endif
+PKCS7 *PKCS7_dup();
+PKCS7 *d2i_PKCS7_bio();
+int i2d_PKCS7_bio();
+long PKCS7_ctrl();
+int PKCS7_set_type();
+int PKCS7_set_content();
+int PKCS7_SIGNER_INFO_set();
+int PKCS7_add_signer();
+int PKCS7_add_certificate();
+int PKCS7_add_crl();
+int PKCS7_content_new();
+int PKCS7_dataSign();
+int PKCS7_dataVerify();
+BIO *PKCS7_dataInit();
+PKCS7_SIGNER_INFO *PKCS7_add_signature();
+X509 *PKCS7_cert_from_signer_info();
+STACK *PKCS7_get_signer_info();
+
+#endif
+
+/* BEGIN ERROR CODES */
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_PKCS7_ADD_SIGNER 100
+#define PKCS7_F_PKCS7_CTRL 101
+#define PKCS7_F_PKCS7_DATAFINAL 102
+#define PKCS7_F_PKCS7_DATAINIT 103
+#define PKCS7_F_PKCS7_DATAVERIFY 104
+#define PKCS7_F_PKCS7_SET_CONTENT 105
+#define PKCS7_F_PKCS7_SET_TYPE 106
+
+/* Reason codes. */
+#define PKCS7_R_INTERNAL_ERROR 100
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 101
+#define PKCS7_R_SIGNATURE_FAILURE 102
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 103
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 104
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 105
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE 106
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 107
+#define PKCS7_R_WRONG_CONTENT_TYPE 108
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c
new file mode 100644
index 0000000000..851691da6a
--- /dev/null
+++ b/crypto/pkcs7/pkcs7err.c
@@ -0,0 +1,99 @@
+/* lib/pkcs7/pkcs7_err.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include "err.h"
+#include "pkcs7.h"
+
+/* BEGIN ERROR CODES */
+static ERR_STRING_DATA PKCS7_str_functs[]=
+ {
+{ERR_PACK(0,PKCS7_F_PKCS7_ADD_SIGNER,0), "PKCS7_add_signer"},
+{ERR_PACK(0,PKCS7_F_PKCS7_CTRL,0), "PKCS7_ctrl"},
+{ERR_PACK(0,PKCS7_F_PKCS7_DATAFINAL,0), "PKCS7_DATAFINAL"},
+{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
+{ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"},
+{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
+{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
+{0,NULL},
+ };
+
+static ERR_STRING_DATA PKCS7_str_reasons[]=
+ {
+{PKCS7_R_INTERNAL_ERROR ,"internal error"},
+{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"},
+{PKCS7_R_SIGNATURE_FAILURE ,"signature failure"},
+{PKCS7_R_UNABLE_TO_FIND_CERTIFICATE ,"unable to find certificate"},
+{PKCS7_R_UNABLE_TO_FIND_MEM_BIO ,"unable to find mem bio"},
+{PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST ,"unable to find message digest"},
+{PKCS7_R_UNKNOWN_DIGEST_TYPE ,"unknown digest type"},
+{PKCS7_R_UNSUPPORTED_CONTENT_TYPE ,"unsupported content type"},
+{PKCS7_R_WRONG_CONTENT_TYPE ,"wrong content type"},
+{0,NULL},
+ };
+
+void ERR_load_PKCS7_strings()
+ {
+ static int init=1;
+
+ if (init)
+ {
+ init=0;
+ ERR_load_strings(ERR_LIB_PKCS7,PKCS7_str_functs);
+ ERR_load_strings(ERR_LIB_PKCS7,PKCS7_str_reasons);
+ }
+ }
diff --git a/crypto/pkcs7/server.pem b/crypto/pkcs7/server.pem
new file mode 100644
index 0000000000..750aac2094
--- /dev/null
+++ b/crypto/pkcs7/server.pem
@@ -0,0 +1,24 @@
+issuer= /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
+subject=/C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Server test cert (512 bit)
+-----BEGIN CERTIFICATE-----
+MIIB6TCCAVICAQAwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV
+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD
+VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNOTcwNjA5MTM1NzQ2WhcNOTgwNjA5
+MTM1NzQ2WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG
+A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl
+cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP
+Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//
+Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB4TMR2CvacKE9wAsu9jyCX8YiW
+mgCM+YoP6kt4Zkj2z5IRfm7WrycKsnpnOR+tGeqAjkCeZ6/36o9l91RvPnN1VJ/i
+xQv2df0KFeMr00IkDdTNAdIWqFkSsZTAY2QAdgenb7MB1joejquYzO2DQIO7+wpH
+irObpESxAZLySCmPPg==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD
+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu
+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj
+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz
+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b
+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA
+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU=
+-----END RSA PRIVATE KEY-----
diff --git a/crypto/pkcs7/sign.c b/crypto/pkcs7/sign.c
new file mode 100644
index 0000000000..9400fe30ba
--- /dev/null
+++ b/crypto/pkcs7/sign.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include "bio.h"
+#include "x509.h"
+#include "pem.h"
+
+main(argc,argv)
+int argc;
+char *argv[];
+ {
+ X509 *x509;
+ EVP_PKEY *pkey;
+ PKCS7 *p7;
+ PKCS7 *p7_data;
+ PKCS7_SIGNER_INFO *si;
+ BIO *in;
+ BIO *data,*p7bio;
+ char buf[1024*4];
+ int i,j;
+ int nodetach=0;
+
+ EVP_add_digest(EVP_md2());
+ EVP_add_digest(EVP_md5());
+ EVP_add_digest(EVP_sha1());
+ EVP_add_digest(EVP_mdc2());
+
+ data=BIO_new(BIO_s_file());
+again:
+ if (argc > 1)
+ {
+ if (strcmp(argv[1],"-nd") == 0)
+ {
+ nodetach=1;
+ argv++; argc--;
+ goto again;
+ }
+ if (!BIO_read_filename(data,argv[1]))
+ goto err;
+ }
+ else
+ BIO_set_fp(data,stdin,BIO_NOCLOSE);
+
+ if ((in=BIO_new_file("server.pem","r")) == NULL) goto err;
+ if ((x509=PEM_read_bio_X509(in,NULL,NULL)) == NULL) goto err;
+ BIO_reset(in);
+ if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err;
+ BIO_free(in);
+
+ p7=PKCS7_new();
+ PKCS7_set_type(p7,NID_pkcs7_signed);
+
+ if (PKCS7_add_signature(p7,x509,pkey,EVP_sha1()) == NULL) goto err;
+
+ /* we may want to add more */
+ PKCS7_add_certificate(p7,x509);
+
+ /* Set the content of the signed to 'data' */
+ PKCS7_content_new(p7,NID_pkcs7_data);
+
+ if (!nodetach)
+ PKCS7_set_detached(p7,1);
+
+ if ((p7bio=PKCS7_dataInit(p7,NULL)) == NULL) goto err;
+
+ for (;;)
+ {
+ i=BIO_read(data,buf,sizeof(buf));
+ if (i <= 0) break;
+ BIO_write(p7bio,buf,i);
+ }
+
+ if (!PKCS7_dataSign(p7,p7bio)) goto err;
+ BIO_free(p7bio);
+
+ PEM_write_PKCS7(stdout,p7);
+ PKCS7_free(p7);
+
+ exit(0);
+err:
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ exit(1);
+ }
+
diff --git a/crypto/pkcs7/verify.c b/crypto/pkcs7/verify.c
new file mode 100644
index 0000000000..bce20ee20f
--- /dev/null
+++ b/crypto/pkcs7/verify.c
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include "asn1.h"
+#include "bio.h"
+#include "x509.h"
+#include "pem.h"
+
+int verify_callback(int ok, X509_STORE_CTX *ctx);
+
+BIO *bio_err=NULL;
+
+main(argc,argv)
+int argc;
+char *argv[];
+ {
+ X509 *x509,*x;
+ PKCS7 *p7;
+ PKCS7_SIGNED *s;
+ PKCS7_SIGNER_INFO *si;
+ PKCS7_ISSUER_AND_SERIAL *ias;
+ X509_STORE_CTX cert_ctx;
+ X509_STORE *cert_store=NULL;
+ X509_LOOKUP *lookup=NULL;
+ BIO *data,*detached=NULL,*p7bio=NULL;
+ char buf[1024*4];
+ unsigned char *p,*pp;
+ int i,j,printit=0;
+ STACK *sk;
+
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+ EVP_add_digest(EVP_md2());
+ EVP_add_digest(EVP_md5());
+ EVP_add_digest(EVP_sha1());
+ EVP_add_digest(EVP_mdc2());
+
+ data=BIO_new(BIO_s_file());
+again:
+ pp=NULL;
+ while (argc > 1)
+ {
+ argc--;
+ argv++;
+ if (strcmp(argv[0],"-p") == 0)
+ {
+ printit=1;
+ }
+ else if ((strcmp(argv[0],"-d") == 0) && (argc >= 2))
+ {
+ detached=BIO_new(BIO_s_file());
+ if (!BIO_read_filename(detached,argv[1]))
+ goto err;
+ argc--;
+ argv++;
+ }
+ else
+ {
+ pp=argv[0];
+ if (!BIO_read_filename(data,argv[0]))
+ goto err;
+ }
+ }
+
+ if (pp == NULL)
+ BIO_set_fp(data,stdin,BIO_NOCLOSE);
+
+
+ /* Load the PKCS7 object from a file */
+ if ((p7=PEM_read_bio_PKCS7(data,NULL,NULL)) == NULL) goto err;
+
+ /* This stuff is being setup for certificate verification.
+ * When using SSL, it could be replaced with a
+ * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
+ cert_store=X509_STORE_new();
+ X509_STORE_set_default_paths(cert_store);
+ X509_STORE_load_locations(cert_store,NULL,"../../certs");
+ X509_STORE_set_verify_cb_func(cert_store,verify_callback);
+
+ ERR_clear_errors();
+
+ /* We need to process the data */
+ if (PKCS7_get_detached(p7))
+ {
+ if (detached == NULL)
+ {
+ printf("no data to verify the signature on\n");
+ exit(1);
+ }
+ else
+ p7bio=PKCS7_dataInit(p7,detached);
+ }
+ else
+ {
+ p7bio=PKCS7_dataInit(p7,NULL);
+ }
+
+ /* We now have to 'read' from p7bio to calculate digests etc. */
+ for (;;)
+ {
+ i=BIO_read(p7bio,buf,sizeof(buf));
+ /* print it? */
+ if (i <= 0) break;
+ }
+
+ /* We can now verify signatures */
+ sk=PKCS7_get_signer_info(p7);
+ if (sk == NULL)
+ {
+ printf("there are no signatures on this data\n");
+ exit(1);
+ }
+
+ /* Ok, first we need to, for each subject entry, see if we can verify */
+ for (i=0; i<sk_num(sk); i++)
+ {
+ si=(PKCS7_SIGNER_INFO *)sk_value(sk,i);
+ i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
+ if (i <= 0)
+ goto err;
+ }
+
+ X509_STORE_free(cert_store);
+
+ printf("done\n");
+ exit(0);
+err:
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ exit(1);
+ }
+
+/* should be X509 * but we can just have them as char *. */
+int verify_callback(ok, ctx)
+int ok;
+X509_STORE_CTX *ctx;
+ {
+ char buf[256];
+ X509 *err_cert;
+ int err,depth;
+
+ err_cert=X509_STORE_CTX_get_current_cert(ctx);
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
+ BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
+ if (!ok)
+ {
+ BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
+ X509_verify_cert_error_string(err));
+ if (depth < 6)
+ {
+ ok=1;
+ X509_STORE_CTX_set_error(ctx,X509_V_OK);
+ }
+ else
+ {
+ ok=0;
+ X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
+ }
+ }
+ switch (ctx->error)
+ {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
+ BIO_printf(bio_err,"issuer= %s\n",buf);
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ BIO_printf(bio_err,"notBefore=");
+ ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
+ BIO_printf(bio_err,"\n");
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ BIO_printf(bio_err,"notAfter=");
+ ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
+ BIO_printf(bio_err,"\n");
+ break;
+ }
+ BIO_printf(bio_err,"verify return:%d\n",ok);
+ return(ok);
+ }