mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
s4:heimdal: import lorikeet-heimdal-201010022046 (commit 1bea031b9404b14114b0272ecbe56e60c567af5c)
This commit is contained in:
parent
a2c4f54dfb
commit
21460dfc14
@ -12,7 +12,7 @@ my $debug = 0;
|
||||
my $oproto = 1;
|
||||
my $private_func_re = "^_";
|
||||
|
||||
do Getopts('x:m:o:p:dqE:R:P:') || die "foo";
|
||||
Getopts('x:m:o:p:dqE:R:P:') || die "foo";
|
||||
|
||||
if($opt_d) {
|
||||
$debug = 1;
|
||||
|
@ -177,7 +177,7 @@ get_password_entry(krb5_context context,
|
||||
return ret;
|
||||
|
||||
ret = _kdc_db_fetch(context, config, clientprincipal,
|
||||
HDB_F_GET_CLIENT, &db, &user);
|
||||
HDB_F_GET_CLIENT, NULL, &db, &user);
|
||||
krb5_free_principal(context, clientprincipal);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -292,7 +292,7 @@ _kdc_do_digest(krb5_context context,
|
||||
krb5_clear_error_message(context);
|
||||
|
||||
ret = _kdc_db_fetch(context, config, principal,
|
||||
HDB_F_GET_SERVER, NULL, &server);
|
||||
HDB_F_GET_SERVER, NULL, NULL, &server);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -314,7 +314,7 @@ _kdc_do_digest(krb5_context context,
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch(context, config, principal,
|
||||
HDB_F_GET_CLIENT, NULL, &client);
|
||||
HDB_F_GET_CLIENT, NULL, NULL, &client);
|
||||
krb5_free_principal(context, principal);
|
||||
if (ret)
|
||||
goto out;
|
||||
@ -874,7 +874,7 @@ _kdc_do_digest(krb5_context context,
|
||||
goto failed;
|
||||
|
||||
ret = _kdc_db_fetch(context, config, clientprincipal,
|
||||
HDB_F_GET_CLIENT, NULL, &user);
|
||||
HDB_F_GET_CLIENT, NULL, NULL, &user);
|
||||
krb5_free_principal(context, clientprincipal);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
@ -1158,7 +1158,7 @@ _kdc_do_digest(krb5_context context,
|
||||
goto failed;
|
||||
|
||||
ret = _kdc_db_fetch(context, config, clientprincipal,
|
||||
HDB_F_GET_CLIENT, NULL, &user);
|
||||
HDB_F_GET_CLIENT, NULL, NULL, &user);
|
||||
krb5_free_principal(context, clientprincipal);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret, "NTLM user %s not in database",
|
||||
|
@ -988,7 +988,7 @@ _kdc_as_rep(krb5_context context,
|
||||
*/
|
||||
|
||||
ret = _kdc_db_fetch(context, config, client_princ,
|
||||
HDB_F_GET_CLIENT | flags, 0,
|
||||
HDB_F_GET_CLIENT | flags, NULL,
|
||||
&clientdb, &client);
|
||||
if(ret){
|
||||
const char *msg = krb5_get_error_message(context, ret);
|
||||
@ -1000,7 +1000,7 @@ _kdc_as_rep(krb5_context context,
|
||||
|
||||
ret = _kdc_db_fetch(context, config, server_princ,
|
||||
HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
|
||||
0, NULL, &server);
|
||||
NULL, NULL, &server);
|
||||
if(ret){
|
||||
const char *msg = krb5_get_error_message(context, ret);
|
||||
kdc_log(context, config, 0, "UNKNOWN -- %s: %s", server_name, msg);
|
||||
|
@ -351,7 +351,7 @@ check_PAC(krb5_context context,
|
||||
*signedpath = 1;
|
||||
ret = _krb5_pac_sign(context, pac, tkt->authtime,
|
||||
client_principal,
|
||||
server_key, krbtgt_key, rspac);
|
||||
server_key, krbtgt_sign_key, rspac);
|
||||
}
|
||||
krb5_pac_free(context, pac);
|
||||
|
||||
@ -1563,7 +1563,7 @@ tgs_build_reply(krb5_context context,
|
||||
|
||||
server_lookup:
|
||||
ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER | HDB_F_CANON,
|
||||
0, NULL, &server);
|
||||
NULL, NULL, &server);
|
||||
|
||||
if(ret){
|
||||
const char *new_rlm, *msg;
|
||||
@ -1624,7 +1624,7 @@ server_lookup:
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
|
||||
0, &clientdb, &client);
|
||||
NULL, &clientdb, &client);
|
||||
if(ret) {
|
||||
const char *krbtgt_realm, *msg;
|
||||
|
||||
@ -1845,7 +1845,7 @@ server_lookup:
|
||||
krb5_pac p = NULL;
|
||||
krb5_data_free(&rspac);
|
||||
ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON,
|
||||
0, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
|
||||
NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
|
||||
if (ret) {
|
||||
const char *msg;
|
||||
|
||||
|
@ -47,7 +47,7 @@ _kdc_db_fetch(krb5_context context,
|
||||
hdb_entry_ex *ent;
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
unsigned kvno;
|
||||
unsigned kvno = 0;
|
||||
|
||||
if (kvno_ptr) {
|
||||
kvno = *kvno_ptr;
|
||||
@ -91,12 +91,22 @@ _kdc_db_fetch(krb5_context context,
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = config->db[i]->hdb_fetch(context,
|
||||
config->db[i],
|
||||
principal,
|
||||
flags | HDB_F_DECRYPT,
|
||||
kvno,
|
||||
ent);
|
||||
if (config->db[i]->hdb_fetch_kvno) {
|
||||
ret = config->db[i]->hdb_fetch_kvno(context,
|
||||
config->db[i],
|
||||
principal,
|
||||
flags | HDB_F_DECRYPT,
|
||||
kvno,
|
||||
ent);
|
||||
} else {
|
||||
flags &= ~HDB_F_KVNO_SPECIFIED;
|
||||
ret = config->db[i]->hdb_fetch(context,
|
||||
config->db[i],
|
||||
principal,
|
||||
flags | HDB_F_DECRYPT,
|
||||
ent);
|
||||
}
|
||||
|
||||
krb5_free_principal(context, enterprise_principal);
|
||||
|
||||
config->db[i]->hdb_close(context, config->db[i]);
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "asn1-template.h"
|
||||
|
||||
time_t _der_timegm (struct tm *);
|
||||
struct tm * _der_gmtime(time_t t, struct tm *);
|
||||
size_t _heim_len_unsigned (unsigned);
|
||||
size_t _heim_len_int (int);
|
||||
|
||||
|
@ -426,22 +426,22 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
|
||||
int
|
||||
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
|
||||
{
|
||||
struct tm *tm;
|
||||
struct tm tm;
|
||||
const size_t len = gtimep ? 15 : 13;
|
||||
|
||||
s->data = malloc(len + 1);
|
||||
if (s->data == NULL)
|
||||
return ENOMEM;
|
||||
s->length = len;
|
||||
tm = gmtime (&t);
|
||||
_der_gmtime(t, &tm);
|
||||
if (gtimep)
|
||||
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
else
|
||||
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,6 +42,10 @@ is_leap(unsigned y)
|
||||
return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
|
||||
}
|
||||
|
||||
static const unsigned ndays[2][12] ={
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||
|
||||
/*
|
||||
* This is a simplifed version of timegm(3) that doesn't accept out of
|
||||
* bound values that timegm(3) normally accepts but those are not
|
||||
@ -51,9 +55,8 @@ is_leap(unsigned y)
|
||||
time_t
|
||||
_der_timegm (struct tm *tm)
|
||||
{
|
||||
static const unsigned ndays[2][12] ={
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||
time_t res = 0;
|
||||
unsigned i;
|
||||
|
||||
if (tm->tm_year < 0)
|
||||
return -1;
|
||||
@ -68,10 +71,51 @@ _der_timegm (struct tm *tm)
|
||||
if (tm->tm_sec < 0 || tm->tm_sec > 59)
|
||||
return -1;
|
||||
|
||||
/* now call to the libc timegm(). This code used to do the
|
||||
* calculation itself, but that calculation didn't account for the
|
||||
* difference between UTC and GMT, which is 24 seconds in 2010. That
|
||||
* caused a mutual authentication failure
|
||||
*/
|
||||
return timegm(tm);
|
||||
for (i = 70; i < tm->tm_year; ++i)
|
||||
res += is_leap(i) ? 366 : 365;
|
||||
|
||||
for (i = 0; i < tm->tm_mon; ++i)
|
||||
res += ndays[is_leap(tm->tm_year)][i];
|
||||
res += tm->tm_mday - 1;
|
||||
res *= 24;
|
||||
res += tm->tm_hour;
|
||||
res *= 60;
|
||||
res += tm->tm_min;
|
||||
res *= 60;
|
||||
res += tm->tm_sec;
|
||||
return res;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
_der_gmtime(time_t t, struct tm *tm)
|
||||
{
|
||||
time_t secday = t % (3600 * 24);
|
||||
time_t days = t / (3600 * 24);
|
||||
|
||||
memset(tm, 0, sizeof(*tm));
|
||||
|
||||
tm->tm_sec = secday % 60;
|
||||
tm->tm_min = (secday % 3600) / 60;
|
||||
tm->tm_hour = secday / 3600;
|
||||
|
||||
tm->tm_year = 70;
|
||||
while(1) {
|
||||
unsigned dayinyear = (is_leap(tm->tm_year) ? 366 : 365);
|
||||
if (days < dayinyear)
|
||||
break;
|
||||
tm->tm_year += 1;
|
||||
days -= dayinyear;
|
||||
}
|
||||
tm->tm_mon = 0;
|
||||
|
||||
while (1) {
|
||||
unsigned daysinmonth = ndays[is_leap(tm->tm_year)][tm->tm_mon];
|
||||
if (days < daysinmonth)
|
||||
break;
|
||||
days -= daysinmonth;
|
||||
tm->tm_mon++;
|
||||
}
|
||||
tm->tm_mday = days + 1;
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
@ -289,6 +289,52 @@ EVP_hcrypto_sha256(void)
|
||||
return &sha256;
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA384 - hcrypto
|
||||
*
|
||||
* @return the message digest type.
|
||||
*
|
||||
* @ingroup hcrypto_evp
|
||||
*/
|
||||
|
||||
const EVP_MD *
|
||||
EVP_hcrypto_sha384(void)
|
||||
{
|
||||
static const struct hc_evp_md sha384 = {
|
||||
48,
|
||||
128,
|
||||
sizeof(SHA384_CTX),
|
||||
(hc_evp_md_init)SHA384_Init,
|
||||
(hc_evp_md_update)SHA384_Update,
|
||||
(hc_evp_md_final)SHA384_Final,
|
||||
NULL
|
||||
};
|
||||
return &sha384;
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA512 - hcrypto
|
||||
*
|
||||
* @return the message digest type.
|
||||
*
|
||||
* @ingroup hcrypto_evp
|
||||
*/
|
||||
|
||||
const EVP_MD *
|
||||
EVP_hcrypto_sha512(void)
|
||||
{
|
||||
static const struct hc_evp_md sha512 = {
|
||||
64,
|
||||
128,
|
||||
sizeof(SHA512_CTX),
|
||||
(hc_evp_md_init)SHA512_Init,
|
||||
(hc_evp_md_update)SHA512_Update,
|
||||
(hc_evp_md_final)SHA512_Final,
|
||||
NULL
|
||||
};
|
||||
return &sha512;
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA1 - hcrypto
|
||||
*
|
||||
|
@ -42,6 +42,8 @@
|
||||
#define EVP_hcrypto_md5 hc_EVP_hcrypto_md5
|
||||
#define EVP_hcrypto_sha1 hc_EVP_hcrypto_sha1
|
||||
#define EVP_hcrypto_sha256 hc_EVP_hcrypto_sha256
|
||||
#define EVP_hcrypto_sha384 hc_EVP_hcrypto_sha384
|
||||
#define EVP_hcrypto_sha512 hc_EVP_hcrypto_sha512
|
||||
#define EVP_hcrypto_des_cbc hc_EVP_hcrypto_des_cbc
|
||||
#define EVP_hcrypto_des_ede3_cbc hc_EVP_hcrypto_des_ede3_cbc
|
||||
#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc
|
||||
@ -70,6 +72,8 @@ const EVP_MD * EVP_hcrypto_md4(void);
|
||||
const EVP_MD * EVP_hcrypto_md5(void);
|
||||
const EVP_MD * EVP_hcrypto_sha1(void);
|
||||
const EVP_MD * EVP_hcrypto_sha256(void);
|
||||
const EVP_MD * EVP_hcrypto_sha384(void);
|
||||
const EVP_MD * EVP_hcrypto_sha512(void);
|
||||
|
||||
const EVP_CIPHER * EVP_hcrypto_rc4(void);
|
||||
const EVP_CIPHER * EVP_hcrypto_rc4_40(void);
|
||||
|
@ -360,6 +360,36 @@ EVP_sha256(void)
|
||||
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha256);
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA384
|
||||
*
|
||||
* @return the message digest type.
|
||||
*
|
||||
* @ingroup hcrypto_evp
|
||||
*/
|
||||
|
||||
const EVP_MD *
|
||||
EVP_sha384(void)
|
||||
{
|
||||
hcrypto_validate();
|
||||
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha384);
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA512
|
||||
*
|
||||
* @return the message digest type.
|
||||
*
|
||||
* @ingroup hcrypto_evp
|
||||
*/
|
||||
|
||||
const EVP_MD *
|
||||
EVP_sha512(void)
|
||||
{
|
||||
hcrypto_validate();
|
||||
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha512);
|
||||
}
|
||||
|
||||
/**
|
||||
* The message digest SHA1
|
||||
*
|
||||
|
@ -96,6 +96,8 @@
|
||||
#define EVP_sha hc_EVP_sha
|
||||
#define EVP_sha1 hc_EVP_sha1
|
||||
#define EVP_sha256 hc_EVP_sha256
|
||||
#define EVP_sha384 hc_EVP_sha384
|
||||
#define EVP_sha512 hc_EVP_sha512
|
||||
#define PKCS5_PBKDF2_HMAC_SHA1 hc_PKCS5_PBKDF2_HMAC_SHA1
|
||||
#define EVP_BytesToKey hc_EVP_BytesToKey
|
||||
#define EVP_get_cipherbyname hc_EVP_get_cipherbyname
|
||||
@ -225,6 +227,8 @@ HC_DEPRECATED_CRYPTO const EVP_MD *EVP_md5(void);
|
||||
const EVP_MD *EVP_sha(void);
|
||||
const EVP_MD *EVP_sha1(void);
|
||||
const EVP_MD *EVP_sha256(void);
|
||||
const EVP_MD *EVP_sha384(void);
|
||||
const EVP_MD *EVP_sha512(void);
|
||||
|
||||
const EVP_CIPHER * EVP_aes_128_cbc(void);
|
||||
const EVP_CIPHER * EVP_aes_192_cbc(void);
|
||||
|
@ -66,4 +66,10 @@ cshift (uint32_t x, unsigned int n)
|
||||
return CRAYFIX((x << n) | (x >> (32 - n)));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
cshift64 (uint64_t x, unsigned int n)
|
||||
{
|
||||
return ((uint64_t)x << (uint64_t)n) | ((uint64_t)x >> ((uint64_t)64 - (uint64_t)n));
|
||||
}
|
||||
|
||||
#endif /* __hash_h__ */
|
||||
|
@ -398,7 +398,7 @@ ltm_rsa_private_decrypt(int flen, const unsigned char* from,
|
||||
if (flen > size)
|
||||
return -2;
|
||||
|
||||
mp_init_multi(&in, &n, &e, &out, &bi, &b, NULL);
|
||||
mp_init_multi(&in, &n, &e, &out, &b, &bi, NULL);
|
||||
|
||||
BN2mpz(&n, rsa->n);
|
||||
BN2mpz(&e, rsa->e);
|
||||
@ -479,7 +479,7 @@ ltm_rsa_private_decrypt(int flen, const unsigned char* from,
|
||||
memmove(to, ptr, size);
|
||||
|
||||
out:
|
||||
mp_clear_multi(&e, &n, &in, &out, NULL);
|
||||
mp_clear_multi(&e, &n, &in, &out, &b, &bi, NULL);
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -518,7 +518,9 @@ ltm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
|
||||
|
||||
ret = -1;
|
||||
|
||||
mp_init_multi(&el, &p, &q, &n, &n, &d, &dmp1, &dmq1, &iqmp, &t1, &t2, &t3, NULL);
|
||||
mp_init_multi(&el, &p, &q, &n, &d,
|
||||
&dmp1, &dmq1, &iqmp,
|
||||
&t1, &t2, &t3, NULL);
|
||||
|
||||
BN2mpz(&el, e);
|
||||
|
||||
@ -588,8 +590,9 @@ ltm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
mp_clear_multi(&el, &p, &q, &n, &d, &dmp1,
|
||||
&dmq1, &iqmp, &t1, &t2, &t3, NULL);
|
||||
mp_clear_multi(&el, &p, &q, &n, &d,
|
||||
&dmp1, &dmq1, &iqmp,
|
||||
&t1, &t2, &t3, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -80,4 +80,30 @@ void SHA256_Init (SHA256_CTX *);
|
||||
void SHA256_Update (SHA256_CTX *, const void *, size_t);
|
||||
void SHA256_Final (void *, SHA256_CTX *);
|
||||
|
||||
/*
|
||||
* SHA-2 512
|
||||
*/
|
||||
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
|
||||
struct hc_sha512state {
|
||||
uint64_t sz[2];
|
||||
uint64_t counter[8];
|
||||
unsigned char save[128];
|
||||
};
|
||||
|
||||
typedef struct hc_sha512state SHA512_CTX;
|
||||
|
||||
void SHA512_Init (SHA512_CTX *);
|
||||
void SHA512_Update (SHA512_CTX *, const void *, size_t);
|
||||
void SHA512_Final (void *, SHA512_CTX *);
|
||||
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
|
||||
typedef struct hc_sha512state SHA384_CTX;
|
||||
|
||||
void SHA384_Init (SHA384_CTX *);
|
||||
void SHA384_Update (SHA384_CTX *, const void *, size_t);
|
||||
void SHA384_Final (void *, SHA384_CTX *);
|
||||
|
||||
#endif /* HEIM_SHA_H */
|
||||
|
@ -117,13 +117,18 @@ hkt_open(krb5_context context, HDB * db, int flags, mode_t mode)
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
hkt_fetch(krb5_context context, HDB * db, krb5_const_principal principal,
|
||||
unsigned flags, hdb_entry_ex * entry)
|
||||
hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal,
|
||||
unsigned flags, unsigned kvno, hdb_entry_ex * entry)
|
||||
{
|
||||
hdb_keytab k = (hdb_keytab)db->hdb_db;
|
||||
krb5_error_code ret;
|
||||
krb5_keytab_entry ktentry;
|
||||
|
||||
if (!(flags & HDB_F_KVNO_SPECIFIED)) {
|
||||
/* Preserve previous behaviour if no kvno specified */
|
||||
kvno = 0;
|
||||
}
|
||||
|
||||
memset(&ktentry, 0, sizeof(ktentry));
|
||||
|
||||
entry->entry.flags.server = 1;
|
||||
@ -143,7 +148,7 @@ hkt_fetch(krb5_context context, HDB * db, krb5_const_principal principal,
|
||||
* enctypes should work.
|
||||
*/
|
||||
|
||||
ret = krb5_kt_get_entry(context, k->keytab, principal, 0, 0, &ktentry);
|
||||
ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry);
|
||||
if (ret) {
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
@ -165,6 +170,13 @@ hkt_fetch(krb5_context context, HDB * db, krb5_const_principal principal,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
hkt_fetch(krb5_context context, HDB * db, krb5_const_principal principal,
|
||||
unsigned flags, hdb_entry_ex * entry)
|
||||
{
|
||||
return hkt_fetch_kvno(context, db, principal, flags & ~HDB_F_KVNO_SPECIFIED, 0, entry);
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
hkt_store(krb5_context context, HDB * db, unsigned flags,
|
||||
hdb_entry_ex * entry)
|
||||
@ -210,6 +222,7 @@ hdb_keytab_create(krb5_context context, HDB ** db, const char *arg)
|
||||
(*db)->hdb_open = hkt_open;
|
||||
(*db)->hdb_close = hkt_close;
|
||||
(*db)->hdb_fetch = hkt_fetch;
|
||||
(*db)->hdb_fetch_kvno = hkt_fetch_kvno;
|
||||
(*db)->hdb_store = hkt_store;
|
||||
(*db)->hdb_remove = NULL;
|
||||
(*db)->hdb_firstkey = hkt_firstkey;
|
||||
|
@ -123,8 +123,18 @@ typedef struct HDB{
|
||||
* should be fetch: client, server, krbtgt.
|
||||
*/
|
||||
krb5_error_code (*hdb_fetch)(krb5_context, struct HDB*,
|
||||
krb5_const_principal, unsigned, unsigned,
|
||||
krb5_const_principal, unsigned,
|
||||
hdb_entry_ex*);
|
||||
/**
|
||||
* Fetch an entry from the backend
|
||||
*
|
||||
* Fetch an entry from the backend, flags are what type of entry
|
||||
* should be fetch: client, server, krbtgt.
|
||||
* knvo (if specified and flags HDB_F_KVNO_SPECIFIED set) is the kvno to get
|
||||
*/
|
||||
krb5_error_code (*hdb_fetch_kvno)(krb5_context, struct HDB*,
|
||||
krb5_const_principal, unsigned, unsigned,
|
||||
hdb_entry_ex*);
|
||||
/**
|
||||
* Store an entry to database
|
||||
*/
|
||||
|
@ -210,10 +210,18 @@ hdb_get_entry(krb5_context context,
|
||||
(*db->hdb_destroy)(context, db);
|
||||
goto out2;
|
||||
}
|
||||
ret = (*db->hdb_fetch)(context, db, principal,
|
||||
HDB_F_DECRYPT|
|
||||
HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
|
||||
0, &ent);
|
||||
|
||||
if (*db->hdb_fetch_kvno) {
|
||||
ret = (*db->hdb_fetch_kvno)(context, db, principal,
|
||||
HDB_F_DECRYPT|HDB_F_KVNO_SPECIFIED|
|
||||
HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
|
||||
kvno, &ent);
|
||||
} else {
|
||||
ret = (*db->hdb_fetch)(context, db, principal,
|
||||
HDB_F_DECRYPT|
|
||||
HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT,
|
||||
&ent);
|
||||
}
|
||||
|
||||
if(ret == HDB_ERR_NOENTRY) {
|
||||
ret = KRB5_KT_NOTFOUND;
|
||||
|
@ -659,7 +659,11 @@ rsa_create_signature(hx509_context context,
|
||||
else
|
||||
sig_oid = signer->signature_alg;
|
||||
|
||||
if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
|
||||
if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
|
||||
digest_alg = hx509_signature_sha512();
|
||||
} else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
|
||||
digest_alg = hx509_signature_sha384();
|
||||
} else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
|
||||
digest_alg = hx509_signature_sha256();
|
||||
} else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
|
||||
digest_alg = hx509_signature_sha1();
|
||||
@ -1241,6 +1245,32 @@ static const struct signature_alg pkcs1_rsa_sha1_alg = {
|
||||
rsa_create_signature
|
||||
};
|
||||
|
||||
static const struct signature_alg rsa_with_sha512_alg = {
|
||||
"rsa-with-sha512",
|
||||
ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
|
||||
&_hx509_signature_rsa_with_sha512_data,
|
||||
ASN1_OID_ID_PKCS1_RSAENCRYPTION,
|
||||
&_hx509_signature_sha512_data,
|
||||
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
|
||||
0,
|
||||
NULL,
|
||||
rsa_verify_signature,
|
||||
rsa_create_signature
|
||||
};
|
||||
|
||||
static const struct signature_alg rsa_with_sha384_alg = {
|
||||
"rsa-with-sha384",
|
||||
ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
|
||||
&_hx509_signature_rsa_with_sha384_data,
|
||||
ASN1_OID_ID_PKCS1_RSAENCRYPTION,
|
||||
&_hx509_signature_sha384_data,
|
||||
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
|
||||
0,
|
||||
NULL,
|
||||
rsa_verify_signature,
|
||||
rsa_create_signature
|
||||
};
|
||||
|
||||
static const struct signature_alg rsa_with_sha256_alg = {
|
||||
"rsa-with-sha256",
|
||||
ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
|
||||
@ -1306,6 +1336,32 @@ static const struct signature_alg dsa_sha1_alg = {
|
||||
/* create_signature */ NULL,
|
||||
};
|
||||
|
||||
static const struct signature_alg sha512_alg = {
|
||||
"sha-512",
|
||||
ASN1_OID_ID_SHA512,
|
||||
&_hx509_signature_sha512_data,
|
||||
NULL,
|
||||
NULL,
|
||||
SIG_DIGEST,
|
||||
0,
|
||||
EVP_sha512,
|
||||
evp_md_verify_signature,
|
||||
evp_md_create_signature
|
||||
};
|
||||
|
||||
static const struct signature_alg sha384_alg = {
|
||||
"sha-384",
|
||||
ASN1_OID_ID_SHA512,
|
||||
&_hx509_signature_sha384_data,
|
||||
NULL,
|
||||
NULL,
|
||||
SIG_DIGEST,
|
||||
0,
|
||||
EVP_sha384,
|
||||
evp_md_verify_signature,
|
||||
evp_md_create_signature
|
||||
};
|
||||
|
||||
static const struct signature_alg sha256_alg = {
|
||||
"sha-256",
|
||||
ASN1_OID_ID_SHA256,
|
||||
@ -1355,6 +1411,8 @@ static const struct signature_alg *sig_algs[] = {
|
||||
&ecdsa_with_sha256_alg,
|
||||
&ecdsa_with_sha1_alg,
|
||||
#endif
|
||||
&rsa_with_sha512_alg,
|
||||
&rsa_with_sha384_alg,
|
||||
&rsa_with_sha256_alg,
|
||||
&rsa_with_sha1_alg,
|
||||
&rsa_with_sha1_alg_secsig,
|
||||
@ -1362,6 +1420,8 @@ static const struct signature_alg *sig_algs[] = {
|
||||
&rsa_with_md5_alg,
|
||||
&heim_rsa_pkcs1_x509,
|
||||
&dsa_sha1_alg,
|
||||
&sha512_alg,
|
||||
&sha384_alg,
|
||||
&sha256_alg,
|
||||
&sha1_alg,
|
||||
&md5_alg,
|
||||
@ -2460,7 +2520,7 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
heim_octet_string **ciphertext)
|
||||
{
|
||||
EVP_CIPHER_CTX evp;
|
||||
size_t padsize;
|
||||
size_t padsize, bsize;
|
||||
int ret;
|
||||
|
||||
*ciphertext = NULL;
|
||||
@ -2488,14 +2548,16 @@ hx509_crypto_encrypt(hx509_crypto crypto,
|
||||
}
|
||||
|
||||
assert(crypto->flags & PADDING_FLAGS);
|
||||
|
||||
bsize = EVP_CIPHER_block_size(crypto->c);
|
||||
padsize = 0;
|
||||
|
||||
if (crypto->flags & PADDING_NONE) {
|
||||
padsize = 0;
|
||||
if (bsize != 1 && (length % bsize) != 0)
|
||||
return HX509_CMS_PADDING_ERROR;
|
||||
} else if (crypto->flags & PADDING_PKCS7) {
|
||||
if (EVP_CIPHER_block_size(crypto->c) == 1) {
|
||||
} else {
|
||||
int bsize = EVP_CIPHER_block_size(crypto->c);
|
||||
if (bsize != 1)
|
||||
padsize = bsize - (length % bsize);
|
||||
}
|
||||
}
|
||||
|
||||
(*ciphertext)->length = length + padsize;
|
||||
|
@ -104,6 +104,18 @@ init_context_from_config_file(krb5_context context)
|
||||
|
||||
INIT_FIELD(context, string, http_proxy, NULL, "http_proxy");
|
||||
|
||||
ret = krb5_config_get_bool_default(context, NULL, FALSE,
|
||||
"libdefaults",
|
||||
"allow_weak_crypto", NULL);
|
||||
if (ret) {
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_CRC);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_MD4);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_MD5);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_NONE);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CFB64_NONE);
|
||||
krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE);
|
||||
}
|
||||
|
||||
ret = set_etypes (context, "default_etypes", &tmptypes);
|
||||
if(ret)
|
||||
return ret;
|
||||
@ -194,18 +206,6 @@ init_context_from_config_file(krb5_context context)
|
||||
context->default_cc_name = NULL;
|
||||
context->default_cc_name_set = 0;
|
||||
|
||||
ret = krb5_config_get_bool_default(context, NULL, FALSE,
|
||||
"libdefaults",
|
||||
"allow_weak_crypto", NULL);
|
||||
if (ret) {
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_CRC);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_MD4);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_MD5);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CBC_NONE);
|
||||
krb5_enctype_enable(context, ETYPE_DES_CFB64_NONE);
|
||||
krb5_enctype_enable(context, ETYPE_DES_PCBC_NONE);
|
||||
}
|
||||
|
||||
s = krb5_config_get_strings(context, NULL, "logging", "krb5", NULL);
|
||||
if(s) {
|
||||
char **p;
|
||||
|
@ -1847,9 +1847,11 @@ verify_checksum(krb5_context context,
|
||||
}
|
||||
if(ct->checksumsize != cksum->checksum.length) {
|
||||
krb5_clear_error_message (context);
|
||||
krb5_set_error_message (context, KRB5KRB_AP_ERR_BAD_INTEGRITY,
|
||||
N_("Decrypt integrity check failed for checksum type %s, length was %u, expected %u", ""),
|
||||
ct->name, (unsigned)cksum->checksum.length, (unsigned)ct->checksumsize);
|
||||
krb5_set_error_message(context, KRB5KRB_AP_ERR_BAD_INTEGRITY,
|
||||
N_("Decrypt integrity check failed for checksum type %s, "
|
||||
"length was %u, expected %u", ""),
|
||||
ct->name, (unsigned)cksum->checksum.length,
|
||||
(unsigned)ct->checksumsize);
|
||||
|
||||
return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
|
||||
}
|
||||
@ -1857,18 +1859,18 @@ verify_checksum(krb5_context context,
|
||||
if(keyed_checksum) {
|
||||
struct checksum_type *kct;
|
||||
if (crypto == NULL) {
|
||||
krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
|
||||
N_("Checksum type %s is keyed but no "
|
||||
"crypto context (key) was passed in", ""),
|
||||
ct->name);
|
||||
krb5_set_error_message(context, KRB5_PROG_SUMTYPE_NOSUPP,
|
||||
N_("Checksum type %s is keyed but no "
|
||||
"crypto context (key) was passed in", ""),
|
||||
ct->name);
|
||||
return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
|
||||
}
|
||||
kct = crypto->et->keyed_checksum;
|
||||
if (kct != NULL && kct->type != ct->type) {
|
||||
krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP,
|
||||
N_("Checksum type %s is keyed, but "
|
||||
"the key type %s passed didnt have that checksum "
|
||||
"type as the keyed type", ""),
|
||||
krb5_set_error_message(context, KRB5_PROG_SUMTYPE_NOSUPP,
|
||||
N_("Checksum type %s is keyed, but "
|
||||
"the key type %s passed didnt have that checksum "
|
||||
"type as the keyed type", ""),
|
||||
ct->name, crypto->et->name);
|
||||
return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */
|
||||
}
|
||||
@ -1878,13 +1880,20 @@ verify_checksum(krb5_context context,
|
||||
return ret;
|
||||
} else
|
||||
dkey = NULL;
|
||||
|
||||
/*
|
||||
* If checksum have a verify function, lets use that instead of
|
||||
* calling ->checksum and then compare result.
|
||||
*/
|
||||
|
||||
if(ct->verify) {
|
||||
ret = (*ct->verify)(context, dkey, data, len, usage, cksum);
|
||||
if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
|
||||
krb5_set_error_message (context, KRB5KRB_AP_ERR_BAD_INTEGRITY,
|
||||
N_("Decrypt integrity check failed for checksum type %s, key type %s", ""),
|
||||
ct->name, crypto->et->name);
|
||||
}
|
||||
if (ret)
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Decrypt integrity check failed for checksum "
|
||||
"type %s, key type %s", ""),
|
||||
ct->name, crypto->et->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = krb5_data_alloc (&c.checksum, ct->checksumsize);
|
||||
@ -1900,10 +1909,11 @@ verify_checksum(krb5_context context,
|
||||
if(c.checksum.length != cksum->checksum.length ||
|
||||
ct_memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
|
||||
krb5_clear_error_message (context);
|
||||
krb5_set_error_message (context, KRB5KRB_AP_ERR_BAD_INTEGRITY,
|
||||
N_("Decrypt integrity check failed for checksum type %s, key type %s", ""),
|
||||
ct->name, crypto->et->name);
|
||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Decrypt integrity check failed for checksum "
|
||||
"type %s, key type %s", ""),
|
||||
ct->name, crypto->et->name);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -1418,6 +1418,17 @@ krb5_init_creds_set_service(krb5_context context,
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for Windows RODC that are picky about what name type
|
||||
* the server principal have, and the really strange part is that
|
||||
* they are picky about the AS-REQ name type and not the TGS-REQ
|
||||
* later. Oh well.
|
||||
*/
|
||||
|
||||
if (krb5_principal_is_krbtgt(context, principal))
|
||||
krb5_principal_set_type(context, principal, KRB5_NT_SRV_INST);
|
||||
|
||||
krb5_free_principal(context, ctx->cred.server);
|
||||
ctx->cred.server = principal;
|
||||
|
||||
|
@ -356,61 +356,66 @@ make_hints(struct addrinfo *hints, int proto)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return an `struct addrinfo *' in `ai' corresponding to the information
|
||||
* in `host'. free:ing is handled by krb5_krbhst_free.
|
||||
/**
|
||||
* Return an `struct addrinfo *' for a KDC host.
|
||||
*
|
||||
* Returns an the struct addrinfo in in that corresponds to the
|
||||
* information in `host'. free:ing is handled by krb5_krbhst_free, so
|
||||
* the returned ai must not be released.
|
||||
*
|
||||
* @ingroup krb5
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
|
||||
struct addrinfo **ai)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
char portstr[NI_MAXSERV];
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (host->ai == NULL) {
|
||||
make_hints(&hints, host->proto);
|
||||
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
|
||||
struct addrinfo hints;
|
||||
char portstr[NI_MAXSERV];
|
||||
char *hostname = host->hostname;
|
||||
|
||||
snprintf (portstr, sizeof(portstr), "%d", host->port);
|
||||
make_hints(&hints, host->proto);
|
||||
|
||||
/**
|
||||
* First try this as an IP address, this allows us to add a
|
||||
* dot at the end to stop using the search domains.
|
||||
*/
|
||||
|
||||
hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
|
||||
|
||||
/* First try this as an IP address - the flags we have set
|
||||
* will prevent it from looking up a name */
|
||||
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
|
||||
if (ret == 0) {
|
||||
*ai = host->ai;
|
||||
return 0;
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
|
||||
/**
|
||||
* If the hostname contains a dot, assumes it's a FQDN and
|
||||
* don't use search domains since that might be painfully slow
|
||||
* when machine is disconnected from that network.
|
||||
*/
|
||||
|
||||
hints.ai_flags &= ~(AI_NUMERICHOST);
|
||||
|
||||
if (strchr(hostname, '.') && hostname[strlen(hostname) - 1] != '.') {
|
||||
ret = asprintf(&hostname, "%s.", host->hostname);
|
||||
if (ret < 0 || hostname == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
hints.ai_flags &= ~AI_NUMERICHOST;
|
||||
|
||||
/* Now that we know it's not an IP, we can manipulate
|
||||
it as a dotted-name, to add a final . if we think
|
||||
it's a fully qualified DNS name */
|
||||
if (strchr(host->hostname, '.') &&
|
||||
host->hostname[strlen(host->hostname)-1] != '.') {
|
||||
char *hostname_dot = NULL;
|
||||
|
||||
/* avoid expansion of search domains from resolv.conf
|
||||
- these can be very slow if the DNS server is not up
|
||||
for the searched domain */
|
||||
hostname_dot = malloc(strlen(host->hostname)+2);
|
||||
if (hostname_dot) {
|
||||
strcpy(hostname_dot, host->hostname);
|
||||
hostname_dot[strlen(host->hostname)] = '.';
|
||||
hostname_dot[strlen(host->hostname)+1] = 0;
|
||||
}
|
||||
ret = getaddrinfo(hostname_dot?hostname_dot:host->hostname, portstr, &hints, &host->ai);
|
||||
if (hostname_dot)
|
||||
free(hostname_dot);
|
||||
} else {
|
||||
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
|
||||
ret = getaddrinfo(hostname, portstr, &hints, &host->ai);
|
||||
if (hostname != host->hostname)
|
||||
free(hostname);
|
||||
if (ret) {
|
||||
ret = krb5_eai_to_heim_errno(ret, errno);
|
||||
goto out;
|
||||
}
|
||||
if (ret)
|
||||
return krb5_eai_to_heim_errno(ret, errno);
|
||||
}
|
||||
out:
|
||||
*ai = host->ai;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static krb5_boolean
|
||||
|
@ -1072,7 +1072,7 @@ void
|
||||
rk_qsort(void *, size_t, size_t, int (*)(const void *, const void *));
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(SOCK_CLOEXEC) && !defined(SOCKET_WRAPPER_REPLACE)
|
||||
#if defined(__linux__) && defined(SOCK_CLOEXEC) && !defined(SOCKET_WRAPPER_REPLACE) && !defined(__SOCKET_WRAPPER_H__)
|
||||
#undef socket
|
||||
#define socket(_fam,_type,_prot) rk_socket(_fam,_type,_prot)
|
||||
int ROKEN_LIB_FUNCTION rk_socket(int, int, int);
|
||||
|
Loading…
x
Reference in New Issue
Block a user