Changes concering RFC 3820 (proxy certificates) integration:

 - Enforce that there should be no policy settings when the language
   is one of id-ppl-independent or id-ppl-inheritAll.
 - Add functionality to ssltest.c so that it can process proxy rights
   and check that they are set correctly.  Rights consist of ASCII
   letters, and the condition is a boolean expression that includes
   letters, parenthesis, &, | and ^.
 - Change the proxy certificate configurations so they get proxy
   rights that are understood by ssltest.c.
 - Add a script that tests proxy certificates with SSL operations.

Other changes:

 - Change the copyright end year in mkerr.pl.
 - make update.
diff --git a/crypto/Makefile.ssl b/crypto/Makefile.ssl
index c03bbc4..b22e08e 100644
--- a/crypto/Makefile.ssl
+++ b/crypto/Makefile.ssl
@@ -227,8 +227,8 @@
 mem_dbg.o: mem_dbg.c
 o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
 o_dir.o: LPdir_unix.c o_dir.c o_dir.h
-o_str.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_str.c
-o_str.o: o_str.h
+o_str.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
+o_str.o: o_str.c o_str.h
 o_time.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c
 o_time.o: o_time.h
 tmdiff.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
diff --git a/crypto/comp/Makefile.ssl b/crypto/comp/Makefile.ssl
index 3a4b513..c295008 100644
--- a/crypto/comp/Makefile.ssl
+++ b/crypto/comp/Makefile.ssl
@@ -91,7 +91,8 @@
 c_rle.o: ../../include/openssl/symhacks.h c_rle.c
 c_zlib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 c_zlib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
-c_zlib.o: ../../include/openssl/e_os2.h ../../include/openssl/obj_mac.h
+c_zlib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+c_zlib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
 c_zlib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index cbdd978..ffc07cc 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -994,6 +994,7 @@
 			goto end;
 
 		/* The last error (if any) is still in the error value */
+		ctx->current_issuer=xi;
 		ctx->current_cert=xs;
 		ok=(*cb)(1,ctx);
 		if (!ok) goto end;
diff --git a/crypto/x509v3/v3_pci.c b/crypto/x509v3/v3_pci.c
index 42fb0d7..b32d968 100644
--- a/crypto/x509v3/v3_pci.c
+++ b/crypto/x509v3/v3_pci.c
@@ -273,6 +273,12 @@
 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
 		goto err;
 		}
+	i = OBJ_obj2nid(language);
+	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
+		{
+		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+		goto err;
+		}
 
 	pci = PROXY_CERT_INFO_EXTENSION_new();
 	if (!pci)
diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c
index ac96c3f..e93f50d 100644
--- a/crypto/x509v3/v3err.c
+++ b/crypto/x509v3/v3err.c
@@ -1,6 +1,6 @@
 /* crypto/x509v3/v3err.c */
 /* ====================================================================
- * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -172,6 +172,7 @@
 {X509V3_R_POLICY_PATH_LENGTH             ,"policy path length"},
 {X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED,"policy path length alreadty defined"},
 {X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED,"policy syntax not currently supported"},
+{X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY,"policy when proxy language requires no policy"},
 {X509V3_R_SECTION_NOT_FOUND              ,"section not found"},
 {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS   ,"unable to get issuer details"},
 {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID     ,"unable to get issuer keyid"},
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index c1662e2..1f801eb 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -737,6 +737,7 @@
 #define X509V3_R_POLICY_PATH_LENGTH			 156
 #define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157
 #define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
+#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
 #define X509V3_R_SECTION_NOT_FOUND			 150
 #define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122
 #define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index f0b3c93..1b6b4e9 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -124,6 +124,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <ctype.h>
 
 #define USE_SOCKETS
 #include "e_os.h"
@@ -132,6 +133,7 @@
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/ssl.h>
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
@@ -180,8 +182,14 @@
 static void free_tmp_rsa(void);
 #endif
 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
-#define APP_CALLBACK "Test Callback Argument"
-static char *app_verify_arg = APP_CALLBACK;
+#define APP_CALLBACK_STRING "Test Callback Argument"
+struct app_verify_arg
+	{
+	char *string;
+	int app_verify;
+	char *proxy_auth;
+	char *proxy_cond;
+	};
 
 #ifndef OPENSSL_NO_DH
 static DH *get_dh512(void);
@@ -212,6 +220,8 @@
 	fprintf(stderr,"\n");
 	fprintf(stderr," -server_auth  - check server certificate\n");
 	fprintf(stderr," -client_auth  - do client authentication\n");
+	fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
+	fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
 	fprintf(stderr," -v            - more output\n");
 	fprintf(stderr," -d            - debug output\n");
 	fprintf(stderr," -reuse        - use session-id reuse\n");
@@ -369,7 +379,8 @@
 	int tls1=0,ssl2=0,ssl3=0,ret=1;
 	int client_auth=0;
 	int server_auth=0,i;
-	int app_verify=0;
+	struct app_verify_arg app_verify_arg =
+		{ APP_CALLBACK_STRING, 0, NULL, NULL };
 	char *server_cert=TEST_SERVER_CERT;
 	char *server_key=NULL;
 	char *client_cert=TEST_CLIENT_CERT;
@@ -430,6 +441,16 @@
 			server_auth=1;
 		else if	(strcmp(*argv,"-client_auth") == 0)
 			client_auth=1;
+		else if (strcmp(*argv,"-proxy_auth") == 0)
+			{
+			if (--argc < 1) goto bad;
+			app_verify_arg.proxy_auth= *(++argv);
+			}
+		else if (strcmp(*argv,"-proxy_cond") == 0)
+			{
+			if (--argc < 1) goto bad;
+			app_verify_arg.proxy_cond= *(++argv);
+			}
 		else if	(strcmp(*argv,"-v") == 0)
 			verbose=1;
 		else if	(strcmp(*argv,"-d") == 0)
@@ -554,7 +575,7 @@
 			}
 		else if	(strcmp(*argv,"-app_verify") == 0)
 			{
-			app_verify = 1;
+			app_verify_arg.app_verify = 1;
 			}
 		else
 			{
@@ -765,20 +786,14 @@
 		SSL_CTX_set_verify(s_ctx,
 			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 			verify_callback);
-		if (app_verify) 
-			{
-			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
-			}
+		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
 		}
 	if (server_auth)
 		{
 		BIO_printf(bio_err,"server authentication\n");
 		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
 			verify_callback);
-		if (app_verify) 
-			{
-			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
-			}
+		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
 		}
 	
 	{
@@ -1560,6 +1575,22 @@
 	return(ret);
 	}
 
+static int get_proxy_auth_ex_data_idx(void)
+	{
+	static volatile int idx = -1;
+	if (idx < 0)
+		{
+		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+		if (idx < 0)
+			{
+			idx = X509_STORE_CTX_get_ex_new_index(0,
+				"SSLtest for verify callback", NULL,NULL,NULL);
+			}
+		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+		}
+	return idx;
+	}
+
 static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
 	{
 	char *s,buf[256];
@@ -1569,7 +1600,8 @@
 	if (s != NULL)
 		{
 		if (ok)
-			fprintf(stderr,"depth=%d %s\n",ctx->error_depth,buf);
+			fprintf(stderr,"depth=%d %s\n",
+				ctx->error_depth,buf);
 		else
 			fprintf(stderr,"depth=%d error=%d %s\n",
 				ctx->error_depth,ctx->error,buf);
@@ -1586,25 +1618,440 @@
 			}
 		}
 
+	if (ok == 1)
+		{
+		X509 *xs = ctx->current_cert;
+#if 0
+		X509 *xi = ctx->current_issuer;
+#endif
+
+		if (xs->ex_flags & EXFLAG_PROXY)
+			{
+			unsigned int *letters =
+				X509_STORE_CTX_get_ex_data(ctx,
+					get_proxy_auth_ex_data_idx());
+
+			if (letters)
+				{
+				int found_any = 0;
+				int i;
+				PROXY_CERT_INFO_EXTENSION *pci =
+					X509_get_ext_d2i(xs, NID_proxyCertInfo,
+						NULL, NULL);
+
+				switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
+					{
+				case NID_Independent:
+					/* Completely meaningless in this
+					   program, as there's no way to
+					   grant explicit rights to a
+					   specific PrC.  Basically, using
+					   id-ppl-Independent is the perfect
+					   way to grant no rights at all. */
+					fprintf(stderr, "  Independent proxy certificate");
+					for (i = 0; i < 26; i++)
+						letters[i] = 0;
+					break;
+				case NID_id_ppl_inheritAll:
+					/* This is basically a NOP, we
+					   simply let the current rights
+					   stand as they are. */
+					fprintf(stderr, "  Proxy certificate inherits all");
+					break;
+				default:
+					s = (char *)
+						pci->proxyPolicy->policy->data;
+					i = pci->proxyPolicy->policy->length;
+
+					/* The algorithm works as follows:
+					   it is assumed that previous
+					   iterations or the initial granted
+					   rights has already set some elements
+					   of `letters'.  What we need to do is
+					   to clear those that weren't granted
+					   by the current PrC as well.  The
+					   easiest way to do this is to add 1
+					   to all the elements whose letters
+					   are given with the current policy.
+					   That way, all elements that are set
+					   by the current policy and were
+					   already set by earlier policies and
+					   through the original grant of rights
+					   will get the value 2 or higher.
+					   The last thing to do is to sweep
+					   through `letters' and keep the
+					   elements having the value 2 as set,
+					   and clear all the others. */
+
+					fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
+					while(i-- > 0)
+						{
+						char c = *s++;
+						if (isascii(c) && isalpha(c))
+							{
+							if (islower(c))
+								c = toupper(c);
+							letters[c - 'A']++;
+							}
+						}
+					for (i = 0; i < 26; i++)
+						if (letters[i] < 2)
+							letters[i] = 0;
+						else
+							letters[i] = 1;
+					}
+
+				found_any = 0;
+				fprintf(stderr,
+					", resulting proxy rights = ");
+				for(i = 0; i < 26; i++)
+					if (letters[i])
+						{
+						fprintf(stderr, "%c", i + 'A');
+						found_any = 1;
+						}
+				if (!found_any)
+					fprintf(stderr, "none");
+				fprintf(stderr, "\n");
+
+				PROXY_CERT_INFO_EXTENSION_free(pci);
+				}
+			}
+		}
+
 	return(ok);
 	}
 
+static void process_proxy_debug(int indent, const char *format, ...)
+	{
+	static const char indentation[] =
+		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+		">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
+	char my_format[256];
+	va_list args;
+
+	BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
+		indent, indent, indentation, format);
+
+	va_start(args, format);
+	vfprintf(stderr, my_format, args);
+	va_end(args);
+	}
+/* Priority levels:
+   0	[!]var, ()
+   1	& ^
+   2	|
+*/
+static int process_proxy_cond_adders(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent);
+static int process_proxy_cond_val(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	char c;
+	int ok = 1;
+	int negate = 0;
+
+	while(isspace(*cond))
+		{
+		cond++; (*pos)++;
+		}
+	c = *cond;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_val at position %d: %s\n",
+			*pos, cond);
+
+	while(c == '!')
+		{
+		negate = !negate;
+		cond++; (*pos)++;
+		while(isspace(*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+		}
+
+	if (c == '(')
+		{
+		cond++; (*pos)++;
+		ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
+			indent + 1);
+		cond = *cond_end;
+		if (ok < 0)
+			goto end;
+		while(isspace(*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+		if (c != ')')
+			{
+			fprintf(stderr,
+				"Weird condition character in position %d: "
+				"%c\n", *pos, c);
+			ok = -1;
+			goto end;
+			}
+		cond++; (*pos)++;
+		}
+	else if (isascii(c) && isalpha(c))
+		{
+		if (islower(c))
+			c = toupper(c);
+		ok = letters[c - 'A'];
+		cond++; (*pos)++;
+		}
+	else
+		{
+		fprintf(stderr,
+			"Weird condition character in position %d: "
+			"%c\n", *pos, c);
+		ok = -1;
+		goto end;
+		}
+ end:
+	*cond_end = cond;
+	if (ok >= 0 && negate)
+		ok = !ok;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_val at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	return ok;
+	}
+static int process_proxy_cond_multipliers(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	int ok;
+	char c;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_multipliers at position %d: %s\n",
+			*pos, cond);
+
+	ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
+	cond = *cond_end;
+	if (ok < 0)
+		goto end;
+
+	while(ok >= 0)
+		{
+		while(isspace(*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+
+		switch(c)
+			{
+		case '&':
+		case '^':
+			{
+			int save_ok = ok;
+
+			cond++; (*pos)++;
+			ok = process_proxy_cond_val(letters,
+				cond, cond_end, pos, indent + 1);
+			cond = *cond_end;
+			if (ok < 0)
+				break;
+
+			switch(c)
+				{
+			case '&':
+				ok &= save_ok;
+				break;
+			case '^':
+				ok ^= save_ok;
+				break;
+			default:
+				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+					" STOPPING\n");
+				EXIT(1);
+				}
+			}
+			break;
+		default:
+			goto end;
+			}
+		}
+ end:
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	*cond_end = cond;
+	return ok;
+	}
+static int process_proxy_cond_adders(unsigned int letters[26],
+	const char *cond, const char **cond_end, int *pos, int indent)
+	{
+	int ok;
+	char c;
+
+	if (debug)
+		process_proxy_debug(indent,
+			"Start process_proxy_cond_adders at position %d: %s\n",
+			*pos, cond);
+
+	ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
+		indent + 1);
+	cond = *cond_end;
+	if (ok < 0)
+		goto end;
+
+	while(ok >= 0)
+		{
+		while(isspace(*cond))
+			{
+			cond++; (*pos)++;
+			}
+		c = *cond;
+
+		switch(c)
+			{
+		case '|':
+			{
+			int save_ok = ok;
+
+			cond++; (*pos)++;
+			ok = process_proxy_cond_multipliers(letters,
+				cond, cond_end, pos, indent + 1);
+			cond = *cond_end;
+			if (ok < 0)
+				break;
+
+			switch(c)
+				{
+			case '|':
+				ok |= save_ok;
+				break;
+			default:
+				fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
+					" STOPPING\n");
+				EXIT(1);
+				}
+			}
+			break;
+		default:
+			goto end;
+			}
+		}
+ end:
+	if (debug)
+		process_proxy_debug(indent,
+			"End process_proxy_cond_adders at position %d: %s, returning %d\n",
+			*pos, cond, ok);
+
+	*cond_end = cond;
+	return ok;
+	}
+
+static int process_proxy_cond(unsigned int letters[26],
+	const char *cond, const char **cond_end)
+	{
+	int pos = 1;
+	return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
+	}
+
 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
 	{
-	char *s = NULL,buf[256];
 	int ok=1;
+	struct app_verify_arg *cb_arg = arg;
+	unsigned int letters[26]; /* only used with proxy_auth */
 
-	fprintf(stderr, "In app_verify_callback, allowing cert. ");
-	fprintf(stderr, "Arg is: %s\n", (char *)arg);
-	fprintf(stderr, "Finished printing do we have a context? 0x%x a cert? 0x%x\n",
-			(unsigned int)ctx, (unsigned int)ctx->cert);
-	if (ctx->cert)
-		s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
-	if (s != NULL)
+	if (cb_arg->app_verify)
 		{
+		char *s = NULL,buf[256];
+
+		fprintf(stderr, "In app_verify_callback, allowing cert. ");
+		fprintf(stderr, "Arg is: %s\n", cb_arg->string);
+		fprintf(stderr, "Finished printing do we have a context? 0x%x a cert? 0x%x\n",
+			(unsigned int)ctx, (unsigned int)ctx->cert);
+		if (ctx->cert)
+			s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+		if (s != NULL)
+			{
 			fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+			}
+		return(1);
+		}
+	if (cb_arg->proxy_auth)
+		{
+		int found_any = 0, i;
+		char *sp;
+
+		for(i = 0; i < 26; i++)
+			letters[i] = 0;
+		for(sp = cb_arg->proxy_auth; *sp; sp++)
+			{
+			char c = *sp;
+			if (isascii(c) && isalpha(c))
+				{
+				if (islower(c))
+					c = toupper(c);
+				letters[c - 'A'] = 1;
+				}
+			}
+
+		fprintf(stderr,
+			"  Initial proxy rights = ");
+		for(i = 0; i < 26; i++)
+			if (letters[i])
+				{
+				fprintf(stderr, "%c", i + 'A');
+				found_any = 1;
+				}
+		if (!found_any)
+			fprintf(stderr, "none");
+		fprintf(stderr, "\n");
+
+		X509_STORE_CTX_set_ex_data(ctx,
+			get_proxy_auth_ex_data_idx(),letters);
 		}
 
+#ifndef OPENSSL_NO_X509_VERIFY
+# ifdef OPENSSL_FIPS
+	if(s->version == TLS1_VERSION)
+		FIPS_allow_md5(1);
+# endif
+	ok = X509_verify_cert(ctx);
+# ifdef OPENSSL_FIPS
+	if(s->version == TLS1_VERSION)
+		FIPS_allow_md5(0);
+# endif
+#endif
+
+	if (cb_arg->proxy_auth)
+		{
+		if (ok)
+			{
+			const char *cond_end = NULL;
+
+			ok = process_proxy_cond(letters,
+				cb_arg->proxy_cond, &cond_end);
+
+			if (ok < 0)
+				EXIT(3);
+			if (*cond_end)
+				{
+				fprintf(stderr, "Stopped processing condition before it's end.\n");
+				ok = 0;
+				}
+			if (!ok)
+				fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
+					cb_arg->proxy_cond);
+			else
+				fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
+					cb_arg->proxy_cond);
+			}
+		}
 	return(ok);
 	}
 
diff --git a/test/Makefile.ssl b/test/Makefile.ssl
index b49dec0..8302f43 100644
--- a/test/Makefile.ssl
+++ b/test/Makefile.ssl
@@ -289,8 +289,8 @@
 		intP1.ss intP2.ss
 	@echo "test SSL protocol"
 	@$(SET_SO_PATHS); sh ./testssl keyU.ss certU.ss certCA.ss
-	@$(SET_SO_PATHS); sh ./testssl keyP1.ss certP1.ss intP1.ss
-	@$(SET_SO_PATHS); sh ./testssl keyP2.ss certP2.ss intP2.ss
+	@$(SET_SO_PATHS); sh ./testsslproxy keyP1.ss certP1.ss intP1.ss
+	@$(SET_SO_PATHS); sh ./testsslproxy keyP2.ss certP2.ss intP2.ss
 
 test_ca:
 	@$(SET_SO_PATHS); if ../apps/openssl no-rsa; then \
@@ -1039,20 +1039,21 @@
 shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c
 ssltest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ssltest.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssltest.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-ssltest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssltest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h
-ssltest.o: ../include/openssl/evp.h ../include/openssl/kssl.h
-ssltest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-ssltest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-ssltest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ssltest.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssltest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssltest.c
+ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h
+ssltest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+ssltest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+ssltest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+ssltest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+ssltest.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssltest.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+ssltest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssltest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssltest.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssltest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssltest.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssltest.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssltest.c
diff --git a/test/P1ss.cnf b/test/P1ss.cnf
index 864e4d2..876a0d3 100644
--- a/test/P1ss.cnf
+++ b/test/P1ss.cnf
@@ -34,4 +34,4 @@
 basicConstraints=CA:FALSE
 subjectKeyIdentifier=hash
 authorityKeyIdentifier=keyid,issuer:always
-proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:foo
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB
diff --git a/test/P2ss.cnf b/test/P2ss.cnf
index 04a76cd..373a87e 100644
--- a/test/P2ss.cnf
+++ b/test/P2ss.cnf
@@ -42,4 +42,4 @@
 [ proxy_ext ]
 language=id-ppl-anyLanguage
 pathlen=0
-policy=text:bar
+policy=text:BC
diff --git a/test/testsslproxy b/test/testsslproxy
new file mode 100644
index 0000000..40469f5
--- /dev/null
+++ b/test/testsslproxy
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+echo 'Testing a lot of proxy conditions.'
+echo 'Some of them may turn out being invalid, which is fine.'
+for auth in A B C BC; do
+    for cond in A B C 'A|B&!C'; do
+	sh ./testssl $1 $2 $3 "-proxy_auth $auth -proxy_cond $cond"
+	if [ $? == 3 ]; then exit 1; fi
+    done
+done
diff --git a/util/mkerr.pl b/util/mkerr.pl
index bd4f859..05d0340 100644
--- a/util/mkerr.pl
+++ b/util/mkerr.pl
@@ -262,7 +262,7 @@
 	} else {
 	    push @out,
 "/* ====================================================================\n",
-" * Copyright (c) 2001-2004 The OpenSSL Project.  All rights reserved.\n",
+" * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.\n",
 " *\n",
 " * Redistribution and use in source and binary forms, with or without\n",
 " * modification, are permitted provided that the following conditions\n",
@@ -404,7 +404,7 @@
 	print OUT <<"EOF";
 /* $cfile */
 /* ====================================================================
- * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions