diff -Nacr openssl-0.9.4.orig/apps/Makefile.ssl openssl-0.9.4/apps/Makefile.ssl
*** openssl-0.9.4.orig/apps/Makefile.ssl	Mon Jun 21 06:04:37 1999
--- openssl-0.9.4/apps/Makefile.ssl	Wed Jan 12 13:40:23 2000
***************
*** 5,11 ****
  DIR=		apps
  TOP=		..
  CC=		cc
! INCLUDES=	-I../include
  CFLAG=		-g -static
  INSTALL_PREFIX=
  INSTALLTOP=	/usr/local/ssl
--- 5,11 ----
  DIR=		apps
  TOP=		..
  CC=		cc
! INCLUDES=	-I../include -I /usr/local/krb5/include
  CFLAG=		-g -static
  INSTALL_PREFIX=
  INSTALLTOP=	/usr/local/ssl
***************
*** 24,31 ****
  
  DLIBCRYPTO=../libcrypto.a
  DLIBSSL=../libssl.a
! LIBCRYPTO=-L.. -lcrypto
! LIBSSL=-L.. -lssl
  
  PROGRAM= openssl
  
--- 24,36 ----
  
  DLIBCRYPTO=../libcrypto.a
  DLIBSSL=../libssl.a
! # LIBCRYPTO=-L.. -lcrypto
! # LIBSSL=-L.. -lssl
! LIBCRYPTO=../libcrypto.a
! LIBSSL=../libssl.a
! LIBKRB5=-L /usr/local/krb5/lib -lgssapi_krb5 -lkrb5 -lcom_err /usr/local/krb5/lib/libcrypto.a  -lresolv
! # MALLOC_LIBS= ./libefence.a
! MALLOC_LIBS=
  
  PROGRAM= openssl
  
***************
*** 135,141 ****
  
  $(PROGRAM): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
  	$(RM) $(PROGRAM)
! 	$(CC) -o $(PROGRAM) $(CFLAGS) $(PROGRAM).o $(E_OBJ) $(PEX_LIBS) $(LIBSSL) $(LIBCRYPTO) $(EX_LIBS)
  	@(cd ..; OPENSSL="`pwd`/apps/openssl"; export OPENSSL; sh tools/c_rehash certs)
  
  progs.h:
--- 140,146 ----
  
  $(PROGRAM): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL)
  	$(RM) $(PROGRAM)
! 	$(CC) -o $(PROGRAM) $(CFLAGS) $(PROGRAM).o $(E_OBJ) $(MALLOC_LIBS) $(PEX_LIBS) $(LIBSSL) $(LIBKRB5) $(LIBCRYPTO) $(EX_LIBS)
  	@(cd ..; OPENSSL="`pwd`/apps/openssl"; export OPENSSL; sh tools/c_rehash certs)
  
  progs.h:
diff -Nacr openssl-0.9.4.orig/apps/s_client.c openssl-0.9.4/apps/s_client.c
*** openssl-0.9.4.orig/apps/s_client.c	Sun Aug  8 10:21:04 1999
--- openssl-0.9.4/apps/s_client.c	Wed Jan 12 13:40:24 2000
***************
*** 373,378 ****
--- 373,383 ----
  	SSL_load_error_strings();
  
  	con=(SSL *)SSL_new(ctx);
+ #ifndef NO_KRB5
+ 	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)  {
+ 		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
+ 		}
+ #endif    /* NO_KRB5  */
  /*	SSL_set_cipher_list(con,"RC4-MD5"); */
  
  re_start:
diff -Nacr openssl-0.9.4.orig/apps/s_server.c openssl-0.9.4/apps/s_server.c
*** openssl-0.9.4.orig/apps/s_server.c	Sun Aug  8 10:21:04 1999
--- openssl-0.9.4/apps/s_server.c	Wed Jan 12 13:40:24 2000
***************
*** 770,775 ****
--- 770,781 ----
  
  	if (con == NULL) {
  		con=(SSL *)SSL_new(ctx);
+ #ifndef NO_KRB5
+ 		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)  {
+ 			kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
+ 			kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
+ 			}
+ #endif	/* NO_KRB5 */
  		if(context)
  		      SSL_set_session_id_context(con, context,
  						 strlen((char *)context));
***************
*** 1127,1132 ****
--- 1133,1144 ----
  	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
  
  	if ((con=(SSL *)SSL_new(ctx)) == NULL) goto err;
+ #ifndef NO_KRB5
+ 	if ((con->kssl_ctx = kssl_ctx_new()) != NULL)  {
+ 		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
+ 		kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
+ 		}
+ #endif	/* NO_KRB5 */
  	if(context) SSL_set_session_id_context(con, context,
  					       strlen((char *)context));
  
diff -Nacr openssl-0.9.4.orig/crypto/evp/e_cbc_3d.c openssl-0.9.4/crypto/evp/e_cbc_3d.c
*** openssl-0.9.4.orig/crypto/evp/e_cbc_3d.c	Sun May 16 08:26:10 1999
--- openssl-0.9.4/crypto/evp/e_cbc_3d.c	Wed Jan 12 13:40:24 2000
***************
*** 127,132 ****
--- 127,138 ----
  	     unsigned char *iv, int enc)
  	{
  	des_cblock *deskey = (des_cblock *)key;
+ #ifdef KSSL_DEBUG
+ 	{ int i;  printf("des_cbc_ede3_init_key(ctx=%lx)\n", ctx);
+ 	printf("\tKEY= "); for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
+ 	printf("\t IV= "); for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
+ 	}
+ #endif    /* KSSL_DEBUG */
  
  	if (iv != NULL)
  		memcpy(&(ctx->oiv[0]),iv,8);
***************
*** 143,148 ****
--- 149,163 ----
  static void des_cbc_ede_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
  	     unsigned char *in, unsigned int inl)
  	{
+ #ifdef KSSL_DEBUG
+ 	{ int i; char *cp;
+ 	printf("des_cbc_ede_cipher(ctx=%lx, buflen=%d)\n",
+ 	ctx, ctx->buf_len);
+ 	printf("\t iv= "); for(i=0;i<8;i++) printf("%02X",ctx->iv[i]);
+ 	printf("\n");
+ 	}
+ #endif    /* KSSL_DEBUG */
+ 
  	des_ede3_cbc_encrypt(in,out,inl, ctx->c.des_ede.ks1,
  		ctx->c.des_ede.ks2,ctx->c.des_ede.ks3,
  		(des_cblock *) &(ctx->iv[0]),
diff -Nacr openssl-0.9.4.orig/ssl/Makefile.ssl openssl-0.9.4/ssl/Makefile.ssl
*** openssl-0.9.4.orig/ssl/Makefile.ssl	Fri May 21 07:16:45 1999
--- openssl-0.9.4/ssl/Makefile.ssl	Wed Jan 12 13:40:24 2000
***************
*** 5,11 ****
  DIR=	ssl
  TOP=	..
  CC=	cc
! INCLUDES= -I../crypto -I../include
  CFLAG=-g
  INSTALL_PREFIX=
  OPENSSLDIR=     /usr/local/ssl
--- 5,11 ----
  DIR=	ssl
  TOP=	..
  CC=	cc
! INCLUDES= -I../crypto -I../include  -I. -I/usr/local/krb5/include
  CFLAG=-g
  INSTALL_PREFIX=
  OPENSSLDIR=     /usr/local/ssl
***************
*** 30,36 ****
  	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
  	ssl_ciph.c ssl_stat.c ssl_rsa.c \
  	ssl_asn1.c ssl_txt.c ssl_algs.c \
! 	bio_ssl.c ssl_err.c
  LIBOBJ= \
  	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
  	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
--- 30,36 ----
  	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
  	ssl_ciph.c ssl_stat.c ssl_rsa.c \
  	ssl_asn1.c ssl_txt.c ssl_algs.c \
! 	bio_ssl.c ssl_err.c  kssl.c
  LIBOBJ= \
  	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
  	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
***************
*** 39,49 ****
  	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
  	ssl_ciph.o ssl_stat.o ssl_rsa.o \
  	ssl_asn1.o ssl_txt.o ssl_algs.o \
! 	bio_ssl.o ssl_err.o
  
  SRC= $(LIBSRC)
  
! EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h
  HEADER=	$(EXHEADER) ssl_locl.h
  
  ALL=    $(GENERAL) $(SRC) $(HEADER)
--- 39,49 ----
  	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
  	ssl_ciph.o ssl_stat.o ssl_rsa.o \
  	ssl_asn1.o ssl_txt.o ssl_algs.o \
! 	bio_ssl.o ssl_err.o  kssl.o
  
  SRC= $(LIBSRC)
  
! EXHEADER= ssl.h ssl2.h ssl3.h ssl23.h tls1.h  kssl.h
  HEADER=	$(EXHEADER) ssl_locl.h
  
  ALL=    $(GENERAL) $(SRC) $(HEADER)
diff -Nacr openssl-0.9.4.orig/ssl/kssl.c openssl-0.9.4/ssl/kssl.c
*** openssl-0.9.4.orig/ssl/kssl.c	Wed Dec 31 19:00:00 1969
--- openssl-0.9.4/ssl/kssl.c	Wed Jan 12 13:40:24 2000
***************
*** 0 ****
--- 1,474 ----
+ /*	ssl/kssl.c  --  Routines to support (& debug) Kerberos5 auth for openssl
+ **
+ **	19990701	VRS 	Started.
+ */
+ 
+ #ifndef NO_KRB5
+ 
+ #include <string.h>
+ #include "ssl.h"
+ 
+ 
+ char 	*kstring(char *string)
+ {
+ 	static char	*null = "[NULL]";
+ 
+ 	return ((string == NULL)? null: string);
+ }
+ 
+ #define	MAXKNUM	255
+ char 	*knumber(int len, krb5_octet *contents)
+ {
+ 	static char	buf[MAXKNUM+1];
+ 	int 		i;
+ 
+ 	snprintf(buf, MAXKNUM, "[%d] ", len);
+ 
+ 	for (i=0; i < len  &&  MAXKNUM > strlen(buf)+3; i++)  {
+ 		snprintf(&buf[strlen(buf)], 3, "%02x", contents[i]);
+ 		}
+ 	
+ 	return (buf);
+ }
+ 
+ 
+ /*	Set kssl_err error info when reason text is a simple string
+ **		kssl_err = struct { int reason; char text[KSSL_ERR_MAX+1]; }
+ */
+ void 	kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text)
+ {
+ 	if (kssl_err == NULL)  return;
+ 
+ 	kssl_err->reason = reason;
+ 	snprintf(kssl_err->text, KSSL_ERR_MAX, text);
+ 	return;
+ }
+ 
+ 
+ /*	Display contents of krb5_data struct, for debugging
+ */
+ void	print_krb5_data(char *label, krb5_data *kdata)
+ {
+ 	int 	i;
+ 
+ 	printf("%s[%d] ", label, kdata->length);
+ 	for (i=0; i < kdata->length; i++)  {
+ 		if (isprint((int) kdata->data[i])) 
+ 				printf(	"%c ",  kdata->data[i]);
+ 		else	printf(	"%02x", kdata->data[i]);
+ 		}
+ 	printf("\n");
+ }
+ 
+ 
+ /*	Display contents of krb5_authdata struct, for debugging
+ */
+ void	print_krb5_authdata(char *label, krb5_authdata **adata)
+ {
+ 	if (adata == NULL)  {
+ 		printf("%s, authdata==0\n", label);
+ 		return;
+ 		}
+ 	printf("%s [%p]\n", label, adata);
+ 	/*
+ 	{ int 	i;
+ 	printf("%s[at%d:%d] ", label, adata->ad_type, adata->length);
+ 	for (i=0; i < adata->length; i++)  {
+ 		printf((isprint(adata->contents[i]))? "%c ": "%02x",adata->contents[i]);
+ 		}
+ 	printf("\n");
+ 	}
+ 	*/
+ }
+ 
+ 
+ /*	Display contents of krb5_keyblock struct, for debugging
+ */
+ void	print_krb5_keyblock(char *label, krb5_keyblock *keyblk)
+ {
+ 	int 	i;
+ 
+ 	if (keyblk == NULL)  {
+ 		printf("%s, keyblk==0\n", label);
+ 		return;
+ 		}
+ 	printf("%s\n\t[et%d:%d]: ", label, keyblk->enctype, keyblk->length);
+ 	for (i=0; i < keyblk->length; i++)  {
+ 		printf("%02x",keyblk->contents[i]);
+ 		}
+ 	printf("\n");
+ }
+ 
+ 
+ /*	Given krb5 service (typically "kssl") and hostname in kssl_ctx,
+ **	Create Kerberos AP_REQ message for SSL Client.
+ **
+ **	19990628	VRS 	Started.
+ */
+ krb5_error_code
+ kssl_cget_tkt(	/* UPDATE */	KSSL_CTX *kssl_ctx,
+ 				/* OUT    */	krb5_data *krb5_app_req, KSSL_ERR *kssl_err)
+ {
+ 	krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
+ 	krb5_context		krb5context = NULL;
+ 	krb5_auth_context	krb5auth_context = NULL;
+ 	krb5_ccache 		krb5ccdef = NULL;
+ 	krb5_creds			krb5creds, *krb5credsp = NULL;
+ 	krb5_data			krb5in_data;
+ 
+ 	kssl_err_set(kssl_err, 0, "");
+ 	memset((char *)&krb5creds, 0, sizeof(krb5creds));
+ 
+ 	if (!kssl_ctx)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n");
+ 		goto err;
+ 		}
+ 	else if (!kssl_ctx->service_host)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+ 				"kssl_ctx service_host undefined.\n");
+ 		goto err;
+ 		}
+ 
+ 	if ((krb5rc = krb5_init_context(&krb5context)) != 0)  {
+ 		snprintf(kssl_err->text,KSSL_ERR_MAX,
+ 				"krb5_init_context() fails: %d\n", krb5rc);
+ 		kssl_err->reason = SSL_R_KRB5_C_INIT;
+ 		goto err;
+ 		}
+ 
+ 	if ((krb5rc = krb5_sname_to_principal(krb5context, kssl_ctx->service_host,
+ 					(kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+ 					KRB5_NT_SRV_HST, &krb5creds.server)) != 0)  {
+ 		snprintf(kssl_err->text,KSSL_ERR_MAX,
+ 					"krb5_sname_to_principal() fails for %s/%s\n",
+ 					kssl_ctx->service_host,
+ 					(kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC);
+ 		kssl_err->reason = SSL_R_KRB5_C_INIT;
+ 		goto err;
+ 		}
+ 	
+ 	if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+ 					"krb5_cc_default fails.\n");
+ 		goto err;
+ 		}
+ 	
+ 	if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
+ 										&krb5creds.client)) != 0)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
+ 					"krb5_cc_get_principal() fails.\n");
+ 		goto err;
+ 		}
+ 
+ 	if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
+ 										&krb5creds, &krb5credsp)) != 0)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
+ 					"krb5_get_credentials() fails.\n");
+ 		goto err;
+ 		}
+ 
+ 	krb5in_data.data = NULL;
+ 	krb5in_data.length = 0;
+ 
+ 	krb5rc = KRB5KRB_ERR_GENERIC;
+ 	/*	caller should free data of krb5_app_req  */
+     if ((krb5rc = krb5_mk_req_extended(krb5context, &krb5auth_context,
+ 						0, &krb5in_data, krb5credsp, krb5_app_req)) != 0)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
+ 					"krb5_mk_req_extended() fails.\n");
+ 		goto err;
+ 		}
+ 	else if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, "kssl_ctx_setkey() fails.\n");
+ 		}
+ 	else	krb5rc = 0;
+ 
+ err:
+ #ifdef KSSL_DEBUG
+ 	kssl_ctx_show(kssl_ctx);
+ #endif	/* KSSL_DEBUG */
+ 
+ 	if (krb5creds.client)	krb5_free_principal(krb5context, krb5creds.client);
+ 	if (krb5creds.server)	krb5_free_principal(krb5context, krb5creds.server);
+ 	if (krb5auth_context)	krb5_auth_con_free(krb5context, krb5auth_context);
+ 	if (krb5context)	 	krb5_free_context(krb5context);
+ 	return (krb5rc);
+ }
+ 
+ 
+ /*	Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"),
+ **		and krb5 AP_REQ message & message length,
+ **	Return Kerberos session key and client principle 
+ **		to SSL Server in KSSL_CTX *kssl_ctx.
+ **
+ **	19990702	VRS 	Started.
+ */
+ krb5_error_code
+ kssl_sget_tkt(	/* UPDATE */	KSSL_CTX *kssl_ctx,
+ 				/* IN     */	char *msg, int msglen,
+ 				/* OUT    */	KSSL_ERR *kssl_err  )
+ {
+ 	krb5_error_code				krb5rc = KRB5KRB_ERR_GENERIC;
+ 	static krb5_context			krb5context = NULL;
+ 	static krb5_auth_context	krb5auth_context = NULL;
+ 	krb5_ticket 				*krb5ticket = NULL;
+ 	krb5_keytab 				krb5keytab = NULL;
+ 	krb5_principal				krb5server;
+ 	krb5_data					krb5in_data;
+ 	krb5_flags					ap_option;
+ 
+ 	kssl_err_set(kssl_err, 0, "");
+ 
+ 	if (!kssl_ctx)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n");
+ 		goto err;
+ 		}
+ 
+ #ifdef KSSL_DEBUG
+ 	printf("in kssl_sget_tkt(%s)\n", kstring(kssl_ctx->service_name));
+ #endif	/* KSSL_DEBUG */
+ 
+ 	if (!krb5context  &&  (krb5rc = krb5_init_context(&krb5context)))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+ 					"krb5_init_context() fails.\n");
+ 		goto err;
+ 		}
+ 	if (krb5auth_context  &&
+ 		(krb5rc = krb5_auth_con_free(krb5context, krb5auth_context)))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+ 					"krb5_auth_con_free() fails.\n");
+ 		goto err;
+ 		}
+ 	else  krb5auth_context = NULL;
+ 	if (!krb5auth_context  &&
+ 		(krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context)))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+ 					"krb5_auth_con_init() fails.\n");
+ 		goto err;
+ 		}
+ 
+ 	if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, 
+ 					(kssl_ctx->service_name)? kssl_ctx->service_name: KRB5SVC,
+ 					KRB5_NT_SRV_HST, &krb5server)) != 0)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
+ 					"krb5_sname_to_principal() fails.\n");
+ 		goto err;
+ 		}
+ 	
+ 	if (kssl_ctx->keytab_file  &&
+ 		((krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
+ 														&krb5keytab))))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "krb5_kt_resolve() fails.\n");
+ 		goto err;
+ 		}
+ 	/*	kssl_ctx->keytab_file == NULL ==> use Kerberos default /etc/krb5.keytab
+ 	*/
+ 
+ 	/*	Actual Kerberos5 krb5_recvauth() has initial conversation here
+ 	**	o	check KRB5_SENDAUTH_BADAUTHVERS unless KRB5_RECVAUTH_SKIP_VERSION
+ 	**	o	check KRB5_SENDAUTH_BADAPPLVERS
+ 	**	o	send "0" msg if all OK
+ 	*/
+ 
+ 	krb5in_data.data = msg;
+ 	krb5in_data.length = msglen;
+ 	if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, &krb5in_data,
+ 							  krb5server, krb5keytab, &ap_option, &krb5ticket))
+ 							  != 0)  {
+ 		snprintf(kssl_err->text, KSSL_ERR_MAX,
+ 								"krb5_rd_req() fails with %x.\n", krb5rc);
+ 		kssl_err->reason = SSL_R_KRB5_S_RD_REQ;
+ 		goto err;
+ 		}
+ 
+ 	krb5rc = KRB5_NO_TKT_SUPPLIED;
+ 	if (!krb5ticket  ||	!krb5ticket->enc_part2  ||
+ 						!krb5ticket->enc_part2->client  || 
+ 						!krb5ticket->enc_part2->client->data  || 
+ 						!krb5ticket->enc_part2->session)  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+ 								"bad ticket from krb5_rd_req.\n");
+ 		}
+ 	else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT,
+ 								&krb5ticket->enc_part2->client->realm,
+ 								krb5ticket->enc_part2->client->data))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+ 								"kssl_ctx_setprinc() fails.\n");
+ 		}
+ 	else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session))  {
+ 		kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET,
+ 								"kssl_ctx_setkey() fails.\n");
+ 		}
+ 	else	krb5rc = 0;
+ 
+ err:
+ #ifdef KSSL_DEBUG
+ 	kssl_ctx_show(kssl_ctx);
+ #endif	/* KSSL_DEBUG */
+ 
+ 	if (krb5ticket) 		krb5_free_ticket(krb5context, krb5ticket);
+ 	if (krb5server) 		krb5_free_principal(krb5context, krb5server);
+ 	return (krb5rc);
+ }
+ 
+ 
+ /*	Allocate & return a new kssl_ctx struct.
+ */
+ KSSL_CTX	*kssl_ctx_new(void)
+ {
+ 	return ((KSSL_CTX *) calloc(1, sizeof(KSSL_CTX)));
+ }
+ 
+ 
+ /*	Frees a kssl_ctx struct and any allocated memory it holds.
+ **	Returns NULL.
+ */
+ KSSL_CTX	*kssl_ctx_free(KSSL_CTX *kssl_ctx)
+ {
+ 	if (kssl_ctx == NULL)  return kssl_ctx;
+ 
+ 	if (kssl_ctx->key)  			memset(kssl_ctx->key, 0, kssl_ctx->length);
+ 	if (kssl_ctx->key)  			free(kssl_ctx->key);
+ 	if (kssl_ctx->client_princ) 	free(kssl_ctx->client_princ);
+ 	if (kssl_ctx->service_host) 	free(kssl_ctx->service_host);
+ 	if (kssl_ctx->service_name) 	free(kssl_ctx->service_name);
+ 	if (kssl_ctx->keytab_file) 		free(kssl_ctx->keytab_file);
+ 
+ 	free(kssl_ctx);
+ 	return (KSSL_CTX *) NULL;
+ }
+ 
+ 
+ /*	Given a (krb5_data *) entity (and optional realm),
+ **	set the plain (char *) client_princ or service_host member
+ **	of the kssl_ctx struct.
+ */
+ krb5_error_code
+ kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,	krb5_data *realm,
+ 													krb5_data *entity)
+ {
+ 	char	**princ;
+ 	int 	length;
+ 
+ 	if (kssl_ctx == NULL  ||  entity == NULL)  return KSSL_CTX_ERR;
+ 
+ 	switch (which)  {
+ 		case KSSL_CLIENT:	princ = &kssl_ctx->client_princ;	break;
+ 		case KSSL_SERVER:	princ = &kssl_ctx->service_host;	break;
+ 		default:			return KSSL_CTX_ERR;				break;
+ 		}
+ 	if (*princ)  free(*princ);
+ 
+ 	length = entity->length + ((realm)? realm->length + 2: 1);
+ 	if ((*princ = calloc(1, length)) == NULL)	return KSSL_CTX_ERR;
+ 	else  {
+ 		strncpy(*princ, entity->data, entity->length);
+ 		if (realm)  {
+ 			strcat (*princ, "@");
+ 			(void) strncat(*princ, realm->data, realm->length);
+ 			}
+ 		}
+ 
+ 	return KSSL_CTX_OK;
+ }
+ 
+ 
+ /*	Set one of the plain (char *) string members of the kssl_ctx struct.
+ **	Default values should be:
+ **		which == KSSL_SERVICE	=>	"kssl" (KRB5SVC)
+ **		which == KSSL_KEYTAB	=>	"/etc/krb5.keytab.kssl" (KRB5KEYTAB)
+ */
+ krb5_error_code
+ kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text)
+ {
+ 	char	**string;
+ 
+ 	if (!kssl_ctx)  return KSSL_CTX_ERR;
+ 
+ 	switch (which)  {
+ 		case KSSL_SERVICE:	string = &kssl_ctx->service_name;	break;
+ 		case KSSL_SERVER:	string = &kssl_ctx->service_host;	break;
+ 		case KSSL_CLIENT:	string = &kssl_ctx->client_princ;	break;
+ 		case KSSL_KEYTAB:	string = &kssl_ctx->keytab_file;	break;
+ 		default:			return KSSL_CTX_ERR;				break;
+ 		}
+ 	if (*string)  free(*string);
+ 
+ 	if (!text)  {
+ 		*string = '\0';
+ 		return KSSL_CTX_OK;
+ 		}
+ 
+ 	if ((*string = calloc(1, strlen(text) + 1)) == NULL)  return KSSL_CTX_ERR;
+ 	else	strcpy(*string, text);
+ 
+ 	return KSSL_CTX_OK;
+ }
+ 
+ 
+ /*	Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx
+ **	struct.  Clear kssl_ctx->key if Kerberos session key is NULL.
+ */
+ krb5_error_code
+ kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session)
+ {
+ 	if (!kssl_ctx)  return KSSL_CTX_ERR;
+ 
+ 	if (kssl_ctx->key)  {
+ 		memset(kssl_ctx->key, 0, kssl_ctx->length);
+ 		free(kssl_ctx->key);
+ 		}
+ 
+ 	if (session)  {
+ 		kssl_ctx->enctype = session->enctype;
+ 		kssl_ctx->length  = session->length;
+ 		}
+ 	else  {
+ 		kssl_ctx->enctype = ENCTYPE_UNKNOWN;
+ 		kssl_ctx->length  = 0;
+ 		return KSSL_CTX_OK;
+ 		}
+ 
+ 	if ((kssl_ctx->key =
+ 			(krb5_octet FAR *) calloc(1, kssl_ctx->length)) == NULL)  {
+ 		kssl_ctx->length  = 0;
+ 		return KSSL_CTX_ERR;
+ 		}
+ 	else	memcpy(kssl_ctx->key, session->contents, session->length);
+ 	
+ 	return KSSL_CTX_OK;
+ }
+ 
+ 
+ /*	Display contents of kssl_ctx struct
+ */
+ void 	kssl_ctx_show(KSSL_CTX *kssl_ctx)
+ {
+ 	int 	i;
+ 
+ 	printf("kssl_ctx: ");
+ 	if (kssl_ctx == NULL)  {
+ 		printf("NULL\n");
+ 		return;
+ 		}
+ 	else	printf("%p\n", kssl_ctx);
+ 
+ 	printf("\tservice:\t%s\n", (kssl_ctx->service_name)? kssl_ctx->service_name:
+ 														"NULL");
+ 	printf("\tclient:\t%s\n", (kssl_ctx->client_princ)? kssl_ctx->client_princ:
+ 														"NULL");
+ 	printf("\tserver:\t%s\n", (kssl_ctx->service_host)? kssl_ctx->service_host:
+ 														"NULL");
+ 	printf("\tkeytab:\t%s\n", (kssl_ctx->keytab_file)? kssl_ctx->keytab_file:
+ 														"NULL");
+ 	printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length);
+ 
+ 	for (i=0; i < kssl_ctx->length  &&  kssl_ctx->key; i++)  {
+ 		printf("%02x", kssl_ctx->key[i]);
+ 		}
+ 	printf("\n");
+ 	return;
+ }
+ 
+ #endif	/* NO_KRB5	*/
+ 
diff -Nacr openssl-0.9.4.orig/ssl/kssl.h openssl-0.9.4/ssl/kssl.h
*** openssl-0.9.4.orig/ssl/kssl.h	Wed Dec 31 19:00:00 1969
--- openssl-0.9.4/ssl/kssl.h	Wed Jan 12 13:40:24 2000
***************
*** 0 ****
--- 1,87 ----
+ /*	ssl/kssl.h
+ **	19990701	VRS 	Started.
+ */
+ 
+ #ifndef NO_KRB5
+ 
+ #ifndef	KSSL_H
+ #define	KSSL_H
+ 
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <strings.h>
+ #include "krb5.h"
+ 
+ /*	Uncomment this to debug kssl problems or
+ **	to trace usage of the Kerberos session key
+ **
+ **	#define		KSSL_DEBUG
+ */
+ 
+ #ifndef	KRB5SVC
+ #define KRB5SVC	"kssl"
+ #endif
+ 
+ #ifndef	KRB5KEYTAB
+ #define KRB5KEYTAB	"/etc/krb5.keytab.kssl"
+ #endif
+ 
+ 
+ #define	KSSL_ERR_MAX	255
+ typedef struct kssl_err_st  {
+ 	int 	reason;
+ 	char	text[KSSL_ERR_MAX+1];
+ 	}	KSSL_ERR;
+ 
+ 
+ /*	Context for passing
+ **		(1) Kerberos session key to SSL, and 
+ **		(2)	Config data between application and SSL lib
+ */
+ typedef struct kssl_ctx_st	{		/*	used by:	disposition:			*/
+ 	char			*service_name;	/*	C,S 		default ok (kssl)		*/
+ 	char			*service_host;	/*	C			input, REQUIRED   		*/
+ 	char			*client_princ;	/*	  S			output from krb5 ticket	*/
+ 	char			*keytab_file;	/*    S 		NULL (/etc/krb5.keytab)	*/
+ 	krb5_enctype	enctype;
+ 	int 			length;
+ 	krb5_octet FAR	*key;
+ 	}	KSSL_CTX;
+ 
+ #define	KSSL_CLIENT 	1
+ #define KSSL_SERVER 	2
+ #define	KSSL_SERVICE	3
+ #define	KSSL_KEYTAB 	4
+ 
+ #define KSSL_CTX_OK 	0
+ #define KSSL_CTX_ERR	1
+ #define KSSL_NOMEM		2
+ 
+ 
+ void			print_krb5_data(char *label, krb5_data *kdata);
+ void			print_krb5_authdata(char *label, krb5_authdata **adata);
+ void			print_krb5_keyblock(char *label, krb5_keyblock *keyblk);
+ 
+ char			*kstring(char *string);
+ char			*knumber(int len, krb5_octet *contents);
+ 
+ 
+ void			kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+ 
+ KSSL_CTX		*kssl_ctx_new(void);
+ KSSL_CTX		*kssl_ctx_free(KSSL_CTX *kssl_ctx);
+ void			kssl_ctx_show(KSSL_CTX *kssl_ctx);
+ krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+ krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+ krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+ 									krb5_data *realm, krb5_data *entity);
+ 
+ krb5_error_code	kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *ap_req,
+ 								KSSL_ERR *kssl_err);
+ krb5_error_code	kssl_sget_tkt(KSSL_CTX *kssl_ctx,  char *msg, int msglen,
+ 								KSSL_ERR *kssl_err);
+ 
+ 
+ #endif	/* KSSL_H 	*/
+ #endif	/* NO_KRB5	*/
+ 
diff -Nacr openssl-0.9.4.orig/ssl/s3_clnt.c openssl-0.9.4/ssl/s3_clnt.c
*** openssl-0.9.4.orig/ssl/s3_clnt.c	Mon Jul 12 13:15:42 1999
--- openssl-0.9.4/ssl/s3_clnt.c	Wed Jan 12 13:40:24 2000
***************
*** 65,70 ****
--- 65,74 ----
  #include <openssl/evp.h>
  #include "ssl_locl.h"
  
+ #ifndef NO_KRB5
+ #include "kssl.h"
+ #endif
+ 
  static SSL_METHOD *ssl3_get_client_method(int ver);
  static int ssl3_client_hello(SSL *s);
  static int ssl3_get_server_hello(SSL *s);
***************
*** 682,687 ****
--- 686,692 ----
  	STACK_OF(X509) *sk=NULL;
  	SESS_CERT *sc;
  	EVP_PKEY *pkey=NULL;
+ 	int 	need_cert = 1;	/* VRS: 0=> will allow null cert if auth == KRB5 */
  
  	n=ssl3_get_message(s,
  		SSL3_ST_CR_CERT_A,
***************
*** 774,783 ****
  	sc->cert_chain=sk;
  	x=sk_X509_value(sk,0);
  	sk=NULL;
  
  	pkey=X509_get_pubkey(x);
  
! 	if ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))
  		{
  		x=NULL;
  		al=SSL3_AL_FATAL;
--- 779,801 ----
  	sc->cert_chain=sk;
  	x=sk_X509_value(sk,0);
  	sk=NULL;
+ 	/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end */
  
  	pkey=X509_get_pubkey(x);
  
!     /* VRS: allow null cert if auth == KRB5 */
!     need_cert =
!         ((s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
!         == (SSL_aKRB5|SSL_kKRB5))? 0: 1;
! 
! #ifdef KSSL_DEBUG
! 	printf("pkey,x = %p, %p\n", pkey,x);
! 	printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
! 	printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name,
! 			s->s3->tmp.new_cipher->algorithms, need_cert);
! #endif    /* KSSL_DEBUG */
! 
! 	if (need_cert  &&  ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
  		{
  		x=NULL;
  		al=SSL3_AL_FATAL;
***************
*** 786,792 ****
  		}
  
  	i=ssl_cert_type(x,pkey);
! 	if (i < 0)
  		{
  		x=NULL;
  		al=SSL3_AL_FATAL;
--- 804,810 ----
  		}
  
  	i=ssl_cert_type(x,pkey);
! 	if (need_cert  &&  i < 0)
  		{
  		x=NULL;
  		al=SSL3_AL_FATAL;
***************
*** 794,812 ****
  		goto f_err;
  		}
  
! 	sc->peer_cert_type=i;
! 	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
! 	if (sc->peer_pkeys[i].x509 != NULL) /* Why would this ever happen?
! 										 * We just created sc a couple of
! 										 * lines ago. */
! 		X509_free(sc->peer_pkeys[i].x509);
! 	sc->peer_pkeys[i].x509=x;
! 	sc->peer_key= &(sc->peer_pkeys[i]);
! 
! 	if (s->session->peer != NULL)
! 		X509_free(s->session->peer);
! 	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
! 	s->session->peer=x;
  
  	x=NULL;
  	ret=1;
--- 812,842 ----
  		goto f_err;
  		}
  
! 	if (need_cert)
! 		{
! 		sc->peer_cert_type=i;
! 		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
! 		if (sc->peer_pkeys[i].x509 != NULL) /* Why would this ever happen?
! 											 * We just created sc a couple of
! 											 * lines ago. */
! 			X509_free(sc->peer_pkeys[i].x509);
! 		sc->peer_pkeys[i].x509=x;
! 		sc->peer_key= &(sc->peer_pkeys[i]);
! 
! 		if (s->session->peer != NULL)
! 			X509_free(s->session->peer);
! 		CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
! 		s->session->peer=x;
! 		}
! 	else
! 		{
! 		sc->peer_cert_type=i;
! 		sc->peer_key= NULL;
! 
! 		if (s->session->peer != NULL)
! 			X509_free(s->session->peer);
! 		s->session->peer=NULL;
! 		}
  
  	x=NULL;
  	ret=1;
***************
*** 1309,1314 ****
--- 1339,1347 ----
  	unsigned char *q;
  	EVP_PKEY *pkey=NULL;
  #endif
+ #ifndef NO_KRB5
+ 	KSSL_ERR kssl_err;
+ #endif
  
  	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
  		{
***************
*** 1376,1381 ****
--- 1409,1478 ----
  			}
  		else
  #endif
+ #ifndef NO_KRB5
+ 		if (l & SSL_kKRB5)
+ 			{
+ 			krb5_error_code	krb5rc;
+ 			KSSL_CTX		*kssl_ctx = s->kssl_ctx;
+ 			krb5_data		krb5_ap_req;
+ 			
+ #ifdef KSSL_DEBUG
+ 			printf("ssl3_send_client_key_exchange(%lx & %lx)\n", l, SSL_kKRB5);
+ #endif	/* KSSL_DEBUG */
+ 
+ 			/*
+ 			**	Tried to send random tmp_buf[] as PMS in Kerberos ticket
+ 			**	by passing  krb5_mk_req_extended(ctx,authctx,opts, tmp_buf, ...)
+ 			**	but: I can't retrieve the PMS on the other side!  There is
+ 			**	some indication in the krb5 source that this is only used
+ 			**	to generate a checksum.  OTOH, the Tung book shows data
+ 			**	("GET widget01.txt") being passed in krb5_mk_req_extended()
+ 			**	by way of krb5_sendauth().  I don't get it.
+ 			**	Until Kerberos goes 3DES, the big PMS secret would only be
+ 			**	encrypted in 1-DES anyway.  So losing the PMS shouldn't be
+ 			**	a big deal.
+ 			*/
+ 			krb5rc = kssl_cget_tkt(kssl_ctx, &krb5_ap_req, &kssl_err);
+ #ifdef KSSL_DEBUG
+ 			{
+ 			printf("kssl_cget_tkt rtn %d\n", krb5rc);
+ 			kssl_ctx_show(kssl_ctx);
+ 			if (krb5rc && kssl_err.text)
+ 					printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
+ 
+ 			}
+ #endif	/* KSSL_DEBUG */
+ 
+ 			if (krb5rc)  {
+ 				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+ 				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason);
+ 				goto err;
+ 				}
+ 
+ 			/*	Send ticket (copy to *p, set n = length)
+ 			*/
+ 			n = krb5_ap_req.length;
+ 			memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
+ 			if (krb5_ap_req.data)  krb5_xfree(krb5_ap_req.data);
+ 
+ 			/*	19991013 VRS -	3DES is kind of bogus here,
+ 			**	at least until Kerberos supports 3DES.  The only
+ 			**	real secret is the 8-byte Kerberos session key;
+ 			**	the other key material ((s->) client_random, server_random)
+ 			**	could be sniffed.  Mixing in these nonces should help 
+ 			**	protect against replay attacks, however.
+ 			**
+ 			**	Alternate code for Kerberos Purists:
+ 			**	
+ 			**	memcpy(s->session->master_key, kssl_ctx->key, kssl_ctx->length);
+ 			**	s->session->master_key_length = kssl_ctx->length;
+ 			*/
+ 			s->session->master_key_length=
+ 				s->method->ssl3_enc->generate_master_secret(s,
+ 					s->session->master_key,	kssl_ctx->key,kssl_ctx->length);
+ 			}
+ 		else
+ #endif
  #ifndef NO_DH
  		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
  			{
***************
*** 1629,1635 ****
  	algs=s->s3->tmp.new_cipher->algorithms;
  
  	/* we don't have a certificate */
! 	if (algs & (SSL_aDH|SSL_aNULL))
  		return(1);
  
  #ifndef NO_RSA
--- 1726,1732 ----
  	algs=s->s3->tmp.new_cipher->algorithms;
  
  	/* we don't have a certificate */
! 	if (algs & (SSL_aDH|SSL_aNULL  | SSL_aKRB5))    /* VRS */
  		return(1);
  
  #ifndef NO_RSA
diff -Nacr openssl-0.9.4.orig/ssl/s3_lib.c openssl-0.9.4/ssl/s3_lib.c
*** openssl-0.9.4.orig/ssl/s3_lib.c	Sat May 15 10:23:29 1999
--- openssl-0.9.4/ssl/s3_lib.c	Wed Jan 12 13:40:53 2000
***************
*** 69,74 ****
--- 69,141 ----
  static long ssl3_default_timeout(void );
  
  OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
+ 
+ #ifndef NO_KRB5
+ /* The Kerberos ciphers
+ ** 20000107 VRS: And the first shall be last,
+ ** in hopes of avoiding the lynx ssl renegotiation problem.
+ */
+ /* Cipher 21 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_40_CBC_SHA,
+ 	SSL3_CK_KRB5_DES_40_CBC_SHA,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_SHA1   |SSL_SSLV3|SSL_EXP40,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ 
+ /* Cipher 22 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_40_CBC_MD5,
+ 	SSL3_CK_KRB5_DES_40_CBC_MD5,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_MD5    |SSL_SSLV3|SSL_EXP40,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ 
+ /* Cipher 23 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_64_CBC_SHA,
+ 	SSL3_CK_KRB5_DES_64_CBC_SHA,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_SHA1   |SSL_SSLV3|SSL_NOT_EXP|SSL_LOW,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ 
+ /* Cipher 24 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_64_CBC_MD5,
+ 	SSL3_CK_KRB5_DES_64_CBC_MD5,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_DES|SSL_MD5    |SSL_SSLV3|SSL_NOT_EXP|SSL_LOW,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ 
+ /* Cipher 25 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_192_CBC3_SHA,
+ 	SSL3_CK_KRB5_DES_192_CBC3_SHA,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_3DES|SSL_SHA1  |SSL_SSLV3|SSL_NOT_EXP|SSL_HIGH,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ 
+ /* Cipher 26 VRS */
+ 	{
+ 	1,
+ 	SSL3_TXT_KRB5_DES_192_CBC3_MD5,
+ 	SSL3_CK_KRB5_DES_192_CBC3_MD5,
+ 	SSL_kKRB5|SSL_aKRB5|  SSL_3DES|SSL_MD5   |SSL_SSLV3|SSL_NOT_EXP|SSL_HIGH,
+ 	0,
+ 	SSL_ALL_CIPHERS,
+ 	},
+ #endif	/* NO_KRB5 */
+ 
  /* The RSA ciphers */
  /* Cipher 01 */
  	{
***************
*** 863,868 ****
--- 930,939 ----
  		ssl_set_cert_masks(cert,c);
  		mask=cert->mask;
  		emask=cert->export_mask;
+ 
+ #ifdef KSSL_DEBUG
+ 		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);
+ #endif    /* KSSL_DEBUG */
  			
  		alg=c->algorithms&(SSL_MKEY_MASK|SSL_AUTH_MASK);
  		if (SSL_IS_EXPORT(c->algorithms))
diff -Nacr openssl-0.9.4.orig/ssl/s3_srvr.c openssl-0.9.4/ssl/s3_srvr.c
*** openssl-0.9.4.orig/ssl/s3_srvr.c	Sun May 23 09:07:03 1999
--- openssl-0.9.4/ssl/s3_srvr.c	Wed Jan 12 13:40:24 2000
***************
*** 68,73 ****
--- 68,77 ----
  #include <openssl/x509.h>
  #include "ssl_locl.h"
  
+ #ifndef NO_KRB5
+ #include "kssl.h"
+ #endif
+ 
  static SSL_METHOD *ssl3_get_server_method(int ver);
  static int ssl3_get_client_hello(SSL *s);
  static int ssl3_send_server_hello(SSL *s);
***************
*** 1174,1179 ****
--- 1178,1186 ----
  	BIGNUM *pub=NULL;
  	DH *dh_srvr;
  #endif
+ #ifndef NO_KRB5
+ 	KSSL_ERR kssl_err;
+ #endif
  
  	n=ssl3_get_message(s,
  		SSL3_ST_SR_KEY_EXCH_A,
***************
*** 1349,1354 ****
--- 1356,1404 ----
  		}
  	else
  #endif
+ #ifndef NO_KRB5
+ 		if (l & SSL_kKRB5)
+ 		{
+ 		krb5_error_code	krb5rc;
+ 		KSSL_CTX		*kssl_ctx = s->kssl_ctx;
+ 
+ 		if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
+ 		if ((krb5rc = kssl_sget_tkt(kssl_ctx,
+ 									s->init_buf->data, s->init_buf->length,
+ 									&kssl_err)) != 0)  {
+ #ifdef KSSL_DEBUG
+ 			printf("kssl_sget_tkt rtn %d [%d]\n", krb5rc, kssl_err.reason);
+ 			if (kssl_err.text)  printf("kssl_err text= %s\n", kssl_err.text);
+ #endif	/* KSSL_DEBUG */
+ 			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason);
+ 			goto err;
+ 			}
+ 
+ #ifdef KSSL_DEBUG
+ 		kssl_ctx_show(kssl_ctx);
+ #endif	/* KSSL_DEBUG */
+ 
+ 		/*	19991013 VRS -	3DES is kind of bogus here,
+ 		**	at least until Kerberos supports 3DES.  The only
+ 		**	real secret is the 8-byte Kerberos session key;
+ 		**	the other key material (client_random, server_random)
+ 		**	could be sniffed.  Nonces may help against replays though.
+ 		**
+ 		**	Alternate code for Kerberos Purists:
+ 		**
+ 		**	memcpy(s->session->master_key,	kssl_ctx->key, kssl_ctx->length);
+ 		**	s->session->master_key_length = kssl_ctx->length;
+ 		*/
+ 		s->session->master_key_length=
+ 			s->method->ssl3_enc->generate_master_secret(s,
+ 				s->session->master_key, kssl_ctx->key, kssl_ctx->length);
+ 		/*	Was doing kssl_ctx_free() here, but it caused problems for apache.
+ 		**	kssl_ctx = kssl_ctx_free(kssl_ctx);
+ 		**	if (s->kssl_ctx)  s->kssl_ctx = NULL;
+ 		*/
+ 		}
+ 	else
+ #endif	/* NO_KRB5 */
  		{
  		al=SSL_AD_HANDSHAKE_FAILURE;
  		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNKNOWN_CIPHER_TYPE);
***************
*** 1666,1672 ****
  	if (s->state == SSL3_ST_SW_CERT_A)
  		{
  		x=ssl_get_server_send_cert(s);
! 		if (x == NULL)
  			{
  			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,SSL_R_INTERNAL_ERROR);
  			return(0);
--- 1716,1725 ----
  	if (s->state == SSL3_ST_SW_CERT_A)
  		{
  		x=ssl_get_server_send_cert(s);
! 		if (x == NULL  &&
! 			/* VRS: allow null cert if auth == KRB5 */
! 			(s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
! 			!= (SSL_aKRB5|SSL_kKRB5))
  			{
  			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,SSL_R_INTERNAL_ERROR);
  			return(0);
diff -Nacr openssl-0.9.4.orig/ssl/ssl.h openssl-0.9.4/ssl/ssl.h
*** openssl-0.9.4.orig/ssl/ssl.h	Sun Aug  8 10:19:44 1999
--- openssl-0.9.4/ssl/ssl.h	Wed Jan 12 13:40:24 2000
***************
*** 65,70 ****
--- 65,74 ----
  
  #include <openssl/safestack.h>
  
+ #ifndef NO_KRB5
+ #include "kssl.h"
+ #endif	/* NO_KRB5 */
+ 
  /* SSLeay version number for ASN.1 encoding of the session information */
  /* Version 0 - initial version
   * Version 1 - added the optional peer certificate
***************
*** 83,88 ****
--- 87,101 ----
  #define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	
  #define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	
  
+ /*    VRS Additional Kerberos5 entries
+ */
+ #define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+ #define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+ #define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+ #define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+ #define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+ #define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+ 
  #define SSL_MAX_SSL_SESSION_ID_LENGTH		32
  #define SSL_MAX_SID_CTX_LENGTH			32
  
***************
*** 103,108 ****
--- 116,125 ----
  #define	SSL_TXT_eNULL		"eNULL"
  #define	SSL_TXT_NULL		"NULL"
  
+ #define SSL_TXT_kKRB5     	"kKRB5"
+ #define SSL_TXT_aKRB5     	"aKRB5"
+ #define SSL_TXT_KRB5      	"KRB5"
+ 
  #define SSL_TXT_kRSA		"kRSA"
  #define SSL_TXT_kDHr		"kDHr"
  #define SSL_TXT_kDHd		"kDHd"
***************
*** 617,622 ****
--- 634,643 ----
  	int error;		/* error bytes to be written */
  	int error_code;		/* actual code */
  
+ #ifndef NO_KRB5
+ 	KSSL_CTX *kssl_ctx;
+ #endif	/* NO_KRB5 */
+ 
  	SSL_CTX *ctx;
  	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
  	 * and SSL_write() calls, good for nbio debuging :-) */
***************
*** 1290,1295 ****
--- 1311,1317 ----
  #define SSL_R_BAD_DH_P_LENGTH				 110
  #define SSL_R_BAD_DIGEST_LENGTH				 111
  #define SSL_R_BAD_DSA_SIGNATURE				 112
+ #define SSL_R_BAD_KMODE					 286
  #define SSL_R_BAD_LENGTH				 271
  #define SSL_R_BAD_MAC_DECODE				 113
  #define SSL_R_BAD_MESSAGE_TYPE				 114
***************
*** 1337,1342 ****
--- 1359,1371 ----
  #define SSL_R_HTTP_REQUEST				 156
  #define SSL_R_INTERNAL_ERROR				 157
  #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
+ #define SSL_R_KRB5_C_CC_PRINC				 279
+ #define SSL_R_KRB5_C_GET_CRED				 280
+ #define SSL_R_KRB5_C_INIT				 281
+ #define SSL_R_KRB5_C_MK_REQ				 282
+ #define SSL_R_KRB5_S_BAD_TICKET				 285
+ #define SSL_R_KRB5_S_INIT				 283
+ #define SSL_R_KRB5_S_RD_REQ				 284
  #define SSL_R_LENGTH_MISMATCH				 159
  #define SSL_R_LENGTH_TOO_SHORT				 160
  #define SSL_R_LIBRARY_BUG				 274
diff -Nacr openssl-0.9.4.orig/ssl/ssl3.h openssl-0.9.4/ssl/ssl3.h
*** openssl-0.9.4.orig/ssl/ssl3.h	Mon Apr 26 23:19:12 1999
--- openssl-0.9.4/ssl/ssl3.h	Wed Jan 12 13:40:24 2000
***************
*** 102,107 ****
--- 102,123 ----
  #define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
  #define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
  
+ /*    VRS Additional Kerberos5 entries
+ */
+ #define SSL3_CK_KRB5_DES_40_CBC_SHA       	0x03000021
+ #define SSL3_CK_KRB5_DES_40_CBC_MD5       	0x03000022
+ #define SSL3_CK_KRB5_DES_64_CBC_SHA       	0x03000023
+ #define SSL3_CK_KRB5_DES_64_CBC_MD5       	0x03000024
+ #define SSL3_CK_KRB5_DES_192_CBC3_SHA 		0x03000025
+ #define SSL3_CK_KRB5_DES_192_CBC3_MD5 		0x03000026
+ 
+ #define SSL3_TXT_KRB5_DES_40_CBC_SHA  		"EXP-KRB5-DES-CBC-SHA"
+ #define SSL3_TXT_KRB5_DES_40_CBC_MD5  		"EXP-KRB5-DES-CBC-MD5"
+ #define SSL3_TXT_KRB5_DES_64_CBC_SHA  		"KRB5-DES-CBC-SHA"
+ #define SSL3_TXT_KRB5_DES_64_CBC_MD5  		"KRB5-DES-CBC-MD5"
+ #define SSL3_TXT_KRB5_DES_192_CBC3_SHA    	"KRB5-DES-CBC3-SHA"
+ #define SSL3_TXT_KRB5_DES_192_CBC3_MD5    	"KRB5-DES-CBC3-MD5"
+ 
  #define SSL3_TXT_RSA_NULL_MD5			"NULL-MD5"
  #define SSL3_TXT_RSA_NULL_SHA			"NULL-SHA"
  #define SSL3_TXT_RSA_RC4_40_MD5 		"EXP-RC4-MD5"
diff -Nacr openssl-0.9.4.orig/ssl/ssl_ciph.c openssl-0.9.4/ssl/ssl_ciph.c
*** openssl-0.9.4.orig/ssl/ssl_ciph.c	Mon Jun  7 16:26:51 1999
--- openssl-0.9.4/ssl/ssl_ciph.c	Wed Jan 12 13:40:24 2000
***************
*** 113,118 ****
--- 113,119 ----
  static SSL_CIPHER cipher_aliases[]={
  	/* Don't include eNULL unless specifically enabled */
  	{0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, 0,SSL_ALL}, /* must be first */
+ 	{0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,SSL_MKEY_MASK},		/* VRS Kerberos5 */
  	{0,SSL_TXT_kRSA,0,SSL_kRSA,  0,SSL_MKEY_MASK},
  	{0,SSL_TXT_kDHr,0,SSL_kDHr,  0,SSL_MKEY_MASK},
  	{0,SSL_TXT_kDHd,0,SSL_kDHd,  0,SSL_MKEY_MASK},
***************
*** 121,126 ****
--- 122,128 ----
  	{0,SSL_TXT_DH,	0,SSL_DH,    0,SSL_MKEY_MASK},
  	{0,SSL_TXT_EDH,	0,SSL_EDH,   0,SSL_MKEY_MASK|SSL_AUTH_MASK},
  
+ 	{0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,SSL_AUTH_MASK},		/* VRS Kerberos5 */
  	{0,SSL_TXT_aRSA,0,SSL_aRSA,  0,SSL_AUTH_MASK},
  	{0,SSL_TXT_aDSS,0,SSL_aDSS,  0,SSL_AUTH_MASK},
  	{0,SSL_TXT_aFZA,0,SSL_aFZA,  0,SSL_AUTH_MASK},
***************
*** 336,341 ****
--- 338,347 ----
  
  	num=ssl_method->num_ciphers();
  
+ #ifdef KSSL_DEBUG
+ 	printf("ssl_create_cipher_list() for %d ciphers\n", num);
+ #endif    /* KSSL_DEBUG */
+ 
  	if ((ret=sk_SSL_CIPHER_new(NULL)) == NULL) goto err;
  	if ((ca_list=(STACK *)sk_new(cmp_by_name)) == NULL) goto err;
  
***************
*** 349,354 ****
--- 355,363 ----
  #ifdef NO_DH
  	mask|=SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
  #endif
+ #ifdef NO_KRB5
+ 	mask|=SSL_kKRB5|SSL_aKRB5;
+ #endif
  
  #ifdef SSL_FORBID_ENULL
  	mask|=SSL_eNULL;
***************
*** 380,385 ****
--- 389,397 ----
  			list[list_num].prev=NULL;
  			list[list_num].active=0;
  			list_num++;
+ #ifdef KSSL_DEBUG
+             printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
+ #endif    /* KSSL_DEBUG */
  			if (!sk_push(ca_list,(char *)c)) goto err;
  			}
  		}
***************
*** 618,624 ****
--- 630,640 ----
  	char *ver,*exp;
  	char *kx,*au,*enc,*mac;
  	unsigned long alg,alg2;
+ #ifdef KSSL_DEBUG
+     static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
+ #else
  	static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
+ #endif    /* KSSL_DEBUG */
  	
  	alg=cipher->algorithms;
  	alg2=cipher->algorithm2;
***************
*** 646,651 ****
--- 662,671 ----
  	case SSL_kDHd:
  		kx="DH/DSS";
  		break;
+ 	case SSL_kKRB5:			/* VRS */
+ 	case SSL_KRB5:			/* VRS */
+ 		kx="KRB5";
+ 		break;
  	case SSL_kFZA:
  		kx="Fortezza";
  		break;
***************
*** 667,672 ****
--- 687,696 ----
  	case SSL_aDH:
  		au="DH";
  		break;
+ 	case SSL_aKRB5:			/* VRS */
+ 	case SSL_KRB5:			/* VRS */
+ 		au="KRB5";
+ 		break;
  	case SSL_aFZA:
  	case SSL_aNULL:
  		au="None";
***************
*** 726,732 ****
--- 750,760 ----
  	else if (len < 128)
  		return("Buffer too small");
  
+ #ifdef KSSL_DEBUG
+ 	sprintf(buf,format,cipher->name,ver,kx,au,enc,mac,exp,alg);
+ #else
  	sprintf(buf,format,cipher->name,ver,kx,au,enc,mac,exp);
+ #endif    /* KSSL_DEBUG */
  	return(buf);
  	}
  
diff -Nacr openssl-0.9.4.orig/ssl/ssl_err.c openssl-0.9.4/ssl/ssl_err.c
*** openssl-0.9.4.orig/ssl/ssl_err.c	Mon May 17 07:15:49 1999
--- openssl-0.9.4/ssl/ssl_err.c	Wed Jan 12 13:40:24 2000
***************
*** 209,214 ****
--- 209,215 ----
  {SSL_R_BAD_DH_P_LENGTH                   ,"bad dh p length"},
  {SSL_R_BAD_DIGEST_LENGTH                 ,"bad digest length"},
  {SSL_R_BAD_DSA_SIGNATURE                 ,"bad dsa signature"},
+ {SSL_R_BAD_KMODE                         ,"bad kmode"},
  {SSL_R_BAD_LENGTH                        ,"bad length"},
  {SSL_R_BAD_MAC_DECODE                    ,"bad mac decode"},
  {SSL_R_BAD_MESSAGE_TYPE                  ,"bad message type"},
***************
*** 256,261 ****
--- 257,269 ----
  {SSL_R_HTTP_REQUEST                      ,"http request"},
  {SSL_R_INTERNAL_ERROR                    ,"internal error"},
  {SSL_R_INVALID_CHALLENGE_LENGTH          ,"invalid challenge length"},
+ {SSL_R_KRB5_C_CC_PRINC                   ,"krb5 c cc princ"},
+ {SSL_R_KRB5_C_GET_CRED                   ,"krb5 c get cred"},
+ {SSL_R_KRB5_C_INIT                       ,"krb5 c init"},
+ {SSL_R_KRB5_C_MK_REQ                     ,"krb5 c mk req"},
+ {SSL_R_KRB5_S_BAD_TICKET                 ,"krb5 s bad ticket"},
+ {SSL_R_KRB5_S_INIT                       ,"krb5 s init"},
+ {SSL_R_KRB5_S_RD_REQ                     ,"krb5 s rd req"},
  {SSL_R_LENGTH_MISMATCH                   ,"length mismatch"},
  {SSL_R_LENGTH_TOO_SHORT                  ,"length too short"},
  {SSL_R_LIBRARY_BUG                       ,"library bug"},
diff -Nacr openssl-0.9.4.orig/ssl/ssl_lib.c openssl-0.9.4/ssl/ssl_lib.c
*** openssl-0.9.4.orig/ssl/ssl_lib.c	Sun Aug  8 10:19:44 1999
--- openssl-0.9.4/ssl/ssl_lib.c	Wed Jan 12 13:40:24 2000
***************
*** 178,183 ****
--- 178,187 ----
  	if (s == NULL) goto err;
  	memset(s,0,sizeof(SSL));
  
+ #ifndef	NO_KRB5
+ 	s->kssl_ctx = kssl_ctx_new();
+ #endif	/* NO_KRB5 */
+ 
  	if (ctx->cert != NULL)
  		{
  		/* Earlier library versions used to copy the pointer to
***************
*** 1259,1264 ****
--- 1263,1273 ----
  	emask|=SSL_aNULL;
  #endif
  
+ #ifndef NO_KRB5
+ 	mask|=SSL_kKRB5|SSL_aKRB5;
+ 	emask|=SSL_kKRB5|SSL_aKRB5;
+ #endif
+ 
  	c->mask=mask;
  	c->export_mask=emask;
  	c->valid=1;
***************
*** 1290,1295 ****
--- 1299,1309 ----
  			i=SSL_PKEY_RSA_SIGN;
  		else
  			i=SSL_PKEY_RSA_ENC;
+ 		}
+ 	else if (kalg & SSL_aKRB5)
+ 		{
+ 		/* VRS something else here? */
+ 		return(NULL);
  		}
  	else /* if (kalg & SSL_aNULL) */
  		{
diff -Nacr openssl-0.9.4.orig/ssl/ssl_locl.h openssl-0.9.4/ssl/ssl_locl.h
*** openssl-0.9.4.orig/ssl/ssl_locl.h	Wed Jun  9 12:33:18 1999
--- openssl-0.9.4/ssl/ssl_locl.h	Wed Jan 12 13:40:24 2000
***************
*** 155,200 ****
  #define DEC32(a)	((a)=((a)-1)&0xffffffffL)
  #define MAX_MAC_SIZE	20 /* up from 16 for SSLv3 */
  
! #define SSL_MKEY_MASK		0x0000001FL
  #define SSL_kRSA		0x00000001L /* RSA key exchange */
  #define SSL_kDHr		0x00000002L /* DH cert RSA CA cert */
  #define SSL_kDHd		0x00000004L /* DH cert DSA CA cert */
  #define SSL_kFZA		0x00000008L
  #define SSL_kEDH		0x00000010L /* tmp DH key no DH cert */
  #define SSL_EDH			(SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL))
  
! #define SSL_AUTH_MASK		0x000003e0L
! #define SSL_aRSA		0x00000020L /* Authenticate with RSA */
! #define SSL_aDSS 		0x00000040L /* Authenticate with DSS */
  #define SSL_DSS 		SSL_aDSS
! #define SSL_aFZA 		0x00000080L
! #define SSL_aNULL 		0x00000100L /* no Authenticate, ADH */
! #define SSL_aDH 		0x00000200L /* no Authenticate, ADH */
  
  #define SSL_NULL		(SSL_eNULL)
  #define SSL_ADH			(SSL_kEDH|SSL_aNULL)
  #define SSL_RSA			(SSL_kRSA|SSL_aRSA)
  #define SSL_DH			(SSL_kDHr|SSL_kDHd|SSL_kEDH)
  #define SSL_FZA			(SSL_aFZA|SSL_kFZA|SSL_eFZA)
  
! #define SSL_ENC_MASK		0x0001Fc00L
! #define SSL_DES			0x00000400L
! #define SSL_3DES		0x00000800L
! #define SSL_RC4			0x00001000L
! #define SSL_RC2			0x00002000L
! #define SSL_IDEA		0x00004000L
! #define SSL_eFZA		0x00008000L
! #define SSL_eNULL		0x00010000L
! 
! #define SSL_MAC_MASK		0x00060000L
! #define SSL_MD5			0x00020000L
! #define SSL_SHA1		0x00040000L
  #define SSL_SHA			(SSL_SHA1)
  
! #define SSL_EXP_MASK		0x00300000L
! #define SSL_EXP40		0x00100000L
! #define SSL_NOT_EXP		0x00200000L
! #define SSL_EXP56		0x00300000L
  #define SSL_IS_EXPORT(a)	((a)&SSL_EXP40)
  #define SSL_IS_EXPORT56(a)	(((a)&SSL_EXP_MASK) == SSL_EXP56)
  #define SSL_IS_EXPORT40(a)	(((a)&SSL_EXP_MASK) == SSL_EXP40)
--- 155,203 ----
  #define DEC32(a)	((a)=((a)-1)&0xffffffffL)
  #define MAX_MAC_SIZE	20 /* up from 16 for SSLv3 */
  
! #define SSL_MKEY_MASK		0x0000003FL
  #define SSL_kRSA		0x00000001L /* RSA key exchange */
  #define SSL_kDHr		0x00000002L /* DH cert RSA CA cert */
  #define SSL_kDHd		0x00000004L /* DH cert DSA CA cert */
  #define SSL_kFZA		0x00000008L
  #define SSL_kEDH		0x00000010L /* tmp DH key no DH cert */
  #define SSL_EDH			(SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL))
+ #define SSL_kKRB5		0x00000020L /* Kerberos5 key exchange */
  
! #define SSL_AUTH_MASK		0x00000fc0L
! #define SSL_aRSA		0x00000040L /* Authenticate with RSA */
! #define SSL_aDSS 		0x00000080L /* Authenticate with DSS */
  #define SSL_DSS 		SSL_aDSS
! #define SSL_aFZA 		0x00000100L
! #define SSL_aNULL 		0x00000200L /* no Authenticate, ADH */
! #define SSL_aDH 		0x00000400L /* no Authenticate, ADH */
! #define SSL_aKRB5		0x00000800L /* Authenticate with Kerberos5 */
  
  #define SSL_NULL		(SSL_eNULL)
  #define SSL_ADH			(SSL_kEDH|SSL_aNULL)
  #define SSL_RSA			(SSL_kRSA|SSL_aRSA)
  #define SSL_DH			(SSL_kDHr|SSL_kDHd|SSL_kEDH)
  #define SSL_FZA			(SSL_aFZA|SSL_kFZA|SSL_eFZA)
+ #define SSL_KRB5		(SSL_kKRB5|SSL_aKRB5)
  
! #define SSL_ENC_MASK		0x0007F000L
! #define SSL_DES			0x00001000L
! #define SSL_3DES		0x00002000L
! #define SSL_RC4			0x00004000L
! #define SSL_RC2			0x00008000L
! #define SSL_IDEA		0x00010000L
! #define SSL_eFZA		0x00020000L
! #define SSL_eNULL		0x00040000L
! 
! #define SSL_MAC_MASK		0x00180000L
! #define SSL_MD5			0x00080000L
! #define SSL_SHA1		0x00100000L
  #define SSL_SHA			(SSL_SHA1)
  
! #define SSL_EXP_MASK		0x00600000L
! #define SSL_EXP40		0x00200000L
! #define SSL_NOT_EXP		0x00400000L
! #define SSL_EXP56		0x00600000L
  #define SSL_IS_EXPORT(a)	((a)&SSL_EXP40)
  #define SSL_IS_EXPORT56(a)	(((a)&SSL_EXP_MASK) == SSL_EXP56)
  #define SSL_IS_EXPORT40(a)	(((a)&SSL_EXP_MASK) == SSL_EXP40)
***************
*** 207,221 ****
  #define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithms)
  #define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algorithms)
  
! #define SSL_SSL_MASK		0x00c00000L
! #define SSL_SSLV2		0x00400000L
! #define SSL_SSLV3		0x00800000L
  #define SSL_TLSV1		SSL_SSLV3	/* for now */
  
! #define SSL_STRONG_MASK		0x07000000L
! #define SSL_LOW			0x01000000L
! #define SSL_MEDIUM		0x02000000L
! #define SSL_HIGH		0x04000000L
  
  /* we have used 0fffffff - 4 bits left to go */
  #define SSL_ALL			0xffffffffL
--- 210,224 ----
  #define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithms)
  #define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algorithms)
  
! #define SSL_SSL_MASK		0x01800000L
! #define SSL_SSLV2		0x00800000L
! #define SSL_SSLV3		0x01000000L
  #define SSL_TLSV1		SSL_SSLV3	/* for now */
  
! #define SSL_STRONG_MASK		0x0e000000L
! #define SSL_LOW			0x02000000L
! #define SSL_MEDIUM		0x04000000L
! #define SSL_HIGH		0x08000000L
  
  /* we have used 0fffffff - 4 bits left to go */
  #define SSL_ALL			0xffffffffL
***************
*** 310,315 ****
--- 313,320 ----
  /*#define SSL_DEBUG	*/
  /*#define RSA_DEBUG	*/ 
  /*#define IDEA_DEBUG	*/ 
+ /*
+ */
  
  #define FP_ICC  (int (*)(const void *,const void *))
  #define ssl_put_cipher_by_char(ssl,ciph,ptr) \
diff -Nacr openssl-0.9.4.orig/ssl/ssltest.c openssl-0.9.4/ssl/ssltest.c
*** openssl-0.9.4.orig/ssl/ssltest.c	Thu Aug  5 07:50:17 1999
--- openssl-0.9.4/ssl/ssltest.c	Wed Jan 12 13:40:24 2000
***************
*** 388,393 ****
--- 388,403 ----
  	c_ssl=SSL_new(c_ctx);
  	s_ssl=SSL_new(s_ctx);
  
+ #ifndef NO_KRB5
+ 	if (c_ssl  &&  c_ssl->kssl_ctx)  {
+ 		char	localhost[257];
+ 
+ 		if (gethostname(localhost, 256) == 0)  {
+ 			kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost);
+ 			}
+ 		}
+ #endif    /* NO_KRB5  */
+ 
  	for (i=0; i<number; i++)
  		{
  		if (!reuse) SSL_set_session(c_ssl,NULL);
diff -Nacr openssl-0.9.4.orig/ssl/t1_enc.c openssl-0.9.4/ssl/t1_enc.c
*** openssl-0.9.4.orig/ssl/t1_enc.c	Tue Apr 27 00:18:53 1999
--- openssl-0.9.4/ssl/t1_enc.c	Wed Jan 12 13:40:24 2000
***************
*** 148,153 ****
--- 148,159 ----
  	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),
  		 s->session->master_key,s->session->master_key_length,
  		 km,tmp,num);
+ #ifdef KSSL_DEBUG
+ 	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+ 			s->session->master_key_length);
+ 	{ int i; for (i=0; i < s->session->master_key_length; i++)  {
+ 	printf("%02X", s->session->master_key[i]);  }  printf("\n");  }
+ #endif    /* KSSL_DEBUG */
  	}
  
  int tls1_change_cipher_state(SSL *s, int which)
***************
*** 174,179 ****
--- 180,196 ----
  	comp=s->s3->tmp.new_compression;
  	key_block=s->s3->tmp.key_block;
  
+ #ifdef KSSL_DEBUG
+ 	printf("tls1_change_cipher_state(which= %d) w/\n", which);
+ 	printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms,comp);
+ 	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+ 	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+ 			c->nid,c->block_size,c->key_len,c->iv_len);
+ 	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
+ 	{ int i; for (i=0; i<s->s3->tmp.key_block_length; i++)
+ 		printf("%02x", key_block[i]);  printf("\n");  }
+ #endif	/* KSSL_DEBUG */
+ 
  	if (which & SSL3_CC_READ)
  		{
  		if ((s->enc_read_ctx == NULL) &&
***************
*** 309,314 ****
--- 326,340 ----
  		}
  
  	s->session->key_arg_length=0;
+ #ifdef KSSL_DEBUG
+ 	{ int i;
+ 	printf("EVP_CipherInit(dd,c,key=,iv=,which)\n");
+ 	printf("\tkey= "); for (i=0; i<c->key_len; i++)  printf("%02x", key[i]);
+ 	printf("\n");
+ 	printf("\t iv= "); for (i=0; i<c->iv_len; i++)  printf("%02x", iv[i]);
+ 	printf("\n");
+ 	}
+ #endif	/* KSSL_DEBUG */
  
  	EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE));
  #ifdef TLS_DEBUG
***************
*** 338,343 ****
--- 364,373 ----
  	int num;
  	SSL_COMP *comp;
  
+ #ifdef KSSL_DEBUG
+ 	printf ("tls1_setup_key_block()\n");
+ #endif	/* KSSL_DEBUG */
+ 
  	if (s->s3->tmp.key_block_length != 0)
  		return(1);
  
***************
*** 417,422 ****
--- 447,456 ----
  			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
  		}
  
+ #ifdef KSSL_DEBUG
+ 	printf("tls1_enc(%d)\n", send);
+ #endif    /* KSSL_DEBUG */
+ 
  	if ((s->session == NULL) || (ds == NULL) ||
  		(enc == NULL))
  		{
***************
*** 447,454 ****
--- 481,509 ----
  			rec->length+=i;
  			}
  
+ #ifdef KSSL_DEBUG
+ 		{  unsigned long i;
+ 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+ 				ds,rec->data,rec->input,l);
+ 		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+ 				ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, DES_SCHEDULE_SZ,
+ 				ds->cipher->iv_len);
+ 		printf("\t\tIV: ");
+ 		for (i=0; i<ds->cipher->iv_len; i++)  printf("%02X", ds->iv[i]);
+ 		printf("\n");
+ 		printf("\trec->input=");
+ 		for (i=0; i<l; i++)  printf(" %02x", rec->input[i]);
+ 		printf("\n");
+ 		}
+ #endif	/* KSSL_DEBUG */
+ 
  		EVP_Cipher(ds,rec->data,rec->input,l);
  
+ #ifdef KSSL_DEBUG
+ 		{  unsigned long i;  printf("\trec->data=");
+ 		for (i=0; i<l; i++)  printf(" %02x", rec->data[i]);  printf("\n");  }
+ #endif	/* KSSL_DEBUG */
+ 
  		if ((bs != 1) && !send)
  			{
  			ii=i=rec->data[l-1];
***************
*** 586,591 ****
--- 641,650 ----
  	unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE];
  	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
  
+ #ifdef KSSL_DEBUG
+ 	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+ #endif	/* KSSL_DEBUG */
+ 
  	/* Setup the stuff to munge */
  	memcpy(buf,TLS_MD_MASTER_SECRET_CONST,
  		TLS_MD_MASTER_SECRET_CONST_SIZE);
***************
*** 596,601 ****
--- 655,663 ----
  	tls1_PRF(s->ctx->md5,s->ctx->sha1,
  		buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
  		s->session->master_key,buff,SSL3_MASTER_SECRET_SIZE);
+ #ifdef KSSL_DEBUG
+ 	printf ("tls1_generate_master_secret() complete\n");
+ #endif	/* KSSL_DEBUG */
  	return(SSL3_MASTER_SECRET_SIZE);
  	}
  
diff -Nacr openssl-0.9.4.orig/test/Makefile.ssl openssl-0.9.4/test/Makefile.ssl
*** openssl-0.9.4.orig/test/Makefile.ssl	Thu Aug  5 07:50:18 1999
--- openssl-0.9.4/test/Makefile.ssl	Wed Jan 12 13:40:24 2000
***************
*** 5,11 ****
  DIR=		test
  TOP=		..
  CC=		cc
! INCLUDES=	-I../include
  CFLAG=		-g
  INSTALL_PREFIX=
  OPENSSLDIR=     /usr/local/ssl
--- 5,11 ----
  DIR=		test
  TOP=		..
  CC=		cc
! INCLUDES=	-I../include -I /usr/local/krb5/include
  CFLAG=		-g
  INSTALL_PREFIX=
  OPENSSLDIR=     /usr/local/ssl
***************
*** 16,21 ****
--- 16,22 ----
  
  PEX_LIBS=
  EX_LIBS= #-lnsl -lsocket
+ LIBKRB5=-L /usr/local/krb5/lib -lgssapi_krb5 -lkrb5 -lcom_err /usr/local/krb5/lib/libcrypto.a  -lresolv
  
  CFLAGS= $(INCLUDES) $(CFLAG)
  
***************
*** 298,304 ****
  	$(CC) -o $(METHTEST) $(CFLAGS) $(METHTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)
  
  $(SSLTEST): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
! 	$(CC) -o $(SSLTEST) $(CFLAGS) $(SSLTEST).o $(PEX_LIBS) $(LIBSSL) $(LIBCRYPTO) $(EX_LIBS)
  
  # DO NOT DELETE THIS LINE -- make depend depends on it.
  
--- 299,305 ----
  	$(CC) -o $(METHTEST) $(CFLAGS) $(METHTEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)
  
  $(SSLTEST): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
! 	$(CC) -o $(SSLTEST) $(CFLAGS) $(SSLTEST).o $(PEX_LIBS) $(LIBSSL) $(LIBKRB5) $(LIBCRYPTO) $(EX_LIBS)
  
  # DO NOT DELETE THIS LINE -- make depend depends on it.
  
diff -Nacr openssl-0.9.4.orig/test/testssl openssl-0.9.4/test/testssl
*** openssl-0.9.4.orig/test/testssl	Fri Jun 11 21:03:40 1999
--- openssl-0.9.4/test/testssl	Wed Jan 12 13:40:25 2000
***************
*** 12,40 ****
  echo test sslv2 with both client and server authentication
  ./ssltest -ssl2 -server_auth -client_auth -CApath ../certs || exit 1
  
! echo test sslv3
! ./ssltest -ssl3 || exit 1
  
  echo test sslv3 with server authentication
! ./ssltest -ssl3 -server_auth -CApath ../certs || exit 1
  
  echo test sslv3 with client authentication
! ./ssltest -ssl3 -client_auth -CApath ../certs || exit 1
  
  echo test sslv3 with both client and server authentication
! ./ssltest -ssl3 -server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3
! ./ssltest || exit 1
  
  echo test sslv2/sslv3 with server authentication
! ./ssltest -server_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with client authentication
! ./ssltest -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with both client and server authentication
! ./ssltest -server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv2 via BIO pair
  ./ssltest -bio_pair -ssl2 || exit 1
--- 12,44 ----
  echo test sslv2 with both client and server authentication
  ./ssltest -ssl2 -server_auth -client_auth -CApath ../certs || exit 1
  
! echo test sslv3 
! ./ssltest -ssl3 -cipher EDH-RSA-DES-CBC-SHA | exit 1
  
  echo test sslv3 with server authentication
! ./ssltest -ssl3 -cipher EDH-RSA-DES-CBC-SHA -server_auth -CApath ../certs  \
! 	|| exit 1
  
  echo test sslv3 with client authentication
! ./ssltest -ssl3 -cipher EDH-RSA-DES-CBC-SHA -client_auth -CApath ../certs  \
! 	|| exit 1
  
  echo test sslv3 with both client and server authentication
! ./ssltest -ssl3 -cipher EDH-RSA-DES-CBC-SHA -server_auth -client_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv2/sslv3
! ./ssltest -cipher EDH-RSA-DES-CBC-SHA || exit 1
  
  echo test sslv2/sslv3 with server authentication
! ./ssltest -cipher EDH-RSA-DES-CBC-SHA -server_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with client authentication
! ./ssltest -cipher EDH-RSA-DES-CBC-SHA -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with both client and server authentication
! ./ssltest -cipher EDH-RSA-DES-CBC-SHA -server_auth -client_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv2 via BIO pair
  ./ssltest -bio_pair -ssl2 || exit 1
***************
*** 49,75 ****
  ./ssltest -bio_pair -ssl2 -server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv3 via BIO pair
! ./ssltest -bio_pair -ssl3 || exit 1
  
  echo test sslv3 with server authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -server_auth -CApath ../certs || exit 1
  
  echo test sslv3 with client authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -client_auth -CApath ../certs || exit 1
  
  echo test sslv3 with both client and server authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 via BIO pair
! ./ssltest || exit 1
  
  echo test sslv2/sslv3 with server authentication
! ./ssltest -bio_pair -server_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with client authentication via BIO pair
! ./ssltest -bio_pair -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with both client and server authentication via BIO pair
! ./ssltest -bio_pair -server_auth -client_auth -CApath ../certs || exit 1
  
  exit 0
--- 53,85 ----
  ./ssltest -bio_pair -ssl2 -server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv3 via BIO pair
! ./ssltest -bio_pair -ssl3 -cipher EDH-RSA-DES-CBC-SHA || exit 1
  
  echo test sslv3 with server authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -cipher EDH-RSA-DES-CBC-SHA -server_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv3 with client authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -cipher EDH-RSA-DES-CBC-SHA -client_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv3 with both client and server authentication via BIO pair
! ./ssltest -bio_pair -ssl3 -cipher EDH-RSA-DES-CBC-SHA  \
! 	-server_auth -client_auth -CApath ../certs || exit 1
  
  echo test sslv2/sslv3 via BIO pair
! ./ssltest -cipher EDH-RSA-DES-CBC-SHA || exit 1
  
  echo test sslv2/sslv3 with server authentication
! ./ssltest -bio_pair -cipher EDH-RSA-DES-CBC-SHA -server_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with client authentication via BIO pair
! ./ssltest -bio_pair -cipher EDH-RSA-DES-CBC-SHA -client_auth  \
! 	-CApath ../certs || exit 1
  
  echo test sslv2/sslv3 with both client and server authentication via BIO pair
! ./ssltest -bio_pair -cipher EDH-RSA-DES-CBC-SHA  \
! 	-server_auth -client_auth -CApath ../certs || exit 1
  
  exit 0
