merge new-crypto branch
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@5332 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -24,7 +24,6 @@ libkrb5_la_SOURCES = \
|
||||
build_auth.c \
|
||||
cache.c \
|
||||
changepw.c \
|
||||
checksum.c \
|
||||
codec.c \
|
||||
config_file.c \
|
||||
convert_creds.c \
|
||||
@@ -32,8 +31,8 @@ libkrb5_la_SOURCES = \
|
||||
context.c \
|
||||
crc.c \
|
||||
creds.c \
|
||||
crypto.c \
|
||||
data.c \
|
||||
encrypt.c \
|
||||
fcache.c \
|
||||
free.c \
|
||||
free_host_realm.c \
|
||||
@@ -67,6 +66,7 @@ libkrb5_la_SOURCES = \
|
||||
mk_safe.c \
|
||||
net_read.c \
|
||||
net_write.c \
|
||||
n-fold.c \
|
||||
padata.c \
|
||||
principal.c \
|
||||
prog_setup.c \
|
||||
@@ -87,7 +87,6 @@ libkrb5_la_SOURCES = \
|
||||
store_emem.c \
|
||||
store_fd.c \
|
||||
store_mem.c \
|
||||
str2key.c \
|
||||
ticket.c \
|
||||
time.c \
|
||||
transited.c \
|
||||
|
@@ -58,8 +58,6 @@ krb5_auth_con_init(krb5_context context,
|
||||
memset (p->authenticator, 0, sizeof(*p->authenticator));
|
||||
p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
|
||||
|
||||
p->cksumtype = CKSUMTYPE_NONE; /* CKSUMTYPE_RSA_MD5_DES */
|
||||
p->enctype = ETYPE_NULL; /* ETYPE_DES_CBC_MD5 */
|
||||
p->local_address = NULL;
|
||||
p->remote_address = NULL;
|
||||
*auth_context = p;
|
||||
@@ -282,8 +280,7 @@ krb5_auth_setcksumtype(krb5_context context,
|
||||
krb5_auth_context auth_context,
|
||||
krb5_cksumtype cksumtype)
|
||||
{
|
||||
auth_context->cksumtype = cksumtype;
|
||||
return 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -291,8 +288,7 @@ krb5_auth_getcksumtype(krb5_context context,
|
||||
krb5_auth_context auth_context,
|
||||
krb5_cksumtype *cksumtype)
|
||||
{
|
||||
*cksumtype = auth_context->cksumtype;
|
||||
return 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -300,7 +296,12 @@ krb5_auth_setenctype(krb5_context context,
|
||||
krb5_auth_context auth_context,
|
||||
krb5_enctype etype)
|
||||
{
|
||||
auth_context->enctype = etype;
|
||||
if(auth_context->keyblock)
|
||||
krb5_free_keyblock(context, auth_context->keyblock);
|
||||
ALLOC(auth_context->keyblock, 1);
|
||||
if(auth_context->keyblock == NULL)
|
||||
return ENOMEM;
|
||||
auth_context->keyblock->keytype = etype;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -309,8 +310,7 @@ krb5_auth_getenctype(krb5_context context,
|
||||
krb5_auth_context auth_context,
|
||||
krb5_enctype *etype)
|
||||
{
|
||||
*etype = auth_context->enctype;
|
||||
return 0;
|
||||
abort();
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
|
@@ -54,6 +54,7 @@ krb5_build_authenticator (krb5_context context,
|
||||
size_t buf_size;
|
||||
size_t len;
|
||||
krb5_error_code ret;
|
||||
krb5_crypto crypto;
|
||||
|
||||
auth = malloc(sizeof(*auth));
|
||||
if (auth == NULL)
|
||||
@@ -129,10 +130,14 @@ krb5_build_authenticator (krb5_context context,
|
||||
}
|
||||
} while(ret == ASN1_OVERFLOW);
|
||||
|
||||
ret = krb5_encrypt (context, buf + buf_size - len, len,
|
||||
enctype,
|
||||
&cred->session,
|
||||
ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
|
||||
ret = krb5_encrypt (context,
|
||||
crypto,
|
||||
KRB5_KU_AP_REQ_AUTH,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
result);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -93,7 +93,7 @@ krb5_cc_resolve(krb5_context context,
|
||||
if(ret) return ret;
|
||||
}
|
||||
|
||||
for(i = 0; context->cc_ops[i].prefix && i < context->num_ops; i++)
|
||||
for(i = 0; i < context->num_ops && context->cc_ops[i].prefix; i++)
|
||||
if(strncmp(context->cc_ops[i].prefix, residual,
|
||||
strlen(context->cc_ops[i].prefix)) == 0){
|
||||
krb5_ccache p;
|
||||
@@ -187,9 +187,6 @@ krb5_cc_close(krb5_context context,
|
||||
{
|
||||
krb5_error_code ret;
|
||||
ret = id->ops->close(context, id);
|
||||
#if 0 /* XXX */
|
||||
free(id->residual);
|
||||
#endif
|
||||
free(id);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -40,9 +40,13 @@
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
/* these functions convert does what the normal asn.1-functions does,
|
||||
but converts the keytype to/from the on-the-wire enctypes */
|
||||
/* these functions does what the normal asn.1-functions does, but
|
||||
converts the keytype to/from the on-the-wire enctypes */
|
||||
|
||||
#if 1
|
||||
#define DECODE(T, K) return decode_ ## T((void*)data, length, t, len)
|
||||
#define ENCODE(T, K) return encode_ ## T(data, length, t, len)
|
||||
#else
|
||||
#define DECODE(T, K) \
|
||||
{ \
|
||||
krb5_error_code ret; \
|
||||
@@ -63,6 +67,7 @@ RCSID("$Id$");
|
||||
return ret; \
|
||||
return encode_ ## T(data, length, t, len); \
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
krb5_decode_EncTicketPart (krb5_context context,
|
||||
@@ -171,6 +176,9 @@ krb5_decode_EncKrbCredPart (krb5_context context,
|
||||
EncKrbCredPart *t,
|
||||
size_t *len)
|
||||
{
|
||||
#if 1
|
||||
return decode_EncKrbCredPart((void*)data, length, t, len);
|
||||
#else
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
ret = decode_EncKrbCredPart((void*)data, length, t, len);
|
||||
@@ -180,6 +188,7 @@ krb5_decode_EncKrbCredPart (krb5_context context,
|
||||
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1)))
|
||||
break;
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -189,6 +198,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
|
||||
EncKrbCredPart *t,
|
||||
size_t *len)
|
||||
{
|
||||
#if 0
|
||||
krb5_error_code ret = 0;
|
||||
int i;
|
||||
|
||||
@@ -196,6 +206,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
|
||||
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0)))
|
||||
break;
|
||||
if(ret) return ret;
|
||||
#endif
|
||||
return encode_EncKrbCredPart (data, length, t, len);
|
||||
}
|
||||
|
||||
@@ -206,6 +217,9 @@ krb5_decode_ETYPE_INFO (krb5_context context,
|
||||
ETYPE_INFO *t,
|
||||
size_t *len)
|
||||
{
|
||||
#if 1
|
||||
return decode_ETYPE_INFO((void*)data, length, t, len);
|
||||
#else
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
|
||||
@@ -217,6 +231,7 @@ krb5_decode_ETYPE_INFO (krb5_context context,
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -226,6 +241,7 @@ krb5_encode_ETYPE_INFO (krb5_context context,
|
||||
ETYPE_INFO *t,
|
||||
size_t *len)
|
||||
{
|
||||
#if 0
|
||||
krb5_error_code ret = 0;
|
||||
|
||||
int i;
|
||||
@@ -235,5 +251,6 @@ krb5_encode_ETYPE_INFO (krb5_context context,
|
||||
if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0)))
|
||||
break;
|
||||
if(ret) return ret;
|
||||
#endif
|
||||
return encode_ETYPE_INFO (data, length, t, len);
|
||||
}
|
||||
|
@@ -40,6 +40,8 @@
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
int issuid(void); /* XXX */
|
||||
|
||||
krb5_error_code
|
||||
krb5_init_context(krb5_context *context)
|
||||
{
|
||||
@@ -86,9 +88,6 @@ krb5_init_context(krb5_context *context)
|
||||
if (val >= 0)
|
||||
p->max_retries = val;
|
||||
|
||||
p->ktype_is_etype = krb5_config_get_bool(p, NULL, "libdefaults",
|
||||
"ktype_is_etype", NULL);
|
||||
|
||||
p->http_proxy = krb5_config_get_string(p, NULL, "libdefaults",
|
||||
"http_proxy", NULL);
|
||||
|
||||
@@ -101,7 +100,7 @@ krb5_init_context(krb5_context *context)
|
||||
for(i = 0; etypes[i]; i++);
|
||||
p->etypes = malloc((i+1) * sizeof(*p->etypes));
|
||||
for(j = 0, k = 0; j < i; j++) {
|
||||
if(krb5_string_to_etype(p, etypes[j], &p->etypes[k]) == 0)
|
||||
if(krb5_string_to_enctype(p, etypes[j], &p->etypes[k]) == 0)
|
||||
k++;
|
||||
}
|
||||
p->etypes[k] = ETYPE_NULL;
|
||||
@@ -169,24 +168,24 @@ krb5_error_code
|
||||
krb5_set_default_in_tkt_etypes(krb5_context context,
|
||||
const krb5_enctype *etypes)
|
||||
{
|
||||
int i;
|
||||
krb5_enctype *p = NULL;
|
||||
int i;
|
||||
krb5_enctype *p = NULL;
|
||||
|
||||
if(etypes) {
|
||||
i = 0;
|
||||
while(etypes[i])
|
||||
if(!krb5_etype_valid(context, etypes[i++]))
|
||||
return KRB5_PROG_ETYPE_NOSUPP;
|
||||
++i;
|
||||
ALLOC(p, i);
|
||||
if(!p)
|
||||
return ENOMEM;
|
||||
memmove(p, etypes, i * sizeof(krb5_enctype));
|
||||
}
|
||||
if(context->etypes)
|
||||
free(context->etypes);
|
||||
context->etypes = p;
|
||||
return 0;
|
||||
if(etypes) {
|
||||
i = 0;
|
||||
while(etypes[i])
|
||||
if(!krb5_enctype_valid(context, etypes[i++]))
|
||||
return KRB5_PROG_ETYPE_NOSUPP;
|
||||
++i;
|
||||
ALLOC(p, i);
|
||||
if(!p)
|
||||
return ENOMEM;
|
||||
memmove(p, etypes, i * sizeof(krb5_enctype));
|
||||
}
|
||||
if(context->etypes)
|
||||
free(context->etypes);
|
||||
context->etypes = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
2108
lib/krb5/crypto.c
Normal file
2108
lib/krb5/crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -46,17 +46,9 @@ krb5_generate_subkey(krb5_context context,
|
||||
krb5_keyblock **subkey)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_keyblock *k;
|
||||
|
||||
k = malloc(sizeof(**subkey));
|
||||
if (k == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ret = krb5_generate_random_keyblock(context, key->keytype, k);
|
||||
if(ret){
|
||||
free(k);
|
||||
return ret;
|
||||
}
|
||||
*subkey = k;
|
||||
return 0;
|
||||
ALLOC(*subkey, 1);
|
||||
ret = krb5_generate_random_keyblock(context, key->keytype, *subkey);
|
||||
if(ret)
|
||||
free(*subkey);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -103,8 +103,10 @@ make_pa_tgs_req(krb5_context context,
|
||||
}
|
||||
free_Ticket(&ticket);
|
||||
|
||||
ret = krb5_mk_req_extended(context, &ac, 0, &in_data, creds,
|
||||
&padata->padata_value);
|
||||
|
||||
ret = krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
|
||||
&padata->padata_value,
|
||||
KRB5_KU_TGS_REQ_AUTH_CKSUM);
|
||||
|
||||
}
|
||||
out:
|
||||
@@ -115,71 +117,6 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
init_tgs_req1(krb5_context context,
|
||||
krb5_authdata *authdata,
|
||||
krb5_creds *krbtgt,
|
||||
krb5_keyblock **subkey,
|
||||
TGS_REQ *t)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_auth_context ac;
|
||||
krb5_keyblock *key = NULL;
|
||||
|
||||
ret = krb5_auth_con_init(context, &ac);
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if(authdata->len){
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
krb5_enctype etype;
|
||||
|
||||
len = length_AuthorizationData(authdata);
|
||||
buf = malloc(len);
|
||||
if (buf == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
ret = encode_AuthorizationData(buf + len - 1, len, authdata, &len);
|
||||
ALLOC(t->req_body.enc_authorization_data, 1);
|
||||
if (t->req_body.enc_authorization_data == NULL) {
|
||||
free (buf);
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
krb5_keytype_to_etype(context, key->keytype, &etype);
|
||||
krb5_encrypt_EncryptedData(context, buf, len, etype, 0,
|
||||
key, t->req_body.enc_authorization_data);
|
||||
free (buf);
|
||||
} else {
|
||||
t->req_body.enc_authorization_data = NULL;
|
||||
}
|
||||
|
||||
ret = make_pa_tgs_req(context,
|
||||
ac,
|
||||
&t->req_body,
|
||||
t->padata->val,
|
||||
krbtgt);
|
||||
out:
|
||||
if (ret == 0)
|
||||
*subkey = key;
|
||||
else
|
||||
krb5_free_keyblock (context, key);
|
||||
krb5_auth_con_free(context, ac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
|
||||
* (if not-NULL), `in_creds', `krbtgt', and returning the generated
|
||||
@@ -204,19 +141,13 @@ init_tgs_req (krb5_context context,
|
||||
t->pvno = 5;
|
||||
t->msg_type = krb_tgs_req;
|
||||
if (in_creds->session.keytype) {
|
||||
krb5_enctype *etypes;
|
||||
|
||||
ret = krb5_keytype_to_etypes(context,
|
||||
in_creds->session.keytype,
|
||||
&etypes);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
krb5_enctype foo[2];
|
||||
foo[0] = in_creds->session.keytype;
|
||||
foo[1] = 0;
|
||||
ret = krb5_init_etype(context,
|
||||
&t->req_body.etype.len,
|
||||
&t->req_body.etype.val,
|
||||
etypes);
|
||||
free (etypes);
|
||||
foo);
|
||||
} else {
|
||||
ret = krb5_init_etype(context,
|
||||
&t->req_body.etype.len,
|
||||
@@ -224,27 +155,27 @@ init_tgs_req (krb5_context context,
|
||||
NULL);
|
||||
}
|
||||
if (ret)
|
||||
goto out;
|
||||
goto fail;
|
||||
t->req_body.addresses = addresses;
|
||||
t->req_body.kdc_options = flags.b;
|
||||
ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto fail;
|
||||
ALLOC(t->req_body.sname, 1);
|
||||
if (t->req_body.sname == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto fail;
|
||||
|
||||
/* req_body.till should be NULL if there is no endtime specified,
|
||||
but old MIT code (like DCE secd) doesn't like that */
|
||||
ALLOC(t->req_body.till, 1);
|
||||
if(t->req_body.till == NULL){
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
*t->req_body.till = in_creds->times.endtime;
|
||||
|
||||
@@ -253,31 +184,73 @@ init_tgs_req (krb5_context context,
|
||||
ALLOC(t->req_body.additional_tickets, 1);
|
||||
if (t->req_body.additional_tickets == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
ALLOC_SEQ(t->req_body.additional_tickets, 1);
|
||||
if (t->req_body.additional_tickets->val == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
ALLOC(t->padata, 1);
|
||||
if (t->padata == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
ALLOC_SEQ(t->padata, 1);
|
||||
if (t->padata->val == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = init_tgs_req1 (context, &in_creds->authdata, krbtgt, subkey, t);
|
||||
{
|
||||
krb5_auth_context ac;
|
||||
krb5_keyblock *key;
|
||||
ret = krb5_auth_con_init(context, &ac);
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
|
||||
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
|
||||
if(ret == ENOMEM)
|
||||
/* XXX */;
|
||||
|
||||
out:
|
||||
if(in_creds->authdata.len){
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
krb5_crypto crypto;
|
||||
len = length_AuthorizationData(&in_creds->authdata);
|
||||
buf = malloc(len);
|
||||
ret = encode_AuthorizationData(buf + len - 1, len, &in_creds->authdata, &len);
|
||||
ALLOC(t->req_body.enc_authorization_data, 1);
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
krb5_encrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
|
||||
/* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
|
||||
buf,
|
||||
len,
|
||||
0,
|
||||
t->req_body.enc_authorization_data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
}else
|
||||
t->req_body.enc_authorization_data = NULL;
|
||||
|
||||
|
||||
ret = make_pa_tgs_req(context,
|
||||
ac,
|
||||
&t->req_body,
|
||||
t->padata->val,
|
||||
krbtgt);
|
||||
if(ret)
|
||||
goto fail;
|
||||
*subkey = key;
|
||||
|
||||
krb5_auth_con_free(context, ac);
|
||||
}
|
||||
fail:
|
||||
if (ret)
|
||||
free_TGS_REQ (t);
|
||||
return ret;
|
||||
@@ -316,36 +289,36 @@ get_krbtgt(krb5_context context,
|
||||
/* DCE compatible decrypt proc */
|
||||
static krb5_error_code
|
||||
decrypt_tkt_with_subkey (krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_keyblock *key,
|
||||
krb5_key_usage usage,
|
||||
krb5_const_pointer subkey,
|
||||
krb5_kdc_rep *dec_rep)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data data;
|
||||
size_t size;
|
||||
krb5_data save;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ret = krb5_data_copy(&save, dec_rep->kdc_rep.enc_part.cipher.data,
|
||||
dec_rep->kdc_rep.enc_part.cipher.length);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
dec_rep->kdc_rep.enc_part.cipher.data,
|
||||
dec_rep->kdc_rep.enc_part.cipher.length,
|
||||
dec_rep->kdc_rep.enc_part.etype,
|
||||
key,
|
||||
&data);
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
usage,
|
||||
&dec_rep->kdc_rep.enc_part,
|
||||
&data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if(ret && subkey){
|
||||
ret = krb5_decrypt (context, save.data, save.length,
|
||||
dec_rep->kdc_rep.enc_part.etype,
|
||||
(krb5_keyblock*)subkey, /* local subkey */
|
||||
&data);
|
||||
/* DCE compat -- try to decrypt with subkey */
|
||||
krb5_crypto_init(context, (krb5_keyblock*)subkey, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY,
|
||||
&dec_rep->kdc_rep.enc_part,
|
||||
&data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
}
|
||||
krb5_data_free(&save);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
ret = krb5_decode_EncASRepPart(context,
|
||||
data.data,
|
||||
data.length,
|
||||
@@ -473,6 +446,7 @@ get_cred_kdc(krb5_context context,
|
||||
*out_creds,
|
||||
&krbtgt->session,
|
||||
NULL,
|
||||
KRB5_KU_TGS_REP_ENC_PART_SESSION,
|
||||
&krbtgt->addresses,
|
||||
nonce,
|
||||
TRUE,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@@ -95,17 +95,7 @@ krb5_get_forwarded_creds (krb5_context context,
|
||||
u_char buf[1024];
|
||||
int32_t sec, usec;
|
||||
krb5_kdc_flags kdc_flags;
|
||||
krb5_enctype enctype;
|
||||
|
||||
if (auth_context->enctype)
|
||||
enctype = auth_context->enctype;
|
||||
else {
|
||||
ret = krb5_keytype_to_etype (context,
|
||||
auth_context->local_subkey->keytype,
|
||||
&enctype);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
krb5_crypto crypto;
|
||||
|
||||
addrs.len = 0;
|
||||
addrs.val = NULL;
|
||||
@@ -226,13 +216,15 @@ krb5_get_forwarded_creds (krb5_context context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_crypto_init(context, auth_context->local_subkey, 0, &crypto);
|
||||
ret = krb5_encrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_CRED,
|
||||
buf + sizeof(buf) - len,
|
||||
len,
|
||||
enctype,
|
||||
0,
|
||||
auth_context->local_subkey,
|
||||
&cred.enc_part);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
free_KRB_CRED(&cred);
|
||||
return ret;
|
||||
|
@@ -65,6 +65,7 @@ krb5_get_host_realm(krb5_context context,
|
||||
const krb5_config_binding *l;
|
||||
struct in_addr addr;
|
||||
struct hostent *hostent;
|
||||
char *orig_host;
|
||||
|
||||
if (host == NULL) {
|
||||
if (gethostname (hostname, sizeof(hostname)))
|
||||
@@ -72,6 +73,8 @@ krb5_get_host_realm(krb5_context context,
|
||||
host = hostname;
|
||||
}
|
||||
|
||||
orig_host = host;
|
||||
|
||||
addr.s_addr = inet_addr(host);
|
||||
hostent = roken_gethostbyname (host);
|
||||
if (hostent == NULL && addr.s_addr != INADDR_NONE)
|
||||
@@ -111,6 +114,9 @@ krb5_get_host_realm(krb5_context context,
|
||||
} else {
|
||||
const char *dot = strchr (host, '.');
|
||||
|
||||
if (dot == NULL)
|
||||
dot = strchr (orig_host, '.');
|
||||
|
||||
if (dot != NULL) {
|
||||
(*realms)[0] = strdup (dot + 1);
|
||||
if ((*realms)[0] == NULL) {
|
||||
|
@@ -80,20 +80,25 @@ cleanup:
|
||||
|
||||
static krb5_error_code
|
||||
decrypt_tkt (krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_keyblock *key,
|
||||
unsigned usage,
|
||||
krb5_const_pointer decrypt_arg,
|
||||
krb5_kdc_rep *dec_rep)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data data;
|
||||
size_t size;
|
||||
krb5_crypto crypto;
|
||||
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
usage,
|
||||
&dec_rep->kdc_rep.enc_part,
|
||||
&data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
dec_rep->kdc_rep.enc_part.cipher.data,
|
||||
dec_rep->kdc_rep.enc_part.cipher.length,
|
||||
dec_rep->kdc_rep.enc_part.etype,
|
||||
key,
|
||||
&data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -119,6 +124,7 @@ _krb5_extract_ticket(krb5_context context,
|
||||
krb5_creds *creds,
|
||||
krb5_keyblock *key,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_key_usage key_usage,
|
||||
krb5_addresses *addrs,
|
||||
unsigned nonce,
|
||||
krb5_boolean allow_server_mismatch,
|
||||
@@ -147,12 +153,16 @@ _krb5_extract_ticket(krb5_context context,
|
||||
|
||||
/* extract ticket */
|
||||
{
|
||||
unsigned char buf[1024];
|
||||
unsigned char *buf;
|
||||
size_t len;
|
||||
encode_Ticket(buf + sizeof(buf) - 1, sizeof(buf),
|
||||
&rep->kdc_rep.ticket, &len);
|
||||
creds->ticket.data = malloc(len);
|
||||
memcpy(creds->ticket.data, buf + sizeof(buf) - len, len);
|
||||
len = length_Ticket(&rep->kdc_rep.ticket);
|
||||
buf = malloc(len);
|
||||
if(buf == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
encode_Ticket(buf + len - 1, len, &rep->kdc_rep.ticket, &len);
|
||||
creds->ticket.data = buf;
|
||||
creds->ticket.length = len;
|
||||
creds->second_ticket.length = 0;
|
||||
creds->second_ticket.data = NULL;
|
||||
@@ -183,7 +193,7 @@ _krb5_extract_ticket(krb5_context context,
|
||||
if (decrypt_proc == NULL)
|
||||
decrypt_proc = decrypt_tkt;
|
||||
|
||||
ret = (*decrypt_proc)(context, key, decryptarg, rep);
|
||||
ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -294,6 +304,7 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
|
||||
krb5_error_code ret;
|
||||
int32_t sec, usec;
|
||||
unsigned usec2;
|
||||
krb5_crypto crypto;
|
||||
|
||||
krb5_us_timeofday (context, &sec, &usec);
|
||||
p.patimestamp = sec;
|
||||
@@ -307,13 +318,15 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_encrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_PA_ENC_TIMESTAMP,
|
||||
buf + sizeof(buf) - len,
|
||||
len,
|
||||
etype,
|
||||
0,
|
||||
key,
|
||||
&encdata);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -338,31 +351,29 @@ add_padata(krb5_context context,
|
||||
krb5_principal client,
|
||||
krb5_key_proc key_proc,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keytype keytype,
|
||||
krb5_data *salt)
|
||||
krb5_enctype enctype,
|
||||
krb5_salt *salt)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
PA_DATA *pa2;
|
||||
krb5_keyblock *key;
|
||||
krb5_enctype etype;
|
||||
krb5_data salt2;
|
||||
krb5_salt salt2;
|
||||
|
||||
krb5_data_zero(&salt2);
|
||||
if(salt == NULL) {
|
||||
/* default to standard salt */
|
||||
ret = krb5_get_salt (client, &salt2);
|
||||
ret = krb5_get_pw_salt (context, client, &salt2);
|
||||
salt = &salt2;
|
||||
}
|
||||
ret = (*key_proc)(context, keytype, salt, keyseed, &key);
|
||||
krb5_data_free(&salt2);
|
||||
ret = (*key_proc)(context, enctype, *salt, keyseed, &key);
|
||||
if(salt == &salt2)
|
||||
krb5_free_salt(context, salt2);
|
||||
if (ret)
|
||||
return ret;
|
||||
pa2 = realloc(md->val, (md->len + 1) * sizeof(*md->val));
|
||||
if(pa2 == NULL)
|
||||
return ENOMEM;
|
||||
md->val = pa2;
|
||||
krb5_keytype_to_etype(context, keytype, &etype);
|
||||
ret = make_pa_enc_timestamp(context, &md->val[md->len], etype, key);
|
||||
ret = make_pa_enc_timestamp(context, &md->val[md->len], enctype, key);
|
||||
krb5_free_keyblock (context, key);
|
||||
if(ret)
|
||||
return ret;
|
||||
@@ -384,7 +395,7 @@ init_as_req (krb5_context context,
|
||||
AS_REQ *a)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data salt;
|
||||
krb5_salt salt;
|
||||
krb5_enctype etype;
|
||||
|
||||
memset(a, 0, sizeof(*a));
|
||||
@@ -478,29 +489,30 @@ init_as_req (krb5_context context,
|
||||
}
|
||||
a->padata->val = tmp;
|
||||
for(j = 0; j < preauth->val[i].info.len; j++) {
|
||||
krb5_keytype keytype = preauth->val[i].info.val[j].etype;
|
||||
if(preauth->val[i].info.val[j].salttype &&
|
||||
*preauth->val[i].info.val[j].salttype ==
|
||||
KRB5_PA_AFS3_SALT) {
|
||||
if(keytype != KEYTYPE_DES) {
|
||||
ret = KRB5_PROG_KEYTYPE_NOSUPP;
|
||||
goto fail;
|
||||
}
|
||||
keytype = KEYTYPE_DES_AFS3;
|
||||
}
|
||||
krb5_salt *sp = &salt;
|
||||
if(preauth->val[i].info.val[j].salttype)
|
||||
salt.salttype = *preauth->val[i].info.val[j].salttype;
|
||||
else
|
||||
salt.salttype = KRB5_PW_SALT;
|
||||
if(preauth->val[i].info.val[j].salt)
|
||||
salt.saltvalue = *preauth->val[i].info.val[j].salt;
|
||||
else
|
||||
if(salt.salttype == KRB5_PW_SALT)
|
||||
sp = NULL;
|
||||
else
|
||||
krb5_data_zero(&salt.saltvalue);
|
||||
add_padata(context, a->padata, creds->client,
|
||||
key_proc, keyseed, keytype,
|
||||
preauth->val[i].info.val[j].salt);
|
||||
key_proc, keyseed,
|
||||
preauth->val[i].info.val[j].etype,
|
||||
sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
/* not sure this is the way to use `ptypes' */
|
||||
if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
|
||||
a->padata = NULL;
|
||||
else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
|
||||
krb5_keytype keytype;
|
||||
ALLOC(a->padata, 1);
|
||||
if (a->padata == NULL) {
|
||||
ret = ENOMEM;
|
||||
@@ -509,18 +521,15 @@ init_as_req (krb5_context context,
|
||||
a->padata->len = 0;
|
||||
a->padata->val = NULL;
|
||||
|
||||
ret = krb5_etype_to_keytype(context, etype, &keytype);
|
||||
if(ret)
|
||||
goto fail;
|
||||
|
||||
/* make a v5 salted pa-data */
|
||||
add_padata(context, a->padata, creds->client,
|
||||
key_proc, keyseed, keytype, NULL);
|
||||
key_proc, keyseed, etype, NULL);
|
||||
|
||||
/* make a v4 salted pa-data */
|
||||
krb5_data_zero(&salt);
|
||||
salt.salttype = KRB5_PW_SALT;
|
||||
krb5_data_zero(&salt.saltvalue);
|
||||
add_padata(context, a->padata, creds->client,
|
||||
key_proc, keyseed, keytype, &salt);
|
||||
key_proc, keyseed, etype, &salt);
|
||||
} else {
|
||||
ret = KRB5_PREAUTH_BAD_TYPE;
|
||||
goto fail;
|
||||
@@ -550,7 +559,7 @@ krb5_get_in_cred(krb5_context context,
|
||||
krb5_kdc_rep rep;
|
||||
krb5_data req, resp;
|
||||
char buf[BUFSIZ];
|
||||
krb5_data salt;
|
||||
krb5_salt salt;
|
||||
krb5_keyblock *key;
|
||||
size_t size;
|
||||
krb5_kdc_flags opts;
|
||||
@@ -627,32 +636,33 @@ krb5_get_in_cred(krb5_context context,
|
||||
}
|
||||
}
|
||||
if(pa) {
|
||||
krb5_keytype keytype;
|
||||
ret = krb5_etype_to_keytype(context, etype, &keytype);
|
||||
if(pa->padata_type == pa_afs3_salt){
|
||||
if(keytype != KEYTYPE_DES)
|
||||
return KRB5_PROG_KEYTYPE_NOSUPP;
|
||||
keytype = KEYTYPE_DES_AFS3;
|
||||
}
|
||||
ret = (*key_proc)(context, keytype, &pa->padata_value, keyseed, &key);
|
||||
salt.salttype = pa->padata_type;
|
||||
salt.saltvalue = pa->padata_value;
|
||||
|
||||
ret = (*key_proc)(context, etype, salt, keyseed, &key);
|
||||
} else {
|
||||
/* make a v5 salted pa-data */
|
||||
krb5_keytype keytype;
|
||||
salt.length = 0;
|
||||
salt.data = NULL;
|
||||
ret = krb5_get_salt (creds->client, &salt);
|
||||
ret = krb5_get_pw_salt (context, creds->client, &salt);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = krb5_etype_to_keytype(context, etype, &keytype);
|
||||
ret = (*key_proc)(context, keytype, &salt, keyseed, &key);
|
||||
krb5_data_free (&salt);
|
||||
ret = (*key_proc)(context, etype, salt, keyseed, &key);
|
||||
krb5_free_salt(context, salt);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = _krb5_extract_ticket(context, &rep, creds, key, keyseed,
|
||||
NULL, nonce, FALSE, decrypt_proc, decryptarg);
|
||||
ret = _krb5_extract_ticket(context,
|
||||
&rep,
|
||||
creds,
|
||||
key,
|
||||
keyseed,
|
||||
KRB5_KU_AS_REP_ENC_PART,
|
||||
NULL,
|
||||
nonce,
|
||||
FALSE,
|
||||
decrypt_proc,
|
||||
decryptarg);
|
||||
memset (key->keyvalue.data, 0, key->keyvalue.length);
|
||||
krb5_free_keyblock_contents (context, key);
|
||||
free (key);
|
||||
|
@@ -42,28 +42,25 @@ RCSID("$Id$");
|
||||
|
||||
krb5_error_code
|
||||
krb5_password_key_proc (krb5_context context,
|
||||
krb5_keytype type,
|
||||
krb5_data *salt,
|
||||
krb5_enctype type,
|
||||
krb5_salt salt,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
char *password = (char *)keyseed;
|
||||
char buf[BUFSIZ];
|
||||
krb5_error_code ret;
|
||||
char *password = (char *)keyseed;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
*key = malloc (sizeof (**key));
|
||||
if (*key == NULL)
|
||||
return ENOMEM;
|
||||
(*key)->keytype = type;
|
||||
(*key)->keyvalue.length = 0;
|
||||
(*key)->keyvalue.data = NULL;
|
||||
if (password == NULL) {
|
||||
des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
|
||||
password = buf;
|
||||
}
|
||||
ret = krb5_string_to_key (password, salt, type, *key);
|
||||
memset (buf, 0, sizeof(buf));
|
||||
return ret;
|
||||
*key = malloc (sizeof (**key));
|
||||
if (*key == NULL)
|
||||
return ENOMEM;
|
||||
if (password == NULL) {
|
||||
des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
|
||||
password = buf;
|
||||
}
|
||||
ret = krb5_string_to_key_salt (context, type, password, salt, *key);
|
||||
memset (buf, 0, sizeof(buf));
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
|
@@ -42,8 +42,8 @@ RCSID("$Id$");
|
||||
|
||||
krb5_error_code
|
||||
krb5_keytab_key_proc (krb5_context context,
|
||||
krb5_keytype type,
|
||||
krb5_data *salt,
|
||||
krb5_enctype enctype,
|
||||
krb5_salt salt,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
@@ -60,7 +60,7 @@ krb5_keytab_key_proc (krb5_context context,
|
||||
real_keytab = keytab;
|
||||
|
||||
ret = krb5_kt_get_entry (context, real_keytab, principal,
|
||||
0, type, &entry);
|
||||
0, enctype, &entry);
|
||||
|
||||
if (keytab == NULL)
|
||||
krb5_kt_close (context, real_keytab);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -42,8 +42,8 @@ RCSID("$Id$");
|
||||
|
||||
static krb5_error_code
|
||||
krb5_skey_key_proc (krb5_context context,
|
||||
krb5_keytype type,
|
||||
krb5_data *salt,
|
||||
krb5_enctype type,
|
||||
krb5_salt salt,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
|
@@ -11,5 +11,6 @@ prefix HEIM_ERR
|
||||
|
||||
error_code LOG_PARSE, "Error parsing log destination"
|
||||
error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal"
|
||||
error_code SALTTYPE_NOSUPP, "Salt type is not supported by enctype"
|
||||
|
||||
end
|
||||
|
@@ -132,7 +132,7 @@ krb5_kt_read_service_key(krb5_context context,
|
||||
krb5_pointer keyprocarg,
|
||||
krb5_principal principal,
|
||||
krb5_kvno vno,
|
||||
krb5_keytype keytype,
|
||||
krb5_enctype enctype,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
krb5_keytab keytab;
|
||||
@@ -147,7 +147,7 @@ krb5_kt_read_service_key(krb5_context context,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = krb5_kt_get_entry (context, keytab, principal, vno, keytype, &entry);
|
||||
r = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
|
||||
krb5_kt_close (context, keytab);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -191,14 +191,14 @@ kt_compare(krb5_context context,
|
||||
krb5_keytab_entry *entry,
|
||||
krb5_const_principal principal,
|
||||
krb5_kvno vno,
|
||||
krb5_keytype keytype)
|
||||
krb5_enctype enctype)
|
||||
{
|
||||
if(principal != NULL &&
|
||||
!krb5_principal_compare(context, entry->principal, principal))
|
||||
return FALSE;
|
||||
if(vno && vno != entry->vno)
|
||||
return FALSE;
|
||||
if(keytype && keytype != entry->keyblock.keytype)
|
||||
if(enctype && enctype != entry->keyblock.keytype)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -208,14 +208,14 @@ krb5_kt_get_entry(krb5_context context,
|
||||
krb5_keytab id,
|
||||
krb5_const_principal principal,
|
||||
krb5_kvno kvno,
|
||||
krb5_keytype keytype,
|
||||
krb5_enctype enctype,
|
||||
krb5_keytab_entry *entry)
|
||||
{
|
||||
krb5_keytab_entry tmp;
|
||||
krb5_error_code r;
|
||||
krb5_kt_cursor cursor;
|
||||
|
||||
if(id->get) return (*id->get)(context, id, principal, kvno, keytype, entry);
|
||||
if(id->get) return (*id->get)(context, id, principal, kvno, enctype, entry);
|
||||
|
||||
r = krb5_kt_start_seq_get (context, id, &cursor);
|
||||
if (r)
|
||||
@@ -223,7 +223,7 @@ krb5_kt_get_entry(krb5_context context,
|
||||
|
||||
entry->vno = 0;
|
||||
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
|
||||
if (kt_compare(context, &tmp, principal, 0, keytype)) {
|
||||
if (kt_compare(context, &tmp, principal, 0, enctype)) {
|
||||
if (kvno == tmp.vno) {
|
||||
krb5_kt_copy_entry_contents (context, &tmp, entry);
|
||||
krb5_kt_free_entry (context, &tmp);
|
||||
|
103
lib/krb5/krb5.h
103
lib/krb5/krb5.h
@@ -71,6 +71,9 @@ typedef const void *krb5_const_pointer;
|
||||
|
||||
typedef octet_string krb5_data;
|
||||
|
||||
struct krb5_crypto_data;
|
||||
typedef struct krb5_crypto_data *krb5_crypto;
|
||||
|
||||
typedef enum krb5_cksumtype {
|
||||
CKSUMTYPE_NONE = 0,
|
||||
CKSUMTYPE_CRC32 = 1,
|
||||
@@ -93,11 +96,20 @@ typedef enum krb5_enctype {
|
||||
ETYPE_DES_CBC_MD4 = 2,
|
||||
ETYPE_DES_CBC_MD5 = 3,
|
||||
ETYPE_DES3_CBC_MD5 = 5,
|
||||
ETYPE_DES3_CBC_SHA1 = 7,
|
||||
#if NEW_DES3_CODE
|
||||
ETYPE_NEW_DES3_CBC_SHA1 = 7,
|
||||
ETYPE_DES3_CBC_SHA1 = ETYPE_NEW_DES3_CBC_SHA1,
|
||||
#else
|
||||
ETYPE_OLD_DES3_CBC_SHA1 = 7,
|
||||
ETYPE_NEW_DES3_CBC_SHA1 = 99,
|
||||
ETYPE_DES3_CBC_SHA1 = ETYPE_OLD_DES3_CBC_SHA1,
|
||||
#endif
|
||||
ETYPE_SIGN_DSA_GENERATE = 8,
|
||||
ETYPE_ENCRYPT_RSA_PRIV = 9,
|
||||
ETYPE_ENCRYPT_RSA_PUB = 10,
|
||||
ETYPE_ENCTYPE_PK_CROSS = 48
|
||||
ETYPE_ENCTYPE_PK_CROSS = 48,
|
||||
ETYPE_DES_CBC_NONE = 0x1000,
|
||||
ETYPE_DES3_CBC_NONE = 0x1001
|
||||
} krb5_enctype;
|
||||
|
||||
typedef enum krb5_preauthtype {
|
||||
@@ -108,11 +120,73 @@ typedef enum krb5_preauthtype {
|
||||
KRB5_PADATA_ENC_SECURID
|
||||
} krb5_preauthtype;
|
||||
|
||||
typedef enum krb5_key_usage {
|
||||
KRB5_KU_PA_ENC_TIMESTAMP = 1,
|
||||
/* AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
|
||||
client key (section 5.4.1) */
|
||||
KRB5_KU_TICKET = 2,
|
||||
/* AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
|
||||
application session key), encrypted with the service key
|
||||
(section 5.4.2) */
|
||||
KRB5_KU_AS_REP_ENC_PART = 3,
|
||||
/* AS-REP encrypted part (includes tgs session key or application
|
||||
session key), encrypted with the client key (section 5.4.2) */
|
||||
KRB5_KU_TGS_REQ_AUTH_DAT_SESSION = 4,
|
||||
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
|
||||
session key (section 5.4.1) */
|
||||
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY = 5,
|
||||
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
|
||||
authenticator subkey (section 5.4.1) */
|
||||
KRB5_KU_TGS_REQ_AUTH_CKSUM = 6,
|
||||
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
|
||||
with the tgs session key (sections 5.3.2, 5.4.1) */
|
||||
KRB5_KU_TGS_REQ_AUTH = 7,
|
||||
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
|
||||
authenticator subkey), encrypted with the tgs session key
|
||||
(section 5.3.2) */
|
||||
KRB5_KU_TGS_REP_ENC_PART_SESSION = 8,
|
||||
/* TGS-REP encrypted part (includes application session key),
|
||||
encrypted with the tgs session key (section 5.4.2) */
|
||||
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY = 9,
|
||||
/* TGS-REP encrypted part (includes application session key),
|
||||
encrypted with the tgs authenticator subkey (section 5.4.2) */
|
||||
KRB5_KU_AP_REQ_AUTH_CKSUM = 10,
|
||||
/* AP-REQ Authenticator cksum, keyed with the application session
|
||||
key (section 5.3.2) */
|
||||
KRB5_KU_AP_REQ_AUTH = 11,
|
||||
/* AP-REQ Authenticator (includes application authenticator
|
||||
subkey), encrypted with the application session key (section
|
||||
5.3.2) */
|
||||
KRB5_KU_AP_REQ_ENC_PART = 12,
|
||||
/* AP-REP encrypted part (includes application session subkey),
|
||||
encrypted with the application session key (section 5.5.2) */
|
||||
KRB5_KU_KRB_PRIV = 13,
|
||||
/* KRB-PRIV encrypted part, encrypted with a key chosen by the
|
||||
application (section 5.7.1) */
|
||||
KRB5_KU_KRB_CRED = 14,
|
||||
/* KRB-CRED encrypted part, encrypted with a key chosen by the
|
||||
application (section 5.8.1) */
|
||||
KRB5_KU_KRB_SAFE_CKSUM = 15,
|
||||
/* KRB-SAFE cksum, keyed with a key chosen by the application
|
||||
(section 5.6.1) */
|
||||
KRB5_KU_OTHER_ENCRYPTED = 16,
|
||||
/* Data which is defined in some specification outside of
|
||||
Kerberos to be encrypted using an RFC1510 encryption type. */
|
||||
KRB5_KU_OTHER_CKSUM = 17
|
||||
/* Data which is defined in some specification outside of
|
||||
Kerberos to be checksummed using an RFC1510 checksum type. */
|
||||
} krb5_key_usage;
|
||||
|
||||
typedef enum krb5_salttype {
|
||||
KRB5_PA_PW_SALT = pa_pw_salt,
|
||||
KRB5_PA_AFS3_SALT = pa_afs3_salt
|
||||
KRB5_PW_SALT = pa_pw_salt,
|
||||
KRB5_AFS3_SALT = pa_afs3_salt
|
||||
}krb5_salttype;
|
||||
|
||||
typedef struct krb5_salt {
|
||||
krb5_salttype salttype;
|
||||
krb5_data saltvalue;
|
||||
} krb5_salt;
|
||||
|
||||
typedef ETYPE_INFO krb5_preauthinfo;
|
||||
|
||||
typedef struct {
|
||||
@@ -139,14 +213,10 @@ typedef HostAddress krb5_address;
|
||||
|
||||
typedef HostAddresses krb5_addresses;
|
||||
|
||||
#define KEYTYPE_USE_AFS3_SALT 0x10000 /* XXX */
|
||||
#define KEYTYPE_KEYTYPE_MASK 0xffff /* XXX */
|
||||
|
||||
typedef enum krb5_keytype {
|
||||
KEYTYPE_NULL = 0,
|
||||
KEYTYPE_DES = 1,
|
||||
KEYTYPE_DES3 = 7,
|
||||
KEYTYPE_DES_AFS3 = KEYTYPE_DES | KEYTYPE_USE_AFS3_SALT
|
||||
KEYTYPE_DES3 = 7
|
||||
} krb5_keytype;
|
||||
|
||||
typedef EncryptionKey krb5_keyblock;
|
||||
@@ -158,7 +228,6 @@ struct krb5_cc_ops;
|
||||
#define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_"
|
||||
|
||||
typedef struct krb5_ccache_data {
|
||||
char *residual;
|
||||
struct krb5_cc_ops *ops;
|
||||
krb5_data data;
|
||||
}krb5_ccache_data;
|
||||
@@ -289,7 +358,6 @@ typedef struct krb5_context_data {
|
||||
struct krb5_log_facility *warn_dest;
|
||||
krb5_cc_ops *cc_ops;
|
||||
int num_ops;
|
||||
krb5_boolean ktype_is_etype;
|
||||
const char *http_proxy;
|
||||
const char *time_fmt;
|
||||
krb5_boolean log_utc;
|
||||
@@ -351,7 +419,7 @@ struct krb5_keytab_data {
|
||||
krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
|
||||
krb5_error_code (*close)(krb5_context, krb5_keytab);
|
||||
krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
|
||||
krb5_kvno, krb5_keytype, krb5_keytab_entry*);
|
||||
krb5_kvno, krb5_enctype, krb5_keytab_entry*);
|
||||
krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
|
||||
krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
|
||||
krb5_keytab_entry*, krb5_kt_cursor*);
|
||||
@@ -378,9 +446,7 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct krb5_auth_context_data {
|
||||
int32_t flags;
|
||||
krb5_cksumtype cksumtype;
|
||||
krb5_enctype enctype;
|
||||
unsigned int flags;
|
||||
|
||||
krb5_address *local_address;
|
||||
krb5_address *remote_address;
|
||||
@@ -443,12 +509,13 @@ typedef int (*krb5_prompter_fct)(krb5_context context,
|
||||
krb5_prompt prompts[]);
|
||||
|
||||
typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
|
||||
krb5_keytype type,
|
||||
krb5_data *salt,
|
||||
krb5_enctype type,
|
||||
krb5_salt salt,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keyblock **key);
|
||||
typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_keyblock *key,
|
||||
krb5_key_usage usage,
|
||||
krb5_const_pointer decrypt_arg,
|
||||
krb5_kdc_rep *dec_rep);
|
||||
|
||||
|
@@ -38,31 +38,33 @@ error_code SERVER_NOMATCH, "Requested server and ticket don't match"
|
||||
|
||||
# 27-30 are reserved
|
||||
index 31
|
||||
prefix KRB5KRB_AP_ERR
|
||||
error_code BAD_INTEGRITY, "Decrypt integrity check failed"
|
||||
error_code TKT_EXPIRED, "Ticket expired"
|
||||
error_code TKT_NYV, "Ticket not yet valid"
|
||||
error_code REPEAT, "Request is a replay"
|
||||
error_code NOT_US, "The ticket isn't for us"
|
||||
error_code BADMATCH, "Ticket/authenticator don't match"
|
||||
error_code SKEW, "Clock skew too great"
|
||||
error_code BADADDR, "Incorrect net address"
|
||||
error_code BADVERSION, "Protocol version mismatch"
|
||||
error_code MSG_TYPE, "Invalid message type"
|
||||
error_code MODIFIED, "Message stream modified"
|
||||
error_code BADORDER, "Message out of order"
|
||||
error_code ILL_CR_TKT, "Illegal cross-realm ticket"
|
||||
error_code BADKEYVER, "Key version is not available"
|
||||
error_code NOKEY, "Service key not available"
|
||||
error_code MUT_FAIL, "Mutual authentication failed"
|
||||
error_code BADDIRECTION, "Incorrect message direction"
|
||||
error_code METHOD, "Alternative authentication method required"
|
||||
error_code BADSEQ, "Incorrect sequence number in message"
|
||||
error_code INAPP_CKSUM, "Inappropriate type of checksum in message"
|
||||
prefix KRB5KRB_AP
|
||||
error_code ERR_BAD_INTEGRITY, "Decrypt integrity check failed"
|
||||
error_code ERR_TKT_EXPIRED, "Ticket expired"
|
||||
error_code ERR_TKT_NYV, "Ticket not yet valid"
|
||||
error_code ERR_REPEAT, "Request is a replay"
|
||||
error_code ERR_NOT_US, "The ticket isn't for us"
|
||||
error_code ERR_BADMATCH, "Ticket/authenticator don't match"
|
||||
error_code ERR_SKEW, "Clock skew too great"
|
||||
error_code ERR_BADADDR, "Incorrect net address"
|
||||
error_code ERR_BADVERSION, "Protocol version mismatch"
|
||||
error_code ERR_MSG_TYPE, "Invalid message type"
|
||||
error_code ERR_MODIFIED, "Message stream modified"
|
||||
error_code ERR_BADORDER, "Message out of order"
|
||||
error_code ERR_ILL_CR_TKT, "Illegal cross-realm ticket"
|
||||
error_code ERR_BADKEYVER, "Key version is not available"
|
||||
error_code ERR_NOKEY, "Service key not available"
|
||||
error_code ERR_MUT_FAIL, "Mutual authentication failed"
|
||||
error_code ERR_BADDIRECTION, "Incorrect message direction"
|
||||
error_code ERR_METHOD, "Alternative authentication method required"
|
||||
error_code ERR_BADSEQ, "Incorrect sequence number in message"
|
||||
error_code ERR_INAPP_CKSUM, "Inappropriate type of checksum in message"
|
||||
error_code PATH_NOT_ACCEPTED, "Policy rejects transited path"
|
||||
|
||||
# 51-59 are reserved
|
||||
index 60
|
||||
prefix KRB5KRB_ERR
|
||||
error_code RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP"
|
||||
# 53-59 are reserved
|
||||
index 60
|
||||
error_code GENERIC, "Generic error (see e-text)"
|
||||
error_code FIELD_TOOLONG, "Field is too long for this implementation"
|
||||
|
||||
|
@@ -62,7 +62,7 @@ krb5_mk_priv(krb5_context context,
|
||||
int32_t sec, usec;
|
||||
KerberosTime sec2;
|
||||
unsigned usec2;
|
||||
krb5_enctype enctype;
|
||||
krb5_crypto crypto;
|
||||
|
||||
/* XXX - Is this right? */
|
||||
|
||||
@@ -73,14 +73,6 @@ krb5_mk_priv(krb5_context context,
|
||||
else
|
||||
key = auth_context->keyblock;
|
||||
|
||||
if (auth_context->enctype)
|
||||
enctype = auth_context->enctype;
|
||||
else {
|
||||
ret = krb5_keytype_to_etype (context, key->keytype, &enctype);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_us_timeofday (context, &sec, &usec);
|
||||
|
||||
part.user_data = *userdata;
|
||||
@@ -127,11 +119,17 @@ krb5_mk_priv(krb5_context context,
|
||||
|
||||
s.pvno = 5;
|
||||
s.msg_type = krb_priv;
|
||||
s.enc_part.etype = enctype;
|
||||
s.enc_part.etype = key->keytype;
|
||||
s.enc_part.kvno = NULL;
|
||||
|
||||
ret = krb5_encrypt (context, buf + buf_size - len, len,
|
||||
enctype, key, &s.enc_part.cipher);
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_encrypt (context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_PRIV,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
&s.enc_part.cipher);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
free(buf);
|
||||
return ret;
|
||||
|
@@ -48,10 +48,10 @@ krb5_mk_rep(krb5_context context,
|
||||
krb5_error_code ret;
|
||||
AP_REP ap;
|
||||
EncAPRepPart body;
|
||||
krb5_enctype etype;
|
||||
u_char *buf = NULL;
|
||||
size_t buf_size;
|
||||
size_t len;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ap.pvno = 5;
|
||||
ap.msg_type = krb_ap_rep;
|
||||
@@ -72,86 +72,50 @@ krb5_mk_rep(krb5_context context,
|
||||
} else
|
||||
body.seq_number = NULL;
|
||||
|
||||
krb5_keytype_to_etype(context, (*auth_context)->keyblock->keytype, &etype);
|
||||
ap.enc_part.etype = etype;
|
||||
ap.enc_part.etype = (*auth_context)->keyblock->keytype;
|
||||
ap.enc_part.kvno = NULL;
|
||||
|
||||
buf_size = 1024;
|
||||
buf_size = length_EncAPRepPart(&body);
|
||||
buf = malloc (buf_size);
|
||||
if (buf == NULL) {
|
||||
free_EncAPRepPart (&body);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = krb5_encode_EncAPRepPart (context, buf + buf_size - 1,
|
||||
buf_size,
|
||||
&body, &len);
|
||||
if (ret) {
|
||||
if (ret == ASN1_OVERFLOW) {
|
||||
u_char *tmp;
|
||||
|
||||
buf_size *= 2;
|
||||
tmp = realloc (buf, buf_size);
|
||||
if (tmp == NULL) {
|
||||
free(buf);
|
||||
free_EncAPRepPart (&body);
|
||||
return ENOMEM;
|
||||
}
|
||||
buf = tmp;
|
||||
} else {
|
||||
free_EncAPRepPart (&body);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} while(ret == ASN1_OVERFLOW);
|
||||
ret = krb5_encode_EncAPRepPart (context,
|
||||
buf + buf_size - 1,
|
||||
buf_size,
|
||||
&body,
|
||||
&len);
|
||||
|
||||
free_EncAPRepPart (&body);
|
||||
krb5_crypto_init(context, (*auth_context)->keyblock,
|
||||
0 /* ap.enc_part.etype */, &crypto);
|
||||
ret = krb5_encrypt (context,
|
||||
buf + buf_size - len, len,
|
||||
ap.enc_part.etype,
|
||||
(*auth_context)->keyblock,
|
||||
crypto,
|
||||
KRB5_KU_AP_REQ_ENC_PART,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
&ap.enc_part.cipher);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
free(buf);
|
||||
free_EncAPRepPart (&body);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
|
||||
if (ret) {
|
||||
if (ret == ASN1_OVERFLOW) {
|
||||
u_char *tmp;
|
||||
|
||||
buf_size *= 2;
|
||||
tmp = realloc (buf, buf_size);
|
||||
if (tmp == NULL) {
|
||||
free_AP_REP (&ap);
|
||||
free_EncAPRepPart (&body);
|
||||
free (buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
buf = tmp;
|
||||
} else {
|
||||
free_AP_REP (&ap);
|
||||
free_EncAPRepPart (&body);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} while (ret == ASN1_OVERFLOW);
|
||||
|
||||
free_AP_REP (&ap);
|
||||
free_EncAPRepPart (&body);
|
||||
|
||||
outbuf->length = len;
|
||||
outbuf->data = malloc(len);
|
||||
if (outbuf->data == NULL) {
|
||||
free (buf);
|
||||
buf_size = length_AP_REP(&ap);
|
||||
buf = realloc(buf, buf_size);
|
||||
if(buf == NULL) {
|
||||
free_AP_REP (&ap);
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy(outbuf->data, buf + buf_size - len, len);
|
||||
free (buf);
|
||||
ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
|
||||
|
||||
free_AP_REP (&ap);
|
||||
|
||||
if(len != buf_size)
|
||||
abort();
|
||||
outbuf->data = buf;
|
||||
outbuf->length = len;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -82,9 +82,8 @@ krb5_mk_req(krb5_context context,
|
||||
if (r)
|
||||
return r;
|
||||
this_cred.times.endtime = 0;
|
||||
if (auth_context && *auth_context && (*auth_context)->enctype)
|
||||
krb5_etype_to_keytype(context, (*auth_context)->enctype,
|
||||
&this_cred.session.keytype);
|
||||
if (auth_context && *auth_context && (*auth_context)->keyblock)
|
||||
this_cred.session.keytype = (*auth_context)->keyblock->keytype;
|
||||
|
||||
r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
|
||||
if (r)
|
||||
|
@@ -41,20 +41,19 @@
|
||||
RCSID("$Id$");
|
||||
|
||||
krb5_error_code
|
||||
krb5_mk_req_extended(krb5_context context,
|
||||
krb5_mk_req_internal(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_flags ap_req_options,
|
||||
krb5_data *in_data,
|
||||
krb5_creds *in_creds,
|
||||
krb5_data *outbuf)
|
||||
krb5_data *outbuf,
|
||||
krb5_key_usage usage)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data authenticator;
|
||||
Checksum c;
|
||||
Checksum *c_opt;
|
||||
krb5_cksumtype cksumtype;
|
||||
krb5_auth_context ac;
|
||||
krb5_enctype enctype;
|
||||
|
||||
if(auth_context) {
|
||||
if(*auth_context == NULL)
|
||||
@@ -67,6 +66,7 @@ krb5_mk_req_extended(krb5_context context,
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
#if 0
|
||||
{
|
||||
/* This is somewhat bogus since we're possibly overwriting a
|
||||
value specified by the user, but it's the easiest way to make
|
||||
@@ -78,9 +78,9 @@ krb5_mk_req_extended(krb5_context context,
|
||||
in_creds->ticket.length,
|
||||
&ticket,
|
||||
NULL);
|
||||
krb5_etype_to_keytype (context,
|
||||
ticket.enc_part.etype,
|
||||
&ticket_keytype);
|
||||
krb5_enctype_to_keytype (context,
|
||||
ticket.enc_part.etype,
|
||||
&ticket_keytype);
|
||||
|
||||
if (ticket_keytype == in_creds->session.keytype)
|
||||
krb5_auth_setenctype(context,
|
||||
@@ -88,32 +88,22 @@ krb5_mk_req_extended(krb5_context context,
|
||||
ticket.enc_part.etype);
|
||||
free_Ticket(&ticket);
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_free_keyblock(context, ac->keyblock);
|
||||
krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock);
|
||||
|
||||
if (ac->enctype)
|
||||
enctype = ac->enctype;
|
||||
else {
|
||||
ret = krb5_keytype_to_etype(context,
|
||||
ac->keyblock->keytype,
|
||||
&enctype);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ac->cksumtype)
|
||||
cksumtype = ac->cksumtype;
|
||||
else
|
||||
krb5_keytype_to_cksumtype (context, ac->keyblock->keytype, &cksumtype);
|
||||
|
||||
if (in_data) {
|
||||
ret = krb5_create_checksum (context,
|
||||
cksumtype,
|
||||
in_data->data,
|
||||
in_data->length,
|
||||
ac->keyblock,
|
||||
&c);
|
||||
krb5_crypto crypto;
|
||||
krb5_crypto_init(context, ac->keyblock, 0, &crypto);
|
||||
ret = krb5_create_checksum(context,
|
||||
crypto,
|
||||
usage,
|
||||
in_data->data,
|
||||
in_data->length,
|
||||
&c);
|
||||
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
c_opt = &c;
|
||||
} else {
|
||||
c_opt = NULL;
|
||||
@@ -121,7 +111,7 @@ krb5_mk_req_extended(krb5_context context,
|
||||
|
||||
ret = krb5_build_authenticator (context,
|
||||
ac,
|
||||
enctype,
|
||||
ac->keyblock->keytype,
|
||||
in_creds,
|
||||
c_opt,
|
||||
NULL,
|
||||
@@ -131,9 +121,26 @@ krb5_mk_req_extended(krb5_context context,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_build_ap_req (context, enctype, in_creds, ap_req_options,
|
||||
authenticator, outbuf);
|
||||
ret = krb5_build_ap_req (context, ac->keyblock->keytype,
|
||||
in_creds, ap_req_options, authenticator, outbuf);
|
||||
if(auth_context == NULL)
|
||||
krb5_auth_con_free(context, ac);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_mk_req_extended(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_flags ap_req_options,
|
||||
krb5_data *in_data,
|
||||
krb5_creds *in_creds,
|
||||
krb5_data *outbuf)
|
||||
{
|
||||
return krb5_mk_req_internal (context,
|
||||
auth_context,
|
||||
ap_req_options,
|
||||
in_data,
|
||||
in_creds,
|
||||
outbuf,
|
||||
KRB5_KU_AP_REQ_AUTH_CKSUM);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -56,17 +56,7 @@ krb5_mk_safe(krb5_context context,
|
||||
size_t buf_size;
|
||||
size_t len;
|
||||
unsigned tmp_seq;
|
||||
krb5_cksumtype cksumtype;
|
||||
|
||||
if (auth_context->cksumtype)
|
||||
cksumtype = auth_context->cksumtype;
|
||||
else {
|
||||
ret = krb5_keytype_to_cksumtype (context,
|
||||
auth_context->keyblock->keytype,
|
||||
&cksumtype);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
krb5_crypto crypto;
|
||||
|
||||
s.pvno = 5;
|
||||
s.msg_type = krb_safe;
|
||||
@@ -92,68 +82,30 @@ krb5_mk_safe(krb5_context context,
|
||||
s.cksum.checksum.length = 0;
|
||||
|
||||
|
||||
buf_size = 1024;
|
||||
buf = malloc (buf_size);
|
||||
if (buf == NULL) {
|
||||
buf_size = length_KRB_SAFE(&s);
|
||||
buf = malloc(buf_size + 128); /* add some for checksum */
|
||||
if(buf == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1,
|
||||
buf_size,
|
||||
&s,
|
||||
&len);
|
||||
if (ret) {
|
||||
if (ret == ASN1_OVERFLOW) {
|
||||
u_char *tmp;
|
||||
|
||||
buf_size *= 2;
|
||||
tmp = realloc (buf, buf_size);
|
||||
if (tmp == NULL) {
|
||||
free (buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
buf = tmp;
|
||||
} else {
|
||||
free (buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
} while (ret == ASN1_OVERFLOW);
|
||||
|
||||
ret = krb5_create_checksum (context,
|
||||
cksumtype,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
auth_context->keyblock,
|
||||
&s.cksum);
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
|
||||
ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
|
||||
ret = krb5_create_checksum(context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_SAFE_CKSUM,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
&s.cksum);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
free (buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
|
||||
if (ret) {
|
||||
if (ret == ASN1_OVERFLOW) {
|
||||
u_char *tmp;
|
||||
|
||||
buf_size *= 2;
|
||||
tmp = realloc (buf, buf_size);
|
||||
if (tmp == NULL) {
|
||||
free (buf);
|
||||
free_Checksum (&s.cksum);
|
||||
return ENOMEM;
|
||||
}
|
||||
buf = tmp;
|
||||
} else {
|
||||
free (buf);
|
||||
free_Checksum (&s.cksum);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} while (ret == ASN1_OVERFLOW);
|
||||
|
||||
buf_size = length_KRB_SAFE(&s);
|
||||
buf = realloc(buf, buf_size);
|
||||
if(buf == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
|
||||
free_Checksum (&s.cksum);
|
||||
|
||||
outbuf->length = len;
|
||||
|
88
lib/krb5/n-fold.c
Normal file
88
lib/krb5/n-fold.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "krb5_locl.h"
|
||||
|
||||
static void
|
||||
rr13(unsigned char *buf, size_t len)
|
||||
{
|
||||
unsigned char *tmp;
|
||||
int bytes = (len + 7) / 8;
|
||||
int i;
|
||||
const int bits = 13 % len;
|
||||
const int lbit = len % 8;
|
||||
|
||||
tmp = malloc(bytes);
|
||||
memcpy(tmp, buf, bytes);
|
||||
if(lbit) {
|
||||
/* pad final byte with inital bits */
|
||||
tmp[bytes - 1] &= 0xff << (8 - lbit);
|
||||
for(i = lbit; i < 8; i += len)
|
||||
tmp[bytes - 1] |= buf[0] >> i;
|
||||
}
|
||||
for(i = 0; i < bytes; i++) {
|
||||
int bb;
|
||||
int b1, s1, b2, s2;
|
||||
/* calculate first bit position of this byte */
|
||||
bb = 8 * i - bits;
|
||||
while(bb < 0)
|
||||
bb += len;
|
||||
/* byte offset and shift count */
|
||||
b1 = bb / 8;
|
||||
s1 = bb % 8;
|
||||
|
||||
if(bb + 8 > bytes * 8)
|
||||
/* watch for wraparound */
|
||||
s2 = (len + 8 - s1) % 8;
|
||||
else
|
||||
s2 = 8 - s1;
|
||||
b2 = (b1 + 1) % bytes;
|
||||
buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* Add `b' to `a', both beeing one's complement numbers. */
|
||||
static void
|
||||
add1(unsigned char *a, unsigned char *b, size_t len)
|
||||
{
|
||||
int i;
|
||||
int carry = 0;
|
||||
for(i = len - 1; i >= 0; i--){
|
||||
int x = a[i] + b[i] + carry;
|
||||
carry = x > 0xff;
|
||||
a[i] = x & 0xff;
|
||||
}
|
||||
for(i = len - 1; carry && i >= 0; i--){
|
||||
int x = a[i] + carry;
|
||||
carry = x > 0xff;
|
||||
a[i] = carry & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
n_fold(const void *str, size_t len, void *key, size_t size)
|
||||
{
|
||||
/* if len < size we need at most N * len bytes, ie < 2 * size;
|
||||
if len > size we need at most 2 * len */
|
||||
size_t maxlen = 2 * max(size, len);
|
||||
size_t l = 0;
|
||||
unsigned char *tmp = malloc(maxlen);
|
||||
unsigned char *buf = malloc(len);
|
||||
|
||||
memcpy(buf, str, len);
|
||||
memset(key, 0, size);
|
||||
do {
|
||||
memcpy(tmp + l, buf, len);
|
||||
l += len;
|
||||
rr13(buf, len * 8);
|
||||
while(l >= size) {
|
||||
add1(key, tmp, size);
|
||||
l -= size;
|
||||
if(l == 0)
|
||||
break;
|
||||
memmove(tmp, tmp + size, l);
|
||||
}
|
||||
} while(l != 0);
|
||||
memset(buf, 0, len);
|
||||
free(buf);
|
||||
memset(tmp, 0, maxlen);
|
||||
free(tmp);
|
||||
}
|
@@ -186,6 +186,8 @@ unparse_name_fixed(krb5_context context,
|
||||
if(i)
|
||||
add_char(name, index, len, '/');
|
||||
index = quote_string(princ_ncomp(principal, i), name, index, len);
|
||||
if(index == len)
|
||||
return ERANGE;
|
||||
}
|
||||
/* add realm if different from default realm */
|
||||
if(short_form) {
|
||||
@@ -202,7 +204,7 @@ unparse_name_fixed(krb5_context context,
|
||||
add_char(name, index, len, '@');
|
||||
index = quote_string(princ_realm(principal), name, index, len);
|
||||
if(index == len)
|
||||
return ENOMEM; /* XXX */
|
||||
return ERANGE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@ krb5_rd_cred (krb5_context context,
|
||||
KRB_CRED cred;
|
||||
EncKrbCredPart enc_krb_cred_part;
|
||||
krb5_data enc_krb_cred_part_data;
|
||||
krb5_crypto crypto;
|
||||
int i;
|
||||
|
||||
ret = decode_KRB_CRED (in_data->data, in_data->length,
|
||||
@@ -68,12 +69,13 @@ krb5_rd_cred (krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
cred.enc_part.cipher.data,
|
||||
cred.enc_part.cipher.length,
|
||||
cred.enc_part.etype,
|
||||
auth_context->remote_subkey,
|
||||
&enc_krb_cred_part_data);
|
||||
krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_CRED,
|
||||
&cred.enc_part,
|
||||
&enc_krb_cred_part_data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@@ -53,6 +53,7 @@ krb5_rd_priv(krb5_context context,
|
||||
size_t len;
|
||||
krb5_data plain;
|
||||
krb5_keyblock *key;
|
||||
krb5_crypto crypto;
|
||||
|
||||
memset(&priv, 0, sizeof(priv));
|
||||
ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
|
||||
@@ -76,12 +77,13 @@ krb5_rd_priv(krb5_context context,
|
||||
else
|
||||
key = auth_context->keyblock;
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
priv.enc_part.cipher.data,
|
||||
priv.enc_part.cipher.length,
|
||||
priv.enc_part.etype,
|
||||
key,
|
||||
&plain);
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_PRIV,
|
||||
&priv.enc_part,
|
||||
&plain);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
goto failure;
|
||||
|
||||
|
@@ -50,6 +50,7 @@ krb5_rd_rep(krb5_context context,
|
||||
AP_REP ap_rep;
|
||||
size_t len;
|
||||
krb5_data data;
|
||||
krb5_crypto crypto;
|
||||
|
||||
krb5_data_zero (&data);
|
||||
ret = 0;
|
||||
@@ -66,10 +67,13 @@ krb5_rd_rep(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_AP_REQ_ENC_PART,
|
||||
&ap_rep.enc_part,
|
||||
auth_context->keyblock,
|
||||
&data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@@ -42,19 +42,22 @@ RCSID("$Id$");
|
||||
|
||||
static krb5_error_code
|
||||
decrypt_tkt_enc_part (krb5_context context,
|
||||
const krb5_keyblock *key,
|
||||
krb5_keyblock *key,
|
||||
EncryptedData *enc_part,
|
||||
EncTicketPart *decr_part)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data plain;
|
||||
size_t len;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
enc_part->cipher.data,
|
||||
enc_part->cipher.length,
|
||||
enc_part->etype,
|
||||
key, &plain);
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_TICKET,
|
||||
enc_part,
|
||||
&plain);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -73,12 +76,15 @@ decrypt_authenticator (krb5_context context,
|
||||
krb5_error_code ret;
|
||||
krb5_data plain;
|
||||
size_t len;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ret = krb5_decrypt (context,
|
||||
enc_part->cipher.data,
|
||||
enc_part->cipher.length,
|
||||
enc_part->etype,
|
||||
key, &plain);
|
||||
krb5_crypto_init(context, key, 0, &crypto);
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_AP_REQ_AUTH,
|
||||
enc_part,
|
||||
&plain);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -145,6 +151,45 @@ krb5_decrypt_ticket(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_verify_authenticator_checksum(krb5_context context,
|
||||
krb5_auth_context ac,
|
||||
void *data,
|
||||
size_t len)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_keyblock *key;
|
||||
krb5_authenticator authenticator;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ret = krb5_auth_getauthenticator (context,
|
||||
ac,
|
||||
&authenticator);
|
||||
if(ret)
|
||||
return ret;
|
||||
if(authenticator->cksum == NULL)
|
||||
return -17;
|
||||
ret = krb5_auth_con_getkey(context, ac, &key);
|
||||
if(ret) {
|
||||
krb5_free_authenticator(context, &authenticator);
|
||||
return ret;
|
||||
}
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
if(ret)
|
||||
goto out;
|
||||
ret = krb5_verify_checksum (context,
|
||||
crypto,
|
||||
KRB5_KU_AP_REQ_AUTH_CKSUM,
|
||||
data,
|
||||
len,
|
||||
authenticator->cksum);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
out:
|
||||
krb5_free_authenticator(context, &authenticator);
|
||||
krb5_free_keyblock(context, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_verify_ap_req(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
@@ -303,7 +348,6 @@ get_key_from_keytab(krb5_context context,
|
||||
krb5_keytab_entry entry;
|
||||
krb5_error_code ret;
|
||||
int kvno;
|
||||
krb5_keytype keytype;
|
||||
krb5_keytab real_keytab;
|
||||
|
||||
if(keytab == NULL)
|
||||
@@ -316,17 +360,11 @@ get_key_from_keytab(krb5_context context,
|
||||
else
|
||||
kvno = 0;
|
||||
|
||||
ret = krb5_etype_to_keytype (context,
|
||||
ap_req->ticket.enc_part.etype,
|
||||
&keytype);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = krb5_kt_get_entry (context,
|
||||
real_keytab,
|
||||
server,
|
||||
kvno,
|
||||
keytype,
|
||||
ap_req->ticket.enc_part.etype,
|
||||
&entry);
|
||||
if(ret)
|
||||
goto out;
|
||||
|
@@ -50,48 +50,36 @@ verify_checksum(krb5_context context,
|
||||
size_t buf_size;
|
||||
size_t len;
|
||||
Checksum c;
|
||||
krb5_crypto crypto;
|
||||
|
||||
c = safe->cksum;
|
||||
safe->cksum.cksumtype = 0;
|
||||
safe->cksum.checksum.data = NULL;
|
||||
safe->cksum.checksum.length = 0;
|
||||
|
||||
buf_size = 1024;
|
||||
buf = malloc (buf_size);
|
||||
|
||||
buf_size = length_KRB_SAFE(safe);
|
||||
buf = malloc(buf_size);
|
||||
|
||||
if (buf == NULL) {
|
||||
free_Checksum(&c);
|
||||
return ENOMEM;
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1,
|
||||
buf_size,
|
||||
safe,
|
||||
&len);
|
||||
if (ret) {
|
||||
if (ret == ASN1_OVERFLOW) {
|
||||
u_char *tmp;
|
||||
|
||||
buf_size *= 2;
|
||||
tmp = realloc (buf, buf_size);
|
||||
if (tmp == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
buf = tmp;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} while(ret == ASN1_OVERFLOW);
|
||||
|
||||
ret = encode_KRB_SAFE (buf + buf_size - 1,
|
||||
buf_size,
|
||||
safe,
|
||||
&len);
|
||||
krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
|
||||
ret = krb5_verify_checksum (context,
|
||||
crypto,
|
||||
KRB5_KU_KRB_SAFE_CKSUM,
|
||||
buf + buf_size - len,
|
||||
len,
|
||||
auth_context->keyblock,
|
||||
&c);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
out:
|
||||
free_Checksum (&c);
|
||||
safe->cksum = c;
|
||||
free (buf);
|
||||
return ret;
|
||||
}
|
||||
@@ -118,8 +106,8 @@ krb5_rd_safe(krb5_context context,
|
||||
ret = KRB5KRB_AP_ERR_MSG_TYPE;
|
||||
goto failure;
|
||||
}
|
||||
if (!krb5_checksum_is_keyed(safe.cksum.cksumtype)
|
||||
|| !krb5_checksum_is_collision_proof(safe.cksum.cksumtype)) {
|
||||
if (!krb5_checksum_is_keyed(context, safe.cksum.cksumtype)
|
||||
|| !krb5_checksum_is_collision_proof(context, safe.cksum.cksumtype)) {
|
||||
ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
|
||||
goto failure;
|
||||
}
|
||||
|
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* 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 acknowledgement:
|
||||
* This product includes software developed by Kungliga Tekniska
|
||||
* H<>gskolan and its contributors.
|
||||
*
|
||||
* 4. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS 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 INSTITUTE OR 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.
|
||||
*/
|
||||
|
||||
#include <krb5_locl.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
/*
|
||||
* Reverse 8 bytes
|
||||
*/
|
||||
|
||||
static void
|
||||
reverse (unsigned char *s)
|
||||
{
|
||||
static const unsigned char tbl[] = {
|
||||
0x0,
|
||||
0x8,
|
||||
0x4,
|
||||
0xC,
|
||||
0x2,
|
||||
0xA,
|
||||
0x6,
|
||||
0xE,
|
||||
0x1,
|
||||
0x9,
|
||||
0x5,
|
||||
0xD,
|
||||
0x3,
|
||||
0xB,
|
||||
0x7,
|
||||
0xF
|
||||
};
|
||||
|
||||
char tmp;
|
||||
|
||||
#define REVONE(str, i, j) \
|
||||
do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0)
|
||||
|
||||
REVONE(s,0,7);
|
||||
REVONE(s,1,6);
|
||||
REVONE(s,2,5);
|
||||
REVONE(s,3,4);
|
||||
#undef REVONE
|
||||
|
||||
#define REVTWO(q) \
|
||||
q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4])
|
||||
|
||||
REVTWO(s[0]);
|
||||
REVTWO(s[1]);
|
||||
REVTWO(s[2]);
|
||||
REVTWO(s[3]);
|
||||
REVTWO(s[4]);
|
||||
REVTWO(s[5]);
|
||||
REVTWO(s[6]);
|
||||
REVTWO(s[7]);
|
||||
|
||||
#undef REVTWO
|
||||
}
|
||||
|
||||
/*
|
||||
* A = A xor B. A & B is 8 bytes.
|
||||
*/
|
||||
|
||||
static void
|
||||
xor (des_cblock *key, const unsigned char *b)
|
||||
{
|
||||
unsigned char *a = (unsigned char*)key;
|
||||
a[0] ^= b[0];
|
||||
a[1] ^= b[1];
|
||||
a[2] ^= b[2];
|
||||
a[3] ^= b[3];
|
||||
a[4] ^= b[4];
|
||||
a[5] ^= b[5];
|
||||
a[6] ^= b[6];
|
||||
a[7] ^= b[7];
|
||||
}
|
||||
|
||||
/*
|
||||
* Init a from b
|
||||
*/
|
||||
|
||||
static void
|
||||
init (unsigned char *a, const unsigned char *b)
|
||||
{
|
||||
a[0] = b[0] << 1;
|
||||
a[1] = b[1] << 1;
|
||||
a[2] = b[2] << 1;
|
||||
a[3] = b[3] << 1;
|
||||
a[4] = b[4] << 1;
|
||||
a[5] = b[5] << 1;
|
||||
a[6] = b[6] << 1;
|
||||
a[7] = b[7] << 1;
|
||||
}
|
||||
|
||||
static void
|
||||
DES_string_to_key(const char *str, size_t len, des_cblock *key)
|
||||
{
|
||||
/* could use des_string_to_key here, but then `str' must be zero
|
||||
terminated, and the final weak-key check has to be added */
|
||||
int even, i;
|
||||
des_key_schedule sched;
|
||||
|
||||
memset (key, 0, sizeof(des_cblock));
|
||||
|
||||
even = 0;
|
||||
for (i = 0; i < len; i += 8) {
|
||||
unsigned char tmp[8];
|
||||
|
||||
init (tmp, (const unsigned char*)(str + i));
|
||||
|
||||
if (even) {
|
||||
reverse (tmp);
|
||||
init (tmp, tmp);
|
||||
}
|
||||
even = !even;
|
||||
xor (key, tmp);
|
||||
}
|
||||
des_set_odd_parity (key);
|
||||
des_set_key (key, sched);
|
||||
des_cbc_cksum ((des_cblock *)str, key, len, sched, key);
|
||||
des_set_odd_parity (key);
|
||||
if (des_is_weak_key (key))
|
||||
xor (key, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
|
||||
}
|
||||
|
||||
static void
|
||||
rr13(unsigned char *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
/* assert(len >= 3); */
|
||||
unsigned a = buf[0], b = buf[len-1];
|
||||
#define F(A, B) ((((A) << 3) | ((B) >> 5)) & 0xff)
|
||||
buf[0] = F(buf[len-2], buf[len-1]);
|
||||
for(i = len - 3; i >= 1; i--)
|
||||
buf[i + 2] = F(buf[i], buf[i+1]);
|
||||
buf[2] = F(a, buf[1]);
|
||||
buf[1] = F(b, a);
|
||||
#undef F
|
||||
}
|
||||
|
||||
/* Add `b' to `a', both beeing one's complement numbers. */
|
||||
static void
|
||||
add1(unsigned char *a, unsigned char *b, size_t len)
|
||||
{
|
||||
int i;
|
||||
int carry = 0;
|
||||
for(i = len - 1; i >= 0; i--){
|
||||
int x = a[i] + b[i] + carry;
|
||||
carry = x > 0xff;
|
||||
a[i] = x & 0xff;
|
||||
}
|
||||
for(i = len - 1; carry && i >= 0; i--){
|
||||
int x = a[i] + carry;
|
||||
carry = x > 0xff;
|
||||
a[i] = carry & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* key should point to a buffer of at least size (24) bytes */
|
||||
static void
|
||||
fold(const unsigned char *str, size_t len, unsigned char *key)
|
||||
{
|
||||
const int size = 24;
|
||||
/* if len < size we need at most N * len bytes, ie < 2 * size;
|
||||
if len > size we need at most 2 * len */
|
||||
size_t maxlen = 2 * max(size, len);
|
||||
size_t l = 0;
|
||||
unsigned char *tmp = malloc(maxlen);
|
||||
unsigned char *buf = malloc(len);
|
||||
|
||||
memcpy(buf, str, len);
|
||||
memset(key, 0, size);
|
||||
do {
|
||||
memcpy(tmp + l, buf, len);
|
||||
l += len;
|
||||
rr13(buf, len);
|
||||
while(l >= size) {
|
||||
add1(key, tmp, size);
|
||||
l -= size;
|
||||
if(l == 0)
|
||||
break;
|
||||
memmove(tmp, tmp + size, l);
|
||||
}
|
||||
} while(l != 0);
|
||||
memset(buf, 0, len);
|
||||
free(buf);
|
||||
memset(tmp, 0, maxlen);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
DES3_string_to_key(const unsigned char *str, size_t len, des_cblock *keys)
|
||||
{
|
||||
unsigned char tmp[24];
|
||||
des_cblock ivec;
|
||||
des_key_schedule s[3];
|
||||
int i;
|
||||
|
||||
fold(str, len, tmp);
|
||||
for(i = 0; i < 3; i++){
|
||||
memcpy(keys + i, tmp + 8 * i, 8);
|
||||
des_set_odd_parity(keys + i);
|
||||
if(des_is_weak_key(keys + i))
|
||||
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
|
||||
des_set_key(keys + i, s[i]);
|
||||
}
|
||||
memset(&ivec, 0, sizeof(ivec));
|
||||
des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
|
||||
s[0], s[1], s[2], &ivec, 1);
|
||||
memset(s, 0, sizeof(s));
|
||||
for(i = 0; i < 3; i++){
|
||||
memcpy(keys + i, tmp + 8 * i, 8);
|
||||
des_set_odd_parity(keys + i);
|
||||
if(des_is_weak_key(keys + i))
|
||||
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
|
||||
}
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
}
|
||||
|
||||
/* This defines the Andrew string_to_key function. It accepts a password
|
||||
* string as input and converts its via a one-way encryption algorithm to a DES
|
||||
* encryption key. It is compatible with the original Andrew authentication
|
||||
* service password database.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Short passwords, i.e 8 characters or less.
|
||||
*/
|
||||
static void
|
||||
afs_cmu_StringToKey (const char *pw, size_t pw_len,
|
||||
const char *cell, size_t cell_len,
|
||||
des_cblock *key)
|
||||
{
|
||||
char password[8+1]; /* crypt is limited to 8 chars anyway */
|
||||
int i;
|
||||
|
||||
memset (password, 0, sizeof(password));
|
||||
|
||||
if(cell_len > 8) cell_len = 8;
|
||||
strncpy (password, cell, cell_len);
|
||||
|
||||
if(pw_len > 8) pw_len = 8;
|
||||
for (i=0; i < pw_len; i++)
|
||||
password[i] ^= pw[i];
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
if (password[i] == '\0') password[i] = 'X';
|
||||
|
||||
/* crypt only considers the first 8 characters of password but for some
|
||||
reason returns eleven characters of result (plus the two salt chars). */
|
||||
strncpy((char *)key, (char *)crypt(password, "#~") + 2, sizeof(des_cblock));
|
||||
|
||||
/* parity is inserted into the LSB so leftshift each byte up one bit. This
|
||||
allows ascii characters with a zero MSB to retain as much significance
|
||||
as possible. */
|
||||
{ char *keybytes = (char *)key;
|
||||
unsigned int temp;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
temp = (unsigned int) keybytes[i];
|
||||
keybytes[i] = (unsigned char) (temp << 1);
|
||||
}
|
||||
}
|
||||
des_fixup_key_parity (key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Long passwords, i.e 9 characters or more.
|
||||
*/
|
||||
static void
|
||||
afs_transarc_StringToKey (const char *pw, size_t pw_len,
|
||||
const char *cell, size_t cell_len,
|
||||
des_cblock *key)
|
||||
{
|
||||
des_key_schedule schedule;
|
||||
des_cblock temp_key;
|
||||
des_cblock ivec;
|
||||
char password[512];
|
||||
size_t passlen;
|
||||
|
||||
memcpy(password, pw, min(pw_len, sizeof(password)));
|
||||
if(pw_len < sizeof(password))
|
||||
memcpy(password + pw_len, cell, min(cell_len,
|
||||
sizeof(password) - pw_len));
|
||||
passlen = min(sizeof(password), pw_len + cell_len);
|
||||
memcpy(&ivec, "kerberos", 8);
|
||||
memcpy(&temp_key, "kerberos", 8);
|
||||
des_fixup_key_parity (&temp_key);
|
||||
des_key_sched (&temp_key, schedule);
|
||||
des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
|
||||
|
||||
memcpy(&temp_key, &ivec, 8);
|
||||
des_fixup_key_parity (&temp_key);
|
||||
des_key_sched (&temp_key, schedule);
|
||||
des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
|
||||
memset(&schedule, 0, sizeof(schedule));
|
||||
memset(&temp_key, 0, sizeof(temp_key));
|
||||
memset(&ivec, 0, sizeof(ivec));
|
||||
memset(password, 0, sizeof(password));
|
||||
|
||||
des_fixup_key_parity (key);
|
||||
}
|
||||
|
||||
static void
|
||||
AFS3_string_to_key(const char *pw, size_t pw_len,
|
||||
const char *cell, size_t cell_len,
|
||||
des_cblock *key)
|
||||
{
|
||||
if(pw_len > 8)
|
||||
afs_transarc_StringToKey (pw, pw_len, cell, cell_len, key);
|
||||
else
|
||||
afs_cmu_StringToKey (pw, pw_len, cell, cell_len, key);
|
||||
}
|
||||
|
||||
static void *
|
||||
get_str(const void *pw, size_t pw_len, const void *salt, size_t salt_len,
|
||||
size_t *ret_len)
|
||||
{
|
||||
char *p;
|
||||
size_t len = pw_len + salt_len;
|
||||
len = (len + 7) & ~7;
|
||||
p = calloc(len, 1);
|
||||
if(p == NULL)
|
||||
return NULL;
|
||||
memcpy(p, pw, pw_len);
|
||||
memcpy(p + pw_len, salt, salt_len);
|
||||
*ret_len = len;
|
||||
return p;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
string_to_key_internal (const unsigned char *str,
|
||||
size_t str_len,
|
||||
krb5_data *salt,
|
||||
krb5_keytype ktype,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *s = NULL;
|
||||
krb5_error_code ret;
|
||||
|
||||
switch(ktype & KEYTYPE_KEYTYPE_MASK){
|
||||
case KEYTYPE_DES:{
|
||||
des_cblock tmpkey;
|
||||
if(ktype & KEYTYPE_USE_AFS3_SALT)
|
||||
AFS3_string_to_key(str, str_len, salt->data, salt->length, &tmpkey);
|
||||
else{
|
||||
s = get_str(str, str_len, salt->data, salt->length, &len);
|
||||
if(s == NULL)
|
||||
return ENOMEM;
|
||||
DES_string_to_key(s, len, &tmpkey);
|
||||
}
|
||||
ret = krb5_data_copy(&key->keyvalue, tmpkey, sizeof(des_cblock));
|
||||
memset(&tmpkey, 0, sizeof(tmpkey));
|
||||
break;
|
||||
}
|
||||
case KEYTYPE_DES3:{
|
||||
des_cblock keys[3];
|
||||
s = get_str(str, str_len, salt->data, salt->length, &len);
|
||||
if(s == NULL)
|
||||
return ENOMEM;
|
||||
/* only des should pad to 8 */
|
||||
DES3_string_to_key(s, str_len + salt->length, keys);
|
||||
ret = krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
|
||||
memset(keys, 0, sizeof(keys));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = KRB5_PROG_KEYTYPE_NOSUPP;
|
||||
break;
|
||||
}
|
||||
if(s){
|
||||
memset(s, 0, len);
|
||||
free(s);
|
||||
}
|
||||
if(ret)
|
||||
return ret;
|
||||
key->keytype = ktype & KEYTYPE_KEYTYPE_MASK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_string_to_key (const char *str,
|
||||
krb5_data *salt,
|
||||
krb5_keytype ktype,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
return string_to_key_internal ((const unsigned char *)str,
|
||||
strlen(str), salt, ktype, key);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_string_to_key_data (krb5_data *str,
|
||||
krb5_data *salt,
|
||||
krb5_keytype ktype,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
return string_to_key_internal (str->data, str->length, salt, ktype, key);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_get_salt (krb5_principal princ,
|
||||
krb5_data *salt)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
krb5_error_code err;
|
||||
char *p;
|
||||
|
||||
len = strlen(princ->realm);
|
||||
for (i = 0; i < princ->name.name_string.len; ++i)
|
||||
len += strlen(princ->name.name_string.val[i]);
|
||||
err = krb5_data_alloc (salt, len);
|
||||
if (err)
|
||||
return err;
|
||||
p = salt->data;
|
||||
strncpy (p, princ->realm, strlen(princ->realm));
|
||||
p += strlen(princ->realm);
|
||||
for (i = 0; i < princ->name.name_string.len; ++i) {
|
||||
strncpy (p,
|
||||
princ->name.name_string.val[i],
|
||||
strlen(princ->name.name_string.val[i]));
|
||||
p += strlen(princ->name.name_string.val[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ make_path(struct tr_realm *r, const char *from, const char *to)
|
||||
return ENOMEM;
|
||||
}
|
||||
strncpy(path->realm, from, p - from);
|
||||
path->realm[p - from] = 0;
|
||||
path->realm[p - from] = '\0';
|
||||
p--;
|
||||
}
|
||||
}else
|
||||
@@ -136,8 +136,8 @@ make_paths(struct tr_realm *realms, const char *client_realm,
|
||||
/* it *might* be that you can have more than one empty
|
||||
component in a row, at least that's how I interpret the
|
||||
"," exception in 1510 */
|
||||
if(r->realm[0] == 0){
|
||||
while(r->next && r->next->realm[0] == 0)
|
||||
if(r->realm[0] == '\0'){
|
||||
while(r->next && r->next->realm[0] == '\0')
|
||||
r = r->next;
|
||||
if(r->next)
|
||||
next_realm = r->next->realm;
|
||||
@@ -218,11 +218,11 @@ make_realm(char *realm)
|
||||
quote = 1;
|
||||
continue;
|
||||
}
|
||||
if(p[0] == '.' && p[1] == 0)
|
||||
if(p[0] == '.' && p[1] == '\0')
|
||||
r->trailing_dot = 1;
|
||||
*q++ = *p;
|
||||
}
|
||||
*q = 0;
|
||||
*q = '\0';
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
|
||||
if(tr[i] == ','){
|
||||
tmp = malloc(tr + i - start + 1);
|
||||
strncpy(tmp, start, tr + i - start);
|
||||
tmp[tr + i - start] = 0;
|
||||
tmp[tr + i - start] = '\0';
|
||||
r = make_realm(tmp);
|
||||
if(r == NULL){
|
||||
free_realms(*realms);
|
||||
@@ -274,7 +274,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
|
||||
}
|
||||
tmp = malloc(tr + i - start + 1);
|
||||
strncpy(tmp, start, tr + i - start);
|
||||
tmp[tr + i - start] = 0;
|
||||
tmp[tr + i - start] = '\0';
|
||||
r = make_realm(tmp);
|
||||
if(r == NULL){
|
||||
free_realms(*realms);
|
||||
@@ -311,7 +311,7 @@ krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
|
||||
/* remove empty components */
|
||||
q = &r;
|
||||
for(p = r; p; ){
|
||||
if(p->realm[0] == 0){
|
||||
if(p->realm[0] == '\0'){
|
||||
free(p->realm);
|
||||
*q = p->next;
|
||||
free(p);
|
||||
@@ -354,7 +354,7 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
|
||||
}
|
||||
len += num_realms - 1;
|
||||
s = malloc(len + 1);
|
||||
*s = 0;
|
||||
*s = '\0';
|
||||
for(i = 0; i < num_realms; i++){
|
||||
if(i && i < num_realms - 1)
|
||||
strcat(s, ",");
|
||||
|
Reference in New Issue
Block a user