Patches from Vern Staats <staatsvr@asc.hpc.mil> to get Kerberos 5 in

SSL according to RFC 2712.  His comment is:

This is a patch to openssl-SNAP-20010702 to support Kerberized SSL
authentication.  I'm expecting to have the full kssl-0.5 kit up on
sourceforge by the end of the week.  The full kit includes patches
for mod-ssl, apache, and a few text clients.  The sourceforge URL
is http://sourceforge.net/projects/kssl/ .

Thanks to a note from Simon Wilkinson I've replaced my KRB5 AP_REQ
message with a real KerberosWrapper struct.  I think this is fully
RFC 2712 compliant now, including support for the optional
authenticator field.  I also added openssl-style ASN.1 macros for
a few Kerberos structs; see crypto/krb5/ if you're interested.
This commit is contained in:
Richard Levitte 2001-07-09 21:46:58 +00:00
parent c148d70978
commit 2a1ef75435
14 changed files with 1641 additions and 173 deletions

View file

@ -723,6 +723,7 @@ if ($no_krb5
}
else
{
my ($lresolv, $lpath, $lext);
if ($withargs{"krb5-flavor"} =~ /^[Hh]eimdal$/)
{
$withargs{"krb5-dir"} = "/usr/heimdal"
@ -732,7 +733,7 @@ else
if $withargs{"krb5-lib"} eq "";
$cflags="-DKRB5_HEIMDAL $cflags";
}
if ($withargs{"krb5-flavor"} =~ /^[Mm][Ii][Tt]$/)
if ($withargs{"krb5-flavor"} =~ /^[Mm][Ii][Tt]/)
{
$withargs{"krb5-dir"} = "/usr/kerberos"
if $withargs{"krb5-dir"} eq "";
@ -740,9 +741,27 @@ else
"/lib -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto"
if $withargs{"krb5-lib"} eq "";
$cflags="-DKRB5_MIT $cflags";
$withargs{"krb5-flavor"} =~ s/^[Mm][Ii][Tt][._-]*//;
if ($withargs{"krb5-flavor"} =~ /^1[._-]*[01]/)
{
$cflags="-DKRB5_MIT_OLD11 $cflags";
}
}
LRESOLV:
foreach $lpath ("/lib", "/usr/lib")
{
foreach $lext ("a", "so")
{
$lresolv = "$lpath/libresolv.$lext";
last LRESOLV if (-r "$lresolv");
$lresolv = "";
}
}
$withargs{"krb5-lib"} .= " -lresolv"
if ("$lresolv");
$withargs{"krb5-include"} = "-I".$withargs{"krb5-dir"}."/include"
if $withargs{"krb5-include"} eq "" && $withargs{"krb5-dir"} ne "";
if $withargs{"krb5-include"} eq "" &&
$withargs{"krb5-dir"} ne "";
}
# The DSO code currently always implements all functions so that no

View file

@ -168,7 +168,7 @@ SDIRS= \
des rc2 rc4 rc5 idea bf cast \
bn ec rsa dsa dh dso engine rijndael \
buffer bio stack lhash rand err objects \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5
# tests to perform. "alltests" is a special word indicating that all tests
# should be performed.
@ -458,7 +458,7 @@ depend:
do \
if [ -d "$$i" ]; then \
(cd $$i && echo "making dependencies $$i..." && \
$(MAKE) SDIRS='${SDIRS}' DEPFLAG='${DEPFLAG}' MAKEDEPPROG='${MAKEDEPPROG}' depend ) || exit 1; \
$(MAKE) SDIRS='${SDIRS}' DEPFLAG='${DEPFLAG}' MAKEDEPPROG='${MAKEDEPPROG}' KRB5_INCLUDES='${KRB5_INCLUDES}' depend ) || exit 1; \
fi; \
done;

View file

@ -863,8 +863,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
#ifndef OPENSSL_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);
kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
KRB5SVC);
kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
KRB5KEYTAB);
}
#endif /* OPENSSL_NO_KRB5 */
if(context)
@ -1249,6 +1251,13 @@ static int www_body(char *hostname, int s, unsigned char *context)
if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
if ((con=SSL_new(ctx)) == NULL) goto err;
#ifndef OPENSSL_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 /* OPENSSL_NO_KRB5 */
if(context) SSL_set_session_id_context(con, context,
strlen((char *)context));

View file

@ -822,6 +822,7 @@ DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)

View file

@ -91,6 +91,9 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING)
IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING)
IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME)

90
crypto/krb5/Makefile.ssl Normal file
View file

@ -0,0 +1,90 @@
#
# OpenSSL/krb5/Makefile.ssl
#
DIR= krb5
TOP= ../..
CC= cc
INCLUDES= -I.. -I$(TOP) -I../../include
CFLAG=-g
INSTALL_PREFIX=
OPENSSLDIR= /usr/local/ssl
INSTALLTOP=/usr/local/ssl
MAKE= make -f Makefile.ssl
MAKEDEPPROG= makedepend
MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
MAKEFILE= Makefile.ssl
AR= ar r
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile README
TEST=
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= krb5_asn.c
LIBOBJ= krb5_asn.o
SRC= $(LIBSRC)
EXHEADER= krb5_asn.h
HEADER= $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
top:
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
all: lib
lib: $(LIBOBJ)
$(AR) $(LIB) $(LIBOBJ)
$(RANLIB) $(LIB)
@touch lib
files:
perl $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
links:
$(TOP)/util/point.sh Makefile.ssl Makefile ;
$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
install:
@for i in $(EXHEADER) ; \
do \
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
done;
tags:
ctags $(SRC)
tests:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
depend:
$(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(LIBSRC)
dclean:
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.
krb5_asn.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
krb5_asn.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
krb5_asn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
krb5_asn.o: ../../include/openssl/krb5_asn.h
krb5_asn.o: ../../include/openssl/opensslconf.h
krb5_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
krb5_asn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
krb5_asn.o: krb5_asn.c

164
crypto/krb5/krb5_asn.c Normal file
View file

@ -0,0 +1,164 @@
/* krb5_asn.c */
/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
** using ocsp/{*.h,*asn*.c} as a starting point
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/krb5_asn.h>
ASN1_SEQUENCE(KRB5_ENCDATA) = {
ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0),
ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1),
ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2)
} ASN1_SEQUENCE_END(KRB5_ENCDATA)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA)
ASN1_SEQUENCE(KRB5_PRINCNAME) = {
ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0),
ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1)
} ASN1_SEQUENCE_END(KRB5_PRINCNAME)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME)
/* [APPLICATION 1] = 0x61 */
ASN1_SEQUENCE(KRB5_TKTBODY) = {
ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1),
ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2),
ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3)
} ASN1_SEQUENCE_END(KRB5_TKTBODY)
ASN1_ITEM_TEMPLATE(KRB5_TICKET) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1,
KRB5_TICKET, KRB5_TKTBODY)
ASN1_ITEM_TEMPLATE_END(KRB5_TICKET)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET)
/* [APPLICATION 14] = 0x6e */
ASN1_SEQUENCE(KRB5_APREQBODY) = {
ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1),
ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2),
ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3),
ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4),
} ASN1_SEQUENCE_END(KRB5_APREQBODY)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY)
ASN1_ITEM_TEMPLATE(KRB5_APREQ) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14,
KRB5_APREQ, KRB5_APREQBODY)
ASN1_ITEM_TEMPLATE_END(KRB5_APREQ)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ)
/* Authenticator stuff */
ASN1_SEQUENCE(KRB5_CHECKSUM) = {
ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1)
} ASN1_SEQUENCE_END(KRB5_CHECKSUM)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM)
ASN1_SEQUENCE(KRB5_ENCKEY) = {
ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1)
} ASN1_SEQUENCE_END(KRB5_ENCKEY)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY)
/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */
ASN1_SEQUENCE(KRB5_AUTHDATA) = {
ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1)
} ASN1_SEQUENCE_END(KRB5_AUTHDATA)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA)
/* [APPLICATION 2] = 0x62 */
ASN1_SEQUENCE(KRB5_AUTHENTBODY) = {
ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0),
ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1),
ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2),
ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3),
ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4),
ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5),
ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6),
ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7),
ASN1_EXP_SEQUENCE_OF_OPT
(KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8),
} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2,
KRB5_AUTHENT, KRB5_AUTHENTBODY)
ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT)
IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT)

256
crypto/krb5/krb5_asn.h Normal file
View file

@ -0,0 +1,256 @@
/* krb5_asn.h */
/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
** using ocsp/{*.h,*asn*.c} as a starting point
*/
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_KRB5_ASN_H
#define HEADER_KRB5_ASN_H
/*
#include <krb5.h>
*/
#include <openssl/safestack.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ASN.1 from Kerberos RFC 1510
*/
/* EncryptedData ::= SEQUENCE {
** etype[0] INTEGER, -- EncryptionType
** kvno[1] INTEGER OPTIONAL,
** cipher[2] OCTET STRING -- ciphertext
** }
*/
typedef struct krb5_encdata_st
{
ASN1_INTEGER *etype;
ASN1_INTEGER *kvno;
ASN1_OCTET_STRING *cipher;
} KRB5_ENCDATA;
DECLARE_STACK_OF(KRB5_ENCDATA)
/* PrincipalName ::= SEQUENCE {
** name-type[0] INTEGER,
** name-string[1] SEQUENCE OF GeneralString
** }
*/
typedef struct krb5_princname_st
{
ASN1_INTEGER *nametype;
STACK_OF(ASN1_GENERALSTRING) *namestring;
} KRB5_PRINCNAME;
DECLARE_STACK_OF(KRB5_PRINCNAME)
/* Ticket ::= [APPLICATION 1] SEQUENCE {
** tkt-vno[0] INTEGER,
** realm[1] Realm,
** sname[2] PrincipalName,
** enc-part[3] EncryptedData
** }
*/
typedef struct krb5_tktbody_st
{
ASN1_INTEGER *tktvno;
ASN1_GENERALSTRING *realm;
KRB5_PRINCNAME *sname;
KRB5_ENCDATA *encdata;
} KRB5_TKTBODY;
typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
DECLARE_STACK_OF(KRB5_TKTBODY)
/* AP-REQ ::= [APPLICATION 14] SEQUENCE {
** pvno[0] INTEGER,
** msg-type[1] INTEGER,
** ap-options[2] APOptions,
** ticket[3] Ticket,
** authenticator[4] EncryptedData
** }
**
** APOptions ::= BIT STRING {
** reserved(0), use-session-key(1), mutual-required(2) }
*/
typedef struct krb5_ap_req_st
{
ASN1_INTEGER *pvno;
ASN1_INTEGER *msgtype;
ASN1_BIT_STRING *apoptions;
KRB5_TICKET *ticket;
KRB5_ENCDATA *authenticator;
} KRB5_APREQBODY;
typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
DECLARE_STACK_OF(KRB5_APREQBODY)
/* Authenticator Stuff */
/* Checksum ::= SEQUENCE {
** cksumtype[0] INTEGER,
** checksum[1] OCTET STRING
** }
*/
typedef struct krb5_checksum_st
{
ASN1_INTEGER *ctype;
ASN1_OCTET_STRING *checksum;
} KRB5_CHECKSUM;
DECLARE_STACK_OF(KRB5_CHECKSUM)
/* EncryptionKey ::= SEQUENCE {
** keytype[0] INTEGER,
** keyvalue[1] OCTET STRING
** }
*/
typedef struct krb5_encryptionkey_st
{
ASN1_INTEGER *ktype;
ASN1_OCTET_STRING *keyvalue;
} KRB5_ENCKEY;
DECLARE_STACK_OF(KRB5_ENCKEY)
/* AuthorizationData ::= SEQUENCE OF SEQUENCE {
** ad-type[0] INTEGER,
** ad-data[1] OCTET STRING
** }
*/
typedef struct krb5_authorization_st
{
ASN1_INTEGER *adtype;
ASN1_OCTET_STRING *addata;
} KRB5_AUTHDATA;
DECLARE_STACK_OF(KRB5_AUTHDATA);
/* -- Unencrypted authenticator
** Authenticator ::= [APPLICATION 2] SEQUENCE {
** authenticator-vno[0] INTEGER,
** crealm[1] Realm,
** cname[2] PrincipalName,
** cksum[3] Checksum OPTIONAL,
** cusec[4] INTEGER,
** ctime[5] KerberosTime,
** subkey[6] EncryptionKey OPTIONAL,
** seq-number[7] INTEGER OPTIONAL,
** authorization-data[8] AuthorizationData OPTIONAL
** }
*/
typedef struct krb5_authenticator_st
{
ASN1_INTEGER *avno;
ASN1_GENERALSTRING *crealm;
KRB5_PRINCNAME *cname;
KRB5_CHECKSUM *cksum;
ASN1_INTEGER *cusec;
ASN1_GENERALIZEDTIME *ctime;
KRB5_ENCKEY *subkey;
ASN1_INTEGER *seqnum;
KRB5_AUTHDATA *authorization;
} KRB5_AUTHENTBODY;
typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
DECLARE_STACK_OF(KRB5_AUTHENTBODY)
/* DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
** type *name##_new(void);
** void name##_free(type *a);
** DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
** DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
** type *d2i_##name(type **a, unsigned char **in, long len);
** int i2d_##name(type *a, unsigned char **out);
** DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
*/
DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -96,6 +96,17 @@ typedef unsigned char krb5_octet;
#define KRB5KEYTAB "/etc/krb5.keytab"
#endif
#ifndef KRB5SENDAUTH
#define KRB5SENDAUTH 1
#endif
#ifndef KRB5CHECKAUTH
#define KRB5CHECKAUTH 1
#endif
#ifndef KSSL_CLOCKSKEW
#define KSSL_CLOCKSKEW 300;
#endif
#define KSSL_ERR_MAX 255
typedef struct kssl_err_st {
@ -139,6 +150,8 @@ void print_krb5_keyblock(char *label, krb5_keyblock *keyblk);
char *kstring(char *string);
char *knumber(int len, krb5_octet *contents);
EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
@ -147,13 +160,21 @@ KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
void kssl_ctx_show(KSSL_CTX *kssl_ctx);
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);
krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp,
krb5_data *authenp, KSSL_ERR *kssl_err);
krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata,
krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
krb5_error_code kssl_build_principal_2(krb5_context context,
krb5_principal *princ, int rlen, const char *realm,
int slen, const char *svc, int hlen, const char *host);
krb5_error_code kssl_validate_times(krb5_timestamp atime,
krb5_ticket_times *ttimes);
krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
krb5_timestamp *atimep, KSSL_ERR *kssl_err);
unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
#ifdef __cplusplus
}

View file

@ -785,13 +785,13 @@ static int ssl3_get_server_certificate(SSL *s)
* certificate, which we don't include in s3_srvr.c */
x=sk_X509_value(sk,0);
sk=NULL;
/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end */
/* 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))
need_cert = ((s->s3->tmp.new_cipher->algorithms
& (SSL_MKEY_MASK|SSL_AUTH_MASK))
== (SSL_aKRB5|SSL_kKRB5))? 0: 1;
#ifdef KSSL_DEBUG
@ -801,11 +801,12 @@ static int ssl3_get_server_certificate(SSL *s)
s->s3->tmp.new_cipher->algorithms, need_cert);
#endif /* KSSL_DEBUG */
if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey)))
{
x=NULL;
al=SSL3_AL_FATAL;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
goto f_err;
}
@ -814,7 +815,8 @@ static int ssl3_get_server_certificate(SSL *s)
{
x=NULL;
al=SSL3_AL_FATAL;
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_UNKNOWN_CERTIFICATE_TYPE);
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto f_err;
}
@ -1427,65 +1429,121 @@ static int ssl3_send_client_key_exchange(SSL *s)
{
krb5_error_code krb5rc;
KSSL_CTX *kssl_ctx = s->kssl_ctx;
krb5_data krb5_ap_req;
/* krb5_data krb5_ap_req; */
krb5_data *enc_ticket;
krb5_data authenticator, *authp = NULL;
EVP_CIPHER_CTX ciph_ctx;
EVP_CIPHER *enc = NULL;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH
+ EVP_MAX_IV_LENGTH];
int padl, outl = sizeof(epms);
#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);
authp = NULL;
#ifdef KRB5SENDAUTH
if (KRB5SENDAUTH) authp = &authenticator;
#endif /* KRB5SENDAUTH */
krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
&kssl_err);
enc = kssl_map_enc(kssl_ctx->enctype);
#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);
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);
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)
kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
/* 20010406 VRS - Earlier versions used KRB5 AP_REQ
** in place of RFC 2712 KerberosWrapper, as in:
**
** 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)
** kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
**
** Now using real RFC 2712 KerberosWrapper
** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
** Note: 2712 "opaque" types are here replaced
** with a 2-byte length followed by the value.
** Example:
** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
** Where "xx xx" = length bytes. Shown here with
** optional authenticator omitted.
*/
/* KerberosWrapper.Ticket */
s2n(enc_ticket->length,p);
memcpy(p, enc_ticket->data, enc_ticket->length);
p+= enc_ticket->length;
n = enc_ticket->length + 2;
/* KerberosWrapper.Authenticator */
if (authp && authp->length)
{
s2n(authp->length,p);
memcpy(p, authp->data, authp->length);
p+= authp->length;
n+= authp->length + 2;
free(authp->data);
authp->data = NULL;
authp->length = 0;
}
else
{
s2n(0,p);/* null authenticator length */
n+=2;
}
if (RAND_bytes(tmp_buf,SSL_MAX_MASTER_KEY_LENGTH) <= 0)
goto err;
/* 20010420 VRS. Tried it this way; failed.
** EVP_EncryptInit(&ciph_ctx,enc, NULL,NULL);
** EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
** kssl_ctx->length);
** EVP_EncryptInit(&ciph_ctx,NULL, key,iv);
*/
memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */
EVP_EncryptInit(&ciph_ctx,enc, kssl_ctx->key,iv);
EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
SSL_MAX_MASTER_KEY_LENGTH);
EVP_EncryptFinal(&ciph_ctx,&(epms[outl]),&padl);
outl += padl;
EVP_CIPHER_CTX_cleanup(&ciph_ctx);
/* KerberosWrapper.EncryptedPreMasterSecret */
s2n(outl,p);
memcpy(p, epms, outl);
p+=outl;
n+=outl + 2;
/* 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);
s->session->master_key,
tmp_buf, SSL_MAX_MASTER_KEY_LENGTH);
memset(tmp_buf, 0, SSL_MAX_MASTER_KEY_LENGTH);
memset(epms, 0, outl);
}
#endif
#ifndef OPENSSL_NO_DH

View file

@ -66,6 +66,7 @@
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/krb5_asn.h>
#include "ssl_locl.h"
#ifndef OPENSSL_NO_KRB5
@ -1452,13 +1453,46 @@ static int ssl3_get_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_KRB5
if (l & SSL_kKRB5)
{
krb5_error_code krb5rc;
KSSL_CTX *kssl_ctx = s->kssl_ctx;
krb5_error_code krb5rc;
krb5_data enc_ticket;
krb5_data authenticator;
krb5_data enc_pms;
KSSL_CTX *kssl_ctx = s->kssl_ctx;
EVP_CIPHER_CTX ciph_ctx;
EVP_CIPHER *enc = NULL;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH];
int padl, outl = sizeof(pms);
krb5_timestamp authtime = 0;
krb5_ticket_times ttimes;
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)
n2s(p,i);
enc_ticket.length = i;
enc_ticket.data = p;
p+=enc_ticket.length;
n2s(p,i);
authenticator.length = i;
authenticator.data = p;
p+=authenticator.length;
n2s(p,i);
enc_pms.length = i;
enc_pms.data = p;
p+=enc_pms.length;
if (n != enc_ticket.length + authenticator.length +
enc_pms.length + 6)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
&kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
printf("kssl_sget_tkt rtn %d [%d]\n",
@ -1471,34 +1505,71 @@ static int ssl3_get_client_key_exchange(SSL *s)
goto err;
}
/* Note: no authenticator is not considered an error,
** but will return authtime == 0.
*/
if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
&authtime, &kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
printf("kssl_check_authent 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;
}
if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
{
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc);
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;
*/
enc = kssl_map_enc(kssl_ctx->enctype);
memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */
EVP_DecryptInit(&ciph_ctx,enc,kssl_ctx->key,iv);
EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
enc_pms.data, enc_pms.length);
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
EVP_DecryptFinal(&ciph_ctx,&(pms[outl]),&padl);
outl += padl;
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto err;
}
EVP_CIPHER_CTX_cleanup(&ciph_ctx);
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;
s->session->master_key, pms, outl);
/* 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 /* OPENSSL_NO_KRB5 */
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNKNOWN_CIPHER_TYPE);
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_UNKNOWN_CIPHER_TYPE);
goto f_err;
}

View file

@ -1459,13 +1459,17 @@ void ERR_load_SSL_strings(void);
#define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_PURPOSE 278
#define SSL_R_INVALID_TRUST 279
#define SSL_R_KRB5 1104
#define SSL_R_KRB5_C_CC_PRINC 1094
#define SSL_R_KRB5_C_GET_CRED 1095
#define SSL_R_KRB5_C_INIT 1096
#define SSL_R_KRB5_C_MK_REQ 1097
#define SSL_R_KRB5_S_BAD_TICKET 1098
#define SSL_R_KRB5_S_INIT 1099
#define SSL_R_KRB5_S_RD_REQ 1100
#define SSL_R_KRB5_S_RD_REQ 1108
#define SSL_R_KRB5_S_TKT_EXPIRED 1105
#define SSL_R_KRB5_S_TKT_NYV 1106
#define SSL_R_KRB5_S_TKT_SKEW 1107
#define SSL_R_LENGTH_MISMATCH 159
#define SSL_R_LENGTH_TOO_SHORT 160
#define SSL_R_LIBRARY_BUG 274

View file

@ -273,13 +273,17 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{SSL_R_INVALID_COMMAND ,"invalid command"},
{SSL_R_INVALID_PURPOSE ,"invalid purpose"},
{SSL_R_INVALID_TRUST ,"invalid trust"},
{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_KRB5 ,"krb5"},
{SSL_R_KRB5_C_CC_PRINC ,"krb5 client cc principal (no tkt?)"},
{SSL_R_KRB5_C_GET_CRED ,"krb5 client get cred"},
{SSL_R_KRB5_C_INIT ,"krb5 client init"},
{SSL_R_KRB5_C_MK_REQ ,"krb5 client mk_req (expired tkt?)"},
{SSL_R_KRB5_S_BAD_TICKET ,"krb5 server bad ticket"},
{SSL_R_KRB5_S_INIT ,"krb5 server init"},
{SSL_R_KRB5_S_RD_REQ ,"krb5 server rd_req (keytab perms?)"},
{SSL_R_KRB5_S_TKT_EXPIRED ,"krb5 server tkt expired"},
{SSL_R_KRB5_S_TKT_NYV ,"krb5 server tkt not yet valid"},
{SSL_R_KRB5_S_TKT_SKEW ,"krb5 server tkt skew"},
{SSL_R_LENGTH_MISMATCH ,"length mismatch"},
{SSL_R_LENGTH_TOO_SHORT ,"length too short"},
{SSL_R_LIBRARY_BUG ,"library bug"},