s4:heimdal: import lorikeet-heimdal-201010022046 (commit 1bea031b9404b14114b0272ecbe5...
authorAndrew Bartlett <abartlet@samba.org>
Sat, 2 Oct 2010 06:32:56 +0000 (16:32 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 3 Oct 2010 01:15:04 +0000 (01:15 +0000)
24 files changed:
source4/heimdal/cf/make-proto.pl
source4/heimdal/kdc/digest.c
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c
source4/heimdal/kdc/misc.c
source4/heimdal/lib/asn1/der_locl.h
source4/heimdal/lib/asn1/der_put.c
source4/heimdal/lib/asn1/timegm.c
source4/heimdal/lib/hcrypto/evp-hcrypto.c
source4/heimdal/lib/hcrypto/evp-hcrypto.h
source4/heimdal/lib/hcrypto/evp.c
source4/heimdal/lib/hcrypto/evp.h
source4/heimdal/lib/hcrypto/hash.h
source4/heimdal/lib/hcrypto/rsa-ltm.c
source4/heimdal/lib/hcrypto/sha.h
source4/heimdal/lib/hdb/hdb-keytab.c
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hdb/keytab.c
source4/heimdal/lib/hx509/crypto.c
source4/heimdal/lib/krb5/context.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/krbhst.c
source4/heimdal/lib/roken/roken.h.in

index 12c6d07f5e524e93e1d61abdd6bc737706845401..566534f2471ad10bd45b608d43809ed6b3b7f5bc 100644 (file)
@@ -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;
index 1a383fa205c8068ddad2bab0ae9420693c57c99d..70b45c2af6fb7b7b1db4e0de075e4c055aa72454 100644 (file)
@@ -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",
index 9fb0998a2aae523346066373197e090d2681d20f..40e597befb51d910ee028058ec677e28451c70be 100644 (file)
@@ -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);
index 23f9674bef21a69cf3810e4a6f25cb6eb5a37f7e..71d99e2bee0dd0afdcfaa9d74bdf46b5ea2fe7d9 100644 (file)
@@ -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;
 
index 3080748463887e5c41bfba24cc7d03aa8d725c51..9feb99cdbc0967818edecace6ff2e182f82ad8cc 100644 (file)
@@ -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]);
index 0f65c50a2234449227e7d1551ab7df4a09575049..a086e18fa4a4ff9572eb912c7339959106739bfd 100644 (file)
@@ -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);
 
index c8192f25fe5ca1e5b87f183bf87ef0f2f3ee9f72..b8101458ad4be9866f3e43dd9e4c08606855a67d 100644 (file)
@@ -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;
 }
index 83f0e33fb8fb1a80603a52e1ff9dfa4af7a2be7e..b5694784138ce12b76833c5d6a069d47d1cfde6a 100644 (file)
@@ -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;
 }
index 9e063545e168342462156568b95de987be53e3ba..bf37b42edcaca83b52d4a64859e71c690053a30e 100644 (file)
@@ -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
  *
index 7915046bdcea12852c8fc67585e20f79cf225055..b7876c67c8a3b1e808b2ca9c8383edbcb7b3d80a 100644 (file)
@@ -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);
index da1a8940be865962f20a75b18832c436d9d932c0..7bd066fd5dccb8e446c22e6b404aa67a5a55166a 100644 (file)
@@ -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
  *
index 03ec175d5976784eaa7774d76bf9b5d8b221f308..c56eedec45b29956a679e81f54e0bcc863437658 100644 (file)
@@ -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);
index cfec9cf3f34deffa27b6282c3386376a0b4d145e..498e5b1af01ccbff67f138f63604950954c0a11f 100644 (file)
@@ -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__ */
index ad3686e403ce00e530b6d6b2634d9ff5bdd99ccb..f4828104b651c1af9742d291b2ae9a0ab94949c5 100644 (file)
@@ -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;
 }
index 39e33cf8d0ade341778f9f42b677381e821d47a6..a1f5a993189ce98ae69af077695dfe8b96dcdf50 100644 (file)
@@ -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 */
index 1b74eab252947af3baf60edcabc012ce5586a5d8..393981e47d845d079b74123490171f14f4573d62 100644 (file)
@@ -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;
index ca67d2ddd838f71a4597505562758ae620a14d5e..bcd190caa3162e13aff23b511347e8585eb66405 100644 (file)
@@ -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
      */
index efaed7f420fba65549c0d888ca27430667486735..b8cc0d47ee85ba7536688c315fddc3b336cb6b3c 100644 (file)
@@ -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;
index c2e5e70748f98fd0f441200c1b7f046418b93f4c..de7717af0297debc1ed350136004389c1f1c8c15 100644 (file)
@@ -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;
index 0897c5e7a09640fd376cdc14fe33855ee4edca53..f68ab46cec9cf3c84aa147b904a3eb4ee730debc 100644 (file)
@@ -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;
index 47f910260e36a0f734cd5268a63db1b1e7e5ac2b..2502cc672f50774160e21d9a92d2b579b52de145 100644 (file)
@@ -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;
     }
index 869687aa63b5a6e40d77103fcdb4bfc2ee82beb0..29b882d053117c878022ab4af49669a5915c3778 100644 (file)
@@ -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;
 
index d8646f0537a8faa6194547ffbc2b3d1e920c31c8..7d111578481b10a6cc50a05fc82748b6a2684542 100644 (file)
@@ -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
index d6e9024bd08d16e1206d5f5eb2b54f083dfd267f..0c0dd20035028a8fc018e64435c1e20bb1e7efe0 100644 (file)
@@ -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);