New function PKCS7_signatureVerify to allow the signing certificate to
be explicitly stated with PKCS#7 verify.

Also fix for util/mkerr.pl: if the -nostatic option is being used this will be
for an external library so the autogenerated C file should include the
header file as:
#include "any/path/to/header.h"
rather than the internal library form:
#include <openssl/header.h>
diff --git a/CHANGES b/CHANGES
index 6dddf4a..278eafb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,14 @@
 
  Changes between 0.9.3a and 0.9.4
 
+  *) Add a new function PKCS7_signatureVerify. This allows the verification
+     of a PKCS#7 signature but with the signing certificate passed to the
+     function itself. This contrasts with PKCS7_dataVerify which assumes the
+     certificate is present in the PKCS#7 structure. This isn't always the
+     case: certificates can be omitted from a PKCS#7 structure and be
+     distributed by "out of band" means (such as a certificate database).
+     [Steve Henson]
+
   *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
      function prototypes in pem.h, also change util/mkdef.pl to add the
      necessary function names. 
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 5481036..dee81b5 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -626,18 +626,10 @@
 int PKCS7_dataVerify(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,i;
-	int md_type;
-	STACK_OF(X509_ATTRIBUTE) *sk;
 	STACK_OF(X509) *cert;
-	BIO *btmp;
 	X509 *x509;
-	EVP_PKEY *pkey;
 
 	if (PKCS7_type_is_signed(p7))
 		{
@@ -674,7 +666,30 @@
 		}
 	X509_STORE_CTX_cleanup(ctx);
 
-	/* So we like 'x509', lets check the signature. */
+	return PKCS7_signatureVerify(bio, p7, si, x509);
+	err:
+	return ret;
+	}
+
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509)
+	{
+	ASN1_OCTET_STRING *os;
+	EVP_MD_CTX mdc_tmp,*mdc;
+	unsigned char *pp,*p;
+	int ret=0,i;
+	int md_type;
+	STACK_OF(X509_ATTRIBUTE) *sk;
+	BIO *btmp;
+	EVP_PKEY *pkey;
+
+	if (!PKCS7_type_is_signed(p7) && 
+				!PKCS7_type_is_signedAndEnveloped(p7)) {
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+						PKCS7_R_WRONG_PKCS7_TYPE);
+		goto err;
+	}
+
 	md_type=OBJ_obj2nid(si->digest_alg->algorithm);
 
 	btmp=bio;
@@ -683,13 +698,15 @@
 		if ((btmp == NULL) ||
 			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
 			{
-			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+					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);
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+							PKCS7_R_INTERNAL_ERROR);
 			goto err;
 			}
 		if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type)
@@ -712,7 +729,8 @@
 		message_digest=PKCS7_digest_from_attributes(sk);
 		if (!message_digest)
 			{
-			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
 			goto err;
 			}
 		if ((message_digest->length != (int)md_len) ||
@@ -726,7 +744,8 @@
 for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
 }
 #endif
-			PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_DIGEST_FAILURE);
+			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+							PKCS7_R_DIGEST_FAILURE);
 			ret= -1;
 			goto err;
 			}
@@ -755,7 +774,8 @@
 	EVP_PKEY_free(pkey);
 	if (i <= 0)
 		{
-		PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_SIGNATURE_FAILURE);
+		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+						PKCS7_R_SIGNATURE_FAILURE);
 		ret= -1;
 		goto err;
 		}
diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
index c1414ed..859718e 100644
--- a/crypto/pkcs7/pkcs7.h
+++ b/crypto/pkcs7/pkcs7.h
@@ -333,6 +333,8 @@
 int PKCS7_content_new(PKCS7 *p7, int nid);
 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
 	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509);
 
 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
@@ -383,6 +385,7 @@
 #define PKCS7_F_PKCS7_SET_CIPHER			 108
 #define PKCS7_F_PKCS7_SET_CONTENT			 109
 #define PKCS7_F_PKCS7_SET_TYPE				 110
+#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
 
 /* Reason codes. */
 #define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c
index 99e4a44..82be3c2 100644
--- a/crypto/pkcs7/pkcs7err.c
+++ b/crypto/pkcs7/pkcs7err.c
@@ -77,6 +77,7 @@
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0),	"PKCS7_set_cipher"},
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0),	"PKCS7_set_content"},
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0),	"PKCS7_set_type"},
+{ERR_PACK(0,PKCS7_F_PKCS7_SIGNATUREVERIFY,0),	"PKCS7_signatureVerify"},
 {0,NULL}
 	};
 
diff --git a/util/libeay.num b/util/libeay.num
index 36c0cd4..4c49be6 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1817,3 +1817,4 @@
 sk_ASN1_OBJECT_insert                   1842
 sk_ASN1_OBJECT_push                     1843
 d2i_ASN1_SET_OF_ASN1_OBJECT             1844
+PKCS7_signatureVerify                   1845
diff --git a/util/mkerr.pl b/util/mkerr.pl
index 60a3028..4b3bccb 100644
--- a/util/mkerr.pl
+++ b/util/mkerr.pl
@@ -284,8 +284,14 @@
 
 	# Rewrite the C source file containing the error details.
 
-	$hfile =~ /([^\/]+)$/;
-	my $hincf = $1;
+	my $hincf;
+	if($static) {
+		$hfile =~ /([^\/]+)$/;
+		$hincf = "<openssl/$1>";
+	} else {
+		$hincf = "\"$hfile\"";
+	}
+
 
 	open (OUT,">$cfile") || die "Can't open $cfile for writing";
 
@@ -351,7 +357,7 @@
 
 #include <stdio.h>
 #include <openssl/err.h>
-#include <openssl/$hincf>
+#include $hincf
 
 /* BEGIN ERROR CODES */
 #ifndef NO_ERR