summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib')
-rw-r--r--source4/heimdal/lib/asn1/der_locl.h1
-rw-r--r--source4/heimdal/lib/asn1/der_put.c12
-rw-r--r--source4/heimdal/lib/asn1/timegm.c62
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.c46
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.h4
-rw-r--r--source4/heimdal/lib/hcrypto/evp.c30
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h4
-rw-r--r--source4/heimdal/lib/hcrypto/hash.h6
-rw-r--r--source4/heimdal/lib/hcrypto/rsa-ltm.c13
-rw-r--r--source4/heimdal/lib/hcrypto/sha.h26
-rw-r--r--source4/heimdal/lib/hdb/hdb-keytab.c19
-rw-r--r--source4/heimdal/lib/hdb/hdb.h12
-rw-r--r--source4/heimdal/lib/hdb/keytab.c16
-rw-r--r--source4/heimdal/lib/hx509/crypto.c76
-rw-r--r--source4/heimdal/lib/krb5/context.c24
-rw-r--r--source4/heimdal/lib/krb5/crypto.c48
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c11
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c83
-rw-r--r--source4/heimdal/lib/roken/roken.h.in2
19 files changed, 389 insertions, 106 deletions
diff --git a/source4/heimdal/lib/asn1/der_locl.h b/source4/heimdal/lib/asn1/der_locl.h
index 0f65c50a22..a086e18fa4 100644
--- a/source4/heimdal/lib/asn1/der_locl.h
+++ b/source4/heimdal/lib/asn1/der_locl.h
@@ -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);
diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c
index c8192f25fe..b8101458ad 100644
--- a/source4/heimdal/lib/asn1/der_put.c
+++ b/source4/heimdal/lib/asn1/der_put.c
@@ -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;
}
diff --git a/source4/heimdal/lib/asn1/timegm.c b/source4/heimdal/lib/asn1/timegm.c
index 83f0e33fb8..b569478413 100644
--- a/source4/heimdal/lib/asn1/timegm.c
+++ b/source4/heimdal/lib/asn1/timegm.c
@@ -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;
}
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.c b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
index 9e063545e1..bf37b42edc 100644
--- a/source4/heimdal/lib/hcrypto/evp-hcrypto.c
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
@@ -290,6 +290,52 @@ EVP_hcrypto_sha256(void)
}
/**
+ * 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
*
* @return the message digest type.
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.h b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
index 7915046bdc..b7876c67c8 100644
--- a/source4/heimdal/lib/hcrypto/evp-hcrypto.h
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
@@ -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);
diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c
index da1a8940be..7bd066fd5d 100644
--- a/source4/heimdal/lib/hcrypto/evp.c
+++ b/source4/heimdal/lib/hcrypto/evp.c
@@ -361,6 +361,36 @@ EVP_sha256(void)
}
/**
+ * 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
*
* @return the message digest type.
diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h
index 03ec175d59..c56eedec45 100644
--- a/source4/heimdal/lib/hcrypto/evp.h
+++ b/source4/heimdal/lib/hcrypto/evp.h
@@ -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);
diff --git a/source4/heimdal/lib/hcrypto/hash.h b/source4/heimdal/lib/hcrypto/hash.h
index cfec9cf3f3..498e5b1af0 100644
--- a/source4/heimdal/lib/hcrypto/hash.h
+++ b/source4/heimdal/lib/hcrypto/hash.h
@@ -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__ */
diff --git a/source4/heimdal/lib/hcrypto/rsa-ltm.c b/source4/heimdal/lib/hcrypto/rsa-ltm.c
index ad3686e403..f4828104b6 100644
--- a/source4/heimdal/lib/hcrypto/rsa-ltm.c
+++ b/source4/heimdal/lib/hcrypto/rsa-ltm.c
@@ -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;
}
diff --git a/source4/heimdal/lib/hcrypto/sha.h b/source4/heimdal/lib/hcrypto/sha.h
index 39e33cf8d0..a1f5a99318 100644
--- a/source4/heimdal/lib/hcrypto/sha.h
+++ b/source4/heimdal/lib/hcrypto/sha.h
@@ -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 */
diff --git a/source4/heimdal/lib/hdb/hdb-keytab.c b/source4/heimdal/lib/hdb/hdb-keytab.c
index 1b74eab252..393981e47d 100644
--- a/source4/heimdal/lib/hdb/hdb-keytab.c
+++ b/source4/heimdal/lib/hdb/hdb-keytab.c
@@ -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;
@@ -166,6 +171,13 @@ hkt_fetch(krb5_context context, HDB * db, krb5_const_principal principal,
}
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;
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index ca67d2ddd8..bcd190caa3 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -123,9 +123,19 @@ 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
*/
krb5_error_code (*hdb_store)(krb5_context, struct HDB*,
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index efaed7f420..b8cc0d47ee 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -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;
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index c2e5e70748..de7717af02 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c
index 0897c5e7a0..f68ab46cec 100644
--- a/source4/heimdal/lib/krb5/context.c
+++ b/source4/heimdal/lib/krb5/context.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 47f910260e..2502cc672f 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -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;
}
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 869687aa63..29b882d053 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -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;
diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c
index d8646f0537..7d11157848 100644
--- a/source4/heimdal/lib/krb5/krbhst.c
+++ b/source4/heimdal/lib/krb5/krbhst.c
@@ -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
diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in
index d6e9024bd0..0c0dd20035 100644
--- a/source4/heimdal/lib/roken/roken.h.in
+++ b/source4/heimdal/lib/roken/roken.h.in
@@ -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);