mirror of https://github.com/openssl/openssl.git
				
				
				
			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.
This commit is contained in:
		
							parent
							
								
									fcd5cca418
								
							
						
					
					
						commit
						a7201e9a1b
					
				|  | @ -227,8 +227,8 @@ mem_dbg.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h | ||||||
| mem_dbg.o: mem_dbg.c | mem_dbg.o: mem_dbg.c | ||||||
| o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h | 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_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: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h | ||||||
| o_str.o: o_str.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: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c | ||||||
| o_time.o: o_time.h | o_time.o: o_time.h | ||||||
| tmdiff.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h | tmdiff.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h | ||||||
|  |  | ||||||
|  | @ -91,7 +91,8 @@ c_rle.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h | ||||||
| c_rle.o: ../../include/openssl/symhacks.h c_rle.c | 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/asn1.h ../../include/openssl/bio.h | ||||||
| c_zlib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.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/objects.h ../../include/openssl/opensslconf.h | ||||||
| c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h | c_zlib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h | ||||||
| c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h | c_zlib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h | ||||||
|  |  | ||||||
|  | @ -994,6 +994,7 @@ static int internal_verify(X509_STORE_CTX *ctx) | ||||||
| 			goto end; | 			goto end; | ||||||
| 
 | 
 | ||||||
| 		/* The last error (if any) is still in the error value */ | 		/* The last error (if any) is still in the error value */ | ||||||
|  | 		ctx->current_issuer=xi; | ||||||
| 		ctx->current_cert=xs; | 		ctx->current_cert=xs; | ||||||
| 		ok=(*cb)(1,ctx); | 		ok=(*cb)(1,ctx); | ||||||
| 		if (!ok) goto end; | 		if (!ok) goto end; | ||||||
|  |  | ||||||
|  | @ -273,6 +273,12 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, | ||||||
| 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); | 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); | ||||||
| 		goto err; | 		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(); | 	pci = PROXY_CERT_INFO_EXTENSION_new(); | ||||||
| 	if (!pci) | 	if (!pci) | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /* crypto/x509v3/v3err.c */ | /* 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 |  * Redistribution and use in source and binary forms, with or without | ||||||
|  * modification, are permitted provided that the following conditions |  * modification, are permitted provided that the following conditions | ||||||
|  | @ -172,6 +172,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= | ||||||
| {X509V3_R_POLICY_PATH_LENGTH             ,"policy path length"}, | {X509V3_R_POLICY_PATH_LENGTH             ,"policy path length"}, | ||||||
| {X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED,"policy path length alreadty defined"}, | {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_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_SECTION_NOT_FOUND              ,"section not found"}, | ||||||
| {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS   ,"unable to get issuer details"}, | {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS   ,"unable to get issuer details"}, | ||||||
| {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID     ,"unable to get issuer keyid"}, | {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID     ,"unable to get issuer keyid"}, | ||||||
|  |  | ||||||
|  | @ -737,6 +737,7 @@ void ERR_load_X509V3_strings(void); | ||||||
| #define X509V3_R_POLICY_PATH_LENGTH			 156 | #define X509V3_R_POLICY_PATH_LENGTH			 156 | ||||||
| #define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157 | #define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157 | ||||||
| #define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158 | #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_SECTION_NOT_FOUND			 150 | ||||||
| #define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122 | #define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122 | ||||||
| #define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123 | #define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123 | ||||||
|  |  | ||||||
							
								
								
									
										489
									
								
								ssl/ssltest.c
								
								
								
								
							
							
						
						
									
										489
									
								
								ssl/ssltest.c
								
								
								
								
							|  | @ -124,6 +124,7 @@ | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
|  | #include <ctype.h> | ||||||
| 
 | 
 | ||||||
| #define USE_SOCKETS | #define USE_SOCKETS | ||||||
| #include "e_os.h" | #include "e_os.h" | ||||||
|  | @ -132,6 +133,7 @@ | ||||||
| #include <openssl/crypto.h> | #include <openssl/crypto.h> | ||||||
| #include <openssl/evp.h> | #include <openssl/evp.h> | ||||||
| #include <openssl/x509.h> | #include <openssl/x509.h> | ||||||
|  | #include <openssl/x509v3.h> | ||||||
| #include <openssl/ssl.h> | #include <openssl/ssl.h> | ||||||
| #ifndef OPENSSL_NO_ENGINE | #ifndef OPENSSL_NO_ENGINE | ||||||
| #include <openssl/engine.h> | #include <openssl/engine.h> | ||||||
|  | @ -180,8 +182,14 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength); | ||||||
| static void free_tmp_rsa(void); | static void free_tmp_rsa(void); | ||||||
| #endif | #endif | ||||||
| static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); | static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); | ||||||
| #define APP_CALLBACK "Test Callback Argument" | #define APP_CALLBACK_STRING "Test Callback Argument" | ||||||
| static char *app_verify_arg = APP_CALLBACK; | struct app_verify_arg | ||||||
|  | 	{ | ||||||
|  | 	char *string; | ||||||
|  | 	int app_verify; | ||||||
|  | 	char *proxy_auth; | ||||||
|  | 	char *proxy_cond; | ||||||
|  | 	}; | ||||||
| 
 | 
 | ||||||
| #ifndef OPENSSL_NO_DH | #ifndef OPENSSL_NO_DH | ||||||
| static DH *get_dh512(void); | static DH *get_dh512(void); | ||||||
|  | @ -212,6 +220,8 @@ static void sv_usage(void) | ||||||
| 	fprintf(stderr,"\n"); | 	fprintf(stderr,"\n"); | ||||||
| 	fprintf(stderr," -server_auth  - check server certificate\n"); | 	fprintf(stderr," -server_auth  - check server certificate\n"); | ||||||
| 	fprintf(stderr," -client_auth  - do client authentication\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," -v            - more output\n"); | ||||||
| 	fprintf(stderr," -d            - debug output\n"); | 	fprintf(stderr," -d            - debug output\n"); | ||||||
| 	fprintf(stderr," -reuse        - use session-id reuse\n"); | 	fprintf(stderr," -reuse        - use session-id reuse\n"); | ||||||
|  | @ -369,7 +379,8 @@ int main(int argc, char *argv[]) | ||||||
| 	int tls1=0,ssl2=0,ssl3=0,ret=1; | 	int tls1=0,ssl2=0,ssl3=0,ret=1; | ||||||
| 	int client_auth=0; | 	int client_auth=0; | ||||||
| 	int server_auth=0,i; | 	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_cert=TEST_SERVER_CERT; | ||||||
| 	char *server_key=NULL; | 	char *server_key=NULL; | ||||||
| 	char *client_cert=TEST_CLIENT_CERT; | 	char *client_cert=TEST_CLIENT_CERT; | ||||||
|  | @ -430,6 +441,16 @@ int main(int argc, char *argv[]) | ||||||
| 			server_auth=1; | 			server_auth=1; | ||||||
| 		else if	(strcmp(*argv,"-client_auth") == 0) | 		else if	(strcmp(*argv,"-client_auth") == 0) | ||||||
| 			client_auth=1; | 			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) | 		else if	(strcmp(*argv,"-v") == 0) | ||||||
| 			verbose=1; | 			verbose=1; | ||||||
| 		else if	(strcmp(*argv,"-d") == 0) | 		else if	(strcmp(*argv,"-d") == 0) | ||||||
|  | @ -554,7 +575,7 @@ int main(int argc, char *argv[]) | ||||||
| 			} | 			} | ||||||
| 		else if	(strcmp(*argv,"-app_verify") == 0) | 		else if	(strcmp(*argv,"-app_verify") == 0) | ||||||
| 			{ | 			{ | ||||||
| 			app_verify = 1; | 			app_verify_arg.app_verify = 1; | ||||||
| 			} | 			} | ||||||
| 		else | 		else | ||||||
| 			{ | 			{ | ||||||
|  | @ -765,20 +786,14 @@ bad: | ||||||
| 		SSL_CTX_set_verify(s_ctx, | 		SSL_CTX_set_verify(s_ctx, | ||||||
| 			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, | 			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, | ||||||
| 			verify_callback); | 			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) | 	if (server_auth) | ||||||
| 		{ | 		{ | ||||||
| 		BIO_printf(bio_err,"server authentication\n"); | 		BIO_printf(bio_err,"server authentication\n"); | ||||||
| 		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER, | 		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER, | ||||||
| 			verify_callback); | 			verify_callback); | ||||||
| 		if (app_verify)  | 		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg); | ||||||
| 			{ |  | ||||||
| 			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	 | 	 | ||||||
| 	{ | 	{ | ||||||
|  | @ -1560,6 +1575,22 @@ err: | ||||||
| 	return(ret); | 	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) | static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) | ||||||
| 	{ | 	{ | ||||||
| 	char *s,buf[256]; | 	char *s,buf[256]; | ||||||
|  | @ -1569,7 +1600,8 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) | ||||||
| 	if (s != NULL) | 	if (s != NULL) | ||||||
| 		{ | 		{ | ||||||
| 		if (ok) | 		if (ok) | ||||||
| 			fprintf(stderr,"depth=%d %s\n",ctx->error_depth,buf); | 			fprintf(stderr,"depth=%d %s\n", | ||||||
|  | 				ctx->error_depth,buf); | ||||||
| 		else | 		else | ||||||
| 			fprintf(stderr,"depth=%d error=%d %s\n", | 			fprintf(stderr,"depth=%d error=%d %s\n", | ||||||
| 				ctx->error_depth,ctx->error,buf); | 				ctx->error_depth,ctx->error,buf); | ||||||
|  | @ -1586,25 +1618,440 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 	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); | 	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) | static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) | ||||||
| 	{ | 	{ | ||||||
| 	char *s = NULL,buf[256]; |  | ||||||
| 	int ok=1; | 	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. "); | 	if (cb_arg->app_verify) | ||||||
| 	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) |  | ||||||
| 		{ | 		{ | ||||||
|  | 		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); | 			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); | 	return(ok); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -289,8 +289,8 @@ test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \ | ||||||
| 		intP1.ss intP2.ss | 		intP1.ss intP2.ss | ||||||
| 	@echo "test SSL protocol" | 	@echo "test SSL protocol" | ||||||
| 	@$(SET_SO_PATHS); sh ./testssl keyU.ss certU.ss certCA.ss | 	@$(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 ./testsslproxy keyP1.ss certP1.ss intP1.ss | ||||||
| 	@$(SET_SO_PATHS); sh ./testssl keyP2.ss certP2.ss intP2.ss | 	@$(SET_SO_PATHS); sh ./testsslproxy keyP2.ss certP2.ss intP2.ss | ||||||
| 
 | 
 | ||||||
| test_ca: | test_ca: | ||||||
| 	@$(SET_SO_PATHS); if ../apps/openssl no-rsa; then \
 | 	@$(SET_SO_PATHS); if ../apps/openssl no-rsa; then \
 | ||||||
|  | @ -1039,20 +1039,21 @@ shatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h | ||||||
| shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c | 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: ../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/bn.h ../include/openssl/buffer.h | ||||||
| ssltest.o: ../include/openssl/comp.h ../include/openssl/crypto.h | ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h | ||||||
| ssltest.o: ../include/openssl/dh.h ../include/openssl/dsa.h | ssltest.o: ../include/openssl/crypto.h ../include/openssl/dh.h | ||||||
| ssltest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h | ssltest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h | ||||||
| ssltest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h | ssltest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h | ||||||
| ssltest.o: ../include/openssl/engine.h ../include/openssl/err.h | ssltest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h | ||||||
| ssltest.o: ../include/openssl/evp.h ../include/openssl/kssl.h | ssltest.o: ../include/openssl/err.h ../include/openssl/evp.h | ||||||
| ssltest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h | ssltest.o: ../include/openssl/kssl.h ../include/openssl/lhash.h | ||||||
| ssltest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h | ssltest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h | ||||||
| ssltest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h | ssltest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h | ||||||
| ssltest.o: ../include/openssl/pem.h ../include/openssl/pem2.h | ssltest.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h | ||||||
| ssltest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h | ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h | ||||||
| ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h | ssltest.o: ../include/openssl/rand.h ../include/openssl/rsa.h | ||||||
| ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h | ssltest.o: ../include/openssl/safestack.h ../include/openssl/sha.h | ||||||
| ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h | ssltest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h | ||||||
| ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h | ssltest.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h | ||||||
| ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h | ssltest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h | ||||||
| ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssltest.c | ssltest.o: ../include/openssl/tls1.h ../include/openssl/x509.h | ||||||
|  | ssltest.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssltest.c | ||||||
|  |  | ||||||
|  | @ -34,4 +34,4 @@ organizationName_value          = Dodgy Brothers | ||||||
| basicConstraints=CA:FALSE | basicConstraints=CA:FALSE | ||||||
| subjectKeyIdentifier=hash | subjectKeyIdentifier=hash | ||||||
| authorityKeyIdentifier=keyid,issuer:always | 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 | ||||||
|  |  | ||||||
|  | @ -42,4 +42,4 @@ proxyCertInfo=critical,@proxy_ext | ||||||
| [ proxy_ext ] | [ proxy_ext ] | ||||||
| language=id-ppl-anyLanguage | language=id-ppl-anyLanguage | ||||||
| pathlen=0 | pathlen=0 | ||||||
| policy=text:bar | policy=text:BC | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | @ -262,7 +262,7 @@ foreach $lib (keys %csrc) | ||||||
| 	} else { | 	} else { | ||||||
| 	    push @out, | 	    push @out, | ||||||
| "/* ====================================================================\n", | "/* ====================================================================\n", | ||||||
| " * Copyright (c) 2001-2004 The OpenSSL Project.  All rights reserved.\n", | " * Copyright (c) 2001-2005 The OpenSSL Project.  All rights reserved.\n", | ||||||
| " *\n", | " *\n", | ||||||
| " * Redistribution and use in source and binary forms, with or without\n", | " * Redistribution and use in source and binary forms, with or without\n", | ||||||
| " * modification, are permitted provided that the following conditions\n", | " * modification, are permitted provided that the following conditions\n", | ||||||
|  | @ -404,7 +404,7 @@ EOF | ||||||
| 	print OUT <<"EOF"; | 	print OUT <<"EOF"; | ||||||
| /* $cfile */ | /* $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 |  * Redistribution and use in source and binary forms, with or without | ||||||
|  * modification, are permitted provided that the following conditions |  * modification, are permitted provided that the following conditions | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue